Nginx 作为 HTTPS 的正向代理

Nginx 作为 HTTPS 的正向代理

虽然我能够成功配置 nginx 来代理 HTTP 流量(使用本指南),所有代理 HTTPS 请求的尝试都导致代码 400(错误的请求)。

Nginx 调试日志根本没有帮助:

2013/06/05 14:38:33 [info] 74946#0: *589
    client sent invalid request while reading client request line, client: 127.0.0.1,
    server: google.com, request: "CONNECT google.com:443 HTTP/1.1"

这些请求是什么?在 nginx 中CONNECT是否可以进行HTTPS 请求?proxy_pass

更新

需要补充的是,代理服务器是我 Web 开发工作流程/工具包的一部分。这是测试/调试客户端 JavaScript 的好方法生产环境(在代理之前使用重写)。

nginx 的配置语言本身也可以说是一门编程语言。它有变量!

答案1

似乎 nginx 不支持使用 SSL 的正向代理模式。您需要使用类似乌贼而是。这里有一个来自 nginx 作者的更多解释的链接:HTTPS 和 nginx 作为正向代理。

答案2

只是为了澄清:正如我在博客的评论提要中所写的,nginx 不处理用于通过 HTTP 代理建立到远程主机的原始 TCP 连接的 CONNECT 方法调用 - 这是有道理的,因为 nginx 不应该作为正向代理工作,无论如何,它恰好可以很好地用于常规 HTTP。

Nginx 根本不知道如何处理这些方法调用,这就是为什么日志中的错误消息毫无用处。我发现自己总是使用 privoxy 进行 HTTPS:http://www.privoxy.org/- 设置起来也非常简单。但仍然不可能过滤或篡改 HTTPS 中继的内容,因为 HTTPS 连接是通过 CONNECT 方法使用原始连接处理的,服务器不知道它中继的是什么。

答案3

如果你不介意从源代码编译 nginx,你可以安装ngx_http_proxy_connect_module。在 Raspberry Pi 上的 Debian 9 “Stretch” 中,以下内容对我有用(在我将 deb-src URL 添加到 /etc/apt/sources.list 并执行 apt-get update 之后):

cd /tmp &&
apt-get source nginx &&
git clone https://github.com/chobits/ngx_http_proxy_connect_module &&
cd nginx-* &&
patch -p1 < ../ngx_http_proxy_connect_module/proxy_connect.patch &&
sudo apt-get install libpcre3-dev &&
./configure --add-module=/tmp/ngx_http_proxy_connect_module &&
make && sudo make install

然后编辑/usr/local/nginx/conf/nginx.conf并使其看起来像这样(我包含了您想要阻止的域的示例,它适用于 SSL 和非 SSL 代理):

user www-data;
worker_processes auto;
events { }
http {
    server_names_hash_bucket_size 128;
    server {
        listen       8888;
        server_name  spam.example.com *.spam.example.com;
        server_name  spam2.example.com *.spam2.example.com;
        access_log off;
        return 404;
    }
    server {
        listen       8888;
        server_name ~.+;
        proxy_connect;
        proxy_max_temp_file_size 0;
        resolver 8.8.8.8;
        location / {
           proxy_pass http://$http_host;
           proxy_set_header Host $http_host;
        }
    }
}

然后运行/usr/local/nginx/sbin/nginxnginx如果您还在端口 80 上运行生产 Web 服务器,并且不想冒险弄乱它(但请确保/usr/local在启动时单独启动该版本),它将与 Debian 的库存包非常愉快地共存;或者,通过更多配置,您可以从编译的 nginx 运行这两个服务。但是,如果您确实将编译的 nginx 设置为在防火墙允许流量的端口上运行,请注意您必须手动检查 nginx 安全更新,因为 Debian 软件包系统将不再为您执行此操作。

答案4

我的团队花了一些时间才弄清楚如何实现这一点。最后,我们通过将下面的代码片段嵌入到 nginx.conf 中来实现它:

stream {
  map_hash_bucket_size 128;
  map $ssl_preread_server_name $sphere {
    site-01.example.com site-01;
    site-02.example.com site-02;
  }

  upstream site-01 {
    server 192.168.0.1:443;
  }

  upstream site-02 {
    server 192.168.0.2:443;
  }

  server {
    listen 443;
    proxy_pass $sphere;
    ssl_preread on;
  }
}

相关内容