【OCI_30】nginxリバースプロキシでURL書き換えとHTTPS → HTTP転送を検証
本記事では、nginxを使ったリバースプロキシ構成で「URL書き換え」と「HTTPS→HTTP転送」がどのように動作するのかを、実際に検証した内容をまとめます。
リバースプロキシとは、利用者とWebサーバの間に入って通信を中継する“代理サーバ”のことです。利用者はプロキシサーバにアクセスしますが、裏側では別のWebサーバへ自動的に転送され、利用者はその存在を意識せずに利用できます。
クライアントからはHTTPSでアクセスしつつ、内部のWebサーバへはHTTPで転送する構成は、よく使われます。
そこで今回は、最小構成のnginxリバースプロキシを構築し、プロキシ設定・証明書設定・名前解決・SELinux制御などを検証していきたいと思います。
同じような構成をこれから試す方の参考になれば幸いです。

証明書は自己署名証明書を利用しています。
自己署名証明書について少し詳細に触れていますので、以下の記事を参考にしてください。
検証の流れとしては以下となります。
証明書を作成
環境構築(VCN、サブネットなど)
インタンス(プロキシサーバ、WEBサーバ)の作成
Webサーバへの設定と接続確認
プロキシサーバの設定
端末から動作確認
当検証は、有償アカウントで検証しています。無償アカウントと挙動が異なる場合がありますのでご了承ください。
また、別検証で作成した自己署名証明書を使いまわしているので証明書ファイル名がロード・バランサを意味していたりします
目次
opensslモジュールの確認
※証明書や秘密鍵は、どのサーバで作成しても問題ありません。
証明書や秘密鍵を作成するために、opensslモジュールがインストールされていることを確認します。
インストールされてない場合は、インストールしてください。
dnf list installed | grep openssl

証明書の作成
CAの証明書とプロキシサーバ用サーバ証明書を作成します。
事前準備としてCA認証書と自己署名証明書(クライアント→プロキシサーバ)を作成します。
CA(認証局)
CA証明書 CN = testca.com
Client → プロキシサーバ
https://www.2026testsite.com
サーバ証明書 CN/SAN = www.2026testsite.com
CA証明書(testca.com)を作成
自己署名証明書でも「クライアントがその発行元(CA)を信頼している」状態にすれば、ブラウザの警告は表示されません。
CA秘密鍵作成
CAの秘密鍵を作成します。
openssl genrsa -out ca.key 4096

CA公開証明書(自己署名CA)
CAの公開証明書(自己署名CA)を作成します。質問は、以下を参照してください。検証用なので特に入力する内容に制限はありませんがCommon Nameは、計画していた値を入れてください。
openssl req -x509 -new -nodes \
-key ca.key \
-sha256 \
-days 3650 \
-out ca.crt

生成されたファイル
ca.key(CA秘密鍵:外部に出さない)
ca.crt(CA公開証明書:FLB・クライアントで使用)

プロキシサーバ用サーバ証明書を作成
CN = www.2026testsite.com
プロキシサーバ用秘密鍵作成
冒頭にも記載したとおり、別検証で作成した自己署名証明書を使いまわしているので秘密鍵名や証明書ファイル名がロード・バランサを意味していたりしますが、ご自身の環境に合わせて自由に設定してください。
openssl genrsa -out flb.key 2048

SANの作成
以下の内容でファイル(flb.cnf)を新規作成します。
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = req_ext
[ dn ]
CN = www.2026testsite.com
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = www.2026testsite.com

CSRの作成
先ほど作成したSAN(flb.cnf)を含んだCSRを作成します。
openssl req -new -key flb.key -out flb.csr -config flb.cnf

CAで署名したプロキシサーバ用サーバ証明書を作成
openssl x509 -req \
-in flb.csr \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-out flb.crt \
-days 825 \
-sha256 \
-extfile flb.cnf \
-extensions req_ext

CAで署名したプロキシサーバ用サーバ証明書「flb.crt」が作成されました。

証明書内容の確認
プロキシサーバのサーバ証明書の内容を確認します。
openssl x509 -in flb.crt -noout -subject -ext subjectAltName

VCN、サブネット(パブリック)、インターネットゲートウェイ、ルート・ルール、セキュリティ・リストの作成
事前準備としてVCN、サブネット、セキュリティ・リスト、サービスゲートウェイを作成します。
事前準備の手順については、ここでは細かくふれておりませんのでご了承ください。
VCNの作成
次のVCN(dnslabel-on)を作成しました。

インターネットゲートウェイを作成
インターネット・ゲートウェイ(igw2)を作成しました。(※右下のルート表のプルダウンの関連付けは、不要 [失敗します])


ルート表(Default Route Table for dnslabel-on)にインターネットゲートウェイのルート・ルールを追加します。


サブネットの作成
インスタンスを配置するパブリック・サブネットとプライベート・サブネットを作成します。
インスタンスを配置するパブリック・サブネット

セキュリティ・リストの作成
パブリック・サブネットに適用されているセキュリティ・リストのイングレス・ルールへ、443番、80番ポートを開けました。

エグレス・ルールにて、すべてのプロトコルを開けました。

プライベート・サブネットに適用されているセキュリティ・リストのイングレス・ルール、エグレス・ルールともにすべてのプロトコルを開けました。

インスタンスの作成
パブリック・サブネットへプロキシサーバの「proxy-sv」、プライベート・サブネットへWEBサーバの「web-sv」を作成しました。

端末からパブリック・サブネットのproxy-svへSSHでログインできることを確認します。

次は、パブリック・サブネットのproxy-svからプライベート・サブネットのweb-svへssh接続するために準備をします。
端末上に保存されている秘密鍵をパブリック・サブネットのproxy-svへアップロードします。
私は、Teratermを利用しているのでドラッグアンドドロップでアップロードできます。
注意として「opcユーザ」で実行してください。「rootユーザ」でアップロードすると最悪、認証系のファイルが破損して誰もログインできなくなります。

ドラッグアンドドロップしたら以下画面が表示されるのでそのまま「OK」をクリックします。

homeディレクトリ配下に秘密鍵がアップロードされました。

秘密鍵の権限を変更します。
権限が緩い(644)とsshログインできませんでした。

sshログインで表示されたエラーメッセージ

準備できたので、パブリック・サブネットのproxy-svからプライベート・サブネットのweb-svへssh接続します。
ssh -i /home/opc/ssh-key-2026-01-31.key opc@10.0.1.134

WEBサーバの設定
私のプライベート・サブネットの環境は、以前の検証でサービス・ゲートウェイを作成済みです。
サービス・ゲートウェイを設定していないと、OCI内サービスのOracle Linux Yum リポジトリが利用できないので事前に作成してください。
プライベート・サブネットのWEBサーバへApache HTTPサーバーをインストールします。「Complete!」が表示されればインストールは完了しています。
sudo yum -y install httpd
サービスを起動して、OSを再起動してもサービスが自動起動するよう設定します。
sudo systemctl start httpd
sudo systemctl enable httpd
firewalldでポート番号を指定して、80番ポート(http)ポートをオープンします。「success」が表示されれば成功しています。
sudo firewall-cmd –permanent –add-port=80/tcp
firewalldをリロードして設定を反映します。
sudo firewall-cmd –reload
index.html ファイルを作成し、「WEBサーバ」と表示されるようにします。

今回は「http://example.com」で接続したいと思います。
DNSサーバはないので/etc/hostsを利用します。
パブリック・サブネットのproxy-svの/etc/hots へプライベート・サブネットのWEBサーバのIPアドレスと接続したい名前を記載します。

準備できたので、パブリック・サブネットのproxy-svからプライベート・サブネットのweb-svへcurlコマンドで確認します。
curl http://10.0.1.134/index.html

curl http://example.com/index.html

プロキシサーバの設定
nginx のインストール
プロキシサーバにリバースプロキシを導入します。
chatgptから初心者はNGINXが一番簡単と言われたのでNGINXをインストールします。
「Complete!」が表示されればインストールは完了しています。
sudo dnf -y install nginx
サービスを起動して、OSを再起動してもサービスが自動起動するよう設定します。
sudo systemctl start nginx
sudo systemctl enable nginx
nginx の設定
URL書き換えなどを設定します。
端末からプロキシサーバへ「https://www.2026testsite.com/」でアクセスし、
プロキシサーバからWEBサーバにはURLを書き換えて「http://example.com/」として転送します。
設定ファイルの proxy.conf が存在しないので作成します。
設定内容は説明入りでchatgptに作成してもらいました。
sudo touch /etc/nginx/conf.d/proxy.conf

# --- HTTP(80)で来たらHTTPS(443)へ強制的に飛ばす設定 ---
server {
listen 80; # HTTPの80番ポートで待ち受け
server_name www.2026testsite.com; # このドメイン宛のアクセスが対象
return 301 https://$host$request_uri;
# ↑ 端末が http://www.2026testsite.com/... で来ても
# https://www.2026testsite.com/... にリダイレクトする(常にHTTPSにする)
}
# --- 本命:HTTPS(443)で受けて、裏のWebへHTTPで転送する設定 ---
server {
listen 443 ssl; # HTTPSの443番ポートで待ち受け(SSLを使う)
server_name www.2026testsite.com; # https://www.2026testsite.com が対象
ssl_certificate /etc/nginx/ssl/flb.crt; # プロキシ用サーバ証明書
ssl_certificate_key /etc/nginx/ssl/flb.key; # 証明書に対応する秘密鍵
location / { # URLの「/」配下すべてを処理対象にする
proxy_pass http://example.com;
# ↑ ここがURL書き換えの本体
# 端末が https://www.2026testsite.com/ に来たら
# 裏へは http://example.com として転送する
# https://www.2026testsite.com/index.html → http://example.com/index.html になる
proxy_set_header Host example.com;
# ↑ 裏のWebサーバへ「example.com宛のアクセスです」と伝える
# (Hostヘッダがズレるとリンクやリダイレクトが壊れることがある)
proxy_set_header X-Real-IP $remote_addr;
# ↑ 利用者の元IPをWebサーバに伝える(ログ解析などに使う)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# ↑ 経路上のIP履歴を追加で渡す(一般的に入れておくと便利)
proxy_set_header X-Forwarded-Proto https;
# ↑ 利用者側はHTTPSで来ている、という情報を裏へ伝える
# アプリ側が「HTTPS前提のURL生成」をする場合に重要
}
}
証明書ファイルの配置
proxy.confで設定したディレクトリへ証明書ファイルを配置します。

sudo mkdir /etc/nginx/ssl
sudo cp -ip flb.key /etc/nginx/ssl/
sudo cp -ip flb.crt /etc/nginx/ssl/

NGINXのサービスを再起動します。
sudo systemctl restart nginx
firewalldでポート番号を指定して、443番ポート(https)ポート、80番ポート(http)ポートをオープンします。「success」が表示されれば成功しています。
sudo firewall-cmd –permanent –add-port=443/tcp
sudo firewall-cmd –permanent –add-port=80/tcp
firewalldをリロードして設定を反映します。
sudo firewall-cmd –reload
次にSELinuxを設定します。
最初、SELinuxを設定せずに端末から「https://www.2026testsite.com」へアクセスすると502エラーが出てアクセスできませんでした。

nginxのエラーログを確認します。
sudo tail -n 80 /var/log/nginx/error.log

chatgpt曰く、SELinux が nginx の upstream(Webサーバ)接続をブロックしていたのが原因のようです。
nginx が upstream に接続できるよう許可します。
※upstream(アップストリーム)とは、プロキシがリクエストを中継して送り先にするバックエンドサーバのことです。今回の構成では、nginxの転送先であるWebサーバが upstream となります。
SELinuxが有効な環境では、nginxは初期状態だと外部サーバ(upstream)への接続を禁止されています。
リバースプロキシでは、nginx → Webサーバへ転送が必要なので、それを許可するスイッチが次の設定となります。
SELinuxは、無効化されることも多いと思いますので無効でもよいと思います。
sudo setsebool -P httpd_can_network_connect 1
nginx を再読み込みします。
sudo systemctl reload nginx
端末の設定
端末に CA 証明書をインストール
今のままでは、証明書エラーが表示されるので証明書エラーが表示されないようクライアント端末にCA証明書をインストールします。
これによりサーバ証明書を信頼することになり証明書エラーが表示されなくなります。
※今回の検証であれば「ca.crt」がCA証明書となります。

CA証明書「ca.crt」を右クリックし、「証明書のインストール」をクリックします。

以下画面で「ローカルコンピューター」を選択し、「次へ」をクリックします。

以下画面で「証明書をすべて次のストアに配置する」を選択、証明書ストアで「信頼されたルート証明機関」を参照して「次へ」をクリックします。

以下画面で「完了」をクリックします。

ポップアップ「正しくインポートされました」に対して「OK」をクリックします。

Windowsの検索バーで「cert」と入力すると「ユーザー証明書の管理」が表示されるのでクリックします。

左ペインの「信頼されたルート証明機関」の「証明書」を選択すると右側の発行先にCA証明書「testca.com」が表示されていることが確認できます。

端末のhostsファイルの編集と動作確認
プロキシサーバのIPアドレスとFQDN「www.2026testsite.com」をhostsファイルに記載して、https通信で証明書エラーが表示されないことを確認します。
hostsファイルの場所
C:\Windows\System32\drivers\etc\hosts
プロキシサーバのhostsファイル

端末からブラウザで「https://www.2026testsite.com」へ接続します。
うまく表示されました。

次に「http://www.2026testsite.com」でも接続します。
リダイレクトされて接続されました!
最後にプロキシサーバのアクセスログを見ておきます。
access.log の形式だけでは「http と https のどちらで来たか」「リダイレクトが起きたか」は分からないようです。
ブラウザが最初からHTTPをHTTPSへ変換してアクセスしている可能性があるとのことでした。

まとめ
nginxリバースプロキシでURL書き換えとHTTPS → HTTP転送を検証してみました。検証を含めプロキシサーバを検証することははじめてでした。特にURLを書き換えるというところがうまくイメージできなかったので、簡単な構成ではありますが実際に検証してみることで理解が深まりました。
以下、他の記事をまとめた一覧です。OCI以外にAWSもまとめています。