ss -tulpnで待ち受けポートを見て「LISTENは想定通りだから大丈夫」と判断していないでしょうか。実はそれだけでは、外部と常時つながっている不審な通信を見逃します。この記事ではss -tulpnとlsof -iの出力を突き合わせ、「開いているポート」ではなく「実際に確立している通信相手」を点検する手順を、Ubuntu/Debian環境でコピーして使えるコマンド付きで解説します。
「ss -tulpnは正常」でも見落とす理由 ― 待ち受けポートと通信相手は別物
ss -tulpnが表示するのは「サーバー側でポートを開いて待っている(LISTEN状態の)プロセス」だけです。攻撃者がSSHのブルートフォース(総当たり)でログインに成功し、サーバーから外部のC2(攻撃者の指令サーバー)へ自らつなぎに行く形の通信(リバースシェルなど)を仕掛けた場合、この通信はLISTENではなくESTABLISHED(確立済み)状態で現れます。ss -tulpnの一覧には出てこないため、「ポートは全部把握している想定通りだから安全」という判断は成立しません。
この見落としは決して珍しいケースではありません。2025年の調査ではLinuxエンドポイントへの攻撃のうち約89%がSSHへの認証情報窃取・ブルートフォースによるもので、Shodanの調査では世界中で2,200万以上のSSHサービスがインターネットに公開されているとされています。さらに2026年時点でも「Linuxはウイルスに強い」という認識自体が危険とされ、攻撃の79%はマルウェアを使わず、設定不備や未パッチの脆弱性を直接悪用する手口が中心という指摘もあります。侵入経路の主戦場がSSHである以上、「待ち受けポートの点検」だけでなく「今まさに確立している通信相手の点検」が必要になります。
まず ss -tulpn で待ち受けポートを洗い出す
コマンドと出力例
何を見ているか:サーバーがどのポートで通信を待ち受けているか(LISTEN状態のソケット)と、それを開いているプロセスを一覧表示します。sudoが必要です(付けないとプロセス名・PIDの列が空欄になります)。設定変更は一切行わない読み取り専用のコマンドです。
sudo ss -tulpn出力例:
Netid State Local Address:Port Peer Address:Port Process
tcp LISTEN 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=812,fd=3))
tcp LISTEN 127.0.0.1:3306 0.0.0.0:* users:(("mysqld",pid=1204,fd=21))
tcp LISTEN 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1530,fd=6))
tcp LISTEN 0.0.0.0:4444 0.0.0.0:* users:(("nc",pid=9981,fd=3))正常/異常の見分け方
- Local Addressが127.0.0.1(自分自身のみ許可)なら外部から到達できないので基本的に安全です。上の例のmysqldがこれにあたります。
- Local Addressが0.0.0.0は外部からアクセス可能を意味します。心当たりのあるサービス(sshd・nginxなど)かをProcess列で確認してください。
- 覚えのないポート番号・プロセス名は要注意です。上の例の
nc(netcat)が4444番で待っている行は、意図的に立てた覚えがなければ典型的な不審サインです。
lsof -i で「実際につながっている相手」を突き合わせる
出力例と見るべき列
何を見ているか:lsof -iは「今ネットワークを使っているすべてのプロセス」を、LISTEN中の待ち受けだけでなくESTABLISHED(接続済み)状態の通信も含めて一覧表示します。ss -tulpnには映らない「サーバー側から外部へつなぎに行っている通信」もここに出てきます。
sudo lsof -iCOMMAND PID USER NODE NAME
sshd 812 root TCP 203.0.113.5:22->198.51.100.20:53211 (ESTABLISHED)
nginx 1530 www TCP *:80 (LISTEN)
curl 9981 root TCP 203.0.113.5:44120->185.220.101.7:443 (ESTABLISHED)見るべき列はCOMMAND(実行しているプログラム)・USER(実行ユーザー)・NAMEの右側(接続先IP:ポート)と状態です。3行目のcurlがrootユーザーで見覚えのない海外IPの443番と常時接続している場合、それ自体が異常とは断定できませんが、心当たりがなければ次章の照合が必要です。
ss -tnp state established との突き合わせ
何を見ているか:ss側でも確立済み接続だけに絞り込み、lsof -iの結果と同じPIDが同じ接続先を指しているかを照合します。両方に同じ情報が出ていれば見間違いではないと確認できます。
sudo ss -tnp state establishedPIDが分かったら、そのプロセスの実体を確認します(読み取り専用・設定変更なし)。
ps -p 9981 -fww
sudo ls -l /proc/9981/exe/proc/PID/exeが指すファイルのパスが/tmpや/dev/shmなど通常プログラムを置かない場所にある場合は強い異常サインです。心当たりのないアカウント経由での侵入が疑われる場合は、/etc/passwd点検2026年8月版|不審アカウント発見法もあわせて確認してください。
Fail2banとufwのログと照合して常時接続の外部通信先を判定する
fail2ban-client status で「入ってこようとした側」を確認
何を見ているか:Fail2banはSSHなどへのログイン失敗を検知して攻撃者からの侵入(inbound)を遮断するツールです。ここで見つかった不審IPと、前章でlsof -i / ssに出てきた接続先IPが一致するかを照合します。
sudo fail2ban-client status sshdBanned IP Listに前章の接続先IPが含まれていれば、少なくともそのIPからのログイン試行は検知・遮断されていたことが分かります。ただしFail2banはinbound(入ってくる通信)だけを見ており、サーバーから外部へ出ていくoutbound通信は監視対象外です。curlやncがサーバー側から外部へつなぎに行くケースはFail2banのログには一切残りません。
ufw status verboseとログでoutboundの扱いを確認
何を見ているか:ufw(Ubuntu標準のファイアウォール)の現在のルールと、デフォルトでoutbound(発信)通信をどう扱っているかを確認します。
sudo ufw status verbose出力のDefault:行がdeny (incoming), allow (outgoing)となっているのが一般的な初期設定です。つまりoutboundは標準で全許可・無記録なので、不審なプロセスが外部と接続していても、ufwのログには最初から残りません。ログ自体は次で確認できます(設定変更なしで見るだけです)。
sudo less /var/log/ufw.log該当行が無ければ「ufwは記録していない=正常が証明された」のではなく「outboundは元々見ていない」だけという点を押さえておいてください。ここがss -tulpn単体の点検で最も見落とされやすい落とし穴です。
不審な通信が見つかったときにやること
各対処のsudo要否・設定変更の有無・元に戻す方法を表にまとめます。
対処 | コマンド | sudo | 設定変更 | 元に戻す方法 |
|---|---|---|---|---|
プロセスを一旦止める |
| 要 | 無し(実行中のプロセス停止のみ) | 正規プロセスなら再起動すれば戻る |
該当IPへの発信を遮断 |
| 要 | 有り(ufwルール追加) |
|
実行ファイルの出所を確認 |
| 要 | 無し(読み取りのみ) | 該当なし |
侵入経路(アカウント)を確認 | /etc/passwd点検記事を参照 | 要 | 無し(読み取りのみ) | 該当なし |
プロセスを止めても不審な接続がすぐ再発する場合は、cronやsystemdの自動起動から復活させられている可能性があります。その場合は自力での対処にこだわらず、ネットワークを一旦切り離した上で調査を続けるか、詳しい人に相談することをおすすめします。無理に一人で完結させようとしてシステムを壊すより、被害範囲を確定させることを優先してください。
なお、今回のような侵入は権限昇格の脆弱性と組み合わされることがあります。2026年8月にはLinuxカーネルの権限昇格脆弱性(CVE-2026-53362)が米CISAの「悪用が確認された脆弱性カタログ」に追加され、行政機関への対応期限が8月30日に設定されました。カーネル・パッケージが最新化されているかはUbuntu apt自動更新の点検2026年8月版で、SUID経由の権限昇格の心当たりはSUID/Capability権限昇格チェック2026年8月版で、あわせて点検しておくと安心です。
まとめ
ss -tulpnは「待ち受けポート」しか見せてくれず、サーバーから外部へつなぎに行くリバースシェル的な通信はESTABLISHED状態のためここには映りません。lsof -iやss -tnp state establishedで確立済み接続を洗い出し、Fail2banのBanned IPやufwのログと突き合わせることで、初めて「実際に今つながっている相手」が正常かどうかを判断できます。すべて読み取り専用のコマンドなので、まずは自分のサーバーで一通り実行し、覚えのある接続先だけになっているかを確認してみてください。