nginx配置ssl加密(单双向认证、部分https)

nginx下配置ssl本来是很简单的,无论是去认证中心买SSL安全证书还是自签署证书,但最近公司OA的一个需求,得以有个机会实际折腾一番。一开始采用的是全站加密,所有访问http:80的请求强制转换(rewrite)到https,后来自动化测试结果说响应速度太慢,https比http慢慢30倍,心想怎么可能,鬼知道他们怎么测的。所以就试了一下部分页面https(不能只针对某类动态请求才加密)和双向认证。下面分节介绍。

默认nginx是没有安装ssl模块的,需要编译安装nginx时加入--with-http_ssl_module选项。

关于SSL/TLS原理请参考 这里,如果你只是想测试或者自签发ssl证书,参考 这里 。

提示:nignx到后端服务器由于一般是内网,所以不加密。

1. 全站ssl

全站做ssl是最常见的一个使用场景,默认端口443,而且一般是单向认证。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
listen 443;
server_name example.com;
 
root /apps/www;
index index.html index.htm;
 
ssl on;
ssl_certificate ../SSL/ittest.pem;
ssl_certificate_key ../SSL/ittest.key;
 
# ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
# ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
# ssl_prefer_server_ciphers on;
 
}

如果想把http的请求强制转到https的话:

1
2
3
4
5
6
7
8
server {
listen 80;
server_name example.me;
rewrite ^ https://$server_name$request_uri? permanent;
 
### 使用return的效率会更高
# return 301 https://$server_name$request_uri;
}

ssl_certificate证书其实是个公钥,它会被发送到连接服务器的每个客户端,ssl_certificate_key私钥是用来解密的,所以它的权限要得到保护但nginx的主进程能够读取。当然私钥和证书可以放在一个证书文件中,这种方式也只有公钥证书才发送到client。

ssl_protocols指令用于启动特定的加密协议,nginx在1.1.13和1.0.12版本后默认是ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2,TLSv1.1与TLSv1.2要确保OpenSSL >= 1.0.1 ,SSLv3 现在还有很多地方在用但有不少被攻击的漏洞。

ssl_ciphers选择加密套件,不同的浏览器所支持的套件(和顺序)可能会不同。这里指定的是OpenSSL库能够识别的写法,你可以通过 openssl -v cipher 'RC4:HIGH:!aNULL:!MD5'(后面是你所指定的套件加密算法) 来看所支持算法。

ssl_prefer_server_ciphers on设置协商加密算法时,优先使用我们服务端的加密套件,而不是客户端浏览器的加密套件。

https优化参数

  • ssl_session_cache shared:SSL:10m; : 设置ssl/tls会话缓存的类型和大小。如果设置了这个参数一般是sharedbuildin可能会参数内存碎片,默认是none,和off差不多,停用缓存。如shared:SSL:10m表示我所有的nginx工作进程共享ssl会话缓存,官网介绍说1M可以存放约4000个sessions。 详细参考serverfault上的问答ssl_session_cache
  • ssl_session_timeout : 客户端可以重用会话缓存中ssl参数的过期时间,内网系统默认5分钟太短了,可以设成30m即30分钟甚至4h

设置较长的keepalive_timeout也可以减少请求ssl会话协商的开销,但同时得考虑线程的并发数了。

提示:在生成证书请求csr文件时,如果输入了密码,nginx每次启动时都会提示输入这个密码,可以使用私钥来生成解密后的key来代替,效果是一样的,达到免密码重启的效果:

1
openssl rsa -in ittest.key -out ittest_unsecure.key

导入证书

如果你是找一个知名的ssl证书颁发机构如VeriSign、Wosign、StartSSL签发的证书,浏览器已经内置并信任了这些根证书,如果你是自建C或获得二级CA授权,都需要将CA证书添加到浏览器,这样在访问站点时才不会显示不安全连接。各个浏览的添加方法不在本文探讨范围内。

2. 部分页面ssl

一个站点并不是所有信息都是非常机密的,如网上商城,一般的商品浏览可以不通过https,而用户登录以及支付的时候就强制经过https传输,这样用户访问速度和安全性都得到兼顾。

但是请注意不要理解错了,是对页面加密而不能针对某个请求加密,一个页面或地址栏的URL一般会发起许多请求的,包括css/png/js等静态文件和动态的java或php请求,所以要加密的内容包含页面内的其它资源文件,否则就会出现http与https内容混合的问题。在http页面混有https内容时,页面排版不会发生乱排现象;在https页面中包含以http方式引入的图片、js等资源时,浏览器为了安全起见会阻止加载。

下面是只对example.com/account/login登录页面进行加密的栗子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
root /apps/www;
index index.html index.htm;
 
server {
listen 80;
server_name example.com;
 
location ^~ /account/login {
rewrite ^ https://$server_name:443$request_uri? permanent;
}
location / {
proxy_pass http://localhost:8080;
 
### Set headers ####
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
}
}
 
server {
listen 443 ssl;
server_name example.com;
 
ssl on;
ssl_certificate ../SSL/ittest.pem;
ssl_certificate_key ../SSL/ittest.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
 
location ^~ /account/login {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
 
### Most PHP, Python, Rails, Java App can use this header -> https ###
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
rewrite ^ http://$server_name$request_uri? permanent;
}
}

关于rewrite与location的写法参考这里。当浏览器访问http://example.com/account/login.xx时,被301到https://example.com/account/login.xx,在这个ssl加密的虚拟主机里也匹配到/account/login,反向代理到后端服务器,后面的传输过程是没有https的。这个login.xx页面下的其它资源也是经过https请求nginx的,登录成功后跳转到首页时的链接使用http,这个可能需要开发代码里面控制。

  • 上面配置中使用了proxy_set_header X-Forwarded-Proto $scheme,在jsp页面使用request.getScheme()得到的是https 。如果不把请求的$scheme协议设置在header里,后端jsp页面会一直认为是http,将导致响应异常。
  • ssl配置块还有个与不加密的80端口类似的location /,它的作用是当用户直接通过https访问首页时,自动跳转到不加密端口,你可以去掉它允许用户这样做。

3. 实现双向ssl认证

上面的两种配置都是去认证被访问的站点域名是否真实可信,并对传输过程加密,但服务器端并没有认证客户端是否可信。(实际上除非特别重要的场景,也没必要去认证访问者,除非像银行U盾这样的情况)

要实现双向认证HTTPS,nginx服务器上必须导入CA证书(根证书/中间级证书),因为现在是由服务器端通过CA去验证客户端的信息。还有必须在申请服务器证书的同时,用同样的方法生成客户证书。取得客户证书后,还要将它转换成浏览器识别的格式(大部分浏览器都认识PKCS12格式):

1
openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12

然后把这个client.p12发给你相信的人,让它导入到浏览器中,访问站点建立连接的时候nginx会要求客户端把这个证书发给自己验证,如果没有这个证书就拒绝访问。

同时别忘了在 nginx.conf 里配置信任的CA:(如果是二级CA,请把根CA放在后面,形成CA证书链)

1
2
3
4
5
6
7
8
9
10
proxy_ignore_client_abort on;
 
ssl on;
...
ssl_verify_client on;
ssl_verify_depth 2;
ssl_client_certificate ../SSL/ca-chain.pem;
 
# 在双向location下加入:
proxy_set_header X-SSL-Client-Cert $ssl_client_cert;

拓展:使用geo模块

nginx默认安装了一个ngx_http_geo_module,这个geo模块可以根据客户端IP来创建变量的值,用在如来自172.29.73.0/24段的IP访问login时使用双向认证,其它段使用一般的单向认证。

1
2
3
4
geo $duplexing_user {
default 1;
include geo.conf; # 注意在0.6.7版本以后,include是相对于nginx.conf所在目录而言的
}

语法 geo [$address] $variable { … },位于http段,默认地址是$reoute_addr,假设 conf/geo.conf 内容:

1
2
3
127.0.0.1/32 LOCAL; # 本地
172.29.73.23/32 SEAN; # 某个IP
172.29.73.0/24 1; # IP段,可以按国家或地域定义后面的不同的值

需要配置另外一个虚拟主机server{ssl 445},里面使用上面双向认证的写法,然后在80或443里使用变量$duplexing_user去判断,如果为1就rewrite到445,否则rewrite到443。具体用法可以参考nginx geo使用方法

http://seanlook.com/2015/05/28/nginx-ssl/

nginx配置ssl加密(单双向认证、部分https)的更多相关文章

  1. [转帖]nginx配置ssl加密(单/双向认证、部分https)

    nginx配置ssl加密(单/双向认证.部分https) https://segmentfault.com/a/1190000002866627   nginx下配置ssl本来是很简单的,无论是去认证 ...

  2. nginx配置ssl加密(单/双向认证、部分https)

    nginx下配置ssl本来是很简单的,无论是去认证中心买SSL安全证书还是自签署证书,但最近公司OA的一个需求,得以有个机会实际折腾一番.一开始采用的是全站加密,所有访问http:80的请求强制转换( ...

  3. 基于SSL协议的双向认证 - 双向认证 [3]

    1      SSL双向认证的实现 这里是基于SSL和Tomcat配置实现的,配置方法如下: 1.1    生成CA数字证书 首先需要配置OPENSSL环境变量. 我的OPENSSL配置文件路径是“D ...

  4. java实现ssl单/双向认证通信[推荐]

    java实现ssl单/双向认证通信[推荐] 学习了:https://blog.csdn.net/zbuger/article/details/51695582 学习了:https://www.cnbl ...

  5. nginx配置ssl双向证书

    CA根证书制作 # 创建CA私钥 openssl genrsa -out ca.key 2048 #制作CA根证书(公钥) openssl req -new -x509 -days 3650 -key ...

  6. nginx 配置 ssl 双向证书

    CA 根证书制作 # 创建 CA 私钥 openssl genrsa -out ca.key 2048 #制作 CA 根证书(公钥) openssl req -new -x509 -days 3650 ...

  7. Windows下Nginx配置SSL实现Https访问(包含证书生成)

    Vincent.李   Windows下Nginx配置SSL实现Https访问(包含证书生成) Windows下Nginx配置SSL实现Https访问(包含证书生成) 首先要说明为什么要实现https ...

  8. Centos 7 环境下,如何使用 Apache 实现 SSL 虚拟主机 双向认证 的详细教程:

    1. testing ! ... 1 1 原文参考链接: http://showerlee.blog.51cto.com/2047005/1266712 很久没有更新LAMP的相关文档了,刚好最近单位 ...

  9. 基于HTTPS的接口测试——nginx配置SSL

    目录 基于HTTPS的接口测试--nginx配置SSL 1. 背景 2. 所需环境与域名备案解析 2.1 云服务器 2.2 域名 2.3 SSL证书 2.4 网站备案 2.5 域名解析 3.nginx ...

随机推荐

  1. 联想S720/S720i通刷刷机包 Vibe V1.0

    ROM介绍 基于官方最新S116底包制作,保证足够的稳定性. 增加VIBE元素,看起来更加大气.美观. 首次增加VIBE元素,720i执行起来无压力,720可能会有点卡.自行酌情刷入. 有bug请文明 ...

  2. U3d 手游优化概述

    移动平台瓶颈 体积小 芯片要求改 功耗小 影响计算系能 带宽小 传输方面受限 性能优化 资源方面 美术方面 自带地形(地形是非常占用资源的) a.控制地形的分辨率 b.地形高度图尺寸小于257 c.地 ...

  3. Windows Server 2012 R2 服务器管理器介绍和配置使用

    1. 服务管理器是用于管理系统服务的管理工具.一般常用于windows系统,使用这个工具你可以启动.停止服务:设置服务是自动.手动启动或禁用:查看某个服务的相关信息:设置服务以什么用户启动等等(一般包 ...

  4. Problem F: Exponentiation

    Problem F: ExponentiationTime Limit: 1 Sec Memory Limit: 128 MBSubmit: 4 Solved: 2[Submit][Status][W ...

  5. USACO Seciton 5.4 Canada Tour(dp)

    因为dp(i,j)=dp(j,i),所以令i>j. dp(i,j)=max(dp(k,j))+1(0<=k<i),若此时dp(i,j)=1则让dp(i,j)=0.(因为无法到达此状态 ...

  6. BZOJ 3224: Tyvj 1728 普通平衡树(BST)

    treap,算是模板题了...我中间还一次交错题... -------------------------------------------------------------------- #in ...

  7. 虚拟机ping不通主机

    centos ping不通主机 首先检查网络设备 ifconfig -a 如果有eth0 , 又存在 eth1 . 那么service eth1 stop  然后在ping主机.(以上前提是网络地址设 ...

  8. Linux 网络编程: xinetd time

    前言 终于把 xinetd 服务装好了,那就在来实现一下 TCP 协议从服务器和本机获取时间吧.那么多思想汇报还没写,我也是醉了. 安装 xinetd apt-get install xinetd 配 ...

  9. Sublime Text2

    Ctrl+L选择整行(按住-继续选择下行) Ctrl+KK 从光标处删除至行尾 Ctrl+Shift+K 删除整行 Ctrl+Shift+D 复制光标所在整行,插入在该行之前 Ctrl+J 合并行(已 ...

  10. python使用easygui写图形界面程序

    我 们首先下载一个类库easygui,它是一个Python用于简单开发图形化界面的类库,打开easygui的下载网页 http://sourceforge.net/projects/easygui/? ...