nginx配置正向代理支持http和https转发 作者: sysit 分类: d 发表于 2020-01-07 386人围观 ## 1. 场景说明 在一次项目中,需要使用nginx配置正向代理,实现HTTPS的转发,但是Nginx本身不支持HTTPS正向代理。按照HTTP配置正向代理后,访问HTTPS遇到HTTP 400错误,安装ngx_http_proxy_connect_module模块后解决。本文记录Nginx编译及模块集成的步骤。 错误信息如下: ``` curl: (56) Received HTTP code 400 from proxy after CONNECT ``` 特别注意:ngx_http_proxy_module用户http代理,ngx_http_proxy_connect_module用于https代理。 ## 2. 编译Nginx ### 2.1 编译环境 ``` yum install gcc gcc-c++ autoconf automake -y yum install pcre pcre-devel -y yum install zlib zlib-devel -y yum install openssl openssl-devel -y yum install patch -y yum install git -y ``` ### 2.2 下载软件 ``` # 下载nginx wget http://nginx.org/download/nginx-1.16.1.tar.gz # 下载ngx_http_proxy_connect_module git clone https://github.com/chobits/ngx_http_proxy_connect_module.git ``` ### 2.3 为nginx打patch >参考文档https://github.com/chobits/ngx_http_proxy_connect_module ``` tar -zxvf nginx-1.16.1.tar.gz cd nginx-1.16.1/ # 选择patch版本 # 文档:https://github.com/chobits/ngx_http_proxy_connect_module#select-patch patch -p1 < /patch/ngx_http_proxy_connect_module/patch/proxy_connect_rewrite_101504.patch ``` ### 2.4 编译安装nginx * 安装pcre ``` mkdir /usr/local/pcre tar zxvf pcre-8.43.tar.gz cd pcre-8.43 ./configure --prefix=/usr/local/pcre make make install ``` * 安装openssl ``` cd /usr/local/src mkdir /usr/local/openssl tar zxvf openssl-1.1.0l.tar.gz cd openssl-1.1.0l ./config --prefix=/usr/local/openssl make make install vi /etc/profile export PATH=$PATH:/usr/local/openssl/bin :wq! source /etc/profile ``` * 安装zlib ``` cd /usr/local/src mkdir /usr/local/zlib tar zxvf zlib-1.2.11.tar.gz cd zlib-1.2.11 ./configure --prefix=/usr/local/zlib make make install ``` * 编译nginx ``` groupadd nginx useradd -g nginx nginx -s /bin/false ./configure --prefix=/usr/local/nginx \ --without-http_memcached_module \ --user=nginx \ --group=nginx \ --with-http_stub_status_module \ --with-http_ssl_module \ --with-http_gzip_static_module \ --with-openssl=/usr/local/src/openssl-1.1.0l \ --with-zlib=/usr/local/src/zlib-1.2.11 \ --with-pcre=/usr/local/src/pcre-8.43 \ --add-module=/downloads/ngx_http_proxy_connect_module ``` > 注意:--with-openssl=/usr/local/src/openssl-1.1.0l --with-zlib=/usr/local/src/zlib-1.2.11 --with-pcre=/usr/local/src/pcre-8.43指向的是源码包解压的路径,而不是安装的路径,否则会报错 > --add-module=/downloads/ngx_http_proxy_connect_module指向ngx_http_proxy_connect的目录 * 启动nginx ``` /usr/local/nginx/sbin/nginx ``` ## 3. nginx正向代理配置文件 ### 3.1 配置文件 ``` server { resolver 114.114.114.114; listen 8080; location / { proxy_pass http://$http_host$request_uri; proxy_set_header HOST $http_host; proxy_buffers 256 4k; proxy_max_temp_file_size 0k; proxy_connect_timeout 30; proxy_send_timeout 60; proxy_read_timeout 60; proxy_next_upstream error timeout invalid_header http_502; } } server { listen 8443; # dns resolver used by forward proxying resolver 114.114.114.114; # forward proxy for CONNECT request proxy_connect; proxy_connect_allow 443 563; proxy_connect_connect_timeout 10s; proxy_connect_read_timeout 10s; proxy_connect_send_timeout 10s; # forward proxy for non-CONNECT request location / { proxy_pass http://$host; proxy_set_header Host $host; } } ``` ## 4. 查看端口和防火墙 * 端口 ``` netstat -tnlp | grep 8080 netstat -tnlp | grep 8443 ``` * 防火墙 ``` firewall-cmd --zone=public --add-port=8080/tcp --permanent firewall-cmd --zone=public --add-port=8443/tcp --permanent firewall-cmd --reload ``` ## 5. 测试代理 ``` # Test HTTP proxy curl --proxy 192.168.87.123:8080 http://www.baidu.com # Test HTTPS proxy curl --proxy 192.168.87.123:8443 https://www.baidu.com ``` ## 6. 附ngx_http_proxy_module和ngx_http_proxy_connect_module参数说明 ### 6.1 ngx_http_proxy_module的指令 该模块用于http连接 * proxy_pass ``` 语法:proxy_pass URL 默认值: 上下文:location 功能:该指令用于设置被代理服务器的协议、主机名、IP地址和端口等形式。 注意: (1)proxy_pass后面的路径不带uri时,其会将location的uri传递给后端主机; (2)proxy_pass后面的路径是一个uri时,其会将location的uri替换为proxy_pass的uri; (3)如果location定义其uri时使用了正则表达式的模式,或在if语句或limt_execept中使用proxy_pass指令,则proxy_pass之后必须不能使用uri; (4)用户请求时传递的uri将直接附加代理到的服务的之后; ``` * proxy_set_header ``` 语法:proxy_set_header field value 功能:设定发往后端主机的请求报文的请求首部的值; 上下文: http, server, location 参数说明: Field:要更改信息所在的头域 value:更改的值,支持使用文本、变量或者变量的组合 示例: proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ``` * proxy_cache_path ``` 语法:proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size]… 功能:定义可用于proxy功能的缓存; 上下文: http 参数说明: levels:设置在对于path指定目录的第几级hash目录中缓存数据 key_zone:Nginx服务器的缓存索引从简进程在内存中为缓存数据建立索引,用来定义放存缓存索引的内存区域的名称和大小 inactive;表示缓存有效时间 max_size:设置硬盘中缓存数据大大小 ``` * proxy_cache ``` 语法:proxy_cache zone | off; 功能:指明要调用的缓存,或关闭缓存机制; 上下文: http, server, location ``` * proxy_cache_key ``` 语法: proxy_cache_key string; 功能: 缓存中用于“键”的内容; 默认值:proxy_cache_key $scheme$proxy_host$request_uri; ``` * proxy_cache_valid ``` 语法:proxy_cache_valid [code …] time; 功能:定义对特定响应码的响应内容的缓存时长; ``` * proxy_cache_use_stale ``` 用法:proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off …; 说明:如果Nginx在访问被代理服务器过程中出现被代理服务器无法访问或者访问错误等现象时,Niginx服务器可以使用历史缓存响应客户端的请求,这些数据不一定和被代理服务器上的最新的数据相一致,但对于更新频率不高的后端服务器来事,nginx服务器的该功能在一定程度上能够为客户端提供不间断访问。 ``` * proxy_cache_methods ``` 语法:proxy_cache_methods GET | HEAD | POST …; 功能:根据客户端请求报文请求方式,来选着需要缓存的数据 ``` * proxy_hide_header ``` 语法:proxy_hide_header field; 功能:该指令用于设置nginx服务器在发送响应报文时,隐藏一些头信息 ``` * proxy_connect_timeout ``` 语法:proxy_connect_timeout time; 功能:该指令来设定nginx服务器域后端被代理服务器尝试连接的超时时间。默认为60s;最长为75s; ``` * proxy_read_timeout ``` 语法:proxy_read_timeout time; 功能:该指令设置nginx服务器向后端被代理服务器发出read请求后,等待响应的超时时间 ``` * proxy_send_timeout ``` 语法:proxy_send_timeout time; 功能:该指令设置nginx服务器向后端被代理服务器发出write请求后,等待响应的超时时间 ``` ### 6.2 ngx_http_proxy_connect_module的指令 * proxy_connect ``` 语法: proxy_connect 默认值: none 上下文: server 功能:Enable "CONNECT" HTTP method support. ``` * proxy_connect_allow ``` 语法: proxy_connect_allow all | [port ...] | [port-range ...] 默认值: 443 563 上下文: server 功能:本指令指定的端口列表或者端口范围代理CONNECT方法连接。 值说明: 默认值是https端口443和snews端口563。 值all允许代理所有的端口; 值port指定端口连接; 值port-range允许代理指定的端口范围,如: proxy_connect_allow 1000-2000 3000-4000; # allow range of port from 1000 to 2000, from 3000 to 4000. ``` * proxy_connect_connect_timeout ``` 语法: proxy_connect_connect_timeout time 默认值: none 上下文: server 功能:定义一个与被代理服务器建立连接的超时时间。 ``` * proxy_connect_read_timeout ``` 语法: proxy_connect_read_timeout time 默认值: 60s 上下文: server 功能:定义一个从被代理服务器读取响应的超时时间。 说明:这个超时时间只是设置在两个连续的读取操作的响应时间,不是全部传输响应时间,如果被代理服务器在这个时间内没有任何响应,连接将被关闭。 ``` * proxy_connect_send_timeout ``` 语法: proxy_connect_send_timeout time 默认值: 60s 上下文: server 功能:设置一个发送请求到被代理服务器的超时时间。 说明:这个超时时间只是设置在两个连续的写操作的响应时间,不是全部传输响应时间,如果被代理服务器没有在超时时间范围内接收到任何请求,连接关闭。 ``` * proxy_connect_address ``` 语法: proxy_connect_address address | off 默认值: none 上下文: server 功能:特定的代理服务器地址,可以包含变量。 说明:值off表示none。 注意:如果set $<nginx variable> 和proxy_connect_address $<nginx variable> 一起使用,需要使用proxy_connect_rewrite.patch ``` * proxy_connect_bind ``` 语法: proxy_connect_bind address [transparent] | off 默认值: none 上下文: server 功能:使用特定的本地的IP地址和端口代理向被代理服务器发起连接。 说明:值可以包含变量;off参数等同于none,允许系统自动分配一个本地IP地址和端口;transparent参数允许非本地IP发起连接,比如使用客户端的真实IP发起请求:proxy_connect_bind $remote_addr transparent; ``` ### 6.3 ngx_http_proxy_connect_module参数 ``` $connect_host 主机名 $connect_port 端口 $connect_addr 远程主机IP地址和端口,如"192.168.1.5:12345" $proxy_connect_connect_timeout 获取或设置proxy_connect_connect_timeout指令。 如 # Set default value proxy_connect_connect_timeout 10s; proxy_connect_read_timeout 10s; proxy_connect_send_timeout 10s; # Overlap default value if ($host = "test.com") { set $proxy_connect_connect_timeout "10ms"; set $proxy_connect_read_timeout "10ms"; set $proxy_connect_send_timeout "10ms"; } $proxy_connect_read_timeout 获取或设置proxy_connect_read_timeout超时时间 $proxy_connect_send_timeout 获取或设置proxy_connect_send_timeout超时时间 ``` ## 7. 附nginx编译参数 ``` nginx参数: --prefix= 指向安装目录 --sbin-path 指向(执行)程序文件(nginx) --conf-path= 指向配置文件(nginx.conf) --error-log-path= 指向错误日志目录 --pid-path= 指向pid文件(nginx.pid) --lock-path= 指向lock文件(nginx.lock)(安装文件锁定,防止安装文件被别人利用,或自己误操作。) --user= 指定程序运行时的非特权用户 --group= 指定程序运行时的非特权用户组 --builddir= 指向编译目录 --with-rtsig_module 启用rtsig模块支持(实时信号) --with-select_module 启用select模块支持(一种轮询模式,不推荐在高载环境下使用)禁用:--without-select_module --with-poll_module 启用poll模块支持(功能与select相同,与select特性相同,为一种轮询模式,不推荐在高载环境下使用) --with-file-aio 启用file aio支持(一种APL文件传输格式) --with-ipv6 启用ipv6支持 --with-http_ssl_module 启用ngx_http_ssl_module支持(使支持https请求,需已安装openssl) --with-http_realip_module 启用ngx_http_realip_module支持(这个模块允许从请求标头更改客户端的IP地址值,默认为关) --with-http_addition_module 启用ngx_http_addition_module支持(作为一个输出过滤器,支持不完全缓冲,分部分响应请求) --with-http_xslt_module 启用ngx_http_xslt_module支持(过滤转换XML请求) --with-http_image_filter_module 启用ngx_http_image_filter_module支持(传输JPEG/GIF/PNG 图片的一个过滤器)(默认为不启用。gd库要用到) --with-http_geoip_module 启用ngx_http_geoip_module支持(该模块创建基于与MaxMind GeoIP二进制文件相配的客户端IP地址的ngx_http_geoip_module变量) --with-http_sub_module 启用ngx_http_sub_module支持(允许用一些其他文本替换nginx响应中的一些文本) --with-http_dav_module 启用ngx_http_dav_module支持(增加PUT,DELETE,MKCOL:创建集合,COPY和MOVE方法)默认情况下为关闭,需编译开启 --with-http_flv_module 启用ngx_http_flv_module支持(提供寻求内存使用基于时间的偏移量文件) --with-http_gzip_static_module 启用ngx_http_gzip_static_module支持(在线实时压缩输出数据流) --with-http_random_index_module 启用ngx_http_random_index_module支持(从目录中随机挑选一个目录索引) --with-http_secure_link_module 启用ngx_http_secure_link_module支持(计算和检查要求所需的安全链接网址) --with-http_degradation_module 启用ngx_http_degradation_module支持(允许在内存不足的情况下返回204或444码) --with-http_stub_status_module 启用ngx_http_stub_status_module支持(获取nginx自上次启动以来的工作状态) --without-http_charset_module 禁用ngx_http_charset_module支持(重新编码web页面,但只能是一个方向--服务器端到客户端,并且只有一个字节的编码可以被重新编码) --without-http_gzip_module 禁用ngx_http_gzip_module支持(该模块同-with-http_gzip_static_module功能一样) --without-http_ssi_module 禁用ngx_http_ssi_module支持(该模块提供了一个在输入端处理处理服务器包含文件(SSI)的过滤器,目前支持SSI命令的列表是不完整的) --without-http_userid_module 禁用ngx_http_userid_module支持(该模块用来处理用来确定客户端后续请求的cookies) --without-http_access_module 禁用ngx_http_access_module支持(该模块提供了一个简单的基于主机的访问控制。允许/拒绝基于ip地址) --without-http_auth_basic_module禁用ngx_http_auth_basic_module(该模块是可以使用用户名和密码基于http基本认证方法来保护你的站点或其部分内容) --without-http_autoindex_module 禁用disable ngx_http_autoindex_module支持(该模块用于自动生成目录列表,只在ngx_http_index_module模块未找到索引文件时发出请求。) --without-http_geo_module 禁用ngx_http_geo_module支持(创建一些变量,其值依赖于客户端的IP地址) --without-http_map_module 禁用ngx_http_map_module支持(使用任意的键/值对设置配置变量) --without-http_split_clients_module 禁用ngx_http_split_clients_module支持(该模块用来基于某些条件划分用户。条件如:ip地址、报头、cookies等等) --without-http_referer_module 禁用disable ngx_http_referer_module支持(该模块用来过滤请求,拒绝报头中Referer值不正确的请求) --without-http_rewrite_module 禁用ngx_http_rewrite_module支持(该模块允许使用正则表达式改变URI,并且根据变量来转向以及选择配置。如果在server级别设置该选项,那么他们将在 location之前生效。如果在location还有更进一步的重写规则,location部分的规则依然会被执行。如果这个URI重写是因为location部分的规则造成的,那么 location部分会再次被执行作为新的URI。 这个循环会执行10次,然后Nginx会返回一个500错误。) --without-http_proxy_module 禁用ngx_http_proxy_module支持(有关代理服务器) --without-http_fastcgi_module 禁用ngx_http_fastcgi_module支持(该模块允许Nginx 与FastCGI 进程交互,并通过传递参数来控制FastCGI 进程工作。 )FastCGI一个常驻型的公共网关接口。 --without-http_uwsgi_module 禁用ngx_http_uwsgi_module支持(该模块用来医用uwsgi协议,uWSGI服务器相关) --without-http_scgi_module 禁用ngx_http_scgi_module支持(该模块用来启用SCGI协议支持,SCGI协议是CGI协议的替代。它是一种应用程序与HTTP服务接口标准。它有些像FastCGI但他的设计 更容易实现。) --without-http_memcached_module 禁用ngx_http_memcached_module支持(该模块用来提供简单的缓存,以提高系统效率) -without-http_limit_zone_module 禁用ngx_http_limit_zone_module支持(该模块可以针对条件,进行会话的并发连接数控制) --without-http_limit_req_module 禁用ngx_http_limit_req_module支持(该模块允许你对于一个地址进行请求数量的限制用一个给定的session或一个特定的事件) --without-http_empty_gif_module 禁用ngx_http_empty_gif_module支持(该模块在内存中常驻了一个1*1的透明GIF图像,可以被非常快速的调用) --without-http_browser_module 禁用ngx_http_browser_module支持(该模块用来创建依赖于请求报头的值。如果浏览器为modern ,则$modern_browser等于modern_browser_value指令分配的值;如 果浏览器为old,则$ancient_browser等于 ancient_browser_value指令分配的值;如果浏览器为 MSIE中的任意版本,则 $msie等于1) --without-http_upstream_ip_hash_module 禁用ngx_http_upstream_ip_hash_module支持(该模块用于简单的负载均衡) --with-http_perl_module 启用ngx_http_perl_module支持(该模块使nginx可以直接使用perl或通过ssi调用perl) --with-perl_modules_path= 设定perl模块路径 --with-perl= 设定perl库文件路径 --http-log-path= 设定access log路径 --http-client-body-temp-path= 设定http客户端请求临时文件路径 --http-proxy-temp-path= 设定http代理临时文件路径 --http-fastcgi-temp-path= 设定http fastcgi临时文件路径 --http-uwsgi-temp-path= 设定http uwsgi临时文件路径 --http-scgi-temp-path= 设定http scgi临时文件路径 -without-http 禁用http server功能 --without-http-cache 禁用http cache功能 --with-mail 启用POP3/IMAP4/SMTP代理模块支持 --with-mail_ssl_module 启用ngx_mail_ssl_module支持 --without-mail_pop3_module 禁用pop3协议(POP3即邮局协议的第3个版本,它是规定个人计算机如何连接到互联网上的邮件服务器进行收发邮件的协议。是因特网电子邮件的第一个离线协议标 准,POP3协议允许用户从服务器上把邮件存储到本地主机上,同时根据客户端的操作删除或保存在邮件服务器上的邮件。POP3协议是TCP/IP协议族中的一员,主要用于 支持使用客户端远程管理在服务器上的电子邮件) --without-mail_imap_module 禁用imap协议(一种邮件获取协议。它的主要作用是邮件客户端可以通过这种协议从邮件服务器上获取邮件的信息,下载邮件等。IMAP协议运行在TCP/IP协议之上, 使用的端口是143。它与POP3协议的主要区别是用户可以不用把所有的邮件全部下载,可以通过客户端直接对服务器上的邮件进行操作。) --without-mail_smtp_module 禁用smtp协议(SMTP即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP协议属于TCP/IP协议族,它帮助每台计算机在发送或中转信件时找到下一个目的地。) --with-google_perftools_module 启用ngx_google_perftools_module支持(调试用,剖析程序性能瓶颈) --with-cpp_test_module 启用ngx_cpp_test_module支持 --add-module= 启用外部模块支持 --with-cc= 指向C编译器路径 --with-cpp= 指向C预处理路径 --with-cc-opt= 设置C编译器参数(PCRE库,需要指定–with-cc-opt=”-I /usr/local/include”,如果使用select()函数则需要同时增加文件描述符数量,可以通过–with-cc- opt=”-D FD_SETSIZE=2048”指定。) --with-ld-opt= 设置连接文件参数。(PCRE库,需要指定–with-ld-opt=”-L /usr/local/lib”。) --with-cpu-opt= 指定编译的CPU,可用的值为: pentium, pentiumpro, pentium3, pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64 --without-pcre 禁用pcre库 --with-pcre 启用pcre库 --with-pcre= 指向pcre库文件目录 --with-pcre-opt= 在编译时为pcre库设置附加参数 --with-md5= 指向md5库文件目录(消息摘要算法第五版,用以提供消息的完整性保护) --with-md5-opt= 在编译时为md5库设置附加参数 --with-md5-asm 使用md5汇编源 --with-sha1= 指向sha1库目录(数字签名算法,主要用于数字签名) --with-sha1-opt= 在编译时为sha1库设置附加参数 --with-sha1-asm 使用sha1汇编源 --with-zlib= 指向zlib库目录 --with-zlib-opt= 在编译时为zlib设置附加参数 --with-zlib-asm= 为指定的CPU使用zlib汇编源进行优化,CPU类型为pentium, pentiumpro --with-libatomic 为原子内存的更新操作的实现提供一个架构 --with-libatomic= 指向libatomic_ops安装目录 --with-openssl= 指向openssl安装目录 --with-openssl-opt 在编译时为openssl设置附加参数 --with-debug 启用debug日志 ``` 如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作! 赞赏支持