在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
nginx下配置ssl本来是很简单的,无论是去认证中心买SSL安全证书还是自签署证书,但最近公司OA的一个需求,得以有个机会实际折腾一番。一开始采用的是全站加密,所有访问http:80的请求强制转换(rewrite)到https,后来自动化测试结果说响应速度太慢,https比http慢慢30倍,心想怎么可能,鬼知道他们怎么测的。所以就试了一下部分页面https(不能只针对某类动态请求才加密)和双向认证。下面分节介绍。 默认nginx是没有安装ssl模块的,需要编译安装nginx时加入 关于SSL/TLS原理请参考 这里,如果你只是想测试或者自签发ssl证书,参考 这里 。 提示:nignx到后端服务器由于一般是内网,所以不加密。 1. 全站ssl 全站做ssl是最常见的一个使用场景,默认端口443,而且一般是单向认证。 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的话: server { listen 80; server_name example.me; rewrite ^ https://$server_name$request_uri? permanent; ### 使用return的效率会更高 # return 301 https://$server_name$request_uri; }
https优化参数
设置较长的 提示:在生成证书请求csr文件时,如果输入了密码,nginx每次启动时都会提示输入这个密码,可以使用私钥来生成解密后的key来代替,效果是一样的,达到免密码重启的效果: 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等资源时,浏览器为了安全起见会阻止加载。 下面是只对 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的写法参考这里。当浏览器访问
3. 实现双向ssl认证 上面的两种配置都是去认证被访问的站点域名是否真实可信,并对传输过程加密,但服务器端并没有认证客户端是否可信。(实际上除非特别重要的场景,也没必要去认证访问者,除非像银行U盾这样的情况) 要实现双向认证HTTPS,nginx服务器上必须导入CA证书(根证书/中间级证书),因为现在是由服务器端通过CA去验证客户端的信息。还有必须在申请服务器证书的同时,用同样的方法生成客户证书。取得客户证书后,还要将它转换成浏览器识别的格式(大部分浏览器都认识PKCS12格式): openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12 然后把这个 同时别忘了在 nginx.conf 里配置信任的CA:(如果是二级CA,请把根CA放在后面,形成CA证书链) 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默认安装了一个 geo $duplexing_user { default 1; include geo.conf; # 注意在0.6.7版本以后,include是相对于nginx.conf所在目录而言的 } 语法 127.0.0.1/32 LOCAL; # 本地 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持极客世界。 |
请发表评论