使用Let's Encrypt 给网站加 HTTPS

2017.03.27更新:/usr/bin/letsencrypt/usr/bin/certbot 替代,更新文章中所用到的命令。参考:Archlinux Let's Encrypt Wiki

Let's Encrypt 证书生成不需要手动进行,官方推荐 certbot 这套自动化工具来实现。3步轻松搞定:

  1. 下载安装 certbot (Let’s Encrypt项目的自动化工具)
  2. 创建配置文件
  3. 执行证书自动化生成命令

环境:
centos7 64位
nginx

一、安装certbot

$yum -y install certbot

#检查安装是否成功

$certbot --help

二、生成域名证书

这里使用的域名为 blog.haohtml.com, 网站根目录为 /data/wwwroot/haohtml/blog

#为一个已经存在的站点生成证书文件,一个证书可以多个域名共用,一次也可以生成多个域名谈证书(内容放在了同一个文件里),命令格式如下:
$certbot certonly --webroot -w /data/wwwroot/haohtml/htdocs -d www.example.com -d example.com -w /var/www/other -d other.example.net -d another.other.example.net

在终端里执行命令

$certbot certonly --webroot -w /data/wwwroot/haohtml/blog/ -d blog.haohtml.com

会看到以下输出信息:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for blog.haohtml.com
Using the webroot path /data/wwwroot/haohtml/blog for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/blog.haohtml.com/fullchain.pem. Your cert
will expire on 2017-09-18. To obtain a new or tweaked version of
this certificate in the future, simply run certbot again. To
non-interactively renew *all* of your certificates, run "certbot
renew"
- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

表示生成证书成功,证书目录为/etc/letsencrypt/live/blog.haohtml.com/,我们看以下此目录都有哪些文件

$ls -al /etc/letsencrypt/live/blog.haohtml.com/

cert.pem chain.pem fullchain.pem privkey.pem README
其中前四个文件均为连接文件

下面我们添加一个启用https的虚拟主机配置文件,内容如下

三、配置虚拟主机
添加一个blog.conf文件(nginx会加载指定目录下的所有,conf文件),内容如下(wordpress)

server {
    listen 443;
    server_name blog.haohtml.com;
    root /data/wwwroot/haohtml/blog;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/blog.haohtml.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/blog.haohtml.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/blog.haohtml.com/chain.pem;

    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_prefer_server_ciphers on;
    add_header Strict-Transport-Security max-age=15768000;
    ssl_stapling on;
    ssl_stapling_verify on;


    location / {
            index index.html index.php index.htm index.shtml;
    }


    rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.xml$ "/index.php?xml_sitemap=params=$2" last;
    rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.xml\.gz$ "/index.php?xml_sitemap=params=$2;zip=true" last;
    rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.html$ "/index.php?xml_sitemap=params=$2;html=true" last;
    rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.html.gz$ "/index.php?xml_sitemap=params=$2;html=true;zip=true" last;

    if (-f $request_filename/index.html){
        rewrite (.*) $1/index.html break;
    }
    if (-f $request_filename/index.php){
                rewrite (.*) $1/index.php;
    }
    if (!-f $request_filename){
                rewrite (.*) /index.php;
    }

    location ^~ /.well-known {
        allow all;
        alias /data/wwwroot/haohtml/blog/.well-known/;
        default_type "text/plain";
        try_files $uri =404;
    }

    location ~* ^/(data|images|data|uploads)/.*\.(php|php5)$
    {
            deny all;
    }

    location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /data/wwwroot/haohtml/blog$fastcgi_script_name;
            include        fastcgi_params;
    }

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
    {
            expires      30d;
    }

    access_log /var/log/httpd/blog/access.log;
    error_log  /var/log/httpd/blog/error.log;
}

四、重启Nginx,测试https是否生效

测试一下nginx配置文件是否存在错误

$/usr/local/nginx/sbin/nginx -t

the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
configuration file /usr/local/nginx/conf/nginx.conf test is successful

$/usr/local/nginx/sbin/nginx -s reload

此时,打开域名 https://xxxxx 应该可以看到效果了

五、定时更新证书

由于 [Let’s Encrypt] 的证书目前有效期为3个月,过期后可以免费重新生成证书,可视为免费证书,只需要添加一个crond脚本即可.(好像每天生成证书有次数限制,一般也用不着如此频繁的操作)

将下行添加到 /etc/crontab文件里,并设定每三个月自动更新一次(脚本不确定是否正确)或者按月份写几个,每三个月为一个周期。

0 0 1 */2 * certbot renew

六、后期优化

由于我们以前网使用的是http访问,现在想平滑过度到https,而还要考虑到seo效果,如需要当用户访问http网站时让其自动转到https网站相对应的网址即可,nginx的配置如下:

server {
listen 80;
server_name www.abc.cn;
rewrite ^(.*) https://$server_name$1 permanent;
}

.用专业在线工具测试你的服务器 SSL 安全性
Qualys SSL Labs 提供了全面的 SSL 安全性测试,填写你的网站域名,给自己的 HTTPS 配置打个分。

参考:https://ksmx.me/letsencrypt-ssl-https/

Switch to HTTPS Now, For Free

From now on, you should see a delightful lock  next to https://konklone.com in your browser’s URL bar, because I’ve switched this site to use HTTPS. I paid $0 for the trouble.Why you should bother doing the same:

This post shows how to do your part in building a surveillance-resistant Internet by switching your site to HTTPS. Though it takes a bunch of steps, each one is very simple, and you should be able to finish this in under an hour.
Continue reading

Windows下apache 实现 SSL

SSL:安全套接层,是netscape公司设计的主要用于web的安全传输协议。这种协议在WEB上获得了广泛的应用。通过证书认证来确保客户端和网站服务器之间的数据是安全,过程大致如下:

SSL客户端在TCP连接建立之后,发出一个消息给服务器,这个消息里面包含了自己可实现的算法列表和其它一些需要的消息,SSL的服务器端会回应一个数据包,这里面确定了这次通信所需要的算法,然后发过去自己的证书(里面包含了身份和自己的公钥)。Client在收到这个消息后会生成一个秘密消息,用SSL服务器的公钥加密后传过去,SSL服务器端用自己的私钥解密后,会话密钥协商成功,双方可以用同一份会话密钥来通信了。

如果对于一般的应用,管理员只需生成“证书请求”(后缀大多为.csr),它包含你的名字和公钥,然后把这份请求交给诸如verisign等有CA服务公司,你的证书请求经验证后,CA用它的私钥签名,形成正式的证书发还给你。管理员再在web server上导入这个证书就行了。如果你不想花那笔钱,或者想了解一下原理,可以自己做CA。从ca的角度讲,你需要CA的私钥和公钥。从想要证书的服 务器角度将,需要把服务器的证书请求交给CA. Continue reading

SSL session resumption原理

很多人熟悉HTTPS,却不知道SSL。HTTPS正是通过SSL和 HTTP的组合来提供加密通讯以及对网络服务器身份的鉴别。SSL全称为 Secure Socket Layer,是一种在两台机器之间提供安全通道的协议。它具有保护传输数据以及识别通信机器的功能。客户与服务器之间的数据是经过加密的。SSL 假定其下层的数据包发送机制是可靠的。写入网络的数据将依顺序发送给另一端的程序,不会出现丢包或重传情况。依赖于可靠传输协议发送数据的特点使得SSL 只能在TCP 上工作,不能在UDP 或直接在IP 上运行。SSL 开始就是为Web 设计的,所以SSL可以很好地服务HTTP。SSL在协议栈中的位置如图1所示。

图1 SSL在协议栈中的位置

SSL 的连接分为两个阶段,即握手和数据传输阶段。握手阶段对服务器进行认证并确立用于保护数据传输的加密密钥。必须在传输任何应用数据之前完成握手。一旦握手完成,数据就被分成一系列经过保护的记录进行传输。 Continue reading

apache2整合weblogic虚拟主机下的ssl配置

apache2整合weblogic 虚拟主机下的ssl配置修订版

修订的部分:

    1. soloris系统上默认的openssl不在PATH变量里面,所以修订文档中执行openssl之前都把找到openssl的执行路径加上了。

    2. 增加了solaris系统启用ssl的两个常见错误的解决方法。

  apache2整合weblogic 虚拟主机下的ssl配置

分四部分

     1。应用目标和环境
     2。apache2 weblogic openssl安装
     3。虚拟主机的配置
     4。补遗或注解

一. 应用目标和环境

    应用目标
    1。jsp支持的webserver,只有一个ip,多个虚拟主机,其中有一个支持ssl的虚拟主机。
   
    应用环境
   
    1. os 为 solaris 9 和建议补丁
    2. weblogic为8.1sp4 ,java为 1.4.1_06-b01
    3. OpenSSL 0.9.7g
    4. apache 2.0.54
       
二. apache2 weblogic openssl安装

    1. apache 2.0.54的安装
   
       略
    2. weblogic 8.1 sp4的安装
   
       略
    3. openssl的安装
   
       略
      
三. 虚拟主机的配置

    1. 需要配置的虚拟主机
   
       www       网站
       bbs       论坛
       diy       后台及个人管理维护平台
       ssl       提供https传输的虚拟主机
       sso       单点登陆
       cis       卡拉蜂接口
      
    2. 虚拟主机使用的ip
      
       192.168.1.254
   
    3. httpd.conf中的相关配置     
    
    
       ......
       ServerName www.colorme.com.cn
       ServerRoot "/usr/local/apache2"
       Listen 80
       <IfDefine SSL>
       LoadModule ssl_module modules/mod_ssl.so
       </IfDefine>
       # support weblogic
       LoadModule weblogic_module modules/mod_wl_20.so
       #
       # load ssl.conf
       <IfModule mod_ssl.c>
       Include conf/ssl.conf
       </IfModule>
       #
       # load VirtualHost
       Include "conf/vhost.conf"
       #
       ......
      
    4. ssl.conf配置
   
       SSLRandomSeed startup builtin
       SSLRandomSeed connect builtin
       <IfDefine SSL>
       #
       Listen 443
       #
       AddType application/x-x509-ca-cert .crt
       AddType application/x-pkcs7-crl    .crl
       #
       SSLPassPhraseDialog  builtin
       #
       SSLMutex default
       </IfDefine>
      
    5. vhost.conf配置
    #    
    NameVirtualHost 192.168.1.254:80
    #
    # Section 1: http virtualhost

        <VirtualHost 192.168.1.254:80>
        ServerAdmin webmaster@colorme.com
        DocumentRoot "/web/webapp"
        ServerName  www.colorme.com
        ErrorLog logs/colorme-error_log
        AddType application/x-httpd-php .php
        AddType text/html .shtml
        CustomLog logs/colorme-access_log combined
        TransferLog logs/colorme-access_log
        <IfModule mod_weblogic.c>
           WebLogicHost 192.168.1.254
           WebLogicPort 7001
           MatchExpression *.jsp
           MatchExpression *.do
           MatchExpression *.jspa
           MatchExpression /myhome/*
        </IfModule>
        <Directory "/web/webapp">
             #php_flag engine on
             Options FollowSymLinks MultiViews Includes
             AddOutputFilter Includes  .shtml
             AddOutputFilter Includes  .php
             AllowOverride None
             Allow from all
        </Directory>
        <Directory "/web/webapp/WEB-INF">
             Order deny,allow
             Deny from all
        </Directory>
        </VirtualHost>

        <VirtualHost 192.168.1.254:80>
        ServerAdmin webmaster@colorme.com
        DocumentRoot "/web/bbs"
        ServerName  bbs.colorme.com
        LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
        CustomLog logs/bbs-access_log combined
        ServerName  bbs.colorme.com
        ServerAlias diy
        ErrorLog logs/bbs-error_log
        TransferLog logs/bbs-access_log
         <IfModule mod_weblogic.c>
           WebLogicHost 192.168.1.254
           WebLogicPort 7001
           MatchExpression *.jsp
           MatchExpression *.jspa
           MatchExpression *.do
        </IfModule>
        <Directory "/web/bbs">
             Options FollowSymLinks MultiViews Includes
             AddOutputFilter Includes html
       
             AllowOverride None
             Allow from all
        </Directory>
        <Directory "/web/bbs/WEB-INF">
             Order deny,allow
             Deny from all
        </Directory>
        </VirtualHost>

        <VirtualHost 192.168.1.254:80>
        ServerAdmin webmaster@colorme.com
        DocumentRoot "/web/diy"
        ServerName  diy.colorme.com
        ErrorLog logs/diy-error_log
        TransferLog logs/diy-access_log
         <IfModule mod_weblogic.c>
           WebLogicHost 192.168.1.254
           WebLogicPort 7001
           MatchExpression *.jsp
           MatchExpression *.jspa
           MatchExpression *.do
        </IfModule>
        <Directory "/web/diy">
             Options FollowSymLinks MultiViews Includes
             AddOutputFilter Includes html
 
             AllowOverride None
             Allow from all
        </Directory>
        <Directory "/web/diy/WEB-INF">
             Order deny,allow
             Deny from all
        </Directory>
        </VirtualHost>

        # Section 2: https VirtualHost

        <VirtualHost 192.168.1.254:443>
   ServerName ssl.colorme.com
   DocumentRoot "/web/ssl"
   CustomLog logs/ssl-access_log  common
   SSLEngine on
   SSLCipherSuite ALL:!ADH:!   EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
   SSLCertificateFile conf/ssl.crt/server.crt
   SSLCertificateKeyFile conf/ssl.key/server.key
   <Files ~ ".(cgi|shtml|phtml|php3?)$">
       SSLOptions +StdEnvVars
   </Files>
   <Directory "/web/ssl">
       SSLOptions +StdEnvVars
   </Directory>
   SetEnvIf User-Agent ".*MSIE.*"
            nokeepalive ssl-unclean-shutdown
            downgrade-1.0 force-response-1.0
        <IfModule mod_weblogic.c>
           WebLogicHost 192.168.1.254
           WebLogicPort 7001
           MatchExpression *.jsp
           MatchExpression *.do
           MatchExpression *.jspa
           MatchExpression /myhome/*
        </IfModule>
        <Directory "/web/ssl">
             Options FollowSymLinks MultiViews Includes
             AddOutputFilter Includes  .shtml
             AddOutputFilter Includes  .php
             AllowOverride None
             Allow from all
        </Directory>
        <Directory "/web/webapp/WEB-INF">
             Order deny,allow
             Deny from all
        </Directory>
        </VirtualHost>

    6. 相关条目的说明
   
        6.1 SSLEngine on 
            在虚拟主机中打开ssl支持,默认主服务主机和虚拟主机是禁用的。
        6.2 SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
            ssl协议握手协商时使用的密码簇,支持所有握手密码
        6.3 SSLCertificateFile conf/ssl.crt/server.crt
            服务器端PEM-encoded X.509认证文件
        6.4 SSLCertificateKeyFile conf/ssl.key/server.key
            服务器端PEM-encoded私匙文件
        6.5 SSLOptions +StdEnvVars
            配置各种运行时的SSL引擎选项, +StdEnvVars创建SSL与CGI&SSI相关的变量,仅用在CGI和SSI的页面中。
       
四. 补遗或注解

    1. 认证文件的认证方式
   
       本例中采用的自认证的方式,就是说没有去购买证书,如果是商业站点可以考虑购买证书。
      
    2. 自认证文件的生成
   
        a. 生成private Key文件
       
           # LD_LIBRARY_PATH=/usr/openwin/lib:/usr/local/ssl/lib;export LD_LIBRARY_PATH
           # PATH=$PATH:/usr/local/ssl/bin; export PATH     
           # LD_LIBRARY_PATH=/usr/openwin/lib:/usr/local/ssl/lib;export LD_LIBRARY_PATH
           # /usr/local/ssl/bin/openssl genrsa -des3 -out server.key 1024 
           openssl genrsa -des3 -out server.key 1024   
        b. 创建服务器端的认证文件
           openssl req -new -x509 -nodes -sha1 -days 365 -key server.key -out server.crt
           在提示输入common name的时候输入域名:www.colorme.com
        c. 按照vhost.conf中的配置,存放b步骤中创建的文件
           存放位置
           conf/ssl.key/server.key
           conf/ssl.crt/server.crt
     3. apache的启动和关闭方式(SSL)
    
        3.1 启动
       
            ./apachectl startssl
            会提示输入创建server.key时的密码,输入正确才能启动
           
        3.2 关闭
       
            ./apachectl stop
           
        3.3 为了测试方便可以关闭启动时输入密码
       
            a. 修改vhost.conf
           
               #SSLCertificateKeyFile conf/ssl.key/server.key
               SSLCertificateKeyFile conf/ssl.key/server.key.unsecure
              
            b. server.key.unsecure的生成
           
               openssl rsa -in server.key -out server.key.unsecure

    4. SSL类型的虚拟主机只用用于基于ip的虚拟主机
   
    5. 基于测试,hosts文件的修改
   
       192.168.1.254     www.colorme.com
       192.168.1.254     ssl.colorme.com
   
    6. 基于正式站点
   
       相应的二级域名必须有Cname  
      
       file vhost.c, line 190, assertion "rv == APR_SUCCESS" failed
      
    7. bug
   
       7.1 死锁bug的解决方法
      
       故障现象如下:
       [warn] (45)Deadlock situation detected/avoided: ap_proxy: couldn't create the lock
      
       在ssl.conf增加下面的配置可以解决
      
       AcceptMutex pthread
       SSLMutex sem
      
       7.2 bug 27525
       故障现象:
       bash-2.05# ../bin/apachectl startssl
[Sun Nov 20 14:52:44 2005] [crit] [Sun Nov 20 14:52:44 2005] file vhost.c, line 190, assertion "rv == APR_SUCCESS" failed
      解决方法1:
    
      Essentially the same problem as bug 27525 -- edit /etc/nsswitch.conf and add
"dns" to the end of the hosts: line to fix it.
      解决方法2:
      删除ssl.conf中的默认的ssl虚拟主机
       Bug 37488 has been added to the database