共有ホスティング (いわゆるレンタルサーバー) に ConoHa WING を使ってきたのだが、ナンタラ調整費とやらで料金変動制になり、胡散臭さと面倒くささがマシマシなので、VPS に Hestia Control Panel (HestiaCP) を入れて代替を検討した記録。
HestiaCP とは:
- cPanel や DirectAdmin、Plesk のようなユーザー向けコントロール・パネル
- Vesta Control Panel (VestaCP) の fork
- Debian / Ubuntu 対応
- カスタムインストールで必要な機能のみインストール可
- httpd は Apache + nginx と nginx のみから選択
- multi PHP (複数バージョンの PHP を入れてユーザーがドメインごとに選べる機能) 対応
- ウェブアプリケーションのインストーラー
- Cloudflare CDN 対応
- ホワイトラベル対応
(私が特に重視した特徴を強調)
元になった VestaCP は開発が止まっている。HestiaCP とは別の fork である myVesta も試してみたが……以下の理由から断念。
- 入れなかった機能の残骸がユーザーから見えてしまう
- Apache + nginx 構成でないと multi PHP に対応しない
ウェブアプリケーション・インストーラーは Softaculous という最強クラスのインストーラーを利用できる myVesta に軍配が上がる。ただ Softaculous は無料版が対応しているアプリケーションが少なく、何より WordPress は無料エリアにない。
インストール
HestiaCP: インストールページで選んだり入力したりすると、パラメーターつきのコマンドラインが表示されるので、コピーしてシェルにペーストするだけ。
注意点
Port
標準ではポート 8083 で HestiaCP が動作するが、コントロールパネルに Cloudflare CDN を使う場合は Cloudflare: Network ports の「HTTPS ports supported by Cloudflare」記載のポートに変更する必要がある。
Hostname
コントロールパネルの URL に使いたいホスト名を入力するわけだが、この欄やインストーラーに入力したホスト名で /etc/hostname
が上書きされ、/etc/hosts
も変更される。
元の /etc/hosts
の末尾に改行がない場合、中身が変になるので、手動で直す必要がある。
直す必要が生じた例:
192.168.0.1 host.example.com127.0.0.1 host.example.com
運用
host.example.com:8083 としてのインストールを仮定して説明。
パッケージ
Apache、Bind、MadiaDB、nginx、PHP は Debian のリポジトリ以外からインストールされる。
(MySQL は確認していない)
各リポジトリは /etc/apt/sources.list.d/
に追加されている。
APT での PHP パッケージ更新時、設定ファイルを更新してはならない
HestiaCP ではセキュリティのため、PHP の disable_functions をかなり厳しく設定している。
一方 Debian のデフォルトはザル。
したがってパッケージ更新時に設定ファイルを更新 (Debian デフォルトでの上書き) してはならない。
翻訳
日本語訳は未完成だったので、Crowdin の HestiaCP 翻訳プロジェクトでだいたい翻訳した。
Language を Japanese にしてインストールした HestiaCP があまり訳されていなかったら、下記の手順で新しい翻訳を入れると良い。
- Crowdin にサインアップ (アカウント持ってない場合)
- ログイン状態で翻訳プロジェクトを開き、hestiacp.pot の右メニューボタンから Download
- hestiacp.po をサーバーにアップロード
- msgfmt で hestiacp.mo にコンパイル
- できた hestiacp.mo を
/usr/local/hestia/web/locale/ja/LC_MESSAGES/hestiacp.mo
に上書き
非ログイン状態で↑↓ボタンから Download translations しても中身は古いので注意。
コンパイル:
% sudo apt install gettext
% msgfmt -o hestiacp.mo hestiacp.po
msgfmt の代わりに Poedit で「MO にコンパイル」しても hestiacp.mo が得られる。
sudoers
/etc/sudoers.d/
下にユーザー admin の設定が作られるので、/etc/sudoers
でここを読み込まないようにしている場合は host.example.com:8083 にアクセスしても 500 エラーになる。
Debian のデフォルトでは読み込むようになっているが、私はサーバーのセットアップ時にコメントアウトしてしまうので、見事に穴を踏み抜いた。
nginx
nginx は2個実行される。
/usr/sbin/nginx
- 設定
/etc/nginx/
- ポート 80、443
- Apache を入れる場合のリバースプロキシ
- Apache を入れない場合のウェブサーバー
/usr/local/hestia/nginx/sbin/hestia-nginx
- 設定
/usr/local/hestia/nginx/conf/
- ポート 8083
- HestiaCP 用
HestiaCP (ポート 8083) の SSL 証明書
hestia-nginx はインストール時に生成された自己署名 SSL 証明書を使う設定になっている。当然ブラウザーで警告が出る。
Hestia ドキュメント: SSL Certificates の手順に従うと Let’s Encrypt の証明書が導入される。
しかしこの手順では host.example.com:443 と host.example.com:8083 に証明書をそれぞれ得ることになってしまう。
そこで先に HestiaCP 上で Web (ウェブ) → host.example.com → Enable SSL for this domain (このドメインで SSL を有効化) にチェック→ Use Let’s Encrypt to obtain SSL certificate (Let’s Encrypt で SSL 証明書を取得) にチェック→ Save (保存) することで 443 の証明書を得ておく。
次に hestia-nginx の証明書を差し替える。
% cd /usr/local/hestia/ssl
% sudo rm certificate.crt certificate.key
% sudo ln -s /home/admin/conf/host.example.com/ssl/host.example.com.crt ./certificate.crt
% sudo ln -s /home/admin/conf/host.example.com/ssl/host.example.com.key ./certificate.key
% sudo systemctl restart hestia
とすることで 443 用の証明書を 8083 でも利用するようになる。
証明書の更新は /usr/local/hestia/bin/v-update-letsencrypt-ssl
で行われる。
既存の証明書の有効期限まで 31 日以下になると更新を行い、
/usr/local/hestia/bin/v-restart-web
(nginx の再起動)
/usr/local/hestia/bin/v-restart-mail
(Exim の再起動)
を実行する。
admin の crontab で v-update-letsencrypt-ssl
を日実行するように設定されている。
hestia-nginx はここで再起動されないので、admin の crontab を編集する。
シェルからでも HestiaCP からでも良い。
シェルで作業する場合
% sudo -u admin crontab -e
この行を:
42 5 * * * sudo /usr/local/hestia/bin/v-update-letsencrypt-ssl
こうする:
42 5 * * * sudo /usr/local/hestia/bin/v-update-letsencrypt-ssl && sudo /usr/local/hestia/bin/v-restart-service hestia
(時刻はインストールにより異なるようなので適宜読み替えて欲しい)
HestiaCP で作業する場合
admin でログインし、Cron タブで次の行を編集:
sudo /usr/local/hestia/bin/v-update-letsencrypt-ssl
こうする:
sudo /usr/local/hestia/bin/v-update-letsencrypt-ssl && sudo /usr/local/hestia/bin/v-restart-service hestia
Save (保存)。
これで 443 と 8083 で同じ証明書を使い、更新後は新しい証明書が読み込まれる。
Fail2Ban
/etc/fail2ban/jail.d/defaults-debian.conf
は削除され、SSH も含めて HestiaCP で管理される。
Exim を入れず外部 SMTP でコントロールパネルからのメイルを送信
私はメイル機能をセルフホストせず MXroute を使っているので、Exim は入れない。
メイルを外部化することで、ウェブサーバーには sendmail コマンドすらなく、ポート 25 への外向き通信をまるごと nftables / iptables でブロックしてしまう運用が可能になる。
そんなわけで外部 SMTP を利用する設定が必要になる。
HestiaCP ドキュメント: Email and mail server の『How do I setup internal mail to be sent over SMTP?』に従う。
% sudo bash /usr/local/hestia/install/upgrade/manual/configure-server-smtp.sh
SMTP Security は ssl か tls を入力する。
- ssl: ポート 465 を使う場合
- tls: ポート 587 で StartTLS する場合
設定は /usr/local/hestia/conf/hestia.conf
にすべて (パスワードも!) 平文で保存される。
一応 /usr/local/hestia/conf/
が root:root パーミッション 750 だから大丈夫だろう、ということかな。
メイルに関するアンチウイルスを有効にできない場合
/usr/local/hestia/conf/hestia.conf
を編集し、下記を書く (情報源)。
そして HestiaCP を再起動。
% sudo systemctl restart hestia
(動作確認のために Exim 入りでインストールした時、インストール時に ClamAV をチェックしているのに hestia.conf にこの設定が記入されていなかったので)
WordPress インストーラー
日本語 (ja) のインストールに対応していなかった。
/usr/local/hestia/web/src/app/WebApp/Installers/WordPress/WordPressSetup.php
を編集して言語が並んでいるあたりに次の行を挿入。
(この変更はプルリクエストを出し、マージされた)
なお、サイト名に日本語を使おうとして変換確定に Enter を叩くとインストールされてしまうので、適当に英数字を入れておいてインストール後に WordPress 上で変更する方が良い。
https://host.example.com/ にアクセスすると工事中ページが表示されて気持ち悪いので、https://host.example.com:8083/ にリダイレクトしてしまいたい。
だが、HestiaCP 上で「Enable domain redirection (ドメイン転送を有効化)」すると phpMyAdmin もリダイレクトされてしまって使えなくなる。
トップページだけ HestiaCP にリダイレクトしたい。
という場合の設定。
なお https://host.example.com/ では、実運用のサイトを公開すべきではない。
このドメインは admin の権限で動作し、admin は sudoers で『/usr/local/vesta/bin/*
、/usr/local/hestia/bin/*
を root として実行する権限』を付与されている。
何らかの脆弱性があった場合に root 権限でのコマンド実行が可能になってしまうおそれがある。
HestiaCP 上で admin としてドメインを追加しようとすると警告が表示されるのも、そうした理由からだ。
nginx の場合
/home/admin/conf/web/host.example.com/nginx.ssl.conf_redirect
を作る。
内容:
location = / {
rewrite ^/$ https://host.example.com:8083/ permanent;
}
(/home/admin/conf/web/host.example.com.ssl.conf
を編集しても同じ結果を得られるが、Rebuild (再構築) で上書きされる可能性がある)
nginx は明示的な再読込が必要。
% sudo systemctl reload nginx
Apache の場合
/home/admin/web/host.example.com/public_html/.htaccess
を作る。
内容:
RedirectMatch permanent ^/$ https://host.example.com:8083/
Aoache は再読込不要。
phpMyAdmin が動かない
結論: 下記を実行 (情報源)。
% sudo chown -R root:www-data /etc/phpmyadmin/
nginx で Brotli 圧縮できない
Debian bookworm における結論: 諦める。
- nginx は Brotli を自らサポートする意志がなく、Google の ngx_brotli を導入する必要がある。
- HestiaCP では nginx リポジトリの nginx を使う。
- nginx リポジトリには ngx_brotli がない。
以上。
Debian bookworm は libnginx-mod-http-brotli-(filter|static) として ngx_brotli を収録しているので nginx mainline から Debian 収録の nginx に乗り換えれば使えるのではと思って試してみたが、設定テンプレートと衝突して動作しない。
理由:
- bookworm 収録の nginx は 1.22.1。
- nginx mainline は本記事執筆時点で 1.25.3。
- nginx 1.25.1 以降、HTTP/2 を使うためのディレクティヴに変更があった。
- HestiaCP は 1.25.1 以降用のディレクティヴを使っている。
自分で ngx_brotli をビルドして入れれば動くだろうが、いちいちやってられないから APT に頼るわけで。
ファイアウォール
ファイアウォール・ルールは一覧の下にある方が優先される。
ファイアウォール・ルールの下から上に向かって iptables に設定しているようだ (iptables は先に記述した方が優先なので)。
コントロールパネル (ポート 8083) へのアクセスを制限したい場合は下記の手順を踏む。
- Add Rule (ルールを追加) でポート 8083 へのアクセスを許可する IP アドレスを書いて Save (保存)。
- ルール一覧でコメント「HESTIA」のルールを編集し、Action (アクション) を Deny (拒否) に変更して保存。
順番は大事。順番を間違えると、すべての IP アドレスからポート 8083 へのアクセスを拒否した時点で自分もコントロールパネルから遮断され、その後の操作ができない (ssh で直すことになる)。