昨日の続きです。
NGINXからNGINX Unitへの転送はdocker内部に閉じた世界の話になるため、仮にhttpで転送して平文が流れてしまっても特に問題とはならないのでは無いかと思うかも知れません。しかし実際には明確な差が出るケースがあり(実際にWordpressを構築しようとして気がつきました)、今回dockerの設定ファイルを二つ用意したのはhttpで転送した場合とhttpsで転送した場合でその差を例示するためでした。
実際にdockerで立ち上げてindex.phpを表示させてみると見た目に差が出ていることがわかります。
HTTP
HTTPS
背景やフォントに差があることがわかりますでしょうか?
どうしてこうなるのかはブラウザのDevtoolなどを使用してコンテンツの読み込みについて確認してみるとわかります。
これがhttpで転送した時のDevtoolの表示ですが、混在コンテンツのエラーと警告が出ています。httpsのページ内に通常のhttp で送られてくるコンテンツがあると混在コンテンツとなりますが、これはNGINXからNGINX Unitへの転送をhttpで転送したことに起因しています。
この図で示した通りPHPの処理はNGINX Unit側で処理されますが、NGINXはhttpsで接続されていてもNGINX Unitへの転送がhttpで転送されているためNGINX Unitとしてはhttpでアクセスされたものと解釈します。そうなった場合にPHP側で画像やCSSなどのURLを現在アクセスされているURLをベースにして組み立ててしまうと画像やCSSのURLもhttpになってしまうということになります。
- ./nginx/html/index.php
<?php $msg = 'Hello, PHP on Unit!'; $url_base = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST']; $css_url = $url_base . '/style.css'; $img_url = $url_base . '/newyear2024.jpg'; ?> <!DOCTYPE html> <html> <head> <title>PHPテスト</title> <link rel="stylesheet" href="<?php echo $css_url; ?>"> </head> <body> <main> <h1>PHPテスト</h1> <p><?php echo $msg; ?></p> <div> <img src="<?php echo $img_url; ?>" alt="初日の出" /> </div> </main> </body> </html>
このファイルの4~6行目で現在アクセスされているURLからこのファイルで読み込むCSSと画像のURLを組み立てていますが、httpで転送されている場合は $_SERVER[‘HTTPS’] の値が空になるので http://~ としてURLが組み立てられることになります。
NGINXからNGINX Unitへの転送はhttpsで
現在は常時SSL化の流れが主流であり、むしろhttpでアクセスする場合はブラウザに警告されてしまう時代です。そのため、NGINXでhttpでアクセスされた場合httpsにリダイレクトしてしまう設定を入れている人も多いのではないでしょうか?
そうなるとNGINXとNGINX Unitを組み合わせて使う場合、アプリケーションの実装方法によって混在コンテンツのエラーになってしまう可能性があるため、NGINXがhttpsで接続されているならばNGINX Unitへの転送もhttpsでやるべきというのが結論になるかと思います。