2026/06/10(水)今日のサーバー整備の話と、サイト改築を始めた話。
今日のサーバー整備
nginxの共通設定にgzipの設定を入れて転送量を削減した。
この設定を入れただけ。
gzip on;
gzip_types
text/plain
text/css
text/javascript
text/xml
application/javascript
application/json
application/xml
application/rss+xml
application/atom+xml
application/font-woff
application/octet-stream
image/gif
image/png
image/jpeg
image/gif
image/webp
image/svg+xml;
nginxとApacheのリバースプロキシについて色々確かめた。
nginxからApacheにリバースプロキシしてる時、nginxを前段のTLS終端、Apacheを後段にしているときにApacheの中でリダイレクトが走るとhttpsが壊れることがある現象を確認した。
これはディレクトリに対しhttps://example.com/hogeのようにアクセスするとhttp://example.com/hoge/に301リダイレクトがかかるのだが、どうもこの時にスキーマが引き継がれずHTTPになってしまうようだ。初めからhttp://example.com/hoge/としてアクセスすれば問題ない。
またこの現象が起きると証明書があるのにエラー表示になることも確認しているが、サブ機やスマホでは起きないようにも見えるので、この端末の証明書が何かしら変になっている可能性がある。キャッシュクリアしてもhttp降格が起きると再発するので、原因はよくわかっていない。GPT-5.5に聞いたもののハルシネーションしか得られず、ググってもnginx→Apacheの情報はほとんど得られなかった。多分ニッチな構成なのだろう。
さくらのレンタルサーバーもnginxからApacheに繋いでいるので、これをどうやっているかが知れれば改善の手掛かりになりそうだが、知る術がないので何ともだ。まさか聞くわけにもいかないし…。
そういえばさくらのレンタルサーバーではSNI SSL[1]が使われていると聞くので、これを使えば上手くいくのかもしれない。
SSL/TLS接続のはじめに、クライアントはSSL/TLSのサーバから(サーバとCAの)証明書を受け取り、証明書の改ざんされていないことなどを確認する。サーバ証明書にはホスト名が書かれており、それが今接続しようとしているホスト名と一致することをクライアントは確認する。そうでない場合、なりすましや中間者攻撃の恐れがあるため、クライアントはユーザに警告をする。ユーザの責任で証明書を信用し、警告を迂回することができるアプリケーションも存在する。
というかWikipediaに上記の記述があったので、これのせいかもしれない。問題が起きているドメインはlycolia.infoで、元々さくら側で証明書を設定していたのでHTTPに落ちたときにその証明書が引っかかってエラーになっているとかはあるのかも?
さくらのドメインであるsakura.ne.jpを踏むとhttpでもhttpsに転送されるのと、ひょっとしたら類似の現象が起きているのかも…?いや、わからないが…。
サイト構成の変更をし始めた
このサイトの構成がイケてないなという思いが強くなったのでやることにした。
まずlycolia.infoが単なるLPに成り下がっていることが勿体なかったので、このドメインの傘下にコンテンツを増やすことにした。
一つ目はtool.lycolia.infoのドメインを廃止して、lycolia.info/tool/にぶら下げた。これはそもそもドメインを分割してやるようなサイトではなかったし、コンテンツの一部でいいと思ったからだ。
二つ目はこのブログにあったリンク集をlycolia.info/link/にぶら下げた。そもそも、本質的にサイトトップではない、このブログにリンク集があることに長らく違和感があったので丁度よかった。また移設に伴い紹介コメントも多少変更しているほか、元々のリンクが間違っていたなどもあったので、そのあたりも修正している。
そして今後は自己紹介などもブログから剝がして移動したいと思っている。ただ今のところすべてサーバー内からのHTML手打ちで、厳しさを感じるので、将来的にはCMSにしたいとも思った。
少なくとも今今は自宅サーバーである以上、家の中にいれば直にファイルをいじれるので問題はない。出先で書き換えたくなった時に困るくらいだ(一応頑張れば出先からもいじれなくはないが…)
サイト構成の変遷
本日リアルタイムでサイトを書き換えていて本番Hot Module Replacementみたいなことになっていた風景の一部を残しておく。
これが元々の状態。
改築途中の状態、なんか色々アレなことに…。
そして一旦本日の作業が終わった状態。また明日以降ちょいちょい直していくと思う。
移設したリンク集
見た目的には大きく変わり映えしないどころか、まともにスタイルを当ててないので殺風景だが、その辺りは追々どうにかしていこうと思う。
これでも一応レスポンシブデザイン、しかもモバイルファーストで作っているのでスマホで見たときの見やすさは向上している。
何せフルスクラッチでHTMLを手書きして、置換ではなく手作業で移設を行ったので移設するだけで時間が溶けてしまったので、今日はこんなところといった感じだ。
- Server Name Indication SSL ↩
2026/02/26(木)nginxからApache2へセキュアにリバプロしたときに真のクライアントIPを取得できるようにする
投稿日:
nginxからApache2のバーチャルホストにいい感じにリバプロする方法の続きで、nginxからApache2にリバースプロキシされた時にクライアントのIPを拾う設定の方法について。
確認環境
| Env | Ver |
|---|---|
| OS | Ubuntu 24.04.3 LTS |
| nginx | 1.26.1 |
| Apache2 | 2.4.58 |
やりたいこと
Apache2で動いているCGIのREMOTE_ADDRからクライアントIPを取れるようにする。
nginxからApache2のバーチャルホストにいい感じにリバプロする方法ではApache2側でREMOTE_ADDRを取得しようとするとnginxのIPになってしまうため、これを回避する方法。
前提条件
- nginxからApache2へのリバースプロキシをする時に、真のクライアントIPを
X-Real-IPヘッダーに入れていること。proxy_set_header X-Real-IP $remote_addr; - nginxとApacheが動いているマシンが同じ
- IPv6を使っている
やること
# remoteipモジュールの有効化
sudo a2enmod remoteip
# ::1からのHTTPリクエストを信頼しX-Real-IPをREMOTE_ADDRとして解釈する
cat <<'EOF' | sudo tee /etc/apache2/conf-available/remoteip.conf
RemoteIPHeader X-Real-IP
RemoteIPInternalProxy 127.0.0.1
RemoteIPInternalProxy ::1
EOF
# 設定の有効化
sudo a2enconf remoteip
# 設定の反映
sudo systemctl restart apache2
意味合いの解説
sudo a2enmod remoteip
remoteipモジュールの有効化をしている。
逆はa2dismodで無効化出来るっぽい。
RemoteIPHeader <header-field>
ここで指定したHTTPヘッダーをクライアントのIPアドレス(useragent IP address)として扱うようにする。
例えばRemoteIPHeader X-Forwarded-ForとすればX-Forwarded-ForをクライアントIPとして扱える。
この設定だけだと問答無用で信頼してしまうため、本来と異なる経路で攻撃を受けた時に偽装されたヘッダをクライアントIPとして解釈するリスクがある。そのため、次項の設定も行う。
参考:mod_remoteip - Apache HTTP Server Version 2.4
RemoteIPInternalProxy <proxy-ip|proxy-ip/subnet|hostname ...>
RemoteIPHeader単品では前段のnginxを無視してApache2へ直にアクセスされたときに偽のX-Real-IPなどが来ていると、偽のIPが取れてしまうので、これを回避する仕組み。
RemoteIPInternalProxy ::1のように指定することで、そのIPから来たRemoteIPHeaderを信頼する。異なるIPからリクエストが来た場合は、RemoteIPHeaderを無視して、そのクライアントのIPが設定される。
RemoteIPTrustedProxyでも同じことができるのだが、違いはよくわかっていない。一応内部用と外部用で分かれているらしいが、RemoteIPTrustedProxy ::1でも期待通り機能したので謎。
公式ドキュメントではIPv4アドレスが指定されているので、恐らくIPv4でも行けると思うが確認していない。
参考:mod_remoteip - Apache HTTP Server Version 2.4
sudo a2enconf remoteip
作成した設定の有効化を行う。これを行っていない場合、設定は反映されない。
やっていることは/etc/apache2/conf-available/にある設定ファイルのシンボリックリンクを/etc/apache2/conf-enabled/に張っているだけだと思われる。
標準では/etc/apache2/apache2.confでIncludeOptional conf-enabled/*.confを指定しているため、これで設定が読み込まれるようになる。
逆はa2disconfで無効化できる。
あとがき
ここまで書いたところで/etc/apache2/sites-available/と/etc/apache2/sites-enabled/の違いに気が付いた。これも多分有効無効を切り替えるもので、sites-enabled側に設定を直書きするのは誤っているのだろう、きっと。
2025/10/21(火)Ubuntu 24.04.3 LTSにApache2を入れる
確認時のApache2のバージョンはApache/2.4.58 (Ubuntu)
Apache2のインストール
sudo apt -y install apache2
公開ディレクトリを触りやすくする
公開ディレクトリの所有者はデフォルトだとroot:rootで、そのままでは扱いづらいため自分自身でも手軽に扱えるように権限を調整する。
# 公開ディレクトリを見たりいじる為に自分をwww-dataに入れる
sudo usermod -aG www-data <自分のユーザー名>
# 公開ディレクトリを扱いやすくするためwww-data:www-dataに変える
sudo chown -R www-data:www-data /var/www
# 公開ディレクトリを扱いやすくするためにグループに全権限を付与する
sudo chmod -R g+rwx /var/www
mod_rewriteやmod_cgiを使えるようにする
CGIの実行に必要なPerlなどのランタイムは必要に応じて別途入れておく。PHPは一般的にCGIとして実行しないため、次項の方法で動かせるようにする。
sudo a2enmod rewrite
sudo a2enmod cgi
sudo service apache2 restart
PHPを使えるようにする
バージョンの部分は適宜書き換える。PHP本体をインストールしていない場合は別途インストールしておく(依存解決で勝手にインストールされるかもしれないが)
sudo apt install -y libapache2-mod-php8.3
sudo a2enmod php8.3
sudo service apache2 restart
2025/10/17(金)nginxからApache2のバーチャルホストにいい感じにリバプロする方法
投稿日:
nginxでhttps://example.comを受けて、https非対応のApache2にリバプロし、Apache2側でもhttps://example.comでアクセスされているように振舞わせる方法。取り敢えず最低限こんだけあると無難だろうという内容。
確認環境
| Env | Ver |
|---|---|
| OS | Ubuntu 24.04.3 LTS |
| nginx | 1.26.1 |
| Apache2 | 2.4.58 |
Apache2(後段)の設定
/etc/apache2/ports.conf
80や443を開けるとnginxと衝突するため、適当にずらしておく。
Listen 8080
/etc/apache2/sites-enabled/001-example.conf
ServerNameは外側と同じものにする。
<VirtualHost *:8080>
ServerName example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/example-error.log
CustomLog ${APACHE_LOG_DIR}/example-access.log combined
</VirtualHost>
nginx(前段)の設定
/etc/nginx/nginx.conf
httpセクションにupstream apacheを追記することで、conf.d/配下の設定ファイルから共通的に参照できるようにする。同じことを複数の設定ファイルに書くと構文エラーで起動しなくなる。
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
upstream apache {
server [::1]:8080;
}
include /etc/nginx/conf.d/*.conf;
}
/etc/nginx/conf.d/example.conf
ここでは/etc/nginx/nginx.confで設定したupstreamにプロキシする設定を作っている。
proxy_set_header Host $host;はnginxが受けたホストヘッダをそのままApacheに飛ばすことで、Apache側がバーチャルホストでルーティングできるようにしている。Apacheとnginxで別々のホスト名にすることもできるが、そうした場合、Apache側はApache側で定義したホスト名で動作するため、CGIなどのスクリプトを動かすときに支障があるうえ、Apache側のホスト名をhostsに書かないと疎通できないこともあり、手間なので基本的に前段のドメインに合わせておくのが無難だ。
proxy_set_header X-Real-IP $remote_addr;はnginxにアクセスしてきたクライアントのIPをApacheに渡すための設定。そのままだとnginxのIPが渡ってしまう。
proxy_set_header X-Forwarded-Proto $scheme;もホストヘッダの転送と似ていて、nginxが受けたプロトコルスキーマをApacheに飛ばすための設定。こうしておくとApache側はhttpで受けているのに、httpsでアクセスされたものとして認識させることが出来るため、プロトコルスキーマ付きでURLを生成するCGIがいるときに都合がいい。単にスキーマを誤魔化しているだけなので実際は暗号化されていない。
server {
listen [::]:443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
access_log /var/log/nginx/example.access.log;
error_log /var/log/nginx/example.error.log;
location / {
proxy_pass http://apache/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
余談:HTTP通信に用いられるHOSTヘッダーについて
HTTP通信で利用されるドメインは単にHOSTヘッダーにドメインを書いているだけなので、以下のようなことをするとhostsを書かなくとも疎通できる。
curl -H "HOST: lycolia.info" http://"[2403:3a00:101:13:133:167:8:98]"
これは一般的なHTTPクライアントの仕組みとして、まずドメインをDNSに問い合わせ、IPを取得したのち、ドメインをホストヘッダーに載せてIPアドレス宛にHTTP要求を出しているからだと思われる。
hostsの書き換えができない環境で、任意のドメインに対してHTTP要求を出したい時にも重宝するので、覚えておくと何かと役に立つ。
関連記事
2024/07/16(火)ローカルにHTTPS対応のnginxを建てる方法
WSL上のUbuntuで動作するnginxでHTTPSに対応したサーバーを作る方法。実機でも同様の手順でいける
確認環境
| Env | Ver |
|---|---|
| nginx | nginx/1.18.0 (Ubuntu) |
| mkcert | v1.4.4 |
| Ubuntu | 20.04.6 LTS |
| Windows 11 | 22621.3880 |
手順
- Windows側にmkcertを入れる
- mkcertで証明書を作る
mkcert sandbox.test
- 以下のpemファイルが生成される
sandbox.test.pemsandbox.test-key.pem
- 生成されたpemファイルを
/etc/nginx/conf.d/ssl/に移動する /etc/nginx/conf.d/sandbox.test.confを作成し、以下のような記述をするserver { listen 443 ssl; client_max_body_size 100m; server_name sandbox.test; ssl_certificate conf.d/ssl/sandbox.test+1.pem; ssl_certificate_key conf.d/ssl/sandbox.test+1-key.pem; access_log /var/log/nginx/sandbox.access.log; error_log /var/log/nginx/sandbox.error.log; # ファイルホスト用 # location / { # root /usr/share/nginx/html/sandbox; # index index.html; # try_files $uri /index.html =404; # } # APサーバーへのリバプロ用 location ~ ^/.*$ { rewrite ^/.*$ / break; proxy_set_header X-Request-Path $request_uri; proxy_set_header X-Host $host; proxy_pass http://127.0.0.1:9999; } # fastcgi用 location ~ \.php$ { root /usr/share/nginx/html/sandbox; fastcgi_pass unix:/run/php/php8.0-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } }- nginxを再起動する
sudo service nginx restart
他の端末に証明書を撒く方法
mkcertのRoot CAをエクスポートして他の端末に突っ込めば、他の端末でもpemが流用できる





