チュートリアル
新しいVPSを保護する方法:最初の10分でやるべきこと
新しいサーバーが最も無防備なのは、IPアドレスを割り当てられた瞬間です。自動化されたスキャナーはIPv4空間全体を絶えず走査しているため、1分前にデプロイしたばかりのサーバーへの最初のログイン試行は、ウェルカムメッセージを読み終える前に届くことも珍しくありません。これはあなたを狙い撃ちしたものではなく、いわば背景放射のようなものです — だからこそ、rootにパスワードを設定しただけの未強化なサーバーは、数か月ではなく数時間単位で乗っ取られます。幸い、これを封じるのは短い作業です:順序立てた10分間の手順で、無差別な攻撃によるリスクはほぼすべて取り除けます。本ガイドでは、そのチェックリストと、自分自身を締め出さないための順序、そしてほとんどの強化系チュートリアルが触れない一点 — 身元と結びつかないよう借りたはずのマシンに、デフォルト設定が静かに書き込んでいく個人情報 — について解説します。
強化が実際に守ってくれるもの
強化に取り組む価値があるのは、その効果が限定的でありながら確実だからです。どこまでが守備範囲かをはっきりさせておけば、対象外の部分について誤った安心感を抱かずに済みます。
- 無差別に狙ってくる攻撃者を完全に排除します。クレデンシャルスタッフィングのボット、SSHへのブルートフォース、管理画面を探すスキャンはいずれも、鍵認証のみの設定とデフォルト拒否のファイアウォールの前では通用しません。
- 稼働させているものに欠陥が見つかったときの影響範囲を限定します。localhostにバインドされ、閉じたポートの内側にあるサービスは、そのCVEが公開された当日でさえ、見知らぬ相手からは到達できません。
- ミスの代償を小さくします。権限を持たないユーザー、用途ごとに分けた鍵、自動パッチ適用があれば、一つの判断ミスがマシン全体の明け渡しには直結しません。
- ホストからサーバーを隠すことはできません。ハイパーバイザーにアクセスできる者は、原理上、稼働中のマシンのメモリを読み取ることができます — これはファイアウォールのルールの問題ではなく、誰から借りるかという問題です。
- あなたを匿名にすることはありません。強化が守るのはマシンそのものであり、そのマシンがあなたの名前と結びついているかどうかは、初めてログインするよりずっと前、登録と支払いの時点ですでに決まっています。
この最後の違いこそ、多くの人が逆に捉えてしまう点です。完璧に強化されたサーバーであっても、本名のクレジットカードで購入すれば、それは依然としてあなたの本名に紐づくサーバーのままです。この二つのレイヤーは補い合う関係にあります:No-KYCホスティングと暗号資産でチャージした残高が、書類上そのマシンが誰のものかを決め、これから紹介する10分間の手順が、誰がそこに入れるかを決めます。
自分自身を締め出さないための順序
強化にまつわる失敗談のほとんどは、実は同じ話です。鍵が使えることを確認する前にパスワード認証を無効にしてしまった、あるいはSSHを許可するルールを含めないままファイアウォールを有効にしてしまい、二度と手が届かないマシンから締め出されてしまう、というものです。手順に順序があるのは、それを起こり得なくするためです。まず鍵を登録し、2つ目のウィンドウでそれが機能することを確認します。パスワードを無効にするのはその後です。ファイアウォールのSSHルールは、有効化する前に必ず追加しておき、後回しにはしません。
必要になる前に、自分の復旧手段を把握しておく価値もあります。SSHでしか到達できないVPSには扉が一つしかないため、プロバイダーのダッシュボードにあるコンソールが、締め出しを再構築ではなく単なる不便で済ませてくれる頼みの綱になります。まだすべてが正常なうちに、それを開けることを確認しておきましょう。
ステップバイステップ: 新しいマシンでの最初の10分
- 01パッケージ索引とインストール済みパッケージを更新するイメージはビルドされた時点のスナップショットにすぎません。最新の状態にすることは、このリストの中で最も費用対効果の高い作業であり、1分もかかりません。
- 02sudo権限を持つ一般ユーザーを作成する常時rootとして作業すると、あらゆる打ち間違いとあらゆるプロセスが全権限で実行されてしまいます。通常のユーザーを作成し、sudoまたはwheelグループに追加して、以後はそちらを使いましょう。
- 03そのユーザーに公開鍵をコピーする手元にまだなければ、自分のマシンでed25519鍵を生成し、公開鍵の側をssh-copy-idで送ります。秘密鍵はノートPCの外に出ることはありません。
- 042つ目のターミナルを開き、鍵でのログインを確認するこれは省略しないでください。認証まわりを何か変更する前に、新しいウィンドウで新しいユーザーとして鍵でログインできることを確かめます。
- 05パスワード認証とrootログインを無効にするPasswordAuthentication noとPermitRootLogin prohibit-passwordを設定し、sshdを再読み込みします。これでブルートフォース攻撃には推測すべきものが何も残りません。
- 06SSHを許可したうえでデフォルト拒否のファイアウォールを有効にするすべての受信を拒否に設定し、SSHのポートを許可してから有効化します。自分のサービスに必要なポートは、その後で一つずつ追加してください。
- 07自動セキュリティ更新を有効にするDebianとUbuntuならunattended-upgrades、RHEL系ならdnf-automaticです。これが、あなたの注意が逸れてしまった半年後もマシンを安全に保ってくれます。
- 08何が待ち受けているかを確認し、不要なものを閉じるss -tulpnを一回実行するだけで、開いているソケットがすべてわかります。自分が意図的に置いたのでないものは、削除するかlocalhostへのバインドに変更してください。
SSH: 鍵認証のみにし、本当に重要な設定を押さえる
公開鍵認証こそが、SSH強化のほぼすべてです。パスワードを無効にしてしまえば、攻撃者は持っていない秘密鍵を必要とすることになり、どれだけ推測を重ねても手に入りません。ed25519鍵を生成しましょう — 短く、高速で、今の標準的な選択です — そして鍵にはパスフレーズを設定し、ノートPCが盗まれてもサーバーまで盗まれることのないようにしましょう。sshd_configの他の設定はすべて、この一つの決定の上に積み重なる細部にすぎません。
- PasswordAuthentication no — ブルートフォースに終止符を打つ設定です。まず2つ目のセッションで鍵が機能することを確認してから設定してください。
- PermitRootLogin prohibit-password — 復旧用に鍵でのrootアクセスは残しつつ、パスワードでのアクセスは一切許しません。sudoユーザーが問題なく機能することを確認できたら、noに設定しましょう。
- AllowUsersまたはAllowGroups — そもそも誰がログインできるのかを明示的に許可リスト化するもので、何らかのパッケージが作成したサービスアカウントがSSHの侵入口になることを防ぎます。
- KbdInteractiveAuthentication no — 一部のディストリビューションで、気づかぬうちにパスワード入力を復活させてしまうもう一つの対話的経路を閉じます。
- 一つの秘密鍵をあちこちにコピーするのではなく、デバイスごとに別の鍵を用意しましょう。スマートフォンを紛失しても、authorized_keysから1行削除すれば済むようにしておくべきで、すべてを作り直す必要はないはずです。
- SSHをポート22から移動すればログの量は劇的に減りますが、これはセキュリティ対策ではなくノイズ対策として捉えてください — あなたのIPを実際に狙っている相手には、何の違いももたらしません。
鍵認証よりもさらに踏み込みたいなら、最も強力な構成はSSHをそもそも公開しないことです:マシンをWireGuardトンネルの内側に置き、ポート22はトンネルのアドレスからの接続しか受け付けないようファイアウォールで制限します。こうすればSSHデーモンはインターネットから一切見えない存在になり、公開したままどれだけ設定を強化するよりも良い結果が得られます。
ファイアウォール: まずデフォルト拒否にし、使うものだけを開ける
ファイアウォールが意味を持つのは、初期設定が「拒否」である場合だけです。すべて許可しておいてから既知の危険なポートを塞ぐというやり方は本末転倒です — 結局、覚えているサービスだけを守り、忘れているサービスを晒すことになります。すべての受信を拒否し、送信は許可したうえで、必要になったものに合わせて個別にポートを開けていきましょう。最近のLinuxは内部でnftablesを使っており、ufwやfirewalldはそのための優れたフロントエンドです — 大切なのはツールそのものよりも、初期設定がどちらを向いているかです。
- ファイアウォールを有効にする前にSSHを許可しておきましょう。順序を逆にすることが、自分を締め出してしまう2番目に多い原因です。
- 外部からの接続が本当に必要なポートだけを開けましょう。ウェブサーバーなら80と443、データベースはほとんどの場合何も開ける必要がありません。
- ローカル専用のサービスは0.0.0.0ではなく127.0.0.1にバインドしましょう。閉じたポートと、そもそも公開待ち受けしないサービスは、それぞれ独立した防御であり、両方とも備えておくべきです。
- IPv4だけでなくIPv6のルールも書きましょう。デュアルスタックのマシンでv4しかカバーしていないルールセットは、同じサービスをv6アドレス側では丸ごと公開したままにしてしまいます。
- 可能な場合は、管理用ポートを送信元アドレスで制限しましょう。管理作業が常に一つのVPNエンドポイントから行われるなら、ルールにもそう明記します。
- サービスを追加したら、ルールを見直しましょう。すでに削除したもののために開けたままのポートは、静かに積み重なってクリーンな状態を台無しにしていきます。
ワークロードによっては、この論理を逆にして意図的に広く開いたポートを必要とすることもあります — Torリレーはどこからの接続でも受け入れなければなりませんし、Bitcoinのフルノードもポート8333に到達できて初めてピアにサービスを提供できます。それで構いません。ルールは「何も開けない」ことではなく「意図して開ける」ことであり、公開されるよう設計されたサービスであれば、それは意図した選択なのです。
fail2ban: 思っているほど重要ではない理由
fail2banはログを監視し、認証に繰り返し失敗したアドレスをBANします。確かに便利なツールですが、パスワード認証をすでに無効にした後で何をしてくれているのかは、正直に見ておく価値があります:その時点で推測によって成功できる者はもういないため、fail2banはもはや侵入を防いでいるわけではありません。fail2banが防いでいるのは、1日に何千行も積み上がる無意味なログ、その接続試行が消費するCPU、そして何か月も前から読まなくなったノイズの中に本物の異常が埋もれてしまうリスクです。
それでも10秒の設定にかける価値は十分にあります。そして、パスワードを受け付ける何か — ウェブアプリのログイン画面、メールサーバー、コントロールパネルなど — を実際に動かした瞬間から、fail2banは本当の意味で防御になります。sshdだけでなく、そうしたログにも向けておきましょう。BAN時間は分単位ではなく時間単位に設定し、打ち間違えたパスワード一つで自分自身を締め出さないよう、自分のアドレスは無視リストに加えておいてください。
覚えていなくても済む更新
きちんと設定されたサーバーにとって現実的な脅威は、誰かがあなたのSSH鍵を突破することではありません。インストールしたまま忘れていた何かの脆弱性が公表され、3日後、他のことをしている間にスキャナーに突かれることです。答えは自動セキュリティ更新です。DebianやUbuntuならセキュリティ用のリポジトリだけを対象に設定したunattended-upgrades、Fedora、Rocky、Almaならdnf-automaticがそれにあたります。最初の10分のうちに有効にしておけば、あなたの意識がとっくに他へ移った後も、マシンは自分自身にパッチを当て続けてくれます。
カーネルとlibcの更新だけは例外で、あなた自身の手が必要です。再起動して初めて有効になるため、稼働日数400日のサーバーは、ディスク上では1年前にパッチが当たっているのに、実際にはまだ古いコードを動かしているという状態にほぼ間違いなくなっています。Debianのneedrestartは、削除済みのライブラリを参照したまま動いているサービスを教えてくれますし、たとえ月1回であっても再起動の予定を組んでおくことが、「パッチが当たっている」状態と「パッチが適用されている」状態の違いを埋めてくれます。そもそも稼働させているものは、突然の再起動にも耐えられるべきです — もし耐えられないなら、それは別に解決すべき問題です。
強化チェックリストが見落とす身元の漏洩
オフショアのNo-KYCホストをあえて選んだ人にとっては、この節が本題です。一般的な強化ガイドは、所有者が公開情報になっている企業のサーバーを前提に書かれているため、初期設定があなたについて何を書き残すかを問うことは決してありません。匿名でレンタルしたマシンでは、そうした初期設定のいくつかが、静かにあなたの名前をマシンへ結びつけ直してしまいます。
- SSH公開鍵にはコメントが付いています — デフォルトではローカルのユーザー名とノートPCのホスト名で、alex@alex-macbookのような形です — そしてこのコメントはサーバー上のauthorized_keysにそのまま保存されます。鍵を生成する際に-Cフラグで指定するか、コピーした後にその行を編集してください。
- 自分で選んだサーバーのホスト名は、ログ、メールヘッダー、監視ツールの出力、そして時にはサービスのバナーにまで残ります。当たり障りのないホスト名なら何も明かしませんが、あなたや会社の名前を使えばそれが漏れてしまいます。
- システムのタイムゾーンです。クラウドイメージは初期状態でUTCになっており、これなら誰にも何も伝えません。ローカルのタイムゾーンに設定すると所在地の範囲が絞り込まれてしまい、あらゆるログのタイムスタンプがあなたの活動時間帯まで裏付けてしまいます。
- マシンにコピーされたGitの設定には、コミットに使っている名前とメールアドレスが含まれています。シェルの履歴ファイル、作業用マシンから同期したdotfiles、急いだテスト中にキャッシュされた認証情報も同様です。
- 証明書の発行時にLet's Encryptへ渡すメールアドレスは、その証明書の公開記録の一部になります。自分の身元と結びつかないアドレスを使いましょう。
- ウェブサーバーのバージョンバナーやX-Powered-Byヘッダー、さらにはアカウント識別子付きでマシンから外部へ通信するアナリティクス、クラッシュレポーター、ベンダーの監視エージェントも同様です。
それぞれの層を混同しないことには価値があります。強化はマシンから見知らぬ者を締め出します。ここで挙げた細部は、すでにマシンを見ている誰かに対して、それがあなたを語ってしまわないようにします。そして支払いの層が決めるのは、そもそも見つけ出せる名前があったかどうかです — この点はBitcoinでVPSを購入するのは本当に匿名かで正直に扱っており、Moneroでチャージすることでさらに一歩進められます。それぞれの層は単体では破られ得ますが、組み合わさることで持ちこたえます。
バックアップ: 強化では代わりにできない部分
データベースの削除、ディスクの故障、その時は妥当に思えた設定変更 — こうしたものからは、どんなファイアウォールのルールも守ってくれません。バックアップは、自分自身が犯したミスから立ち直らせてくれる唯一の対策であり、統計的に見て、しっかり保護されたマシンでデータを失う最も可能性の高い原因はまさにそこです。サーバーを出る前に暗号化し、少なくとも1つはサーバー自身が到達できない場所にコピーを保管し、思い出したときではなくスケジュールに従って実行されるようにしておきましょう。
最後の点は見た目以上に重要です:サーバー自身が上書きできるバックアッププロセスは、サーバー上でrootを握った何者かにも破壊できてしまいます。暗号化したアーカイブを別のストレージサーバーへ送る — あるいはそちらから取得しに行き、認証情報をバックアップ対象のマシンの外に置く — ことで、そのマシンが失われても生き残るコピーが手に入ります。そして、何も問題が起きていないうちに、あえて一度リストアを試しておきましょう。テストしていないバックアップは、安全網ではなく単なる仮説にすぎません。
気づかぬうちに、それまでの作業を台無しにするミス
- 鍵をテストする前にパスワード認証を無効にしてしまい、もうログインできなくなったノートPCの前でそのミスに気づく。
- SSHを許可する前にファイアウォールを有効にしてしまう — 逆方向から辿り着く、同じ締め出し。
- IPv4のルールしか書かず、マシンのIPv6アドレス側ではすべてのサービスに到達できる状態を残してしまう。
- 初日は入念に強化しておきながら、その後コントロールパネル、データベース、監視スタックを次々にインストールし、それぞれが尋ねもせず自分のポートを開いてしまう。
- sudoを打つ手間を惜しんですべてをrootとして実行してしまい、そのうちのどれか一つに欠陥が見つかった瞬間、マシン全体が乗っ取られる。
- fail2banを鍵認証の代わりとして扱ってしまい、単に速度が遅くなっただけのパスワード推測ゲームを走らせ続けてしまう。
- ディスクを暗号化すれば、レンタルしたサーバーをホストから隠せると思い込んでしまう — ディスク全体の暗号化が守るのは盗まれたドライブであって、稼働中のマシンではありません。
- 一度も再起動せず、何か月分ものカーネルパッチがディスク上に積み上がったまま、古いカーネルが動き続けてしまう。
ここまでのどれも難しくはなく、時間もかかりません。順序通りに進め、次に移る前に各ステップを2つ目のターミナルから確認していけば、数分前にデプロイしたそのマシンは、アドレス空間を走査する誰にとってももう狙い目ではなくなります。そのうえで、本来やりたかったことをデプロイしましょう — ウェブサイトでも、ノードでも、トンネルでも、プライベートなモデルエンドポイントでも — 中身を把握できる土台の上に構築するのです。