服务器 ssl 配置

— By BingqiChen

emmmm...搁置了这么久,终于把自己的网站搭起来了,然后还挺想要浏览器上的的小绿条的,就开始有上https的打算了。

获取证书

证书有免费和付费的,广为流传的免费的就有Let's Encrypt,国内也有很多推出了合作的免费证书,像又拍云和七牛也有免费的开放申请,大都是单域名的。

由于我需要同时支持多个二级域名,我就在cheapsslsecurity购买了 comodo 家多域名证书。 price

包含不带www的主域名和两个子域名,23刀,再另加一个子域名,总共32刀,能接受,下单了,可以使用 PayPal 支付,支付成功之后会让填写个人信息。

然后就可以下一步了,(忘了截图…只能徒手画了)。

证书信息

大概长这样,填写域名,选择域名验证方式,我一般选择 CNAME 验证,去域名控制台设置一下解析就可以通过验证了。

下面是一块填写.scr文件内容的区域,这个文件需要到服务器生成:

$ openssl req -new -newkey rsa:2048 -sha256 -nodes -out example.com.csr -keyout example.com.key -subj "/C=CN/ST=ZheJiang/L=HangZhou/O=Example Inc./OU=Web Security/CN=example.com"

# C:Country,单位所在国家,为两位数的国家缩写,如:CN 就是中国
# ST:State/Province,单位所在州或省
# L:Locality,单位所在城市/或县区
# O:Organization,此网站的单位名称
# OU:Organization Unit,下属部门名称;也常常用于显示其他证书相关信息,如证书类型,证书产品名称或身份验证类型或验证内容等
# CN:Common Name,网站的域名

运行后会得到两个文件,example.com.csrexample.com.key,把example.com.csr的内容以完整的pem格式提交到网站上。

接下去会让你选择需要添加进该证书的子域名(不带www的主域名是默认包含的),最后一个选择服务器类型,不知道会对格式有什么影响(我的是 nginx server)。

以上完成会有一个新的页面,里面会包含需要设置的 CNAME 的信息,设置完之后就等着收到包含证书的邮件。

配置ssl证书

收到的邮件压缩包内包含了4个文件:

证书

分别属于:

这里有个证书链的概念,可以查看这篇文章了解,我们要做的是把这几个证书串联起来:

$ cat 93485680.crt COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > ssl.bundle.crt

然后把这个证书链和先前生成的example.com.csrexample.com.key放到同一处管理,接下去就是配置 nginx 服务器了:

listen                443 ssl;
server_name         example.com www.example.com;

# ssl config
ssl                    on;
ssl_certificate        /etc/ssl/private/ssl.bundle.crt; # 证书链
ssl_certificate_key    /etc/ssl/private/example.com.key; # 私钥
# ssl_protocols 和 ssl_ciphers 可以用来限制连接只包含 SSL/TLS 的加強版本和算法
ssl_protocols        TLSv1 TLSv1.1 TLSv1.2; # 支持的协议,Windows XP 不支持
ssl_ciphers            HIGH:!aNULL:!MD5; # 算法

这个配置完成之后重启 nginx 就可以使用 https 形式访问网站了。

其他

强制https访问

如果网站需要强制https形式访问,可以加入HSTS(HTTP Strict Transport Security)策略:

# 启用 HSTS ,仅通过 https 访问
add_header Strict-Transport-Security max-age=31536000;
# add_header X-Frame-Options DENY;  # 如果不需要引用 iframe 则可以加上
add_header X-Content-Type-Options nosniff;

然后在另一个单独的 server 配置中监听同域名的80端口并重定向至 https 链接:

server {
    listen       80;
    server_name  example.com www.example.com;
    location / {
        return 301 https://example.com$request_uri;    # 要重定向的地址
    }
}

完整配置

server {
    listen       443 ssl;
    server_name  example.com www.example.com;

      # ssl config
    ssl on;
    ssl_certificate      /etc/ssl/private/ssl.bundle.crt; # 证书链
    ssl_certificate_key  /etc/ssl/private/example.com.key; # 私钥

    # 为了更安全 ,可以考虑使用迪菲-赫尔曼密钥交换
    # openssl dhparam -out /etc/ssl/private/dhparam.pem 2048
    ssl_prefer_server_ciphers on;    # 启用 Forward Secrecy
    ssl_dhparam /etc/ssl/private/dhparam.pem;
    ssl_protocols TLSv1.2 TLSv1.1 TLSv1;    # 支持的协议,Windows XP 不支持
    ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
    keepalive_timeout 70;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # 启用 HSTS ,仅通过 https 访问
    add_header Strict-Transport-Security max-age=31536000;
    # add_header X-Frame-Options DENY;  # 如果不需要引用 iframe 则可以加上
    add_header X-Content-Type-Options nosniff;

    location / {
        # root   /usr/share/nginx/html;
        # index  index.html index.htm;
        index index;
        # proxy_pass http://127.0.0.1:7001;
        proxy_pass http://127.0.0.1:7001/blog/index;
    }
}

emmmm...亲身实践了一次,总体来说还是挺简单的,但是其中某些配置项暂不甚了解,同志仍需努力。