nginx-7 配置HTTPS服务器

想要配置一个HTTPS服务器,必须启用在server块中listen端口的ssl,同时使用server_certificate和private_key指令指定相关文件。

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ...
}

服务器证书是一个公共实体。它会被发送给每个连接服务器的客户端。私钥是一个安全实体,保持于访问限制的文件中,但对nginx的master进程是可读取的。私钥可以与证书交替存储在同一个文件中。

ssl_certificate     www.example.com.cert;
ssl_certificate_key www.example.com.cert;

在这种情况下,文件访问权限也应该受到限制。尽管证书和密钥存储在一个文件中,但只有证书被发送到客户机。

指令ssl_protocols和ssl_ciphers可以用来限制连接只包括SSL/TLS的强版本和加密算法。默认情况下,nginx使用ssl_protocols TLSv1 TLSv1.1 TLSv1.2ssl_ciphers HIGH:!aNULL:!MD5,所以没必要显示配置他们,但是要注意nginx的不同版本他们对应的默认值可能是不一样的。下面会讲到。

HTTPS服务器性能优化

SSL操作会消耗CPU资源,其中,SSL握手最为突出。因此,要提高HTTPS服务器的性能,就要最小化每个客户端连接SSL操作的次数。nginx对此有两种应对方式。

  1. 启用keepalive,使得通过一个连接可以发送多个请求,而不是一个连接一个请求
  2. 重用ssl session,对于并行和后续连接,避免SSL握手
    ssl_session_cache
    ssl_session_timeout 默认5m
worker_processes auto;

http {
    # shared 在worker进程间共享
    # SSL
    # 10m/10M  10兆内存空间(megabyte)
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;

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

        ssl_certificate     www.example.com.crt;
        ssl_certificate_key www.example.com.key;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ...

SSL中间证书

对于由知名证书颁发机构签署的证书,有的浏览器可能会不认同,有的浏览器会毫无问题地接受。出现这种情况是因为中间证书,颁发机构使用中间证书对服务器证书进行了签名,而中间证书不在已知受信任证书颁发机构的证书库中。为了解决这种问题,颁发机构提供了一组链接的证书,这些证书链接已签名的服务器证书。如下命令,服务器证书必须出现在链接证书之前。

$ cat www.example.com.crt bundle.crt > www.example.com.chained.crt

如果服务器证书在链接证书之后,nginx会启动失败,并展示以下错误信息。

SSL_CTX_use_PrivateKey_file(" ... /www.example.com.key") failed
   (SSL: error:0B080074:x509 certificate routines:
    X509_check_private_key:key values mismatch)

生成的文件应作为ssl_certificate指令的参数。

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.chained.crt;
    ssl_certificate_key www.example.com.key;
    ...
}

一个HTTP/HTTPS服务器例子

server {
    listen              80;
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ...
}

基于名称的HTTPS服务器

当在一个ip地址上配两个或两个以上的HTTPS服务器,会出现一个常见的问题。

server {
    listen          443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
    ...
}

server {
    listen          443 ssl;
    server_name     www.example.org;
    ssl_certificate www.example.org.crt;
    ...
}

使用这个配置,客户端不管请求的域名是www.example.com还是www.example.org,只会收到www.example.com.crt证书。因为在建立SSL连接的时候,服务器名称是未知的,这种情况下,IP地址一样,nginx会选择一个默认服务器,也就是第一个,来处理请求,所以客户端收到的总是第一个服务器的证书。可以通过配置不同IP地址来规避这个问题。

server {
    listen          192.168.1.1:443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
    ...
}

server {
    listen          192.168.1.2:443 ssl;
    server_name     www.example.org;
    ssl_certificate www.example.org.crt;
    ...
}

除此之外,解决方法还有拥有多个域名的证书SNI(Server Name Indication)

可以匹配多个域名的证书

  1. 拥有多个全称域名的证书
    全称域名的长度是有限制的
# 这种证书,可以提升作用域,不必写在server里
ssl_certificate     common.crt;
ssl_certificate_key common.key;

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

server {
    listen          443 ssl;
    server_name     www.example.org;
    ...
}
  1. 通配符域名证书
    与在服务器名称中讲的不一致,这里的通配符只能匹配一个部分。比如*.example.org,只能匹配www.example.org,而不能匹配example.org或者www.sub.example.org

SNI(Server Name Indication)

SNI允许在SSL握手的时候,客户端传递一个服务器名称给服务器。这种情况下,即使多个HTTPS服务器使用同一个IP,只要服务器名称不同,nginx就知道使用哪个服务器了。这是一种更常用的解决方法。现在大多数浏览器都支持SNI。

注意:SNI只传递域名,不应该是IP

为了在nginx中使用sni,必须在构建nginx二进制文件的openssl库以及在运行时动态链接到的库中都支持它。OpenSSL从0.9.8f版本开始支持SNI,前提OpenSSL使用配置选项 --enable-tlsext 构建。自从0.9.8j这个配置选项是默认的。如果nginx是支持SNI的,使用 nginx -V 如下。

$ nginx -V
...
TLS SNI support enabled
...

但是,如果支持SNI的nginx动态链接的OpenSSL库不支持SNI,将会有如下警告。

nginx was built with SNI support, however, now it is linked
dynamically to an OpenSSL library which has no tlsext support,
therefore SNI is not available

考虑兼容性

  • 0.7.14 开始支持在listen指令中指定ssl参数
  • 0.5.23 开始支持SNI
  • 0.5.6 开始支持shared SSL session cached
  • 1.9.1 开始默认的SSL协议是TLSv1, TLSv1.1, and TLSv1.2(如果由OpenSSL支持)
  • 0.7.65,0.8.19以后,默认的SSL协议是 SSLv3, TLSv1, TLSv1.1, and TLSv1.2(如果由OpenSSL支持)
  • 0.7.64,0.8.18以前,默认的SSL协议是 SSLv2, SSLv3, and TLSv1
  • 1.0.5 开始默认SSL加密算法是 HIGH:!aNULL:!MD5
  • 0.7.65,0.8.20之后,默认SSL加密算法是 HIGH:!ADH:!MD5
  • 0.8.19,默认SSL加密算法是 ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM
  • 0.7.64, 0.8.18以前,默认SSL加密算法是 ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容

  • 默认配置 要配置HTTPS服务器,必须 在服务器块中的侦听套接字上启用ssl参数 ,并且 应指定服务器证书 和 私...
    MicoCube阅读 2,040评论 0 1
  • 编译自:[configuring_https_servers][1][1]: http://nginx.org/e...
    C86guli阅读 2,667评论 2 6
  • 浏览器地址栏标志着 HTTPS 的绿色小锁头从心理层面上可以给用户专业安全的心理暗示,本文简单总结一下如何在 Ng...
    QieZi阅读 37,952评论 0 10
  • 我是有多丑陋啊,我可以按着想象生活,我做一个个的美梦,白天梦完,夜晚流泪,只因为空洞。 我知道我可以清醒,这种知晓...
    红回阅读 195评论 0 0
  • 大学时我很少回家,除大四一年不停辗转外,几乎一直住校,一年最多回两三次。每次回家都必须乘坐出租车、高铁、地铁或公交...
    王因止阅读 318评论 1 2