個人用のパソコンにChat GPTをいれてWorkを使うと、自分のパソコンを横取りして、色々なことをやってくれる。Oracle CloudのVMが無料で使えるので、それらをデコイとダッシュボードに仕立てた。クラウドの環境に立てておいたインスタンスのファイヤウォールを変えて、クラウドインスタンスにログインしてダッシュボードを作ってくれたりする。さらにダッシュボードの改修もできる。前回、デコイを作ったので今回は、そのレビュー。まずは、SSH編。
SSHをインターネットに公開すると、ものの10分くらいで攻撃が来る。以前から気にはなっていた。
sshd のログを見れば、root や admin に対するログイン試行が大量に記録されていることも珍しくない。しかし、実際に改めてSSHデコイを公開し、ログインを試した後にBotが何をするのかまで観察してみると、想像していた以上に激しかった。今回、Cowrieを使ったSSHデコイをインターネットに公開して観測してみた。24時間の結果がこれである。

|
項目
|
24時間
|
|---|---|
|
SSH接続
|
3,816
|
|
認証試行
|
3,628
|
|
Unique Source IP
|
174
|
|
IPv4 / IPv6
|
172 / 2
|
|
Cowrie上の疑似ログイン成功
|
3,619
|
|
コマンド実行
|
2,410
|
単純平均なら、
3816 / 24 ≒ 159接続/時
3816 / 86400 ≒ 1接続/23秒
となる。
SSHのポートを1個インターネットに開けただけで、24時間に3,800回以上接続された。
ただし、これを「3,816回、人間の攻撃者に攻撃された」と解釈するのは正しくない。
大部分は自動化されたスキャナやBotだ。
問題は、そのBotがどこまで自動化されているかである。
root は当然のように狙われる
認証に使われたユーザー名を見ると、突出していたのが
root だった。root 1430
ubuntu 85
admin 69
user 53
deploy 46
test 34
support 28
postgres 22
…
root だけで1,430回。ubuntu、admin、user、deploy、postgres といった、Linuxサーバーに存在しそうな名前も次々と試されている。つまり、
「ユーザー名くらい知られても大丈夫だろう」
というより、よくあるユーザー名なら最初から知られているものとして考えた方がいい。
そして、ここで重要になるのがパスワード認証である。
SSHのパスワードログインは止める
公開SSHでまずやるべきなのは、SSHでのパスワード認証を使わないことだ。
例えば、
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
として、公開鍵認証だけを使う。
これならBotが、
root / root
root / password
admin / admin
ubuntu / ubuntu
…
と何千回試しても、そもそもパスワード認証という入口が存在しない。
もちろん、SSHそのものやOSに脆弱性があれば別問題なので、OpenSSHやOSを更新し続けることも必要だ。
しかし少なくとも、今回大量に観測したようなパスワード総当たりを認証手段として成立させないことはできる。
「SSHを22番から変えればいい」は半分正しく、半分違う
では、
22番を2222番や10022番に変更すればいいのでは?
という話になる。
これは無意味ではない。
22/tcpだけを探している雑なBotは来なくなるため、アクセスログのノイズはかなり減る可能性がある。
しかし、これは本質的な防御ではない。
全ポートをスキャンすれば、SSHが別のポートで待ち受けていることは発見できる。
したがって、
SSHポートの変更はセキュリティ境界ではなく、主としてノイズを減らす対策
くらいに考えている。
ポートを変えたからパスワードログインを有効にしてよい、という話にはならない。
怖いのは「ログインを試して終わり」ではない
今回Cowrieを置いて面白かったのは、ここからだった。
Cowrieは攻撃者に対して、あたかもSSHログインに成功したような環境を提供できる。
そこで観察すると、Botはログインできたと思った瞬間に次の行動へ進んだ。
24時間で記録されたコマンド実行は 2,410回。
つまり単なる、
「SSH開いてる?」「rootで入れる?」
で終わるBotばかりではない。
入れたら、そのまま自動的にサーバー内部の調査を始める。

実際に多かったのが、
uname -s -v -n -r -m
hostname
などである。
さらに長いスクリプトを送り込み、
/etc/os-release
/proc/version
/proc/cpuinfo
lscpu
/proc/uptime
lspci
nvidia-smi
$SHELL
busybox
などをまとめて調べるBotもいた。
調べている内容を見ると、やっていることは分かりやすい。
SSHログイン成功
│
├── OSは何か
├── x86_64かARMか
├── CPUは何か
├── GPUはあるか
├── NVIDIA GPUか
├── nvidia-smiは使えるか
├── BusyBox環境か
└── どのコマンドが利用可能か
侵入した環境を調査し、そのマシンで何ができるのかを自動判定しているわけだ。
nvidia-smi まで確認してGPUの有無を調べているのは、いかにも今風で興味深い。ただし、このログだけでは、そのGPUを何に使おうとしていたのかまでは分からない。
そしてSSH鍵を書き換えようとした
さらに露骨なものも来た。
概略すると、こんな処理である。
cd ~
rm -rf .ssh
mkdir .ssh
echo “<public key>” >> .ssh/authorized_keys
chmod -R go= ~/.ssh
これはかなり分かりやすい。
既存の
.ssh を削除して、新しい .ssh を作り、攻撃者側の公開鍵を authorized_keys に登録しようとしている。つまり、
侵入成功
↓
~/.ssh を削除
↓
攻撃者のSSH公開鍵を登録
↓
次回から攻撃者自身の鍵でログイン
である。
Cowrieなので実際のサーバーが乗っ取られたわけではない。
しかし、これが普通のLinuxサーバーで、本当に認証を突破された後だったら話はまったく違う。
「パスワードが漏れたので変更しました」で終わらない。
すでに攻撃者の公開鍵が
authorized_keys に登録されていれば、新しいパスワードなど必要ないからだ。しかも今回のBotは
.ssh を丸ごと削除しようとしている。かなり乱暴である。
攻撃は一日中均等に来るわけでもなかった
もう一つ興味深かったのが時間分布だ。
ある時間帯の認証試行を見ると、
2026-09-27 16:00 UTC 1
2026-09-27 17:00 UTC 171
2026-09-27 18:00 UTC 1008
2026-09-27 19:00 UTC 2
2026-09-27 20:00 UTC 10
…
2026-09-27 23:00 UTC 560
2026-09-28 00:00 UTC 499
2026-09-28 01:00 UTC 515
2026-09-28 02:00 UTC 602
2026-09-28 03:00 UTC 33
となっていた。
24時間で3,816接続なので、平均すれば約23秒に1回だが、実際には均等ではない。
特定の時間に数百〜1,000件規模のwaveが押し寄せる。
平常時は比較的静かなのに、ある時間になるとBot群が一斉にやって来る。
この挙動を見ると、「1日3,800アクセス」という数字だけでは実態を表現しきれていないことも分かった。
174個のIPアドレスから来た
24時間で観測した送信元は174 IPだった。
国別では米国、中国、英国など複数地域に分散しており、ASNを見るとクラウドやホスティング事業者なども含まれていた。
ここで注意したいのは、送信元IPの国やクラウド事業者と攻撃者の所在地は同じではないということだ。
侵害されたサーバー、VPS、クラウドインスタンス、プロキシなどを経由している可能性もある。
したがって、
「○○国から攻撃された」
と単純化するより、
世界中に分散したインフラから自動スキャンが飛んでくる
と理解した方が実態に近い。
SSHを公開するということ
今回デコイを動かして、一番印象が変わったのはここだった。
以前から、
SSHをインターネットに公開すればBotが来る
こと自体は知っていた。
しかし実際にログイン後まで見てみると、
SSHポート発見
↓
ユーザー名探索
↓
パスワード試行
↓
ログイン
↓
OS・CPU・GPU調査
↓
実行環境確認
↓
SSH鍵による永続化
↓
さらに次の処理へ
というところまで自動化されている。
しかも、それが特別な標的にだけ行われるわけではない。
ただインターネットにSSHを公開しただけのIPアドレスに飛んでくる。
だからSSHを公開するなら、
攻撃されるかもしれない
ではなく、
常時スキャンされ、認証を試され、突破されたら即座に自動処理が走る
ことを前提に設計する必要がある。
最低限でも、
-
パスワード認証を無効化する
-
rootの直接ログインを無効化する
-
公開鍵認証を使用する
-
OpenSSHとOSを更新する
-
不要なユーザーをSSHログイン可能にしない
-
ログを監視する
くらいは必要だろう。
22番から別ポートへの変更も、ノイズ低減策としては意味がある。しかし、それを防御そのものと考えるべきではない。
さらに環境が許すなら、SSHを世界中へ公開せず、VPN、WireGuard/Tailscale、踏み台、送信元IP制限などで、到達可能な範囲そのものを狭くする方法もある。
デコイを置いて初めて見えたもの
通常のSSHサーバーなら、こうしたアクセスの多くは、
Failed password for root …
というログになって流れていく。
「SSHをインターネットに公開すると、大量のログイン試行が来る」。
それ自体は以前から知っていた。
しかし今回はCowrieを使い、攻撃してきたBotにあえて「ログインできた」と思わせたことで、その先が見えた。
24時間で3,816接続。
2,410回のコマンド実行。
OSやCPUを調査するBot。
GPUの有無まで確認するBot。
そして、自分のSSH公開鍵を登録して、次回以降のアクセス手段を確保しようとするBot。
「SSHには大量のログイン試行が来る」という事実よりも、「もし本当に入れたらBotは何をするのか」が見えたことが、今回一番興味深かった。
Cowrieだから今回は観察していられる。
本物のサーバーなら、認証を突破されたところから先は「ログイン試行」ではなく「侵入後の処理」になる。
SSHのポートをインターネットに開けるということは、こうした相手に対して24時間365日、入口を置いておくということなのだ。
そもそもSSHは、インターネットに公開する必要があるのか
ここまで観察して、もう一つ考えるようになった。
SSHとWebサーバーでは、「インターネットに公開する」という意味が少し違う。
一般公開するWebサイトは、不特定多数の人にアクセスしてもらうためのものだ。
HTTP/HTTPSの入口をPublic Internetに開けること自体が、サービスを成立させるために必要になる。
しかしSSHは違う。
SSHを利用するのが自分や限られた管理者だけなら、世界中のIPアドレスからSSHへ到達できる必要はない。
VPN、WireGuard、Tailscale、踏み台サーバー、あるいはファイアウォールによる送信元IP制限などを利用すれば、例えば次のような構成にできる。
Internet
│
├── 一般ユーザー ──X── SSH
│
└── 管理ネットワーク ──→ SSH
今回のデコイでは、SSHをPublic Internetに公開しただけで、24時間に3,816接続、174の送信元IPを観測した。
ならば、
これらすべてと戦えるSSHを作る
ことだけを考えるのではなく、
そもそも、これらの相手からSSHへ到達できる必要があるのか
を最初に考えるべきなのだと思う。
もちろん、運用上の理由からSSHをインターネットに直接公開する場合もある。
その場合でも、パスワード認証を無効化し、rootによる直接ログインを禁止し、公開鍵認証を使用する。そしてOpenSSHやOSを継続的に更新する、といった対策は必要になる。
SSHの待受ポートを22番から別の番号へ変更する方法もある。
これは無意味ではない。
22番だけを機械的に探しているBotを避けられるため、スキャンや認証試行によるログのノイズを減らす効果は期待できる。
しかし、それをセキュリティの中心に置くべきではない。
全ポートを探索する相手なら、別のポートで動いているSSHも発見できる。
ポート変更はSSHを安全にする仕組みというより、主として大量の自動スキャンによるノイズを減らすためのもの、と考えた方がいい。
そして、ここで別の疑問が出てくる。
では、Webサーバーはどうなのだろうか
SSHなら、「そもそもPublic Internetへ公開しない」という選択ができる。
しかし、一般公開Webサイトでは同じ方法は使えない。
不特定多数の人に見てもらう以上、HTTP/HTTPSの入口はPublic Internetに開けておかなければならない。
そして、人間に公開したその入口は、当然Botからも見える。
┌── 人間
│
Internet ──→ HTTPS ─┼── 検索エンジン
│
├── 正常なBot
│
└── 攻撃・探索Bot
SSHでは、入口そのものへの到達を制限するという防御ができる。
Webでは、一般公開する入口を開けたまま守らなければならない。
では、何も宣伝していないWebサーバーをPublic Internetに置いたら、その「開けておかなければならない入口」には何がやって来るのだろうか。
そこでSSHとは別に Web Decoy も公開し、実際に飛んでくるHTTP/HTTPSリクエストを観測してみた。
.env を探すもの。/.git/config を覗こうとするもの。PHP、Docker、Spring、WordPressなど、使っている技術を片っ端から探ろうとするもの。
SSHとはまた違う世界が見えてきた。
SSHは、公開しないという選択ができる。
Webは、公開することそのものが目的になる。
では、その入口には24時間で何がやって来るのか。
次回は、Web Decoyで観測した1日を見てみる。