概要
nginxをリバースプロキシとして動作させます。
TLSによる暗号化、およびクライアント認証を行う手順を記載します。
動作確認用にアプリケーションとして PHP+Apache を使いました。
前提条件
本記事で使用する環境・ソフトウェアはDocker、docker-compose、nginxです。
nginxの設定
nginxの設定は .template ファイルを読み込ませることで、コンテナ起動時に自動生成させます。
ローカル環境で作成した templates ディレクトリをnginxコンテナの /etc/nginx/templates へマウントします。
nginxは起動時に /etc/nginx/templates ディレクトリ内部にある .template ファイルを読み込むためです。
server {
server_name www.example.com:443;
root /var/www/;
index index.php index.html;
listen 443 ssl;
location / {
proxy_pass http://backend.example.com;
}
ssl_certificate /ssl/server/server.crt;
ssl_certificate_key /ssl/server/server.key;
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE+AESGCM:DHE+aRSA+AESGCM:ECDHE+AESCCM:DHE+aRSA+AESCCM:+AES256:ECDHE+CHACHA20:DHE+aRSA+CHACHA20:+DHE:ECDHE+AES128:ECDHE+CAMELLIA128:ECDHE+AES:ECDHE+CAMELLIA:+ECDHE+SHA:DHE+aRSA+AES128:DHE+aRSA+CAMELLIA128:DHE+aRSA+AES:DHE+aRSA+CAMELLIA:+DHE+aRSA+SHA;
ssl_verify_client on;
ssl_stapling on;
ssl_client_certificate /ssl/ca/ca.pem;
}
以下、個々の設定を説明します。
SSL/TLSに関する設定
server {
server_name www.example.com;
listen 443 ssl;
ssl_certificate /ssl/server/server.crt;
ssl_certificate_key /ssl/server/server.key;
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE+AESGCM:DHE+aRSA+AESGCM:ECDHE+AESCCM:DHE+aRSA+AESCCM:+AES256:ECDHE+CHACHA20:DHE+aRSA+CHACHA20:+DHE:ECDHE+AES128:ECDHE+CAMELLIA128:ECDHE+AES:ECDHE+CAMELLIA:+ECDHE+SHA:DHE+aRSA+AES128:DHE+aRSA+CAMELLIA128:DHE+aRSA+AES:DHE+aRSA+CAMELLIA:+DHE+aRSA+SHA;
}
- server
- server_name:仮想サーバー名(FQDN)を指定
- listen:この仮想サーバーが通信を待ち受けるポートを指定。 ssl オプションはHTTPとHTTPS構成を簡単に設定するために使用
- ssl_certificate:SSL証明書名
- ssl_certificate_key:SSL証明書の対となる秘密鍵名
- ssl_protocols:使用可能なSSLプロトコルバージョン
- ssl_ciphers:使用可能な暗号化プロトコル
リバースプロキシ
server {
location / {
proxy_pass backend.example.com;
}
}
- location
- proxy_pass:プロキシされているサーバー(ここではバックエンドとなるアプリケーション)のホスト名(FQDN)
バックエンドのアプリケーションへhttpヘッダーを使って情報を渡したい場合は、 proxy_set_header を使用します。
以下に参考例を記載します。
server {
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
クライアント認証
server {
ssl_verify_client on;
ssl_stapling on;
ssl_client_certificate /ssl/ca/ca.pem;
}
- ssl_verify_client:クライアント認証を有効化
- ssl_stapling:証明書の失効チェック
- ssl_client_certificate:クライアント証明書名
docker-compose
version: '3'
services:
httpd:
image: php:7.2-apache
volumes:
- ./index.php:/var/www/html/index.php
ports:
- "80:80"
restart: always
nginx:
image: nginx:latest
volumes:
- ./templates:/etc/nginx/templates
- ./server.crt:/ssl/server/server.crt
- ./server.key:/ssl/server/server.key
ports:
- "443:443"
restart: always
environment:
NGINX_PROXY_PATH: backend.example.com:80
httpヘッダ確認のために以下ファイルを使用しました。
getallheaders — 全てのHTTPリクエストヘッダを取得する
<?php
foreach (getallheaders() as $name => $value) {
echo "$name: $value\n";
}
?>
ディレクトリ構成は以下になる。
- docker-compose.yaml
- index.php
- server.crt
- server.key
- templates #ディレクトリ
- nginx.conf.template
コンテナ起動
以下のコマンドでコンテナを起動します。
docker-compose up -d
確認
クライアント認証
ブラウザから ホスト名 へ接続してクライアント認証画面が出ることを確認します。
ブラウザでクライアント証明書について聞かれない場合は、直近の履歴を削除してみると良いです
※以下はFirefoxの場合
httpヘッダー
接続したページにヘッダー情報が記載されているため確認します。
コンテナ停止
以下のコマンドでコンテナを停止します。
docker-compose stop