Ubuntu 24.04にWebminを導入して安全に設定する方法
Ubuntu 24.04にWebminを3コマンドで導入し、SSHトンネルまたはIP制限、Let's Encrypt証明書、2要素認証、port 10000のFail2banで保護する手順です。
構築するもの
Webmin は、Linux サーバー全体の Web インターフェースを提供する Web コントロールパネルです。ブラウザーから、ユーザー、パッケージ、cron ジョブ、ファイアウォール、Apache、BIND、ディスク、その他多数のモジュールを管理できます。HTTPS の port 10000 でアクセスします。インストール自体は 3 つのコマンドで実行でき、約 1 分で完了します。
このガイドの大半を後半に割く理由は、Webmin が root としてログインし、root と同じ操作を実行できるためです。無制限に公開された Webmin や認証のない Webmin は、「管理すべきリスク」ではありません。ログインページを備えたサーバー全体の侵害です。そのため、10 分でインストールした後、残りの時間を使って、自分だけがアクセスできることを確認します。
前提条件と、正直な注意点
root または sudo ユーザーでアクセスできる、Ubuntu 24.04 の新しい KVM VPS を用意します。Webmin は Perl 製で軽量です。RAM は 1 GB あれば十分で、アイドル時の使用量は 0.25 GB を大きく下回ります。Webmin は内蔵 Web サーバー (miniserv.pl) で TCP 10000 番ポートを待ち受けます。Apache や nginx は使用しないため、事前に別のソフトウェアをインストールする必要はありません。
開始前に、2 つの点を決めます。1 つ目は、ログインに使用するアカウントです。Webmin は PAM を通じて Unix アカウントを認証します。そのため、root または sudo グループに所属するユーザーとして、そのアカウントの Unix パスワード を使用してログインします。クラウドイメージは通常、デフォルトユーザーが鍵認証のみで、パスワードが設定されていません。Webmin はパスワードのないアカウントではログインできません。先に sudo passwd youruser でパスワードを設定してください。設定しない場合、入力内容にかかわらずログインに失敗します。
2 つ目は、重要な注意点です。ポート 10000 番をインターネットに単純に公開したままにしないでください。Webmin に SSH トンネル経由で接続する方法(推奨、外部公開なし)と、自分の IP アドレスからの接続だけを許可する方法のどちらかを、ここで決めます。この判断が以下のすべての手順に影響するため、ファイアウォールを変更する前に両方の方法を確認してください。
公式リポジトリからWebminをインストールする
Webminは署名付きのaptリポジトリを公開しています。セットアップスクリプトはリポジトリとGPG署名キーを追加するため、今後のapt upgrade実行では、他のパッケージと同じようにWebminが取得されます。自動更新されないダウンロード済みの.debに頼るのではなく、認証済みの更新を受けられます。
curl -o webmin-setup-repo.sh https://raw.githubusercontent.com/webmin/webmin/master/webmin-setup-repo.sh
sudo sh webmin-setup-repo.shスクリプトは実行する内容を表示し、Setup repository? (y/N)を求めます。yと入力してください。完了したら、パッケージをインストールします。--install-recommendsフラグを指定すると、共通のPerlおよびSSLモジュールの依存関係も取得できます。これにより、後で個別のモジュールがライブラリ不足のエラーで失敗することを防げます。
sudo apt-get install --install-recommends webminWebminは以前にもこのスクリプト名を変更しており、古いガイドではsetup-repos.shが参照されています。そのため、raw URLが404を返す場合は、名前を固定せず、webmin.com/downloadから現在のワンライナーを直接取得してください。正しくインストールされると、Webmin install complete. You can now login to https://your-host:10000/ as rootのような行で終了します。サービスは有効化され、実行中になります。設定は/etc/webmin以下に保存され、リクエストは/var/webmin/miniserv.logに記録されます。ログイン失敗はsyslogに記録されますが、Ubuntu 24.04ではsystemd journalに記録されます。
ブラウザーを開く前に、実際に起動して待ち受けていることを確認してください。
sudo systemctl status webmin --no-pager
sudo ss -tlnp | grep 10000active (running)のステータスと、0.0.0.0:10000にminiserv.plがバインドされていることを示す行が表示されれば正常です。以下のトンネル経由に切り替えると、そのアドレスは127.0.0.1:10000に変わります。10000でssに何も表示されない場合、Webminは起動していません。先にjournalctl -u webmin -n 50を確認してください。
初回ログインと証明書の警告
ブラウザーで https://YOUR_SERVER_IP:10000 を開きます。新規インストール直後は、2 つのことが起こります。
ufw が有効な場合、ページはまったく読み込まれません。Ubuntu のサーバーイメージでは ufw は無効になっていますが、多くのプロバイダーはあらかじめ有効にしています。この問題については、後述の障害例で説明します。ポートが開いている場合、ブラウザーにはページ全体を覆うブロック画面が表示されます。Chrome では 「この接続ではプライバシーが保護されません」 とコード NET::ERR_CERT_AUTHORITY_INVALID、Firefox では SEC_ERROR_UNKNOWN_ISSUER / 「警告: セキュリティ上の潜在的なリスクがあります」 と表示されます。これは想定された動作であり、侵入されたわけではありません。Webmin はインストール時に自己署名証明書を生成します(/etc/webmin/miniserv.pem)。この証明書を認証局が保証していないため、ブラウザーは暗黙的に信頼することを拒否します。接続自体は暗号化されています。認証局による保証がないだけです。ひとまず警告を進めます(Advanced、次に Proceed)。この証明書は、後ほど適切なものに置き換えます。
root または sudo ユーザーとその Unix パスワードでログインすると、System Information ダッシュボードが表示されます。ここでよくある入力ミスは、https:// の代わりに http:// と入力することです。miniserv はそのポートでプレーン HTTP に応答し、「この Web サーバーは SSL モードで実行されています。URL https://... を試してください」 と正確に表示します。対処方法は、アドレスバーの http を https に変更するだけです。
セキュリティ上の判断: Webmin にはどのように接続しますか?
ここが重要です。root と同等の権限を持つパネルをインターネットに直接公開し、世界中のスキャナーからのログイン試行に応答させるべきではありません。十分に妥当な選択肢は2つあります。推奨順に説明します。セルフホストする管理インターフェースでは、必ずこの問題に行き着きます。そのため、Vaultwarden が安全かどうかは暗号化ではなく、管理エンドポイントとバックアップファイルによって決まります。
Option B の SSH トンネルのほうが優れています。何も公開しないためです。アドレスが固定されている場合は、Option A の IP allowlist も許容できます。どちらも実施しないことが、このガイド全体で防ごうとしているまさにその誤りです。どちらの方法よりもプライベートネットワーク経由で Webmin に接続したい場合は、サーバーを セルフホストの WireGuard VPN の背後に置き、Webmin をパブリックアドレスではなくトンネルのアドレスにバインドしてください。
オプション A: Webmin へのアクセスを自分の IP に制限する
パネルで Webmin、次に Webmin Configuration、次に IP Access Control を開きます。「一覧にあるアドレスからのみ許可」を選択し、ノートパソコンで curl ifconfig.me を実行して確認できるパブリック IP を入力します。保存します。Webmin は /etc/webmin/miniserv.conf の allow= 行にこの設定を書き込み、自動的に再起動します。
注意点は、自宅の IP が動的で変更された場合や、アドレスを入力し間違えた場合に、アクセスできなくなることです。ブラウザーには 「<your IP> のアクセスが拒否されました」 と表示され、ログインフォームも表示されません。Webmin の Web インターフェースから復旧する方法はありません。SSH またはプロバイダーの VNC でサーバーコンソールに接続し、次の操作を行います。
sudo nano /etc/webmin/miniserv.conf
# find the line that begins allow=
# correct your IP, or delete the whole line to allow all again
sudo systemctl restart webminallow= 行を削除すると、すべてのアクセスが許可された状態に戻ります。これは復旧時だけ行い、直後に正しい値を設定してください。
オプション B: localhost にバインドし、SSH 経由でトンネル接続する(推奨)
どの許可リストよりも確実なのは、パブリックインターフェースで待ち受けないことです。miniserv をループバックにのみバインドし、信頼済みの暗号化された SSH トンネル経由で接続します。
/etc/webmin/miniserv.confを編集し、次の行を追加または変更します。
bind=127.0.0.1sudo systemctl restart webminで再起動します。これで Webmin はインターネットから到達できなくなり、10000 番ポートをスキャンしても何も検出されません。前述の ss の確認結果も、127.0.0.1:10000で待ち受けていることを示します。ラップトップからトンネルを開きます。
ssh -L 10000:localhost:10000 youruser@YOUR_SERVER_IPこのセッションを開いたまま、https://localhost:10000にアクセスします。通信は SSH 内部を通過します。SSH はすでに鍵で認証され、暗号化されているため、ここでは自己署名証明書を安全に受け入れられます。実際の保護は SSH 層が担います。SSH セッションを閉じると、Webmin に接続できなくなります。許可リストも、公開されたサービスも、追加で保護するサービスもありません。
bind=127.0.0.1を設定してトンネルを忘れた場合、リモートアクセスは停止します。これは障害ではなく、この機能が正常に動作している状態です。オプション A と同じ方法で復旧できます。コンソールから bind の行を削除するか、bind=0.0.0.0に設定してから再起動します。これは、tmux で Claude Code を実行しているリモート開発ボックスに接続するときにも使う、同じトンネル接続の方法です。1 つの SSH セッションですべてを非公開にし、パブリックインターフェースでは何も待ち受けさせません。
自己署名証明書を正規の証明書に置き換える
Option A でホスト名を使って Webmin を公開する場合は、正規の Let's Encrypt 証明書に置き換えてブラウザーの警告をなくします。panel.example.com などの DNS 名を用意し、その A レコードがサーバーを指すようにします。また、検証中にポート 80 の HTTP チャレンジへ応答できる状態が必要です。
Webmin にはこの機能が組み込まれています。Webmin、次に Webmin Configuration、次に SSL Encryption、次に Let's Encrypt タブの順に開きます。ホスト名を入力し、「website root directory」に、そのドメインのポート 80 で配信されるパスを指定して、証明書を要求します。Webmin は証明書を取得し、miniserv.conf 内の certfile= 行と keyfile= 行を更新します。証明書の有効期限が切れる前に自動更新も行います。ページを再読み込みすると、ブラウザーの鍵アイコンから警告がなくなります。
注意点が1つあります。Webmin 自身のサーバーはポート 80 ではなく 10000 で動作します。そのため、http-01 チャレンジには、ポート 80 で panel.example.com に応答する Apache または nginx などの実際の Web サーバーが必要です。代わりに DNS ベースの検証を使うこともできます。ポート 80 で何も動作していない Webmin 専用サーバーでは、Let's Encrypt がチャレンジファイルへアクセスできる方法を用意するまで、要求は検証エラーで失敗します。仕組み、DNS レコード、ポート 80 のチャレンジ、更新手順は、任意の Web サイト用に証明書を発行する場合と同じです。詳しい背景を確認する場合は、Certbot と nginx で Let's Encrypt TLS 証明書を発行するガイドで、検証の流れと DNS 設定を詳しく説明しています。SSH トンネルを使う方法を選んだ場合は、このセクションを完全に省略できます。SSH 経由では自己署名証明書で問題ありません。また、panel.example.com 用に発行した正規の証明書を使用しても、https://localhost:10000 にアクセスした際には名前の不一致による警告が表示されるだけです。
2 要素認証を有効にする
root パネルをパスワードだけで保護するのは不十分なため、2 つ目の要素を追加します。Webmin、次に Webmin Configuration、次に Two-Factor Authentication を開きます。Google Authenticator プロバイダーを選択します。これは標準の TOTP であるため、Authy、1Password、その他の認証アプリで使用できます。保存します。Webmin は必要な Perl モジュール(Authen::OATH と QR コード生成機能)をインストールして、この機能を有効にします。この操作だけでは、どのアカウントもまだ保護されません。
次に、各アカウントで使用するデバイスを登録します。2FA を有効にした状態で、Webmin、次に Webmin Users を開き、対象のアカウントを選択して Enable Two-Factor For User を選びます。Webmin に QR コードが表示されるため、認証アプリでスキャンし、生成されたコードを 1 つ入力して確認します。それ以降、ログイン時にはパスワードの後に 6 桁のトークンが求められます。ログアウトする前に登録してください。2FA が必須なのにアカウントでコードを一度もスキャンしていない場合でも、コンソールから要件を解除できますが、先に登録しておく方がはるかに簡単です。
ブルートフォースログインを禁止するために Fail2ban を追加する
制限されたログインエンドポイントでも、失敗を繰り返す接続元は拒否するべきです。Webmin は失敗したログインを syslog に webmin[12345]: Invalid login as root from 10.0.0.9 の形式で記録します。Unix アカウントとして存在しないユーザー名の場合は Non-existent login as ... になります。Ubuntu 24.04 では、標準イメージに /var/log/auth.log がないため、これらの行は systemd journal に記録されます。Fail2ban には、この2種類の行に正確に一致する標準の webmin-auth フィルターが含まれています。以下の jail では backend = systemd 自体を設定するため、カスタム正規表現やログパスは不要です。
/etc/fail2ban/jail.d/webmin.local を作成します。
[webmin-auth]
enabled = true
port = 10000
filter = webmin-auth
backend = systemd
maxretry = 4
bantime = 1hsudo systemctl restart fail2ban で再読み込みし、jail が稼働していることを確認します。
sudo fail2ban-client status webmin-auth最初は ban カウンターが 0 の状態で jail が表示されます。journal バックエンドでは File list: 行はありません。設定が最後まで機能することを確認するには、別のネットワークから意図的に数回ログインを失敗させます。その後、ステータスコマンドを再実行し、Currently banned が増えることを確認します。増えない場合は、テスト元のアドレスが Fail2ban の ignoreip に含まれていないことを確認してください。また、サーバー上で journalctl SYSLOG_IDENTIFIER=webmin を実行し、Invalid login 行が実際に書き込まれていることを確認します。このサーバーに Fail2ban がまだインストールされていない場合は、Ubuntu 24.04 で SSH 用に Fail2ban を設定するガイドで、インストール手順と、この jail と併用すべき SSH jail を説明しています。
各 Webmin ユーザーが操作できる範囲を制限する
パネルを必要とするすべてのユーザーに、すべての操作に対する root 権限を与える必要はありません。Webmin、次に Webmin Users を開き、追加の Webmin ログインを作成して、それぞれに必要なモジュールだけを許可します。たとえば、バックアップ担当者には cron とファイルシステムのモジュールだけを表示します。ユーザーを編集すると、すべてのモジュールのチェックリストが表示されます。チェックを外すと、そのユーザーのメニューからモジュールが削除され、対応する URL へのアクセスもブロックされます。これは多層防御の一環です。Users モジュールが一覧にない場合、権限の低い Webmin セッションを盗まれても /etc/shadow を書き換えることはできません。
Webmin を最新の状態に保つ
apt リポジトリからインストールしたため、sudo apt update && sudo apt upgrade はシステムの他の更新と同時に Webmin の新しいリリースを取得します。コントロールパネルは攻撃対象になりやすいため、速やかにパッチを適用してください。Webmin は Webmin、Webmin Configuration、Upgrade Webmin の順に選択して自身を更新することもできますが、Ubuntu では apt を使う方法のほうが適しています。他のパッケージ管理対象とバージョンを一貫させられるためです。これは任意の作業ではありません。過去には Webmin の複数の CVE がリモートコード実行の脆弱性でした。「パッチ適用済み」と「侵害済み」を分けたのは、管理者がどれだけ速くアップグレードを実行したかだけでした。
確認できるエラーと表示内容
「接続はプライベートではありません」 / NET::ERR_CERT_AUTHORITY_INVALID。 初回の読み込み直後に表示されます。原因は、Webmin のインストール時に生成された自己署名証明書に、信頼された発行者が設定されていないことです。攻撃ではありません。通信は暗号化されていますが、証明書による検証はできません。対処として、ひとまず警告を進み、後で正式な Let's Encrypt 証明書を発行します。SSH トンネル経由で Webmin に接続する場合は、証明書を恒久的に受け入れてもかまいません。
「この Web サーバーは SSL モードで動作しています。URL https://... を試してください」 http://server:10000 と入力しています。miniserv はそのポートで TLS 接続だけを受け付けており、そのことを平文で通知しています。対処として、アドレスバーの http を https に変更します。
ページがタイムアウトする、ERR_CONNECTION_TIMED_OUT / 「このサイトにアクセスできません」。 リクエストが Webmin に到達していません。Ubuntu では、ほとんどの場合 ufw がポート 10000 を破棄しています。sudo ufw status で確認します。10000 が一覧にない場合は、sudo ufw allow 10000/tcp でポートを開くか、より安全な方法として閉じたままにし、Option B の SSH トンネルを使用します。違いに注意してください。タイムアウトは、ファイアウォールがパケットを黙って破棄していることを示します。一方、ERR_CONNECTION_REFUSED はポートには到達できますが Webmin が動作していないことを示します。sudo systemctl status webmin を確認してください。
「<your IP> のアクセスが拒否されました」。 Option A で IP Access Control を設定し、現在のアドレスが許可リストに含まれていないか、動的 IP が変更されたか、入力を誤っています。ブラウザーから元に戻す方法はありません。コンソールから対処します。/etc/webmin/miniserv.conf の allow= 行を編集して、内容を修正するか削除し、sudo systemctl restart webmin を実行します。
「ログインに失敗しました。もう一度お試しください。」正しいと分かっている認証情報を使っている場合。 そのアカウントに Unix パスワードがありません。鍵認証だけを使用するクラウドイメージでは一般的な状態です。Webmin は PAM を通じて Unix パスワードで認証しますが、そのユーザーにはパスワードが設定されていません。対処として、サーバーで sudo passwd youruser を実行してからログインします。/var/webmin/miniserv.log に Non-existent login as ... と表示される場合、入力しているユーザー名は Unix アカウントではありません。
サーバーが数台を超える場合は、各サーバーにコントロールパネルを配置するより自動化のほうが拡張しやすくなります。そこから始めるのが 最初の Ansible playbook です。
FAQ
Webmin をパブリックインターネットに公開しても安全ですか?
インターネットからアクセスできる Webmin は、ログイン画面付きの root shell と考えてください。実際にそのものだからです。安全性を確保するには、複数の対策を重ねる必要があります。正式な証明書、二要素認証、Fail2ban、厳格な IP 許可リストのいずれかを設定し、できれば公開自体を避けてください。最もリスクが低い構成は、Webmin を 127.0.0.1 に bind し、SSH tunnel 経由でアクセスする方法です。この場合、port 10000 はパブリックインターネット上の誰にも応答しません。
Webmin の証明書警告を消すにはどうすればよいですか?
Webmin には self-signed certificate が付属しているため、警告(NET::ERR_CERT_AUTHORITY_INVALID)が表示されます。Webmin の Webmin Configuration、SSL Encryption、Let's Encrypt から正式な証明書を発行してください。検証用に port-80 challenge を提供するサービスをサーバー上で動かし、サーバーを指す DNS 名を使用します。Webmin に localhost への SSH tunnel 経由でしかアクセスしない場合、警告は無害です。SSH が接続をすでに暗号化して認証しているため、self-signed certificate を安全に受け入れられます。
Webmin を自分の IP アドレスだけに制限するにはどうすればよいですか?
Webmin、Webmin Configuration、IP Access Control の順に開き、「Only allow from listed addresses」を選択して、curl ifconfig.me から自分のパブリック IP を入力します。Webmin はこの設定を /etc/webmin/miniserv.conf の allow= 行に保存します。自宅の IP が動的に変わる場合は注意してください。IP が変わると締め出され、サーバーコンソールから allow= 行を修正する必要があります。そのため、実際の運用では固定アドレスまたは SSH-tunnel 方式の方が信頼性に優れます。
正しいパスワードを入力してもログインに失敗するのはなぜですか?
Webmin は PAM を通じて Unix password を認証します。しかし、cloud image は通常、key-only で、デフォルトアカウントに password が設定されていません。そのため PAM が照合できるものがなく、ログインは拒否されます。サーバー上で sudo passwd youruser を実行して password を設定してから、ログインしてください。/var/webmin/miniserv.log に Non-existent login as ... 行がある場合は、username 自体が実在する Unix account ではないことを示します。
通常の SSH と比べて、Webmin は何に適していますか?
Webmin は、システムの機能を見つけやすくし、操作を簡単にするレイヤーです。すべてのコマンドを覚えなくても、ログファイルの閲覧、ユーザーと cron の管理、firewall rule の編集、ディスクと service の状態確認を行えるため、たまに管理する担当者やスキルが混在するチームには実用的です。通常の作業では、通常の SSH の方が高速で script 化しやすく、攻撃面も大幅に小さくなります。多くの管理者は両方を使用します。日常の操作には SSH を使い、たまに必要になる point-and-click 操作のために、Webmin を localhost に bind して tunnel の背後で動かします。質問が panel と shell の比較ではなく、どの panel を選ぶべきかということであれば、まず Cockpit と Webmin の比較 を検討するとよいでしょう。両者では、実際に変更できるシステム範囲と、ユーザーを認証する方法が異なるためです。