关于反向代理
Nginx能够作为一个反向代理来终结来自客户端的请求,并且向上游服务器打开一个新连接。新连接代表客户端向上游服务器发送请求。代理到上游服务器的配置中,最重要的是proxy_pass指令。该指令有一个参数,URL请求将会被转换,带有URI部分的proxy_pass指令将会使用该URI代替客户端request_uri部分。
location /uri { proxy_pass http://localhost:8080/newuri; }
实例:
[root@master vhost]# cat proxy.conf server { listen 80; server_name localhost.myserver.com; access_log /usr/local/nginx/logs/proxy_access.log normal; location /test { proxy_pass http://localhost:8080/index; } } [root@master vhost]# cat localhost_myserver_com.conf server { listen 8080; server_name localhost.myserver.com; access_log /usr/local/nginx/logs/localhost_access.log normal; location / { root /usr/local/nginx/html; } }
此时,在localhost_access.log中记录的请求发生了改变:
[root@master logs]# tail -1 proxy_access.log 192.168.1.38 - - 2019-03-28T04:02:58-04:00 "GET http://localhost.myserver.com/test.html HTTP/1.1"200 249 393 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.96 Safari/537.36""-" 0.001 0.001 [root@master logs]# [root@master logs]# tail -1 localhost_access.log 127.0.0.1 - - 2019-03-28T04:02:58-04:00 "GET http://localhost.myserver.com/index.html HTTP/1.0"200 205 414 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.96 Safari/537.36""-" 0.001 -
这个规则有两个例外情况:
如果location定义了一个正则表达式,或者在location中有rewrite规则改变了URI时,在proxy_pass指定URI部分是不被允许的。
向上游服务器传递客户端真实IP
location / { 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_pass http://192.168.1.202:8080; }
upstream模块
upstream模块经常与proxy搭配使用。upstream模块启用新的配置区段,定义了一组上游服务器。这些服务器可能被设置了不同的权重(权重越高的服务器将被Nginx分配更多的连接),也可能是不同的类型(TCP或UNIX域),也可能出于对服务器的维护而标记为down。
使用指定的负载均衡算法:
Nginx默认会采用轮询算法,如果想切换为ip_hash或least_conn,只需要在upstream开始位置指定负载均衡算法
upstream nginxservers { least_conn; server 192.168.1.201:8080; server 192.168.1.202:8080; keepalive 32; }
向上游服务器保持活动连接:
Nginx服务器将会为每一个worker进程保持同上游服务器的连接。在Nginx需要同上游服务器持续保持一定数量的打开连接时,连接缓存非常有用。Nginx将会使用HTTP/1.1协议的持久连接机制维护这些打开的连接。
在下面的例子中,Nginx起初仅需要为每一个worker进程打开32个TCP连接,然后通过不发送close的Connection头保持这些连接。
使用proxy_http_version指定使用HTTP/1.1协议同上游服务器进行通信。
使用proxy_set_header指令清除了Connection头的内容。
在业务高峰期,Nginx会打开超过32个TCP连接,当高峰期结束,Nginx将关闭最近最少使用的连接,使连接数回落到32。
upstream nginxservers { server 192.168.1.201:8080; server 192.168.1.202:8080; keepalive 32; } server { listen 80; server_name localhost.myserver.com; access_log /usr/local/nginx/logs/proxy_access.log normal; location / { proxy_http_version 1.1; proxy_set_header Connection ""; proxy_pass http://nginxservers; } }
使用Memcached作为上游服务器:
upstream memcaches { server 192.168.1.201:11211; server 192.168.1.202:11211; } server { location / { set $memcached_key "$uri?$args"; memcached_pass memcaches; error_page 404 = @appserver; } location @appserver { proxy_pass http://127.0.0.1:8080; } }
使用FastCGI作为上游服务器:
upstream fastcgis { server 192.168.1.201:9000; server 192.168.1.202:9000; } server { location / { fastcgi_pass fastcgis; } }
Nginx通过uwsgi模块提供基于Python的上游服务器的连接,配置类似于FastCGI模块,使用uwsgi_pass指令指定上游服务器。
使用错误文件处理上游服务器问题
有一些上游服务器无法响应请求的情况,此时,可以让Nginx从本地返回一个文件。
server { listen 80; server_name localhost.myserver.com; access_log /usr/local/nginx/logs/proxy_access.log normal; location / { proxy_pass http://nginxservers; error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/local/nginx/html; } } }
或者在上游服务器无法响应请求时,想将请求转发至另一组定义好的后备服务器(fallback)。
server { listen 80; server_name localhost.myserver.com; access_log /usr/local/nginx/logs/proxy_access.log normal; location / { proxy_pass http://nginxservers; error_page 500 502 503 504 = @fallback; } location @fallback { proxy_pass http://localhost:8080; } }
使用SSL对流量进行加密:
使用OpenSSL生成SSL证书:
# openssl req -newkey rsa:2048 -nodes -out localhost.myserver.com -keyout localhost.myserver.com.key ---- 命令执行时提示输入公司名、邮件等信息,直接回车即可; ---- 完成以上命令会得到证书签名请求(Certificate Signing Requests),保存在“localhost.myserver.com”文件中; ---- 证书签名由证书颁发机构授予。或者也可以自己签名,自己的签名不能用在公网服务器上 # openssl x509 -req -days 365 -in localhost.myserver.com -signkey localhost.myserver.com.key -out localhost.myserver.com.pem Signature ok subject=/C=XX/L=Default City/O=Default Company Ltd Getting Private key
对客户端和反向代理之间的流量进行加密:
server { listen 443 default ssl; server_name localhost.myserver.com; ssl_prefer_server_ciphers on; ssl_protocols SSLv2 SSLv3 TLSv1; ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL; ssl_session_timeout 5m; ssl_session_cache shared:WEB:10m; ssl_certificate /usr/local/nginx/ssl_key/localhost.myserver.com.pem; ssl_certificate_key /usr/local/nginx/ssl_key/localhost.myserver.com.key; location / { access_log /usr/local/nginx/logs/ssl.log normal; proxy_set_header X-Forwarded-For-Proto $scheme; proxy_pass http://127.0.0.1:8080; } }
首先使用listen指令的ssl参数激活了SSL模块。
然后指定了希望客户端使用服务器密码,以及协议类型和使用的认证方法;
ssl_session_cache指令被设定为shared,第二部分和第三部分分别是缓存的名称和大小;
然后指明证书和key的路径,要保证文件能被Nginx使用的用户访问。
最后设置X-Forwarded-For-Proto头的值为$scheme,告诉上游服务器原始请求使用的是http还是https。
对反向代理和上游服务器之间的流量进行加密:
server { …… location / { …… proxy_pass https://127.0.0.1:8080; } }
要保证上游服务器也启用了SSL模块,这里的上游服务器使用Nginx提供服务,设置方法同“对客户端和反向代理之间的流量进行加密”。
转载于:https://blog.51cto.com/13568014/2371438