什么,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; 关闭了之后就没有出现这个问题。

相关推荐
山岚的运维笔记4 分钟前
SQL Server笔记 -- 第69章:时态表
数据库·笔记·后端·sql·microsoft·sqlserver
Cache技术分享26 分钟前
330. Java Stream API - 处理 Optional 对象:像流一样优雅地使用 Optional
前端·后端
水冗水孚28 分钟前
使用Nginx auth_basic实现轻量级用户名密码登录认证(小项目快速落地)
nginx
qq_2562470532 分钟前
AI 时代下的创意工作:迈向“意义经济”与全新的高价值技能栈
后端
catoop37 分钟前
Nginx 解决 upstream sent too big header 错误
运维·nginx
感性的程序员小王38 分钟前
别再手撸架构图了!我写了个 AI 工具,把 Spring Boot 代码一键变成 Draw.io 流程图
前端·后端
jzzzzz1 小时前
Singleflight 巧妙解决缓存击穿
后端
玄〤1 小时前
个人博客网站搭建day2-Spring Boot 3 + JWT + Redis 实现后台权限拦截与单点登录(漫画解析)
java·spring boot·redis·后端·jwt
BigGGGuardian1 小时前
六合一 Spring Boot API 防护框架:防重、限流、幂等、自动Trim、慢接口检测、链路追踪,一个 Starter 搞定
java·后端
Kiyra1 小时前
云端编排与算力解构:2026 春晚亿级 AI 互动背后的极致弹性架构
人工智能·架构