Nginx的反向代理通常用来映射内网中提供的Apache、IIS、Lighttpd服务,以实现负载均衡;同时,由于动态服务程序运行在内网,服务器的整体安全性也有所提高,那么怎样用nginx设置SSL的反向代理呢?
使用nginx设置SSL的优点不少:
- 易用性:nginx安装、升级简单,nginx的平滑升级使得网站服务器不需要重启就可以完成升级任务。
- 安全性:nginx对于代理是透明的,因此,相当于为放置在代理后的Apache等服务器提供一道安全屏障、可以抵御一些基本web的攻击。
- 低负载:负载低是nginx的另一大优点。可以在nginx代理后配置多个apache服务器以满足不同需求
- 缓存:可以将除动态文件以外的文件,如css、js、静态html页直接交给nginx处理,以进一步降低负载
- 文件压缩:nginx可以优化并减小文件传输尺寸,缩短文件读取时间。
说了一大堆优点,相信诸位看官该跃跃欲试了吧,闲话少提^_^,下面给出配置实例:
由于,下面的代码只是用来演示整个配置过程,因此,我使用的SSL安全证书是自己签名的,如果需要能够通过验证的SSL安全证书,请到CAs自我了断^_^(网站地址:www.verisign.com)。
一、生成SSL安全证书
在nginx的配置目录下新建一个文件夹用以存放证书
# cd /usr/local/nginx/conf
# mkdir ssl
# cd ssl
生成一个私有key
# openssl genrsa -des3 -out nixcraft.in.key 1024
生成CSR(Certificate Signing Request)文件:
# openssl req -new -key nixcraft.in.key -out nixcraft.in.csr
请输入自己的证书域名。上图红框的部分
二、配置SSL反向代理
编辑nginx的配置文件
#vi /usr/local/ngnix/conf/nginx.conf
添加如下代码:
server { ### server port and name ### listen 443 ssl; server_name yourdomian.com; ### SSL log files ### access_log logs/ssl-access.log; error_log logs/ssl-error.log; ### SSL cert files ### ssl_certificate ssl/yourdomain.com.crt; ssl_certificate_key ssl/yourdomain.com.key; ### Add SSL specific settings here ### keepalive_timeout 60; ### Limiting Ciphers ######################## # Uncomment as per your setup #ssl_ciphers HIGH:!ADH; #ssl_perfer_server_ciphers on; #ssl_protocols SSLv3; ############################################## ### We want full access to SSL via backend ### location / { proxy_pass http://yourdomain.com; ### force timeouts if one of backend is died ## proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; ### 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; ### Most PHP, Python, Rails, Java App can use this header ### proxy_set_header X-Forwarded-Proto https; ### By default we don't want to redirect it #### proxy_redirect off; }
保存、并重新加载配置文件
# /usr/local/nginx/sbin/nginx -t
# /usr/local/nginx/sbin/nginx -s reload
查看是否配置成功:
# netstat -tulpn | grep :443
SSL配置大功告成了,你可以使用https://youdomain.com访问你的网站了。
重定向端品丢失情况:
server { listen 80; server_name yourdomain.com; location / { proxy_pass http://yourdomain.com; ### force timeouts if one of backend is died ## proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; ### 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; ### Most PHP, Python, Rails, Java App can use this header ### proxy_set_header X-Forwarded-Proto https; ### set server host proxy_set_header Host $host:$server_port; ### By default we don't want to redirect it #### proxy_redirect off; }
Rewrite:
正则表达式匹配,其中:
* ~ 为区分大小写匹配
* ~* 为不区分大小写匹配
* !~和!~*分别为区分大小写不匹配及不区分大小写不匹配
文件及目录匹配,其中:
* -f和!-f用来判断是否存在文件
* -d和!-d用来判断是否存在目录
* -e和!-e用来判断是否存在文件或目录
* -x和!-x用来判断文件是否可执行
flag标记有:
* last 相当于Apache里的[L]标记,表示完成rewrite
* break 终止匹配, 不再匹配后面的规则
* redirect 返回302临时重定向 地址栏会显示跳转后的地址
* permanent 返回301永久重定向 地址栏会显示跳转后的地址
一些可用的全局变量有,可以用做条件判断
$args, 请求中的参数;
$content_length, HTTP请求信息里的"Content-Length";
$content_type, 请求信息里的"Content-Type";
$document_root, 针对当前请求的根路径设置值;
$document_uri, 与$uri相同;
$host, 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
$limit_rate, 对连接速率的限制;
$request_method, 请求的方法,比如"GET"、"POST"等;
$remote_addr, 客户端地址;
$remote_port, 客户端端口号;
$remote_user, 客户端用户名,认证用;
$request_filename, 当前请求的文件路径名
$request_body_file
$request_uri, 请求的URI,带查询字符串;
$query_string, 与$args相同;
$scheme, 所用的协议,比如http或者是https,比如rewrite ^(.+)$ $scheme://example.com$1 redirect;
$server_protocol, 请求的协议版本,"HTTP/1.0"或"HTTP/1.1";
$server_addr, 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
$server_name, 请求到达的服务器名;
$server_port, 请求到达的服务器端口号;
$uri, 请求的URI,可能和最初的值有不同,比如经过重定向之类的。
语法:rewrite regex replacement flag
按照相关的正则表达式与字符串修改URI,指令按照在配置文件中出现的顺序执行。
可以在重写指令后面添加标记。
如果替换的字符串以http://开头,请求将被重定向,并且不再执行多余的rewrite指令。
尾部的标记(flag)可以是以下的值:
- last - 完成重写指令,之后搜索相应的URI或location。
- break - 完成重写指令。
- redirect - 返回302临时重定向,如果替换字段用http://开头则被使用。
- permanent - 返回301永久重定向。
...