Nginx反向代理功能-实现HTTP反向代理客户端IP透传案例
Nginx反向代理功能-实现HTTP反向代理客户端IP透传案例
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.Nginx反向代理概述
1>.什么是反向代理
反向代理也叫reverse proxy,指的是代理外网用户的请求到内部的指定web服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式。
2>.Nginx支持的反向代理
Nginx除了可以在企业提供高性能的web服务之外,另外还可以将本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能:
ngx_http_proxy_module:
将客户端的请求以http协议转发至指定服务器进行处理。
ngx_stream_proxy_module:
将客户端的请求以tcp协议转发至指定服务器处理,很少有人使用Nginx来跑TCP的反向代理,因为它的这种功能出来的比较晚,一般TCP反向代理使用Haproxy或者LVS的居多。
ngx_http_fastcgi_module:
将客户端对php的请求以fastcgi协议转发至指定服务器助理,比如使用Laravel,Yii Framework等Web开发工具开发的程序就可以使用这种方式部署LNMP
ngx_http_uwsgi_module:
将客户端对Python的请求以uwsgi协议转发至指定服务器处理,比如使用Django等Web开发的程序就可以使用这种方式部署LNMP。
博主推荐阅读:
https://nginx.org/en/docs/http/ngx_http_proxy_module.html
3>.Nginx逻辑调用关系如下图所示
二.试验环境说明
1>.虚拟机操作系统配置
[root@node101.yinzhengjie.org.cn ~]# uname -r 3.10.0-957.el7.x86_64 [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# uname -m x86_64 [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# free -h total used free shared buff/cache available Mem: 7.6G 152M 6.7G 9.7M 851M 7.2G Swap: 7.9G 0B 7.9G [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# hostname -i 172.30.1.101 [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.30.1.101 node101.yinzhengjie.org.cn node101.yinzhengjie.com 172.30.1.102 node102.yinzhengjie.org.cn 172.30.1.103 node103.yinzhengjie.org.cn 172.30.1.104 node104.yinzhengjie.org.cn 172.30.1.105 node105.yinzhengjie.org.cn 172.30.1.106 node106.yinzhengjie.org.cn 172.30.1.107 node107.yinzhengjie.org.cn 172.30.1.108 node108.yinzhengjie.org.cn [root@node101.yinzhengjie.org.cn ~]#
2>.反向代理说明
node101.yinzhengjie.org.cn:
Nginx反向代理服务器
node108.yinzhengjie.org.cn:
Apache httpd的web服务器
三.Apache httpd服务器部署
1>.安装Apache httpd服务
[root@node108.yinzhengjie.org.cn ~]# yum -y install httpd Loaded plugins: fastestmirror Determining fastest mirrors * base: mirrors.neusoft.edu.cn * extras: mirror.bit.edu.cn * updates: mirror.bit.edu.cn base | 3.6 kB 00:00:00 extras | 2.9 kB 00:00:00 updates | 2.9 kB 00:00:00 (1/4): extras/7/x86_64/primary_db | 153 kB 00:00:00 (2/4): base/7/x86_64/primary_db | 6.0 MB 00:00:01 (3/4): updates/7/x86_64/primary_db | 5.9 MB 00:00:02 (4/4): base/7/x86_64/group_gz | 165 kB 00:00:04 Resolving Dependencies --> Running transaction check ---> Package httpd.x86_64 0:2.4.6-90.el7.centos will be installed --> Processing Dependency: httpd-tools = 2.4.6-90.el7.centos for package: httpd-2.4.6-90.el7.centos.x86_64 --> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.6-90.el7.centos.x86_64 --> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.6-90.el7.centos.x86_64 --> Running transaction check ---> Package apr.x86_64 0:1.4.8-5.el7 will be installed ---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed ---> Package httpd-tools.x86_64 0:2.4.6-90.el7.centos will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================================================ Package Arch Version Repository Size ============================================================================================================================================================================ Installing: httpd x86_64 2.4.6-90.el7.centos base 2.7 M Installing for dependencies: apr x86_64 1.4.8-5.el7 base 103 k apr-util x86_64 1.5.2-6.el7 base 92 k httpd-tools x86_64 2.4.6-90.el7.centos base 91 k Transaction Summary ============================================================================================================================================================================ Install 1 Package (+3 Dependent packages) Total download size: 3.0 M Installed size: 9.9 M Downloading packages: (1/4): apr-util-1.5.2-6.el7.x86_64.rpm | 92 kB 00:00:00 (2/4): httpd-2.4.6-90.el7.centos.x86_64.rpm | 2.7 MB 00:00:00 (3/4): httpd-tools-2.4.6-90.el7.centos.x86_64.rpm | 91 kB 00:00:00 (4/4): apr-1.4.8-5.el7.x86_64.rpm | 103 kB 00:00:05 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Total 505 kB/s | 3.0 MB 00:00:06 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : apr-1.4.8-5.el7.x86_64 1/4 Installing : apr-util-1.5.2-6.el7.x86_64 2/4 Installing : httpd-tools-2.4.6-90.el7.centos.x86_64 3/4 Installing : httpd-2.4.6-90.el7.centos.x86_64 4/4 Verifying : apr-1.4.8-5.el7.x86_64 1/4 Verifying : httpd-tools-2.4.6-90.el7.centos.x86_64 2/4 Verifying : apr-util-1.5.2-6.el7.x86_64 3/4 Verifying : httpd-2.4.6-90.el7.centos.x86_64 4/4 Installed: httpd.x86_64 0:2.4.6-90.el7.centos Dependency Installed: apr.x86_64 0:1.4.8-5.el7 apr-util.x86_64 0:1.5.2-6.el7 httpd-tools.x86_64 0:2.4.6-90.el7.centos Complete! [root@node108.yinzhengjie.org.cn ~]#
2>.创建Apache httpd测试首页并修改apache的默认日志格式
[root@node108.yinzhengjie.org.cn ~]# echo "<h1>The Apache Web App01 index.</h1>" > /var/www/html/index.html [root@node108.yinzhengjie.org.cn ~]# [root@node108.yinzhengjie.org.cn ~]# cat /var/www/html/index.html <h1>The Apache Web App01 index.</h1> [root@node108.yinzhengjie.org.cn ~]# [root@node108.yinzhengjie.org.cn ~]# grep yinzhengjie_nginx_ip_forwarded /etc/httpd/conf/httpd.conf #注意,关于"yinzhengjie_nginx_ip_forwarded"变量名称要和nginx配置配置文件的要一致哟~ LogFormat "\"%{yinzhengjie_nginx_ip_forwarded}i\" %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined [root@node108.yinzhengjie.org.cn ~]#
[root@node108.yinzhengjie.org.cn ~]# egrep -v "^ *#|^$" /etc/httpd/conf/httpd.conf ServerRoot "/etc/httpd" Listen 80 Include conf.modules.d/*.conf User apache Group apache ServerAdmin root@localhost <Directory /> AllowOverride none Require all denied </Directory> DocumentRoot "/var/www/html" <Directory "/var/www"> AllowOverride None Require all granted </Directory> <Directory "/var/www/html"> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory> <IfModule dir_module> DirectoryIndex index.html </IfModule> <Files ".ht*"> Require all denied </Files> ErrorLog "logs/error_log" LogLevel warn <IfModule log_config_module> LogFormat "\"%{yinzhengjie_nginx_ip_forwarded}i\" %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common <IfModule logio_module> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio </IfModule> CustomLog "logs/access_log" combined </IfModule> <IfModule alias_module> ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" </IfModule> <Directory "/var/www/cgi-bin"> AllowOverride None Options None Require all granted </Directory> <IfModule mime_module> TypesConfig /etc/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz AddType text/html .shtml AddOutputFilter INCLUDES .shtml </IfModule> AddDefaultCharset UTF-8 <IfModule mime_magic_module> MIMEMagicFile conf/magic </IfModule> EnableSendfile on IncludeOptional conf.d/*.conf [root@node108.yinzhengjie.org.cn ~]# [root@node108.yinzhengjie.org.cn ~]#
3>.启动Apache httpd服务
[root@node108.yinzhengjie.org.cn ~]# ss -ntl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* LISTEN 0 128 :::22 :::* [root@node108.yinzhengjie.org.cn ~]# [root@node108.yinzhengjie.org.cn ~]# systemctl start httpd [root@node108.yinzhengjie.org.cn ~]# [root@node108.yinzhengjie.org.cn ~]# ss -ntl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:80 *:* LISTEN 0 128 *:22 *:* LISTEN 0 128 :::22 :::* [root@node108.yinzhengjie.org.cn ~]# [root@node108.yinzhengjie.org.cn ~]#
4>.验证服务是否可以正常访问
浏览器访问"http://node108.yinzhengjie.org.cn/",发现的确是咱们的测试页面,如下图所示,服务是正常的。
5>.创建多业务模拟数据
[root@node108.yinzhengjie.org.cn ~]# mkdir /var/www/html/{static,image,dynamic} [root@node108.yinzhengjie.org.cn ~]# [root@node108.yinzhengjie.org.cn ~]# echo "<h1>The apache httpd static page.</h1>" > /var/www/html/static/index.html [root@node108.yinzhengjie.org.cn ~]# [root@node108.yinzhengjie.org.cn ~]# echo "<h1>The apache httpd image page.</h1>" > /var/www/html/image/index.html [root@node108.yinzhengjie.org.cn ~]# [root@node108.yinzhengjie.org.cn ~]# echo "<h1>The apache httpd dynamic page.</h1>" > /var/www/html/dynamic/index.html [root@node108.yinzhengjie.org.cn ~]# [root@node108.yinzhengjie.org.cn ~]# ll /var/www/html/ -R /var/www/html/: total 4 drwxr-xr-x 2 root root 24 Dec 26 14:19 dynamic drwxr-xr-x 2 root root 24 Dec 26 14:18 image -rw-r--r-- 1 root root 37 Dec 26 14:04 index.html drwxr-xr-x 2 root root 24 Dec 26 14:18 static /var/www/html/dynamic: total 4 -rw-r--r-- 1 root root 40 Dec 26 14:19 index.html /var/www/html/image: total 4 -rw-r--r-- 1 root root 38 Dec 26 14:18 index.html /var/www/html/static: total 4 -rw-r--r-- 1 root root 39 Dec 26 14:18 index.html [root@node108.yinzhengjie.org.cn ~]#
四.Nginx服务器实现http反向代理配置客户端IP透传实战
1>.编辑主配置文件
[root@node101.yinzhengjie.org.cn ~]# cat /yinzhengjie/softwares/nginx/conf/nginx.conf worker_processes 4; worker_cpu_affinity 00000001 00000010 00000100 00001000; events { worker_connections 100000; use epoll; accept_mutex on; multi_accept on; } http { include mime.types; default_type text/html; server_tokens off; charset utf-8; log_format my_access_json '{"@timestamp":"$time_iso8601",' '"host":"$server_addr",' '"clientip":"$remote_addr",' '"size":$body_bytes_sent,' '"responsetime":$request_ti me,' '"upstreamtime":"$upstream_response_time",' '"upstreamhost":"$upstream_addr",' '"http_host":"$host",' '"uri":"$uri",' '"domain":"$host",' '"xff":"$http_x_forwarded_for",' '"referer":"$http_referer",' '"tcp_xff":"$proxy_protocol_addr",' '"http_user_agent":"$http_user_agent",' '"status":"$status"}'; access_log logs/access_json.log my_access_json; ssl_certificate /yinzhengjie/softwares/nginx/certs/www.yinzhengjie.org.cn.crt; ssl_certificate_key /yinzhengjie/softwares/nginx/certs/www.yinzhengjie.org.cn.key; ssl_session_cache shared:sslcache:20m; ssl_session_timeout 10m; include /yinzhengjie/softwares/nginx/conf.d/*.conf; } [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# nginx -t nginx: the configuration file /yinzhengjie/softwares/nginx/conf/nginx.conf syntax is ok nginx: configuration file /yinzhengjie/softwares/nginx/conf/nginx.conf test is successful [root@node101.yinzhengjie.org.cn ~]#
2>.编辑子配置文件
[root@node101.yinzhengjie.org.cn ~]# cat /yinzhengjie/softwares/nginx/conf.d/node101_yinzhengjie_org.cn.conf server { listen 80; listen 443 ssl; server_name node101.yinzhengjie.org.cn; access_log /yinzhengjie/softwares/nginx/logs/node101_yinzhengjie_org_cn_access.log my_access_json; error_log /yinzhengjie/softwares/nginx/logs/node101_yinzhengjie_org_cn_error.log; location / { root /yinzhengjie/data/web/nginx/static/cn; index index.html; #定义有效的请求referer,用空格隔开即可 valid_referers none blocked server_names *.baidu.com example.* ~\.google\.; #如果没有在上面的有效链接定义那么均属于无效请求referer if ($invalid_referer) { return 403; } #如果是一些常见的压测试工具,咱们直接进给他拒绝访问 if ($http_user_agent ~ "ApacheBench|WebBench|TurnitinBot|Sougou web spider|Grid Server"){ return 403; } } location = /favicon.ico { root /yinzhengjie/data/web/nginx/images/jd; } location /app01 { #proxy_pass指令用来设置将客户端请求转发给的后端服务器的主机,可以是主机名、IP地址:端口的方式,也可以代理到预先设置的主机群组,需要模块gx_http_upstream_module支持。 #带斜线,等于访问后端服务器的http://172.30.108:80/index.html内容返回给客户端。 proxy_pass http://172.30.1.108/; #proxy_connect_timeout time;配置nginx服务器与后端服务器尝试建立连接的超时时间,默认为60秒,用法如下: proxy_connect_timeout 60s; } location /static { #不带斜线将访问的/static,等于访问后端服务器 http://172.30.1.108:80/static/index.html,即后端服务器配置的站点根目录要有/static目录才可以被访问。 proxy_pass http://172.30.1.108; } location /image { proxy_pass http://172.30.1.108; #proxy_hide_header指令用于nginx作为反向代理的时候,在返回给客户端http响应的时候,用于隐藏后端服务器特定的响应首部, #默认nginx在响应报文中不传递后端服务器的首部字段Dte, Server, XPad,X-Accel等,可以设置在http,server,location块. #隐藏掉ETag的文本值,CDN会根据ETag的值是否发生变化而决定该文件内容是否发生变化,一旦发生变化CDN会重新抓取该数据并缓存,此处我故意隐藏该值。 proxy_hide_header ETag; } location /dynamic { proxy_pass http://172.30.1.108; #proxy_set_header可以更改或添加客户端的请求头部信息内容并转发至后端服务器,比如在后端服务器想要获取客户端的真实IP的时候,就要更改每一个报文的头部。 #添加HOST到报文头部,如果客户端为NAT上网那么其值为客户端的共用的公网IP地址。 proxy_set_header yinzhengjie_nginx_ip_forwarded $proxy_add_x_forwarded_for; } } [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# nginx -t nginx: the configuration file /yinzhengjie/softwares/nginx/conf/nginx.conf syntax is ok nginx: configuration file /yinzhengjie/softwares/nginx/conf/nginx.conf test is successful [root@node101.yinzhengjie.org.cn ~]#
3>.重新加载nginx的配置文件
[root@node101.yinzhengjie.org.cn ~]# ps -ef | grep nginx | grep -v grep root 21155 1 0 13:38 ? 00:00:00 nginx: master process nginx nginx 21156 21155 5 13:38 ? 00:00:00 nginx: worker process nginx 21157 21155 5 13:38 ? 00:00:00 nginx: worker process nginx 21158 21155 6 13:38 ? 00:00:00 nginx: worker process nginx 21159 21155 8 13:38 ? 00:00:00 nginx: worker process [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# nginx -s reload [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# ps -ef | grep nginx | grep -v grep root 21155 1 3 13:38 ? 00:00:00 nginx: master process nginx nginx 21165 21155 32 13:38 ? 00:00:00 nginx: worker process nginx 21166 21155 28 13:38 ? 00:00:00 nginx: worker process nginx 21167 21155 32 13:38 ? 00:00:00 nginx: worker process nginx 21168 21155 10 13:38 ? 00:00:00 nginx: worker process [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]#
4>.浏览器访问"http://node101.yinzhengjie.org.cn/app01",如下图所示。
5>.浏览器访问"http://node101.yinzhengjie.org.cn/static/",如下图所示。
6>.浏览器访问"http://node101.yinzhengjie.org.cn/image/",如下图所示。
7>.浏览器访问"http://node101.yinzhengjie.org.cn/dynamic/",如下图所示。
五.Nginx服务器反向代理常用的配置指令说明
1>.proxy_pass
用来设置将客户端请求转发给的后端服务器的主机,可以是主机名、IP地址:端口的方式,也可以代理到预先设置的主机群组,需要模块gx_http_upstream_module支持。 博主推荐阅读:
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
2>.proxy_hide_header
用于nginx作为反向代理的时候,在返回给客户端http响应的时候,隐藏后端服务版本相应头部的信息,可以设置在http/server或location块,用于隐藏后端服务器特定的响应首部,默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, XPad,X-Accel等。 博主推荐阅读: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header
3>.proxy_pass_request_body
是否向后端服务器发送HTTP包体部分,可以设置在http/server或location块,默认即为开启。 博主推荐阅读: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass_request_body
4>.proxy_pass_request_headers
是否将客户端的请求头部转发给后端服务器,可以设置在http/server或location块,默认即为开启。
博主推荐阅读: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass_request_headers
5>.proxy_set_header
可以更改或添加客户端的请求头部信息内容并转发至后端服务器,比如在后端服务器想要获取客户端的真实IP的时候,就要更改每一个报文的头部。即添加HOST到报文头部,如果客户端为NAT上网那么其值为客户端的共用的公网IP地址。 博主推荐阅读: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
6>.proxy_connect_timeout
配置nginx服务器与后端服务器尝试建立连接的超时时间,默认为60秒。 博主推荐阅读:
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_connect_timeout
7>.proxy_read_timeout
配置nginx服务器向后端服务器或服务器组发起read请求后,等待的超时时间,默认60s。 博主推荐阅读: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout
8>.proxy_send_timeout
配置nginx项后端服务器或服务器组发起write请求后,等待的超时时间,默认60s 博主推荐阅读:
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_send_timeout
9>.proxy_http_version
用于设置nginx提供代理服务的HTTP协议的版本,默认http 1.0版本。 博主推荐阅读: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version
10>.proxy_ignore_client_abort
当客户端网络中断请求时,nginx服务器中断其对后端服务器的请求。即如果此项设置为on开启,则服务器会忽略客户端中断并一直等着代理服务执行返回,如果设置为off,则客户端中断后Nginx也会中断客户端请求并立即记录499日志,默认为off。 博主推荐阅读: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_client_abort
11>.proxy_headers_hash_bucket_size
当配置了 proxy_hide_header和proxy_set_header的时候,用于设置nginx保存HTTP报文头的hash表的上限。 博主推荐阅读: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_headers_hash_bucket_size
12>.proxy_headers_hash_max_size
设置proxy_headers_hash_bucket_size的最大可用空间,设置服务器名称的hash表上限大小。 博主推荐阅读: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_headers_hash_max_size
本文来自博客园,作者:尹正杰,转载请注明原文链接:https://www.cnblogs.com/yinzhengjie/p/12099808.html,个人微信: "JasonYin2020"(添加时请备注来源及意图备注,有偿付费)
当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。