什么,NGINX无法正向代理HTTPS?

需求

内网的机器无法访问互联网,但是有些业务服务必须要上网,这个时候就需要一个正向代理,将正向代理部署在一台可以上网的机器,业务应用通过正向代理去访问互联网,同时使用正向代理控制上网策略和权限。

什么是正向代理?

正向代理就是客户端client知道服务器server的地址,也知道proxy的地址,但是client通过proxy,并且告诉proxy,我要访问server的地址,proxy将请求直接转发到server。正向代理最常见的应用是VPN,用来突破client到server的网络限制。

与之对应的就是反向代理,反向代理是client不知道server的地址,但知道proxy的地址,client请求proxy,proxy根据配置的规则转发给server,这里client是不知道具体server的地址,都是通过proxy里的规则进行转发。反向代理最常见的工具就是Nginx。

我现在需要在linux服务器上做正向代理,查了下可以用的工具Squid,Nginx。作为研发来说,Squid比较陌生,nginx那是经常打交道,那就用nginx来搭建了。(nginx是反向代理的代表,其实也可以用来做正向代理)

nginx搭建正向代理

简单介绍下nginx做正向代理的原理,在nginx的配置中加上 resolver 8.8.8.8,其他配置通用,就可以做正向代理了,而这个配置的作用是:指定固定的DNS服务器,而8.8.8.8是Google提供的全球DNS服务器。这样就可以把请求直接转到Google的DNS服务器,然后DNS直接转发出去。完整配置如下:

ini 复制代码
worker_processes  3;
​
events {
    worker_connections  1024;
}
​
http {
    include       mime.types;
    default_type  application/octet-stream;
​
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                              '$status $body_bytes_sent $request_body "$http_referer" '
                              '"$http_user_agent" "$http_x_forwarded_for" "$request_time"';
​
    access_log  /etc/nginx/logs/access.log  main;
​
​
    sendfile        on;
​
    server {
      listen 10080; # 代理监听的端口
      proxy_connect;
      server_name *.com;
      proxy_max_temp_file_size 0; 
      resolver 8.8.8.8; # DNS 解析器,使用 Google 的公共 DNS
​
      # 处理所有 HTTP 请求
      location / {
        proxy_pass http://$http_host;
        proxy_set_header Host $http_host;
        proxy_ssl_server_name on;
        proxy_ssl_session_reuse off;
        proxy_next_upstream error timeout invalid_header http_502;
        proxy_buffer_size 4k; # 调整缓冲区大小
        proxy_buffers 4 8k;
        proxy_busy_buffers_size 16k;
        }   
     }
}

将nginx运行起来之后,可以直接用curl进行测试代理是否正常,脚本如下:

rust 复制代码
curl --proxy "http://xx.xx.xx.xx:xx" 'http://www.baidu.com'

如无意外的情况下,可以得到正常返回了。但是我把http改成https之后,立马就返回400 bad request了。这时候可能以为是配置出问题了,其实是nginx代理并不支持https的正向代理转发,搞了半天,不支持https,有点扎心,那么nginx能否支持https的正向代理呢?答案是可以的。

github上有个大神,写了个ngx_http_proxy_connect_module(github.com/chobits/ngx...),用来解决nginx代理无法转发https的问题。可以参照文档内容将模块编译到nginx中。当然如果你觉得这样比较麻烦的话,有更简单的方法。我现在运维部署一些开源软件时,基本都是用docker去部署的,使用docker部署的好处我就不在这里赘述了。那现在我就介绍一下使用docker部署nginx的方式。

首先我们就是找一个已经编译了ngx_http_proxy_connect_module的nginx打包好的镜像,我用的是这个:github.com/reiz/nginx_...。部署就简单了,docker-compose文件如下

yaml 复制代码
version: '2'
services:
  nginx:
    image: reiz/nginx_proxy:0.0.5
    container_name: proxy_nginx
    restart: always
    ports:
      - '10080:10080'
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - ./nginx.conf:/usr/local/nginx/conf/nginx.conf
      - ./logs:/etc/nginx/logs

接下来是nginx.conf:

ini 复制代码
daemon off;
worker_processes  auto;
​
events {
    worker_connections  1024;
}
​
​
http {
    server_names_hash_bucket_size 128;
​
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                              '$status $body_bytes_sent $request_body "$http_referer" '
                              '"$http_user_agent" "$http_x_forwarded_for" "$request_time"';
​
​
    access_log  /etc/nginx/logs/access.log;
    error_log   /etc/nginx/logs/error.log;
    sendfile        on;
    keepalive_timeout 65;
​
    server {
        listen       10080;
        #server_name  *.com;
​
        proxy_connect;
        resolver 8.8.8.8 ipv6=off;
        location / {
           proxy_pass http://$http_host;
           proxy_set_header Host $http_host;
        }
      }
}

nginx.conf可以配置访问的地址和禁止访问的地址,及其他的配置,可以看作者的使用文档。

问题

Cannot assign requested address

在连续请求的时候,有一半的请求会报无法分配地址,这个问题还挺棘手,最后发现是ipv6的问题,要关闭ipv6才行,resolver 8.8.8.8 ipv6=off; 关闭了之后就没有出现这个问题。

相关推荐
qq_17448285756 小时前
springboot基于微信小程序的旧衣回收系统的设计与实现
spring boot·后端·微信小程序
锅包肉的九珍7 小时前
Scala的Array数组
开发语言·后端·scala
心仪悦悦7 小时前
Scala的Array(2)
开发语言·后端·scala
2401_882727577 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
心仪悦悦7 小时前
Scala中的集合复习(1)
开发语言·后端·scala
代码小鑫8 小时前
A043-基于Spring Boot的秒杀系统设计与实现
java·开发语言·数据库·spring boot·后端·spring·毕业设计
真心喜欢你吖8 小时前
SpringBoot与MongoDB深度整合及应用案例
java·spring boot·后端·mongodb·spring
激流丶8 小时前
【Kafka 实战】Kafka 如何保证消息的顺序性?
java·后端·kafka
uzong9 小时前
一个 IDEA 老鸟的 DEBUG 私货之多线程调试
java·后端
墨鸦_Cormorant9 小时前
使用docker快速部署Nginx、Redis、MySQL、Tomcat以及制作镜像
redis·nginx·docker