prodnote.dev本番ノート

Index/05

VPSを契約したら最初にやる4つのこと — 自分を閉め出してから覚えた順番

VPSの初期設定として実際にやった4つを、順番と理由つきで書きます。作業用ユーザーの作成、SSHの鍵認証、rootログインの無効化、ファイアウォールの確認。私は途中で fail2ban に自分のIPをブロックされ、SSHが無応答になりました。その復旧手順と、設定したのに効いていない状態になる落とし穴も含めて残します。

Published
Tags
VPSSSHセキュリティ個人開発

PR本記事にはアフィリエイトリンクを含みます

ノートパソコンの画面がほとんど空白のまま、キーボードに手を置いて止まっている人を、肩ごしに見たイラスト。契約した直後で、まだ何も設定していない状態を表している。

何から手をつける?

サーバーを借りました。管理画面に「IPアドレス」と「rootパスワード」が表示されています。

それで、次に何をすればいいのか分かりませんでした。

検索すると「初期設定」の記事がたくさん出てきます。私が読んだいくつかは項目が多く、どれが必須でどれが好みなのかを、自分では判断できませんでした。 全部やるべきなのか、後回しでいいのか分かりませんでした。

この記事は、私が実際にやった 4つ をその順番で書いたものです。やらなくていいと判断したことも書きます。

そして、私は途中で自分をサーバーから閉め出しました。その話も含めます。初めてVPSを触る人がいちばん怖いのは、たぶん「壊したら戻れないのでは」だからです。


やることは4つだけです

先に全体を出します。

0. 逃げ道を先に作る      ← いちばん大事
1. 自分用のユーザーを作る
2. 鍵でログインできるようにする
3. root でログインできないようにする
4. ファイアウォールを確認する

番号が0から始まっているのは、0を飛ばすと詰むからです。私は0の一部を先にやっていたので助かりました。


0. 逃げ道を先に作る

これから、ログインの方法そのものを変えます。失敗すると入れなくなります。

入れなくなったサーバーは、外からはどうにもなりません。中に入れないと直せないのに、直さないと入れないという状態になります。

なので、作業を始める前に2つ用意します。

VNCコンソールの場所を確認しておく

契約したVPSの管理画面に、ブラウザからサーバーの画面に直接つなぐ機能があることがあります。私が使っている ConoHa VPS では「コンソール」という名前でした。

あるかどうか、名前が何かは、契約先によって違います。 管理画面を見て探してください。

これは SSH とは別の経路です。SSHが完全に壊れても、こちらからは入れます。

ターミナルをもう1つ開いたまま作業する

これがいちばん効きます。

ターミナルA … 作業する。設定を変える
ターミナルB … 何もしない。開いたまま放置する

SSHの設定を変えても、すでにつながっている接続は切れません。 つまり、Aで設定を壊しても、Bはまだ生きています。Bから元に戻せます。

新しい設定が正しいかどうかは、Bで作業を続けるのではなく、3つ目の接続を新しく開いて確かめます。既存の接続で試しても、それは古い設定のまま生きているだけなので、確認になりません。

私はこの記事の全部の確認を、そのつど新しく開いた接続でやりました。


1. 自分用のユーザーを作る

root のまま使い続けません。普段の作業用に、別のユーザーを作ります。

理由は「安全のため」と説明されることが多いのですが、実感としてはもう少し具体的です。rootは打ち間違いが全部通ります。消すつもりのないものを消すコマンドも、確認なしで実行されます。

adduser --disabled-password yourname

--disabled-password は「パスワードを設定しないで作る」という指定です。外から総当たりで破られるパスワードが、そもそも存在しない状態になります。

(このあと、sudo を使うためにパスワードを設定する選択肢が出てきます。それでも外からは使えないままです。理由はそこで説明します。)

作ったユーザーに、2つの権限を足します。

usermod -aG sudo yourname

Docker を使う予定があるならdocker グループにも入れます。

usermod -aG docker yourname

⚠️ ここは飛ばせません。sudo が使えないユーザーになります

さっき --disabled-password で作ったので、このユーザーにはパスワードがありません

そして sudo は、既定ではそのユーザー自身のパスワードを尋ねます。 つまりこのままだと、sudo グループに入れたのに sudo が使えません

さらに次の3番で root のログインを止めるので、管理者権限を使う手段が無くなります。

A. パスワードを設定する(迷ったらこちら)

passwd yourname

「さっきパスワードなしで作ったのに、逆では」と思うかもしれません。 そうではありません。このパスワードは、SSHでは使えないままです。

3番で PasswordAuthentication no を入れるので、外からパスワードで入る道は閉じたままです。 このパスワードが使えるのは sudo のときと、VNCコンソールから入ったときだけになります。

つまりAを選ぶと、逃げ道がもう1本増えます。 VNCコンソールに入ったあと、 そこでも管理者権限を使えるからです。

B. パスワードを尋ねられないようにする(私はこちら)

# /etc/sudoers.d/yourname という新しいファイルに1行だけ書く
yourname ALL=(ALL) NOPASSWD:ALL

私がBにしたのは、自動化のたびに入力を求められると処理が止まるからです。 自動でデプロイする予定がないなら、Bを選ぶ理由はありません。


2. 鍵でログインできるようにする

パスワードの代わりに、鍵ファイルでログインします。

手元(自分のパソコン)で鍵を作ります。

ssh-keygen -t ed25519 -C "yourname@yourserver"

ed25519 は鍵の種類です。今から作るなら基本これで問題ありません。

できた公開鍵(.pub のほう)を、サーバー側の作業用ユーザーに置きます。

まだパスワードでログインできる状態なら、専用のコマンドが使えます。

ssh-copy-id -i ~/.ssh/id_ed25519.pub yourname@サーバーのIPアドレス

これは置き場所も所有者も権限も、全部正しくやってくれます。 使えるなら、これがいちばん確実です。

使えない場合(パスワードログインが既に無効など)は、手で置きます。

/home/yourname/.ssh/authorized_keys

手で置いたときは、所有者と権限の両方を直します。片方だけでは足りません。

chown -R yourname:yourname /home/yourname/.ssh
chmod 700 /home/yourname/.ssh
chmod 600 /home/yourname/.ssh/authorized_keys

ここで新しい接続を開いて、作ったユーザーで入れることを確かめます。 入れなければ、次には進みません。


3. root でログインできないようにする

2番までが成功していれば、root で入る理由はもうありません。止めます。

ここがこの記事でいちばん危ない操作です。 0番の逃げ道を確保していない状態では、やらないでください。

設定ファイルが1つではない、という話

SSHの設定は /etc/ssh/sshd_config にあります。ここを開くと、たいてい上のほうにこう書いてあります。

Include /etc/ssh/sshd_config.d/*.conf

これは「このフォルダの中身も設定として読む」という意味です。そして重要なのは、この行がファイルの先頭近くにあることです。

SSHの設定は 先に書いてあるほうが勝ちます。つまり:

/etc/ssh/sshd_config.d/ の中の設定   ← 先に読まれる。こちらが勝つ
/etc/ssh/sshd_config の本文          ← あとに読まれる

私が触ったサーバーでは、本文のほうに PermitRootLogin yes(rootのログインを許す)と書かれていました。本文を書き換えても直せますが、そうしませんでした。

sshd_config.d の中に新しいファイルを作って、そこに書けば勝てるからです。 元のファイルを触っていないので、そのファイルを消せば元に戻ります。 戻し方が単純なほうが、怖くありません。

⚠️ 99- で作ると負けます(私はそれで、たまたま動いていました)

sshd_config.d の中にすでにファイルがあることがほとんどです。まず見てください。

ls /etc/ssh/sshd_config.d/

たとえば 50-cloud-init.conf というファイルがよく入っています。 そしてフォルダの中は、ファイル名の順に読まれます。

00-hardening.conf     ← 先に読まれる。勝つ
50-cloud-init.conf    ← あとに読まれる

さっき書いたとおり、SSHの設定は先に書いてあるほうが勝ちます。 つまり、番号が小さいファイルが勝ちます。

なので、小さい番号で作ります。

# /etc/ssh/sshd_config.d/00-hardening.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no

3行目を不思議に思うかもしれません。パスワードで入る道は、実は2本あります。

PasswordAuthentication を止めても、KbdInteractiveAuthentication という別の入口が残ります。 こちらのSSH本来の既定は yes で、環境によってはここからパスワードを聞かれます。

多くのUbuntuでは、本文側で既に no になっています。でも当てにしません。 この記事では、その本文に PermitRootLogin yes が書かれているのを実際に見ています本文は契約先が書き換えていることがある、というのがこの記事で分かったことです。

反映する前に、必ず検証する

sshd -t

これは設定ファイルの書き方が正しいかを確かめるだけのコマンドです。何も反映しません。ここでエラーが出たら、作ったファイルを消して終わりです。

正しければ、書いた2つが実際に効いているかを見ます。ここが最後の砦です。

sshd -T | grep -E "permitrootlogin|passwordauthentication|kbdinteractive"
permitrootlogin no
passwordauthentication no
kbdinteractiveauthentication no

この3行が出れば、狙いどおりです。

yes のままなら、フォルダの中で負けています。 番号の小さいファイルに書き直してください。 sshd -T最終的にどう解釈されたかを出すので、ファイルを何枚書いたかに関係なく、 ここに出た値が本当の設定です。

restart ではなく reload

systemctl reload ssh

反映したら、新しい接続を開いて2つ確かめます。

作業用ユーザーで入れる     → 入れた
root で入ろうとすると断られる → Permission denied (publickey)

Permission denied が出たら成功です。断られることが目的なので、ここでエラーが出るのが正解です。


4. ファイアウォールを確認する

ここは手順というより、知らないとハマるという話です。

ファイアウォールは、2つあります

① VPS事業者側の設定(管理画面にある)
② サーバーのOS側の設定(ufw など)

この2つは別のものです。 片方で通していても、もう片方で塞がっていればつながりません。

私はこれを知らずに、OS側だけ見て「開いているのになぜつながらないのか」と悩みました。 実際には事業者側の管理画面で、SSH用とWeb用の許可を追加する必要がありました。

つながらないときは、両方を見てください。片方だけ見て原因を探すと、いつまでも見つかりません。


⚠️ fail2ban に自分のIPをブロックされ、SSHが無応答になった(復旧手順)

作業中、突然SSHがつながらなくなりました。エラーも出ず、ただ応答がありません。

原因は fail2ban でした。

鍵の設定を試行錯誤している間に、私は何度もログインに失敗していました。fail2ban から見れば、それは攻撃と区別がつきません。 自分の家のIPアドレスがブロックされました。

助かったのは、0番で確認しておいたVNCコンソールです。ブラウザからサーバーに入って、ブロックを解除しました。

fail2ban-client set sshd unbanip <自分のIPアドレス>

sshd の部分はブロックの種類の名前で、環境によって違うことがあります。分からなければ先に一覧を見ます。

fail2ban-client status

これが、0番をいちばん最初に置いている理由です。 逃げ道を先に作っていなければ、ここで詰んでいました。


やらなくていいと判断したこと

初期設定の記事によく出てくるけれど、私がやらなかったことです。やってはいけないという意味ではありません。「最初の1台では要らない」と判断したものです。

項目やらなかった理由
SSHのポート番号を変えるログに残る攻撃の記録は減りますが、パスワードでのログインを止めた時点で、パスワードの総当たりは通りません。ポートを覚える手間のほうが大きいと判断しました
秘密鍵にパスフレーズを付ける私は付けていません。ただしこれは勧められる選択ではありません。下に補足します
監視ツールの導入動かすものが決まる前に監視だけ入れても、何を見ればいいか分かりません。後回しにしました

判断の基準は「今この1台で、何を守りたいか」です。 それが決まらないうちに項目を増やすと、設定しただけで終わります。


まだやっていないこと

正直に書いておきます。

fail2ban に、自分のIPアドレスを最初から除外する設定(ignoreip)を、私はまだ入れていません。 入れておけば、上に書いた閉め出しは起きませんでした。

やっていない理由は、単にまだ手を付けていないからです。効果があると分かっていて、まだやっていない、という状態です。


まとめ

契約した直後にやることは、この4つでした。

0. 逃げ道を先に作る      VNCコンソールの確認 + ターミナルをもう1つ開く
1. 自分用のユーザーを作る  root のまま使わない
2. 鍵でログインできるように パスワードを使わない
3. root のログインを止める  設定は sshd_config.d に追加。reload で反映
4. ファイアウォールを確認   事業者側とOS側の2つある

難しいのは手順ではなく、失敗したときに戻れる状態を先に作っておくことでした。

私が閉め出されたときに助かったのは、技術ではなく、先に逃げ道を確認していたことだけです。

次にやること

まだVPSを契約していない状態でこれを読んでいるなら、ここまでが「契約したあとにやること」の全体です。できそうだと思えたなら、次はプラン選びです。

VPSのメモリは何GB必要か — 個人開発のアプリを46日動かして実際に測ってみた

実際に2GBのプランで46日動かして測った数字を載せています。限界は「動かす」ではなく「ビルドする」に出ました。

もう契約して、この4つを終えたなら、次はアプリを載せる作業です。私はDocker Composeで動かしていて、そこでも1つ踏んでいます。

Docker Compose の ports は override ファイルに書いても上書きされない