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

相关推荐
love530love4 小时前
LiveTalking 数字人项目 Windows 部署完全指南(EPGF 架构)
人工智能·windows·python·架构·livetalking·epgf
星辰徐哥4 小时前
Spring Boot 微服务架构设计与实现
spring boot·后端·微服务
星辰徐哥4 小时前
Spring Boot 数据导入导出与报表生成
spring boot·后端·ui
明夜之约5 小时前
Spring Boot 自动装配源码
java·spring boot·后端
Leaton Lee5 小时前
Spring Boot分层架构详解:从Controller到Service再到Mapper的完整流程
java·spring boot·后端·架构
Micro麦可乐5 小时前
Spring Boot 实战:从零设计一个短链系统(含完整代码与数据库设计)
数据库·spring boot·后端·哈希算法·雪花算法·短链系统
Jinkxs5 小时前
Resilience4j- 与 Spring Boot 快速集成:自动配置与基础注解使用
java·spring boot·后端
毕设源码_郑学姐5 小时前
计算机毕业设计springboot网络相册设计与实现 基于Spring Boot框架的在线相册管理系统开发与应用 Spring Boot驱动的网络影集设计与实践
spring boot·后端·课程设计
辣机小司5 小时前
【踩坑记录:Spring Boot 配置文件读取值不一致?警惕 YAML 的“八进制陷阱”与 SnakeYAML 版本之谜】
java·spring boot·后端·yaml·踩坑记录
码农阿豪5 小时前
从零到一:Spring Boot快速接入金仓数据库实战
数据库·spring boot·后端