これは、なにをしたくて書いたもの?
nginxでForward Proxyが立てられるのかな?と思って、ちょっと調べてみました。
結論としては可能といえば可能(?)ですが、CONNECTメソッドについては標準では対応していません。
環境
今回利用する、nginx。
$ nginx -v nginx version: nginx/1.17.3
HTTPに対するForward Proxyを立てる
こんな感じの設定になります。
server { listen 8080; server_name localhost; location / { resolver 8.8.8.8; proxy_pass http://$http_host$request_uri; } }
proxy_passで、Hostヘッダーの値とリクエストURIを、そのまま転送先に設定します。
変数「$http_host」と「$request_uri」の意味は前述のとおりですが、説明は以下に記載があります。
Alphabetical index of variables
ngx_http_core_module / Embedded Variables
$http_name
arbitrary request header field; the last part of a variable name is the field name converted to lower case with dashes replaced by underscores$request_uri
full original request URI (with arguments)
また、resolverの指定が入っていますが、転送先のホスト名を名前解決する必要がある場合は、resolverの指定は必須のようです。
ご注意を。
ngx_http_proxy_module / proxy_pass
Parameter value can contain variables. In this case, if an address is specified as a domain name, the name is searched among the described server groups, and, if not found, is determined using a resolver.
ngx_http_core_module / resolver
とはいえ、Reverse Proxyで使うような機能をちょっと外れたような使い方をしているような感が否めないですが。
確認してみる
では、簡単なサーバーを立てて確認してみましょう。
Quarkusで作成。
$ mvn io.quarkus:quarkus-maven-plugin:0.21.2:create \ -DprojectGroupId=org.littlewings \ -DprojectArtifactId=simple-rest-api \ -DclassName="org.littlewings.quarkus.HelloResource" \ -Dpath="/hello" \ -Dextensions="resteasy-jsonb"
生成されたJAX-RSリソースクラスを、ちょっと修正。
src/main/java/org/littlewings/quarkus/HelloResource.java
package org.littlewings.quarkus; import java.util.Map; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; @Path("/hello") public class HelloResource { @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return "hello"; } @GET @Path("query") @Produces(MediaType.TEXT_PLAIN) public String query(@QueryParam("param") String param) { return "query param = " + param; } @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.TEXT_PLAIN) public String post(Map<String, String> request) { return request.get("param"); } }
ビルドして起動。
$ mvn package && java -jar target/simple-rest-api-1.0-SNAPSHOT-runner.jar
nginxが172.17.0.2、アプリケーションが192.168.0.2で動作しているものとします。
確認。
## GET $ http_proxy=http://172.17.0.2:8080 http://192.168.0.2:8080/hello hello ## QueryString付き $ http_proxy=http://172.17.0.2:8080 curl http://192.168.0.2:8080/hello/query?param=value query param = value ## POST $ http_proxy=http://172.17.0.2:8080 curl -XPOST -H 'Content-Type: application/json' http://192.168.0.2:8080/hello -d '{"param": "value"}' value
OKそうですね。
CONNECTメソッドについて
HTTPのプロキシはできましたが、HTTPSのプロキシを行うためのCONNECTメソッドは、nginxはサポートしていないようです。
サードパーティ製のこちらのモジュールがあり、ビルドして組み込むことになるようです。
GitHub - chobits/ngx_http_proxy_connect_module: A forward proxy module for CONNECT request handling
今回は、ここまではやらなくていいかなぁと思います…。