開いているポートの一覧は、あなたのサーバーへ至る経路の一覧です。ほかのすべて——ファイアウォール、WAF、侵入検知——はその上に築かれます。だからこそどんな監査でも「ここで何が待ち受けているか」が最初に来るのであり、だからこそこれは最も頻繁に不愉快な答えを返す確認でもあります。見つかるものの半分はあなたが開けたのではなく、どこかのパッケージのインストーラが開けたものです。

出力の読み方

sudo ss -tulpn

フラグは、t が TCP、u が UDP、l が待ち受けているものだけ、p がプロセス、n が数字を数字のままにするもの。sudo が無いとプロセスの列は空になり、この作業そのものの意味が失われます。

重要なのは Local Address:Port の列で、そこでの違いは根本的です。

  • 127.0.0.1:3306——そのマシン自身からしか届きません。これはよいことです;
  • 0.0.0.0:3306——あらゆる IPv4 アドレスから、つまりインターネットから。これこそ確認すべきものです;
  • [::]:3306——IPv6 についての同じこと。別の行であり、そして定期的に見落とされます;
  • 203.0.113.25:443——特定のアドレス上で、たいていは意図的なもの。

そして 0.0.0.0[::] のある各行について、問いは一つです。見知らぬ相手がこれに届いてよいのか。80 と 443 については答えは「はい」。それ以外のほぼすべてについては「いいえ」です。

よくある発見

Redis、ポート 6379。そこで最も危険な一行です。既定で Redis はパスワードを要求せず、そのコマンドはディスクへファイルを書くことを許します——つまり authorized_keys に他人の鍵を置けるということです。Redis が公開アドレスに現れてから使われるまでの間は数時間、ときにはもっと短いこともあります。設定の bind 127.0.0.1protected-mode yes を確認してください。

Memcached、11211/UDP。中身に価値がなくても、あなたのサーバーは他人の攻撃の増幅器になります——そして苦情はあなたのプロバイダーから来ます。

MySQL と PostgreSQL、3306 と 5432。パスワードはありますが、その推測は絶え間なく行われ、データベースのバージョンは望ましいほど頻繁には更新されません。外を向く必要はほとんどありません。アプリケーションは同じマシンにあり、自分の作業には SSH トンネルで十分です。

Elasticsearch 9200、MongoDB 27017。歴史的に既定では認証がありませんでした。これらの公開インスタンスはデータ流出のニュースの常設の供給源です。

Docker API、2375。開いた Docker の制御ポートは、パスワードも何も無しのホスト上の root そのものです。たいてい Docker へのリモートアクセスの実験の後に現れます。

コントロールパネルと phpMyAdmin、それぞれのポートで:8080、8083、10000。決して開けてはならないというわけではありませんが、試行の大半を集めるのはまさにこれらです。

ファイアウォールではなくサービス側で直す

見つけたものを片端から UFW のルールで塞ぎたくなる気持ちは分かりますが、それは一線目ではなく二線目です。ルールは誤って消され得ますし、障害調査中に一時的にファイアウォールが切られることもあり、Docker に至っては UFW をすっかり迂回してポートを公開します。サービス自身の設定にある束縛の指定は、そのすべてを生き延びます。

  • MySQL/MariaDB——bind-address = 127.0.0.1
  • PostgreSQL——listen_addresses = 'localhost'
  • Redis——bind 127.0.0.1 ::1
  • Docker Compose——"127.0.0.1:5432:5432" の形で公開。

ファイアウォールはその上に保険として重ねるものであり、これの代わりではありません。

はっきりしないときにプロセスを特定する

ss は名前と pid を出します。次に:

sudo systemctl status <pid>
sudo lsof -i :8080

最初のコマンドは、そのプロセスがどの systemd ユニットのものかを教えます——たいていそれが何で、必要かどうかを理解するには十分です。高位ポートで待ち受け、しかもシステムのディレクトリの外から——たとえば /tmp/dev/shm から——起動された見知らぬプロセスは、もはや設定の問題ではなく、別途の調査の根拠です。

外部からの確認は必須

ss が答えるのは「何が待ち受けているか」であって、「どこへ届くか」ではありません。その二つの間にはファイアウォールと NAT とプロバイダー自身の規則が立っています。正直な答えは別のマシンからのスキャンでしか得られません。

nmap -Pn -p- 203.0.113.25
nmap -Pn -p- -6 2001:db8::1

二つ目のコマンドを省かないでください。ほぼすべての VPS が IPv6 アドレスを持ち、その規則は別に書かれ、サービスは両方のバージョンで同時に待ち受けています。

これは一度きりの確認ではない

開いているポートの一覧はひとりでに変わります。パッケージを入れたらサービスがついてきてポートを開けた。パネルを更新したら既定値が戻った。コンテナを起動したらファイアウォールを迂回してポートが公開された。一度きりの確認は今日についてしか答えず、それ以上ではありません。

価値は一覧そのものではなくその変化にあります。昨日は無かった新しいポートは、短くて非常に情報量の多い信号です。まさにそうやって見張る価値があるのです——履歴つきのスナップショットとして、記憶から思い出した ss の出力としてではなく。下のデモページが示すのはまさにそれです。