0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AIで作ったアプリをVPSに載せた直後に見る10項目(SSH・UFW・自動更新・待ち受け)

0
Posted at

はじめに:「公開できた」と「安全」は別の話

AIや入門記事を見ながらVPSにアプリを公開できた。初期設定も一通りやった。でも、このまま放っておいて大丈夫かは分からない、という人は多いと思います。

世の中のチェックリストの多くは「契約直後にこう設定しよう」という手順です。この記事は向きが逆で、アプリを公開した直後に、今のサーバーの状態を確認するためのものです。

結論を先に書きます。

見るべきなのは「設定した覚え」ではなく「今、実際に効いている値」です。

設定ファイルを書いた覚えがあっても、別のファイルで上書きされていたり、そもそも有効になっていなかったりします。なので、この記事では各項目について 確認コマンド → 見方 → 次にやること の順に並べました。

10項目の一覧

# 項目 確認コマンド 期待する状態
1 SSHの実効設定 sudo sshd -T パスワード認証 no / root直ログイン no か prohibit-password
2 鍵で入れる一般ユーザー 別端末から ssh 一般ユーザーで鍵ログインできる
3 UFWの状態 sudo ufw status verbose active、許可は必要なポートだけ
4 待ち受けの棚卸し sudo ss -tlnp 想定外の 0.0.0.0 / [::] がない
5 Docker公開ポート docker ps DB等が 0.0.0.0 で公開されていない
6 事業者側ファイアウォール VPSのコントロールパネル 必要なポートだけ許可
7 自動セキュリティ更新 cat /etc/apt/apt.conf.d/20auto-upgrades Unattended-Upgrade "1"
8 再起動待ち ls /var/run/reboot-required ファイルがない(または計画的に再起動)
9 Fail2Ban(任意) sudo fail2ban-client status sshd 入れているなら sshd jail が動いている
10 時刻とタイムゾーン timedatectl 時刻同期が有効、意図したタイムゾーン

検証環境

Ubuntu 22.04.5 LTS / OpenSSH 8.9p1 / ufw 0.36.1 / Docker 29.5.2

この記事のコマンドと出力は Ubuntu 22.04 で確認したものです。24.04 でもコマンドは同じものが使える想定ですが、出力や既定値の違いは確認していません(推測)。

出力例は筆者のVPSの実際の出力をもとに、サービス名・ユーザー名・ポート番号を一般的なものに置き換えています。


1. SSHの実効設定を見る

sudo sshd -T | grep -E '^(passwordauthentication|permitrootlogin|pubkeyauthentication|kbdinteractiveauthentication) '

sshd -T は、設定ファイルを読み込んだ結果、最終的に効いている設定を一覧表示するモードです(sshd(8) の -T: Extended test mode)。

出力例(Ubuntu 22.04.5 で確認):

permitrootlogin no
pubkeyauthentication yes
passwordauthentication no
kbdinteractiveauthentication no

見方

表示 意味 次にやること
passwordauthentication no パスワードでのログイン不可 OK
passwordauthentication yes パスワード総当たりの対象になる 項目2を確認してから no にする
permitrootlogin no / prohibit-password rootはログイン不可/鍵のみ OK
permitrootlogin yes rootにパスワードで入れる 項目2を確認してから変更

なぜ設定ファイルを読むだけではダメなのか

sshd_config は Include で別ファイルを読み込めます。また、同じキーワードは最初に出てきた値が使われます(sshd_config(5))。

Ubuntu 22.04.5 の筆者環境では、/etc/ssh/sshd_config の12行目に Include /etc/ssh/sshd_config.d/*.conf があり、sshd_config.d 配下のファイルが本体の設定より先に読み込まれていました。つまり、本体に PasswordAuthentication no と書いても、sshd_config.d/*.conf に yes があればそちらが効きます。だから「書いたファイル」ではなく sshd -T の結果を見ます。

sshd -T の全体値だけでは見えない例外

もう一つ落とし穴があります。Match ブロックで特定のユーザーだけ設定を変えている場合です。筆者の環境にも、バックアップ用ユーザーだけパスワード認証を許すファイルがありました(以下は名前を一般化した例)。

# /etc/ssh/sshd_config.d/90-backup.conf
Match User backup-user
    PasswordAuthentication yes

この状態でも、sudo sshd -T の全体値は passwordauthentication no と表示されました。Match の条件に当てはまる接続を指定しないと、例外は表示されないためです。

-T に -C で接続条件(ユーザー・ホスト・アドレスなど)を渡すと、その接続に Match を当てはめた結果を確認できます(sshd(8) の -C connection_spec)。

sudo sshd -T -C user=backup-user,host=localhost,addr=127.0.0.1 | grep passwordauthentication

マニュアルでは、-C を指定すると、その接続条件に合う Match ブロックの設定が反映された結果が表示されると説明されています。上の例なら、backup-user の接続では passwordauthentication yes と表示されるはずです(このコマンドの出力そのものは、筆者は確認していません)。

例外がないかは、まず Match を探すのが手早いです。

sudo grep -rn '^\s*Match' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/

例外が意図したものなら、そのユーザーは鍵認証に切り替えられないか、接続元アドレスで絞れないか(Match User backup-user Address ...)を検討します。


2. 鍵で入れる一般ユーザーがいるか

項目1で設定を変える前に、必ずこれを確認します。

  1. 今つないでいるSSHセッションは閉じずに残しておく
  2. 別の端末(別ターミナル)から、一般ユーザー+鍵でログインする
ssh -i ~/.ssh/id_ed25519 youruser@<VPSのIP>
  1. ログインできて sudo も使えたら、パスワード認証やroot直ログインを止める

順番を逆にすると、自分も締め出されます。締め出された場合は、VPS事業者のWebコンソールから入って直すことになります。


3. UFWの状態と許可ポート

sudo ufw status verbose

status verbose で、有効かどうか、既定のポリシー、ルール一覧が表示されます(ufw(8) Ubuntu manpage)。

出力例(Ubuntu 22.04.5 で確認、v6の行は省略):

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
80,443/tcp (Nginx Full)    ALLOW IN    Anywhere

見方

  • Status: inactive → ファイアウォールが動いていない。SSHを許可してから sudo ufw enable
  • Default: deny (incoming) になっているか
  • 許可が 22 / 80 / 443 など必要なものだけか。開発中に開けた 3000 や 8080 が残っていないか

注意: Dockerで公開したポートにはUFWのルールが効きません(Docker: Packet filtering and firewalls)。上の例のようにUFWが 22/80/443 だけでも、Dockerで公開したポートは別に確認が必要です(項目5)。


4. 待ち受けの棚卸し

sudo ss -tlnp

今どのポートで、どのアドレスに対して待ち受けているかを一覧します。

Local Address の表示 意味
127.0.0.1:5432 / [::1]:5432 サーバー内からだけ届く
0.0.0.0:5432 / [::]:5432 / *:5432 すべてのアドレスで待ち受け。ファイアウォール次第で外から届く

筆者のVPSでは、nginx(80/443)と sshd(22)のほかに、アプリのAPIサーバーが複数のポート(3000番台相当で4つ)、Dockerの docker-proxy が2つ待ち受けていました。公開しているつもりのサービスより、待ち受けているプロセスのほうが多いのはよくあることです。それぞれの Local Address が 127.0.0.1 か 0.0.0.0 かを1行ずつ見ます。

特に注意したいのは DB系(5432 PostgreSQL、3306 MySQL、6379 Redis、27017 MongoDB) と、開発用サーバー(3000、5173、8000、8080など)です。これらが 0.0.0.0 で出ていたら、本当に外から届くかを確かめます。

表示の見方と外からの実測の詳細は、DockerとUFWの記事を参照してください。


5. Docker公開ポート

docker ps --format 'table {{.Names}}\t{{.Ports}}'

出力例(筆者環境をもとに名前とポートを一般化、アドレスは省略):

NAMES        PORTS
app-api-1    <アドレス>:3001->3001/tcp
app-api-2    <アドレス>:3002->3002/tcp
app-db-1     5432/tcp
app-db-2     5432/tcp

読み方:

  • app-db-1 5432/tcp のように -> がない → コンテナ内だけで待ち受けていて、ホストには公開されていない。DBはこれが理想
  • 0.0.0.0:3001->3001/tcp のように出る → ホストの全アドレスで公開。Composeでホスト側アドレスを省略して "3001:3001" と書くとこうなります(Docker: Port publishing and mapping)
  • 127.0.0.1:3001->3001/tcp → ホスト内からだけ届く(nginx経由で公開する構成ならこれでよい)

ここでは深掘りしません。0.0.0.0 が出たら、DockerとUFWの記事の手順に進んでください。

  • アプリのコンテナからしか使わないDBなら、ports: 自体を書かない(サービス名で届く)
  • 手元から触りたいなら "127.0.0.1:5432:5432" + SSHトンネル

6. 事業者側のファイアウォール

多くのVPSには、サーバーの外側で通信を絞る仕組み(パケットフィルタ、セキュリティグループなど、名前は事業者によって違います)があります。画面や名称は事業者ごとに違うので、ここでは一般的な確認方法だけ書きます。

  • VPSのコントロールパネルで、その機能が有効か、どのポートが許可されているかを確認する
  • 許可の一覧と、項目3(UFW)・項目5(Docker)の結果を並べて、意図しないポートが外側でも許可されていないかを見る
  • 実際に外から届くかは、手元のPCから確かめる(DockerとUFWの記事のStep2)

7. 自動セキュリティ更新

cat /etc/apt/apt.conf.d/20auto-upgrades

出力例(Ubuntu 22.04.5 で確認):

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

Ubuntuは unattended-upgrades パッケージで、セキュリティ更新を自動適用します。このファイルが有効/無効と実行間隔を決めていて、"1" は毎日、"0" は無効です(Ubuntu Server docs: Automatic updates)。

公式ドキュメントでは「既定でインストールされ、セキュリティ更新の自動適用が有効」とされています(同上)。筆者の 22.04.5 のVPSでも上のとおり有効でした。VPS事業者のイメージによって違う可能性はあるので、自分のサーバーで確かめます。24.04 のイメージでの値は確認していません。

実際に動いているかはログで見ます。ログの場所は /var/log/unattended-upgrades/ です(同上)。

sudo ls -l /var/log/unattended-upgrades/
sudo tail -n 20 /var/log/unattended-upgrades/unattended-upgrades.log

ファイルが無い場合は sudo apt install unattended-upgrades で入れられます(同上)。


8. 再起動待ちになっていないか

ls /var/run/reboot-required && cat /var/run/reboot-required.pkgs

更新の中には、再起動しないと反映されないもの(カーネルなど)があります。Ubuntuでは、再起動が必要な更新があると /var/run/reboot-required が作られ、unattended-upgrades もこのファイルを見て再起動要否を判断します(Ubuntu Server docs: Automatic updates – Reboots)。

自動再起動は既定で無効(Automatic-Reboot "false")です(同上)。筆者の 22.04.5 でも 50unattended-upgrades の Automatic-Reboot はコメントアウトされたまま(既定の false)で、確認した時点で /var/run/reboot-required が存在していました。自動更新は毎日動いていても、再起動しない限り反映されない更新が溜まっていたわけです。

  • ファイルがある → アプリへの影響が少ない時間に sudo reboot
  • 再起動後、アプリやコンテナが自動で起動するか(restart: unless-stopped など)も確認

9. Fail2Ban(任意)

この記事では必須にはしません。項目1でパスワード認証を切っていれば、総当たりで侵入されるリスクは大きく下がるからです。筆者のVPSにも入れていません。

ただし、項目1の Match の例外でパスワード認証を許しているユーザーがいるなら、話は別です。その場合は、例外をなくすか、接続元を絞るか、Fail2Ban を入れるかを検討します。

入れている場合は、sudo fail2ban-client status sshd で sshd の jail が動いているかを確認できます。


10. 時刻とタイムゾーン

timedatectl

出力例(Ubuntu 22.04.5 で確認、時刻の行は省略):

                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
  • System clock synchronized: yes か。時刻がずれると、ログの突き合わせや証明書の期限判断を誤る
  • Time zone が意図どおりか。UTCのままでも問題はないが、ログを読むときにどちらか分かっていること

タイムゾーンは timedatectl set-timezone で変更できます。指定できる値は timedatectl list-timezones で一覧できます(timedatectl(1))。

sudo timedatectl set-timezone Asia/Tokyo

まとめ:コピー用チェックリスト

[ ] 1  sudo sshd -T で passwordauthentication no / permitrootlogin no or prohibit-password
       Match の例外がないか grep し、あれば sshd -T -C user=... で確認
[ ] 2  別端末から一般ユーザー+鍵でログインできる(設定変更の前に確認)
[ ] 3  sudo ufw status verbose で active、deny (incoming)、許可は必要なポートだけ
[ ] 4  sudo ss -tlnp で想定外の 0.0.0.0 / [::] がない(特にDB・開発用ポート)
[ ] 5  docker ps で DB 等が 0.0.0.0 公開になっていない → あればDocker×UFWの記事へ
[ ] 6  VPSコントロールパネルのファイアウォールも確認
[ ] 7  20auto-upgrades が "1"、/var/log/unattended-upgrades/ にログがある
[ ] 8  /var/run/reboot-required がない(あれば計画的に再起動)
[ ] 9  (任意)Fail2Ban を入れているなら sshd jail が動いている
[ ] 10 timedatectl で時刻同期 yes、タイムゾーンが意図どおり

関連記事

同じ確認を一括で見たい場合

この記事の確認のうち一部は、拙作の読み取り専用CLI vps-check で一括表示できます。設定は変更せず、結果を PASS / INFO / WARN / HIGH / SKIP で表示します。

この記事の項目 vps-check のチェックID
1. SSHの実効設定 SSH-001(パスワード認証)、SSH-002(rootログイン)
3. UFWの状態 FW-001
4. 待ち受けの棚卸し NET-001(待ち受けポート)、NET-002(全アドレスで待ち受けるDB)
5. Docker公開ポート DKR-001(コンテナ)、DKR-002(Composeファイル)
7. 自動セキュリティ更新 UPD-001

Match による特定ユーザーの例外、事業者側のファイアウォール、再起動待ち、時刻は今のバージョンでは確認しないので、この記事の手順で見てください。

更新情報やちょっとしたTipsは X(@supportapp3_lab)で発信しています。


タグ案: VPS, Ubuntu, SSH, ufw, セキュリティ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?