Ubuntu環境でnginxをリバースプロキシーとして設定し、裏の処理を同一サーバー内のApacheに任せる構成でWebサーバーのセットアップを行います。
利点として、Wordpressが生成する.htaccessがそのまま使うことができ、nginxが持つキャッシュ機能も設定追加で活用することが可能です。
前回に引き続き、今回も少し長めの内容となりますがご了承ください。
- 親記事:ブログ環境の構築作業まとめ
- 前記事:Ubuntu22.04の初期セットアップ
- 次記事:UbuntuでMySQL8.0のセットアップ
nginx1.24のインストール
最新のnginxをインストールできるよう、設定ファイルを新規作成します。
/etc/apt/sources.list.d/nginx.listdeb https://nginx.org/packages/ubuntu/ jammy nginx
deb-src https://nginx.org/packages/ubuntu/ jammy nginx
詳細は次の公式情報(英文)からご確認ください。
次にnginx公式が公開している署名鍵をインポートします。
次のコマンドを順に実行して、署名鍵の取得・インポート・不要になった署名鍵を削除してます。
wget https://nginx.org/keys/nginx_signing.key
sudo apt-key add nginx_signing.key
rm nginx_signing.key
次のコマンドを実行すると、nginxがインストールされます。
sudo apt update -y
sudo apt install -y nginx
インストールが完了したら、次のコマンドでnginxの自動起動設定と起動を行います。
sudo systemctl enable nginx
sudo systemctl start nginx
nginxが使用する80番,443番ポートを開放するため。次のコマンドでファイアウォールの設定を変更します。
sudo ufw allow 'nginx Full'
sudo ufw reload
ここまでサーバー設定に問題がなければ、IPアドレスによるアクセスでnginxの標準ページが表示されるはずです。
http://xxx.xxx.xxx.xxx/
「xxx.xxx.xxx.xxx」の箇所をVPSのグローバルIPに変えてアクセスしてみましょう。
PHP8.2とApache含むモジュール一式のインストール
最新のPHPをインストールできるよう、リポジトリーの追加を行います。
sudo apt-add-repository ppa:ondrej/php
sudo apt update
次にインストールしたいバージョンのPHP(今回はPHP8.2)とWordPress稼働に必要な関連モジュールを一括インストールします。
sudo apt update -y
sudo apt install -y php8.2 php8.2-mysql php8.2-curl php8.2-dom php8.2-imagick php8.2-gd php8.2-mbstring php8.2-zip php8.2-intl
PHP8.2をインストールするとApache2.4もセットで付いてきます。
もしnginx単独でPHPを動かしたい場合、「php8.2」を指定せず「php8.2-fpm」に変更してください。PHP8.2本体だけインストールされてApache2.4はインストールされません。
インストールが完了したら、次のコマンドでApacheの自動起動設定と起動を行います。
sudo systemctl enable apache2
sudo systemctl start apache2
PHP8.2の設定を行う
PHPの設定ファイルである「php.ini」を編集します。
設定項目が膨大であるため、編集前に初期の状態を把握できるようにオリジナルファイルをコピーしておきましょう。
sudo cp /etc/php/8.2/apache2/php.ini /etc/php/8.2/apache2/php.ini.proto
設定変更箇所ですが、まずPHPのバージョン情報を晒す「expose_php」を無効にします。
また、ファイルアップロードに関わる設定として
- memory_limit (1プロセス辺りのメモリー上限)
- post_max_size (ヘッダー含めた1リクエストで扱う総データサイズ上限)
- upload_max_filesize (1リクエストで扱うファイルサイズ上限)
の設定も変更します。これを行っていないとWordPressでテーマやプラグインのアップロードが行えません。設定値のバランスですが、
memory_limit >> post_max_size > upload_max_filesize
となるよう、うまく調整してください。
/etc/php/8.2/apache2/php.ini・・・
expose_php = On
expose_php = Off
・・・
memory_limit 128M
・・・
post_max_size = 8M
post_max_size = 64M
・・・
upload_max_filesize = 2M
upload_max_filesize = 50M
・・・
・・・
設定例では「memory_limit」のみデフォルト値のままにしています。
もし128Mより大きいファイルを取り扱いたい場合、サーバーのメモリースペックを意識しつつ「memory_limit」の値を調整してください。
Apache2.4の設定を行う
まずnginxで使用するポートと被らないよう、ポート関連の設定ファイルを編集します。
80番ポートはnginxがHTTP通信で使用するため、内部通信用に「8080」に書き換えます。
443番ポートはnginxがHTTPS通信で使用し、内部通信では使用しないためコメントアウトします。
/etc/apache2/ports.conf・・・
Listen 80
Listen 8080
<IfModule ssl_module>
Listen 443
</IfModule>
#<IfModule ssl_module>
# Listen 443
#</IfModule>
<IfModule mod_gnutls.c>
Listen 443
</IfModule>
#<IfModule mod_gnutls.c>
# Listen 443
#</IfModule>
・・・
次にApacheの実行ユーザーを変更します。
今回は前回の記事で作成したWebサーバー統括ユーザーに設定します。
・・・
# Since there is no sane way to get the parsed apache2 config in scripts, some
# settings are defined via environment variables and then used in apache2ctl,
# /etc/init.d/apache2, /etc/logrotate.d/apache2, etc.
export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data
export APACHE_RUN_USER=USER_NAME
export APACHE_RUN_GROUP=USER_NAME
# temporary state file location. This might be changed to /run in Wheezy+1
・・・
次にセキュリティ面で修正しておきたい設定を変更します。
/etc/apache2/apache2.conf・・・
Options Indexes FollowSymLinks
Options FollowSymLinks
・・・
/etc/apache2/conf-available/security.conf・・・
ServerTokens OS
ServerTokens Prod
・・・
ServerSignature On
ServerSignature Off
・・・
リバースプロキシー配下のApacheがリモートIPを取得できるよう、読込モジュールを設定します。
/etc/apache2/mods-available/remoteip.confRemoteIPInternalProxy 127.0.0.1
RemoteIPHeader X-Forwarded-For
RemoteIPProxiesHeader X-Forwarded-By
「RemoteIPInternalProxy」は同一サーバーのnginxをリバースプロキシとして使用しているため、「127.0.0.1」を指定しています。
もし外部のプロキシーを使用する場合、「RemoteIPInternalProxy」ではなく「RemoteIPTrustedProxy」にて対象IPを追加設定しましょう。
設定ファイルの編集が完了したら、次のコマンドで必要なモジュール一式を有効にします。
sudo a2enmod remoteip headers
a2enmodコマンドはmods-enabledディレクトリーに対し、指定のload/confファイルのシンボリックをまとめて作成してくれます。
スペース区切りで複数モジュールを一括指定できるため、個別でシンボリックリンクを作成するより楽です。
次にバーチャルホストの設定を行います。
まず、/var/www/
配下に独自ドメインのディレクトリーを作成し、更にその中に公開用ディレクトリーを作成します。
sudo install -o USER_NAME -g USER_NAME -d /var/www/your-domain.tld/public
sudo chown USER_NAME:USER_NAME /var/www/your-domain.tld
その後、画面表示の確認に使用するPHPファイルも作成します。
出力内容については、動作確認できるものであれば何でもかまいません。
/var/www/your-domain.tld/public/index.php<?php
echo '<h1>View test.</h1>';
echo '<pre>';
print_r($_SERVER);
echo '</pre>';
ディレクトリーとテストファイルの作成が完了したら、バーチャルホスト設定ファイルを新規作成します。WordPressの脆弱性となり得るアクセスに対する制限も同時に行っています。
/etc/apache2/sites-available/your-domain.tld.conf<VirtualHost *:8080>
ServerName your-domain.tld
DocumentRoot /var/www/your-domain.tld/public
DirectoryIndex index.php index.html index.htm
<Directory /var/www/your-domain.tld/public>
AllowOverride all
<Files "license.txt">
Require all denied
</Files>
<Files "readme.html">
Require all denied
</Files>
<Files "wp-config.php">
Require all denied
</Files>
<Files "wp-config-sample.php">
Require all denied
</Files>
<Files "xmlrpc.php">
Require all denied
</Files>
</Directory>
<LocationMatch ^/wp-includes/(.*)\.php$>
Require all denied
</LocationMatch>
<LocationMatch ^/wp-content/(.*)\.php$>
Require all denied
</LocationMatch>
</VirtualHost>
もしWordPressの管理画面へアクセスする端末が固定IP環境下である場合、次の設定も追加します。
/etc/apache2/sites-available/your-domain.tld.conf・・・
<Files "xmlrpc.php">
Require all denied
</Files>
<Files "wp-login.php">
Require ip xxx.xxx.xxx.xxx
</Files>
<Files "wp-signup.php">
Require ip xxx.xxx.xxx.xxx
</Files>
</Directory>
<Directory /var/www/your-domain.tld/public/wp-admin>
Require ip xxx.xxx.xxx.xxx
<FilesMatch admin-ajax.php$>
Require all granted
</FilesMatch>
</Directory>
<LocationMatch ^/wp-includes/(.*)\.php$>
Require all denied
</LocationMatch>
<LocationMatch ^/wp-content/(.*)\.php$>
Require all denied
</LocationMatch>
・・・
権限制御の詳細は次の公式マニュアル(英文)をご確認ください。
その後、次のコマンドでバーチャルホスト設定を有効にします。
sudo a2ensite your-domain.tld
最後に構文チェックを行います。
sudo apache2ctl -t
nginx1.24の設定を行う
まず共通設定の編集を行います。
/etc/nginx/nginx.conf・・・
keepalive_timeout 65;
gzip off;
gzip on;
gzip_types text/css text/javascript application/json application/octet-stream;
server_tokens off;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
また、text/htmlは標準で圧縮されるため指定する必要がありません。指定すると重複指定の警告が出ます。
なお、JavaScriptのMIMEタイプを誤って記載してるサイトが多いですが、正解はtext/javascriptです。現在の各MIMEタイプについては次のサイトを確認するようにしましょう。
サーバーへ送信可能なファイルサイズ上限を引き上げるため、次の設定ファイルを新規作成します。
php.iniの「post_max_size」で設定した値と同じになるようサイズを指定してください。
/etc/nginx/conf.d/client_max_body_size.confclient_max_body_size 64M;
次にバーチャルホストの設定を行います。
/etc/nginx/sites-available/your-domain.tldserver {
listen 80;
server_name your-domain.tld;
access_log /var/log/nginx/your-domain.tld.access.log;
error_log /var/log/nginx/your-domain.tld.error.log;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_pass http://127.0.0.1:8080;
}
}
設定変数で1点注意があります。
設定例で「$host」を使用している箇所ですが、インターネット上で情報を調べると「$host」ではなく「$http_host」にしている記事がいくつか散見されます。
「$http_host」を使うとホスト・ヘッダー・インジェクションの原因となるため、意図的な理由がなければ「$host」を常に使用することを推奨します。
有効サイトとしてsites-enabledディレクトリーにシンボリックリンクを作成します。
Apacheと違い便利コマンドはないため、普通のコマンドを使います。
sudo ln -s /etc/nginx/sites-available/your-domain.tld /etc/nginx/sites-enabled/your-domain.tld
最後に構文チェックを行います。
sudo nginx -t
バーチャルホストのページ表示を確認する
設定ファイルの編集が終わったら、Apacheとnginxを再起動します。
sudo systemctl restart nginx apache2
再起動後、Webブラウザで独自ドメインにアクセスします。
http://your-domain.tld/
先程作成したテスト用PHPファイルの内容が表示されていればOKです。
無料SSL「Let’s Encrypt」の導入と設定を行う
Let’s Encryptの証明書を簡単に導入するため、certbotをインストールします。
次のコマンドで必要なモジュールをまとめてインストールします。
sudo apt update -y
sudo apt install -y certbot python3-certbot-nginx
インストールが完了したら、次のコマンドを実行します。
nginxの指定ドメインのバーチャルホスト設定ファイルが自動更新され、SSL対応が完了します。
sudo certbot --nginx -d your-domain.tld --register-unsafely-without-email
Ubuntuだとこういう便利パッケージが充実していて楽ですね。
また、証明書の自動更新が有効になっているどうかは次のコマンドで確認可能です。
sudo certbot renew --dry-run
対象ドメインにHTTPS接続可能か確認し、問題なく画面表示されればOKです。
https://your-domain.tld/
HTTPS接続での画面表示も確認できたら、テスト用PHPファイルは削除します。
rm /var/www/your-domain/public/index.php
次回はMySQL8.0のセットアップを行っていきます。