Nginxの設定に関する問題と解決策

Nginxの設定

server {
        listen       666 ssl;
        server_name  www.abc.com;

        ssl_certificate      ..//ssl/shidian.crt;
        ssl_certificate_key  ..//ssl/server_unsecure.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
		
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        location / {
            proxy_pass http://192.168.1.221:7000/;
            proxy_connect_timeout 600;
            proxy_read_timeout 600;
        }
    }
  

問題1

HTTPS経由でHTTPサーバーにリバースプロキシする設定を行い、HTTPS経由でHTTPベースのJavaアプリケーションにアクセスできるようにしたが、Javaアプリケーション側でrequest.getRequestURL()を使用して取得したURLはHTTPスキームとして返却される。

例:クライアントからのリクエストURLがhttps://www.abc.com/の場合、アプリケーション内ではhttp://www.abc.com/として取得される。

対処法:

Nginxのlocationセクションに以下の設定を追加する。

proxy_set_header X-Forwarded-Proto  $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

JavaプロジェクトのTomcat設定を変更する(Spring Boot 2.xを使用しているため、組み込みTomcat)。

@Configuration
public class TomcatConfig {
    @Bean
    public ServletWebServerFactory servletContainer(){
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
        // RemoteIpValveを新規作成
        RemoteIpValve remoteIpValve = new RemoteIpValve();
        // Nginxのヘッダー名に対応させる
        remoteIpValve.setRemoteIpHeader("x-forwarded-for");
        remoteIpValve.setProtocolHeader("x-forwarded-proto");
        // TomcatにValveを追加
        tomcat.addEngineValves(remoteIpValve);
        return tomcat;
    }
}

これにより、request.getRequestURL()はHTTPSスキームのURLを正しく返すようになる。

問題2

request.getRequestURL()で取得されるURLは、実際のクライアントリクエストではなくプロキシ先のアドレスが返る。

例:クライアントのリクエストURLがhttps://www.abc.com/であるにもかかわらず、アプリケーション内ではhttps://192.168.1.221/が取得される。

対処法:

Nginxのlocationセクションに以下の設定を追加する。

proxy_set_header Host $http_host;

これにより、正しいホスト名が取得できるようになり、https://www.abc.com/のような正しいURLが返るようになる。

問題3

取得されたURLには、実際のリクエストで指定されたポート番号が含まれず、デフォルトの443ポートのみが反映される。

例:実際のリクエストURLがhttps://www.abc.com:666/であるにもかかわらず、取得されるURLはhttps://www.abc.com/でポートは443となる。

対処法:

Nginxのlocationセクションに以下の設定を追加する。

proxy_set_header X-Real-Port $server_port;

JavaプロジェクトのTomcat設定にも以下の設定を追加する。

remoteIpValve.setPortHeader("x-real-port");

これにより、https://www.abc.com:666/のように実際のポート番号が含まれたURLが取得できるようになる。

問題4

Nginxを停止しても依然としてアクセス可能な状態が続く。

対処法:

プロセスを終了する必要がある。タスクマネージャーではプロセスが見つからない場合もあるため、コマンドラインから終了させる。

ステップ1:Nginxプロセスを検索

tasklist /fi "imagename eq nginx.exe"

該当するプロセスが存在する場合、以下のような出力が表示される。

ステップ2:プロセスを終了

PIDを指定してプロセスを終了する。

taskkill -t -f /pid PID値

例えば:

taskkill -t -f /pid 230524

この操作によりプロセスが終了し、再度アクセスできなくなるはずである。それでもアクセス可能であれば、手順1と2を繰り返し実行し、アクセス不可になるまで続ける。

問題5

Nginxによるリバースプロキシの設定後、WebSocket接続が失敗する。

対処法:

上記Nginx設定のlocationブロックに以下の設定を追加する(内容は環境に応じて調整)。

			proxy_http_version 1.1;
			proxy_set_header Upgrade $http_upgrade;
			proxy_set_header Connection "upgrade";

タグ: nginx reverse-proxy HTTPS websocket Tomcat

6月1日 21:46 投稿