跳至主要內容

Nginx搭建http代理服务器

xlc520LinuxLinux大约 7 分钟约 1982 字

Nginx 搭建 http 代理服务器

参考 : https://blog.csdn.net/weixin_43834401/article/details/130670792open in new window

Nginx 服务器作为正向代理服务器和反向代理服务器,但美中不足的是仅支持http协议,不支持https协议

http 和 https 的区别:

  • http 协议:协议以明文方式发送数据,不提供任何方式的数据加密。不适合传输一些敏感信息,例如密码。其使用的端口是80
  • https 协议:在 http 协议的基础上,加入了SSL(Secure Sockets Layer),用于对数据进行加密。其使用的端口为443

1.Nginx 正向代理(http)

我们来回顾一下 Nginx 作为正向代理服务器支持 http 协议的配置。

代理服务器:192.168.110.101

代理服务器配置:

server {
    listen 8080;
    server_name localhost;
    # 解析域名时需要配置
    resolver 8.8.8.8;
    location / {
        proxy_pass http://$host$request_uri;
    }
}

客户端配置:

我们使用 Windows 系统作为客户端环境。

访问http://nginx.org/en/index.html,可以正常访问。

访问https://www.baidu.com,则无法正常访问了。

查看代理服务器的error.log,发现其报 400 错误码。

这是因为,Nginx 作为正向代理服务器时,默认仅支持 http 协议,是不支持 https 协议的。

2.Nginx 正向代理(https)

那么怎么让 Nginx 作为正向代理服务器的时候支持 https 协议呢?

我们可以使用第三方模块ngx_http_proxy_connect_module

下载地址:https://github.com/chobits/ngx_http_proxy_connect_moduleopen in new window

我们知道如果要为 Nginx 添加第三方模块,需要在配置configure时添加--add-module。从 Nginx1.9.11 版本开始,支持load_module指令来动态加载模块。

我们这里使用--add-module进行模块的添加。

1)查看 Nginx 版本以及 configure 信息

nginx -V

nginx version: nginx/1.22.1
built by gcc 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1) 
configure arguments: --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_gzip_static_module

2)下载模块

下载地址:https://codeload.github.com/chobits/ngx_http_proxy_connect_module/zip/refs/heads/masteropen in new window

3)重新编译

这里我们两种添加第三方模块的方式都尝试一下。

使用--add-module

cd /home/stone/nginx-1.22.1

# 1、添加patch
patch -p1 < /home/stone/nginx-1.22.1/module/ngx_http_proxy_connect_module/patch/proxy_connect_rewrite_102101.patch

# 2、configure
./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_gzip_static_module --add-module=/home/stone/nginx-1.22.1/module/ngx_http_proxy_connect_module

# 3、make
make

# 4、备份旧的nginx可执行文件,复制编译之后的可执行文件
mv /usr/local/nginx/nginx /usr/local/nginx/nginx.old
cp objs/nginx /usr/local/nginx/nginx

# 5、升级
make upgrade

使用load_module,需要将--add-module替换为--add-dynamic-module

cd /home/stone/nginx-1.22.1

# 1、添加patch
patch -p1 < /home/stone/nginx-1.22.1/module/ngx_http_proxy_connect_module/patch/proxy_connect_rewrite_102101.patch

# 2、configure
./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_gzip_static_module --add-dynamic-module=/home/stone/nginx-1.22.1/module/ngx_http_proxy_connect_module

# 3、make
make

# 4 创建module文件夹,并将编译生成的ngx_http_proxy_connect_module.so拷贝过去
mkdir /usr/local/nginx/module
cp /home/stone/nginx-1.22.1/objs/ngx_http_proxy_connect_module.so /usr/local/nginx/module

# 5、备份旧的nginx可执行文件,复制编译之后的可执行文件
mv /usr/local/nginx/nginx /usr/local/nginx/nginx.old
cp objs/nginx /usr/local/nginx/nginx

# 6、升级
make upgrade

4)修改配置文件

# --add-dynamic-module动态添加第三方模块时使用
# load_module module/ngx_http_proxy_connect_module.so;

http {

 server {
        resolver 114.114.114.114 8.8.8.8;
        resolver_timeout 10s;
        listen 82;
        proxy_connect;                          #启用 CONNECT HTTP方法
        #proxy_connect_allow  443 80;  #指定代理CONNECT方法可以连接的端口号或范围的列表,all;#支持不同端口https
        proxy_connect_allow            all;  #支持不同端口https
        proxy_connect_connect_timeout  20s;     #定义客户端与代理服务器建立连接的超时时间
        proxy_connect_read_timeout     20s;     #定义客户端从代理服务器读取响应的超时时间
        proxy_connect_send_timeout     20s;     #设置客户端将请求传输到代理服务器的超时时间
        proxy_connect_data_timeout     10s;
        location / {
             proxy_pass $scheme://$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 8080;
        server_name localhost;
        resolver 114.114.114.114 ipv6=off;
        proxy_connect;
        proxy_connect_allow 443 80;
        proxy_connect_connect_timeout  20s;     #定义客户端与代理服务器建立连接的超时时间
        proxy_connect_read_timeout     20s;     #定义客户端从代理服务器读取响应的超时时间
        proxy_connect_send_timeout     20s;     #设置客户端将请求传输到代理服务器的超时时间
        proxy_connect_data_timeout     10s;
        # 指定代理日志
        access_log logs/access_proxy.log main;
        location / {
            proxy_pass $scheme://$host$request_uri;
        }
    }
}

此时访问https://www.baidu.com,在access_proxy.log产生如下日志,说明 https 代理成功。

需要出网服务器配置 打开/etc/profile 文件,在最下面添加如下配置即可

#http代理,ip是nginx的ip,端口是步骤4配置的监听端口
export http_proxy="http://ip:82"
#https代理
export https_proxy="http://ip:82"
#不需要代理的ip,访问这些ip,不会走代理
export no_proxy="127.0.0.1, localhost"

测试

curl http://www.baidu.com
curl https://www.baidu.com

访问成功就恭喜你了

3.Nginx 反向代理(http)

同样的,Nginx 作为反向代理服务器,默认也是只支持 http 协议,我们来回顾一下 Nginx 作为反向代理服务器支持 http 协议的配置。

server {
    listen       80;
    server_name  localhost;
    location /proxy {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://192.168.110.98;
    }
}

可以看到,我们配置的server_namelocalhost,但在实际项目中,我们是使用域名绑定 Nginx 服务器的 IP,并且使用 https 协议进行访问,配置的server_name就是指定的域名,例如www.aaa.com

Nginx 为我们提供了ngx_http_ssl_module来支持 https 协议,并且在提供的默认配置文件里已经给出了示例。

4.Nginx 反向代理(https)

添加ngx_http_ssl_module的步骤和添加ngx_http_proxy_connect_module的步骤一致,只是这是 Nginx 提供的模块,因此在 configure 时使用--with-http_ssl_module 即可。

我们再来看看采用 https 协议时的配置:

server {
    listen       443 ssl;
    server_name  www.aaa.com;
    
    # 申请ssl证书后,会提供cert.pem和cert.key
    ssl_certificate      cert.pem;
    ssl_certificate_key  cert.key;

    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;

    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    location /proxy {
        proxy_pass http://192.168.110.98;
    }
}

我们需要去为指定的域名申请 ssl 证书,然后将证书中的cert.pemcert.key 放到指定文件,并在配置文件中指定。例如我们这里指定的server_namewww.aaa.com,所以我们就需要为www.aaa.com申请 ssl 证书。

后续我们访问https://www.aaa.com/proxy就可以被代理到指定服务端了。

其他(第二种)

如果不想写到 ngnix.conf 中,那么可以在相同的目录下建立另外一个文件夹存放单独的文件,比如新建一个 proxy 的子目录,然后再在里面新建文件 prox.conf ,然后添加如下内容:

server {
    resolver        8.8.8.8;
    access_log      off;
    listen  8088;
    location / {
        proxy_pass      $scheme://$host$request_uri;
        proxy_set_header Host $http_host;
        proxy_buffers   256 4k;
        proxy_max_temp_file_size        0k;
    }
}

接着在 ngnix.conf 的 http 块中添加:

include proxy/*.conf;

将上面文件的配置包含进来。

上面使用谷歌 DNS 8.8.8.8,你可能在本地也需要使用这个 DNS,否则可能会出现 502 的错误。不然可以配置 resolver 地址为你 ISP 分配的 DNS 地址。

配置完后,重启一下 nginx 或 reload 一下即可。

注意:由于 HTTP 代理和 VPN 不一样,后者加密,而前者不加密,所以 HTTP 代理是不能用来 FQ 的。

下面是类似配置内容:

server {
    resolver 202.106.0.20;
    resolver_timeout 5s;
    listen 81;
    location / {
        proxy_pass $scheme://$host$request_uri;
        proxy_set_header Host $http_host;
        proxy_buffers 256 4k;
        proxy_max_temp_file_size 0;
        proxy_connect_timeout 30;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 301 1h;
        proxy_cache_valid any 1m;
    }
}

Example2

server {
    listen 8899;
    charset utf-8;
    resolver 114.114.114.114;
    client_max_body_size     50m;
    access_log logs/proxy.log;

    #引用ngx_proxy模块
    proxy_connect;
    proxy_connect_allow            443 80;
    proxy_connect_connect_timeout  10s;
    proxy_connect_read_timeout     10s;
    proxy_connect_send_timeout     10s;

    location / {
        proxy_pass $scheme://$http_host$request_uri;
        proxy_connect_timeout 10;
         proxy_send_timeout 10;
         proxy_read_timeout 10;
         proxy_redirect     off;
         proxy_set_header Host $http_host;
         proxy_buffers 256 4k;
         proxy_next_upstream error timeout invalid_header http_502;
         proxy_max_temp_file_size 0k;
        proxy_ssl_server_name on;
    }
}

参数解析: 1,配置 DNS 解析 IP 地址,比如 北京 dns,以及超时时间(5 秒)。 resolver 202.106.0.20; resolver_timeout 5s;

注意项

  1. 不能有 hostname
  2. 必须有 resolver, 即 dns,即上面的 x.x.x.x,换成你们的 DNS 服务器 ip 即可

2,配置正向代理参数,均是由 Nginx 变量组成。其中 proxy_set_header 部分的配置,是为了解决如果 URL 中带 "."(点)后 Nginx 503 错误。 proxy_pass $scheme://$host$request_uri; $http_host 和$request_uri是nginx系统变量,不要想着替换他们,保持原样就OK。 proxy_set_header Host $http_host;

3,配置缓存大小,关闭磁盘缓存读写减少 I/O,以及代理连接超时时间。 proxy_buffers 256 4k; proxy_max_temp_file_size 0; proxy_connect_timeout 30;

4,配置代理服务器 Http 状态缓存时间。 proxy_cache_valid 200 302 10m; proxy_cache_valid 301 1h; proxy_cache_valid any 1m;

三、不支持代理 Https 网站 因为 Nginx 不支持 CONNECT,所以无法正向代理 Https 网站(网上银行,Gmail)。