はじめに
Nginx では「proxy_pass」ディレクティブを指定することでフォワードプロキシ(Forward Proxy)として動作させることが可能です。
しかし、モジュール等を追加していない素の Nginx の場合、 HTTPS 通信をフォワードプロキシすることはできません。
後述する「ngx_http_proxy_connect_module」を利用して解決します。
試しにNginxプロキシ経由でHTTPSのサイトにアクセスしたら以下のようにエラーとなりました。
$ curl -Lv https://github.com/ -x 127.0.0.1:3128 * Trying 127.0.0.1... * TCP_NODELAY set * Connected to 127.0.0.1 (127.0.0.1) port 3128 (#0) * Establish HTTP proxy tunnel to github.com:443 > CONNECT github.com:443 HTTP/1.1 > Host: github.com:443 > User-Agent: curl/7.54.0 > Proxy-Connection: Keep-Alive > < HTTP/1.1 400 Bad Request < Server: nginx/1.16.1 < Date: Wed, 18 Mar 2020 05:24:05 GMT < Content-Type: text/html < Content-Length: 157 < Connection: close < * Received HTTP code 400 from proxy after CONNECT * Closing connection 0 curl: (56) Received HTTP code 400 from proxy after CONNECT
HTTPS 通信をプロキシする「ngx_http_proxy_connect_module」モジュール
「ngx_http_proxy_connect_module」モジュールを利用することで HTTPS サイトへのサクセスをプロキシ経由で行うことができます。
↓ このモジュールの説明
This module provides support for the CONNECT method request. This method is mainly used to tunnel SSL requests through proxy servers.
環境構築
Nginx と モジュール の ダウンロード & インストール
configure 時に --add-module=../ngx_http_proxy_connect_module
オプションを指定することで、 Nginx に ngx_http_proxy_connect モジュールを組み込むことができます。
導入にあたって Nginx に対してパッチを当てる必要があるため、Nginxをコンパイルする必要があります。
# 作業用ディレクトリを作成 $ mkdir work && cd work # Nginxの取得 $ wget http://nginx.org/download/nginx-1.16.1.tar.gz $ tar zxvf nginx-1.16.1.tar.gz $ rm -f nginx-1.16.1.tar.gz # ngx_http_proxy_connect_moduleの取得(現時点の最新版は「0.0.1」) $ git clone https://github.com/chobits/ngx_http_proxy_connect_module.git -b v0.0.1 # 作業用ディレクトリの内容は以下のようになっています $ ls nginx-1.16.1/ ngx_http_proxy_connect_module/ # Nginxに対してのパッチ適用 と Nginxのインストール $ cd nginx-1.16.1 $ patch -p1 < ../ngx_http_proxy_connect_module/patch/proxy_connect_rewrite_101504.patch $ ./configure --prefix=/path/to/nginx --add-module=../ngx_http_proxy_connect_module $ make && make install
Nginx の設定 & 起動
# Nginxのディレクトリに移動 $ cd /path/to/nginx # 設定を以下のように修正します $ vim conf/nginx.conf --------------------------------------------- worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 3128; # dns resolver used by forward proxying resolver 8.8.8.8; # forward proxy for CONNECT request proxy_connect; proxy_connect_allow 443 563; proxy_connect_connect_timeout 10s; proxy_connect_read_timeout 10s; proxy_connect_send_timeout 10s; # forward proxy for non-CONNECT request location / { proxy_pass $scheme://$http_host$request_uri; proxy_set_header Host $host; } } } --------------------------------------------- # Nginx の起動 $ ./sbin/nginx
動作確認
$ curl -Lv https://github.com/ -x 127.0.0.1:3128 * Trying 127.0.0.1... * TCP_NODELAY set * Connected to 127.0.0.1 (127.0.0.1) port 3128 (#0) * Establish HTTP proxy tunnel to github.com:443 > CONNECT github.com:443 HTTP/1.1 < HTTP/1.1 200 Connection Established < Proxy-agent: nginx > GET / HTTP/1.1 > Host: github.com > User-Agent: curl/7.54.0 < HTTP/1.1 200 OK < date: Tue, 17 Mar 2020 09:25:15 GMT
ダイナミック(動的)モジュール
ngx_http_proxy_connect_module は動的モジュールとして .so
ファイルを作成することが可能です。
しかし導入の際に Nginx に対してパッチを適用する必要があるため、すでにインストールされている Nginx にこのモジュールを導入することはできなさそうです。
ダイナミックモジュールが動作しない件については、いくつか ISSUE があるようでした。
そんな感じでダイナミックモジュールとして組み込むことは厳しそう。
参考
更新履歴
- 2020年3月18日 新規作成