【OCI_31】nginxリバースプロキシのcronでnginx設定ファイルを切り替えて2つのサイトを表示する
前回記事では、nginxを使ったリバースプロキシ構成で「URL書き換え」と「HTTPS→HTTP転送」がどのように動作するのかを検証しました。
リバースプロキシとは、利用者とWebサーバの間に入って通信を中継する“代理サーバ”のことです。利用者はプロキシサーバにアクセスしますが、裏側では別のWebサーバへ自動的に転送され、利用者はその存在を意識せずに利用できます。
今回は、前回の構成を少し変更し、cronを利用して時間帯によって2つのサイトを切り替えて表示できるか検証してみます。
昼用ページ、夜用ページを時間帯によってcronで切り替えてWebページを表示させます。
昼用ページは、前回検証したnginxを使ったリバースプロキシ構成で「URL書き換え」と「HTTPS→HTTP転送」でWEBページを表示させます。
夜用ページは、リバースプロキシサーバ自体でWEBページを表示させます。

【アーキテクチャ図】

証明書は自己署名証明書を利用しています。
自己署名証明書について少し詳細に触れていますので、以下の記事を参考にしてください。
検証の流れとしては以下となります。
証明書を作成
環境構築(VCN、サブネットなど)
インタンス(プロキシサーバ、WEBサーバ)の作成
Webサーバへの設定と接続確認
プロキシサーバの設定
端末から動作確認
当検証は、有償アカウントで検証しています。無償アカウントと挙動が異なる場合がありますのでご了承ください。
また、別検証で作成した自己署名証明書を使いまわしているので証明書ファイル名がロード・バランサを意味していたりします
目次
- 1 opensslモジュールの確認
- 2 証明書の作成
- 3 VCN、サブネット(パブリック)、インターネットゲートウェイ、ルート・ルール、セキュリティ・リストの作成
- 4 インスタンスの作成
- 5 WEBサーバの設定
- 6 プロキシサーバの設定
- 7 端末側の証明書設定
- 8 動作確認(手動で切替テスト)
- 8.1 手動で夜用ページが表示されることを確認
- 8.2 sudo ln -sf /etc/nginx/conf.d/switch/site_night.conf /etc/nginx/conf.d/site.conf
- 8.3 sudo nginx -t && sudo systemctl reload nginx
- 8.4 手動で昼用ページが表示されることを確認
- 8.5 sudo ln -sf /etc/nginx/conf.d/switch/site_day.conf /etc/nginx/conf.d/site.conf
- 8.6 sudo nginx -t && sudo systemctl reload nginx
- 9 cronで自動切替を設定
- 10 動作確認(自動で切替テスト)
- 11 まとめ
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/hosts へプライベート・サブネットのWEBサーバのIPアドレスと接続したい名前を記載します。

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

プロキシサーバの設定
パブリック・サブネットのproxy-svでプロキシサーバの設定をします。
プロキシサーバは、nginxを利用します。(chatgptから初心者はNGINXが一番簡単と言われたので)
サーバ時刻をJSTに変更する
今回は、cronを利用するので時刻がわかりやすいようにTime zoneを Asia/Tokyo に設定します。
timedatectl

Time zone: Asia/Tokyo でないので変更します。
sudo timedatectl set-timezone Asia/Tokyo
Time zoneが Asia/Tokyo になりました。
timedatectl

date

夜用ページをプロキシサーバに用意
夜用ページを配置するためのディレクトリを作成してパーミッションを設定します。
sudo mkdir -p /var/www/html
sudo chmod 755 /var/www/html
作成したディレクトリに夜用ページを作成します。内容は任意です。
sudo touch /var/www/html/index.html
sudo vi /var/www/html/index.html

パーミッションを設定します。
sudo chmod 644 /var/www/html/index.html
nginx のインストール
プロキシサーバにリバースプロキシを導入します。
chatgptから初心者はNGINXが一番簡単と言われたのでNGINXをインストールします。
「Complete!」が表示されればインストールは完了しています。
sudo dnf -y install nginx
サービスを起動して、OSを再起動してもサービスが自動起動するよう設定します。
sudo systemctl start nginx
sudo systemctl enable nginx
nginx の設定
nginx設定を「昼用ページ」「夜用ページ」で2つ作ります。
検証中に昼用ページ、夜用ページのconfファイルをconf.dディレクトリ配下に配置したところ間違って読み込まれてしまうことが何度もあったので、別途、switchディレクトリを作成し、そこに昼用ページ、夜用ページのconfファイルを保存します。
昼用ページ:/etc/nginx/conf.d/switch/site_day.conf
夜用ページ:/etc/nginx/conf.d/switch/site_night.conf
conf.dディレクトリ配下は、site.confファイルだけになるようにします。
site.confは、シンボリックリンクとしてcronで時間帯によって切り替えます。
実際に読み込むファイル:/etc/nginx/conf.d/site.conf(←ここを差し替える)
switchディレクトリを作成してパーミッションを設定します。
sudo mkdir -p /etc/nginx/conf.d/switch
sudo chmod 755 /etc/nginx/conf.d/switch
昼用ページ設定ファイルの作成(site_day.conf)
URL書き換えなどを設定します。
端末からプロキシサーバへ「https://www.2026testsite.com/」でアクセスし、プロキシサーバからWEBサーバにはURLを書き換えて「http://example.com/」として転送します。
設定ファイルの site_day.conf が存在しないので作成します。
設定内容は説明入りでchatgptに作成してもらいました。
sudo touch /etc/nginx/conf.d/switch/site_day.conf
sudo vi /etc/nginx/conf.d/switch/site_day.conf

■site_day.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生成」をする場合に重要
}
}
夜用ページ設定ファイルの作成(site_night.conf)
メンテナンスページの表示を設定します。
端末からプロキシサーバへ「https://www.2026testsite.com/」でアクセスし、
メンテナンスページ(/var/www/html/index.html)を表示します。
設定ファイルの site_night.conf が存在しないので作成します。
sudo touch /etc/nginx/conf.d/switch/site_night.conf
sudo vi /etc/nginx/conf.d/switch/site_night.conf

■site_night.conf
# --- HTTPS(443)で受けて、メンテナンスページを表示する設定 ---
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; # 証明書に対応する秘密鍵
# 静的ファイルを返す
root /var/www/html;
index index.html;
location / { # URLの「/」配下すべてを処理対象にする
# try_files $uri /index.html; により、/ でも /aaa でも 必ず index.html を返す
try_files $uri /index.html;
}
}
証明書ファイルの配置
site_day.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の設定
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を停止します。
検証中、SELinuxを設定せずに端末から「https://www.2026testsite.com」へアクセスすると502エラーが出てアクセスできませんでした。
chatgpt曰く、SELinux が nginx の upstream(Webサーバ)接続をブロックしていたのが原因のようです。
nginx が upstream に接続できるよう許可します。
※upstream(アップストリーム)とは、プロキシがリクエストを中継して送り先にするバックエンドサーバのことです。今回の構成では、nginxの転送先であるWebサーバが upstream となります。

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

SELinuxが有効な環境では、nginxは初期状態だと外部サーバ(upstream)への接続を禁止されています。
リバースプロキシでは、nginx → Webサーバへ転送が必要なので、SELinuxを無効化して転送されるよう設定します。
SELinuxの設定ファイルを編集して無効化します。
sudo vi /etc/selinux/config
・変更前:
SELINUX=enforcing
・変更後:
SELINUX=disabled
設定ファイルを保存して、OSを再起動し、設定を反映します。
sudo reboot
端末側の証明書設定
端末に 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ファイル

動作確認(手動で切替テスト)
自動切換えを設定する前にまずは手動で切り替えることができるか確認します。
昼用ページ、夜用ページの実体ファイルは、以下に格納しています。

ln -s コマンドで昼用ページ、夜用ページの実体ファイルの「シンボリックリンク(ショートカット)」が
/etc/nginx/conf.d ディレクトリ配下に配置されるようにします。
以下の画像は、昼用ページ「/etc/nginx/conf.d/switch/site_day.conf」の「シンボリックリンク(ショートカット)」が site.conf ファイルとして作成されていることを意味しています。

手動で夜用ページが表示されることを確認
ln -s コマンドで昼用ページ、夜用ページの実体ファイルの「シンボリックリンク(ショートカット)」が/etc/nginx/conf.d/site.conf として作成されます。
sudo ln -sf /etc/nginx/conf.d/switch/site_night.conf /etc/nginx/conf.d/site.conf
設定ファイルが正しいかチェックしてから、nginxに設定を再読み込みします。
「syntax is ok」と「successful」が表示されれば大丈夫です。
sudo nginx -t && sudo systemctl reload nginx

「シンボリックリンク(ショートカット)」/etc/nginx/conf.d/site.conf が作成されました。

端末からブラウザで「https://www.2026testsite.com」へ接続すると夜用ページ(プロキシサーバの/var/www/html/index.html)が表示されることを確認します。

手動で昼用ページが表示されることを確認
ln -s コマンドで昼用ページ、夜用ページの実体ファイルの「シンボリックリンク(ショートカット)」が/etc/nginx/conf.d/site.conf として作成されます。
sudo ln -sf /etc/nginx/conf.d/switch/site_day.conf /etc/nginx/conf.d/site.conf
設定ファイルが正しいかチェックしてから、nginxに設定を再読み込みさせます。
sudo nginx -t && sudo systemctl reload nginx

「シンボリックリンク(ショートカット)」/etc/nginx/conf.d/site.conf が作成されました。(※昼用に上書きされる)

端末からブラウザで「https://www.2026testsite.com」へ接続すると昼用ページ(別Webサーバ「http://example.com」)が表示されることを確認します。

cronで自動切替を設定
最初は、crontabに手動切り替えするコマンドを直接記述していたのですが、何度も失敗するの chatgptのアドバイスもあり、手動切り替えするコマンドを個別スクリプトファイルとしました。
個別スクリプトファイルは、/usr/local/sbin ディレクトリに格納します。
昼用ページのスクリプト
/usr/local/sbin/nginx_switch_day.sh
夜用ページのスクリプト
/usr/local/sbin/nginx_switch_night.sh
昼用ページのスクリプト作成
昼用ページのスクリプト(nginx_switch_day.sh)を作成します。
sudo touch /usr/local/sbin/nginx_switch_day.sh
sudo vi /usr/local/sbin/nginx_switch_day.sh
sudo chmod 755 /usr/local/sbin/nginx_switch_day.sh
#!/bin/bash
# 途中のコマンドが1つでも失敗したら、その時点でスクリプトを中断する設定
set -e
LOG=/var/log/nginx/switch.log
echo "$(date '+%F %T') day: START" >> "$LOG"
ln -sf /etc/nginx/conf.d/switch/site_day.conf /etc/nginx/conf.d/site.conf
/usr/sbin/nginx -t
/usr/bin/systemctl reload nginx
echo "$(date '+%F %T') day: OK" >> "$LOG"
夜用ページのスクリプト作成
夜用ページのスクリプト(nginx_switch_night.sh)を作成します。
sudo touch /usr/local/sbin/nginx_switch_night.sh
sudo vi /usr/local/sbin/nginx_switch_night.sh
sudo chmod 755 /usr/local/sbin/nginx_switch_night.sh
#!/bin/bash
# 途中のコマンドが1つでも失敗したら、その時点でスクリプトを中断する設定
set -e
LOG=/var/log/nginx/switch.log
echo "$(date '+%F %T') night: START" >> "$LOG"
ln -sf /etc/nginx/conf.d/switch/site_night.conf /etc/nginx/conf.d/site.conf
/usr/sbin/nginx -t
/usr/bin/systemctl reload nginx
echo "$(date '+%F %T') night: OK" >> "$LOG"
rootのcronを編集
crontab を編集します。crontab にはスクリプトの呼び出しだけを記述します。
(以下の設定時刻は、検証結果がすぐに確認できるように短い期間に設定しています。)
sudo crontab -e
SHELL=/bin/bash
PATH=/usr/sbin:/usr/bin:/sbin:/bin
# 昼用切り替えスクリプト
30 17 * * * /usr/local/sbin/nginx_switch_day.sh
# 夜用切り替えスクリプト
27 17 * * * /usr/local/sbin/nginx_switch_night.sh

動作確認(自動で切替テスト)
以下画像より、17時26分は、昼用ページが表示されています。

17時27分になるとcrontabで夜用ページのスクリプトが実行されて夜用ページが表示されました。


ログを出力するように設定していたので /var/log/nginx/switch.log を確認します。

ログより、crontab の設定時刻に実行されていることが確認できます。

17時30分になるとcrontabで昼用ページのスクリプトが実行されて昼用ページが表示されました。


ログより、crontab の設定時刻に実行されていることが確認できます。

まとめ
今回は、1台のリバースプロキシサーバのcronを利用して時間帯によって2つのサイトを切り替えて表示する検証をしました。いろいろなところで「リバプロ」と利用すればと言われてますが、私はいつも曖昧な理解でした。検証を通してリバースプロキシについて理解が深まり、今後は会話に着いて行けそうです。
下、他の記事をまとめた一覧です。OCI以外にAWSもまとめています。