ハニーポッド入門でセキュリティを学ぶ
以前の記事でHetzner VPSを構築した。セキュリティ設定も一通り終えて、fail2banが攻撃を自動ブロックしてくれている。でも、ただブロックするだけじゃもったいない。攻撃者を偽の環境に招き入れて、何をするか観察できたら面白いんじゃないかと思った。それがハニーポットだ。
ハニーポットとは
ハニーポット(Honeypot)とは、攻撃者を意図的に引き寄せるための囮サーバーのこと。今回使うのは cowrie という有名なSSHハニーポットツール。
cowrieの仕組みはシンプルで、攻撃者が「侵入できた」と思い込めるような偽のSSH環境を提供しつつ、その中で実行されたコマンドをすべてログに記録する。実際には何もできないサンドボックス環境なので、サーバー本体へのダメージはない。
全体の構成
今回目指すのは以下の構成だ。
攻撃者 → XX番ポート(cowrie / ハニーポット)
自分 → XXXXポート(本物のSSH)
攻撃者はXX番に来る。cowrieが「どうぞどうぞ」と偽の環境に招き入れる。自分は別のポートで本物の環境に入る。完全に分離されているので安全だ。
Step 1: 本物のSSHポートを変更する
まずサーバーに接続して、SSHの設定ファイルを編集する。
sudo vim /etc/ssh/sshd_config
#Port XX という行を見つけて以下に変更する。
Port XXXX
Ubuntu 24.04では ssh.socket がポートを管理しているため、単純にreloadするだけでは反映されない。以下の手順が必要だった。
sudo systemctl disable ssh.socket
sudo systemctl stop ssh.socket
sudo systemctl restart ssh
これで変更後のポート番号でSSHが起動する。
Step 2: Hetzner FirewallとufwにTCP XXXXを追加する
ポートを変えただけでは外からアクセスできない。Hetzner CloudコンソールのFirewallと、サーバー上のufwの両方に変更後のポート番号を許可する必要がある。
Hetzner Firewall(コンソールから):
- Inbound Rules に TCP XXXX を追加
- Source: Any
ufw(サーバー上で):
sudo ufw allow [変更後のポート番号]/tcp
Step 3: 新しいポートで接続確認してからXX番を閉じる
ここが一番大事なポイント。 新しいターミナルを開いてXXXX番で接続できることを確認してから、XX番を閉じる。先に閉じてしまうとロックアウトされる。
ローカルの ~/.ssh/config に変更後のポート番号を追加して:
Host foo
HostName xxx.xxx.xxx.xxx
User bar
Port [変更後のポート番号]
別ターミナルから ssh foo で繋がることを確認したら、XX番を削除する。
sudo ufw delete allow OpenSSH
HetznerのFirewallからもXX番を削除する。
Step 4: cowrieをインストールする
cowrieはセキュリティのためにrootではなく専用ユーザーで動かすのがベストプラクティスだ。
# 依存パッケージ
sudo apt install -y python3-virtualenv python3-dev python3.12-venv \
libssl-dev libffi-dev build-essential
# cowrie専用ユーザー作成
sudo adduser --disabled-password cowrie
# cowrieユーザーに切り替え
sudo su - cowrie
# ソースコードをclone
git clone https://github.com/cowrie/cowrie.git
cd cowrie
# 仮想環境を作成(cowrieディレクトリの外に作られることに注意)
python3 -m venv /home/cowrie/cowrie-env
source /home/cowrie/cowrie-env/bin/activate
# インストール
pip install --upgrade pip
pip install -r requirements.txt
pip install -e .
pip install -e . を実行しないと cowrie コマンドが使えないので注意。
Step 5: cowrieを設定する
cp etc/cowrie.cfg.dist etc/cowrie.cfg
vim etc/cowrie.cfg
変更箇所は2つ。
1. ホスト名(攻撃者に見せる偽の名前)
[honeypot]
hostname = 攻撃者が興味を惹く名前
本番データベースサーバーっぽい名前にした。攻撃者が「データベースに侵入した!」と思って色々試してくれそうで、ログが面白くなる。
2. リッスンポート
[ssh] セクションの listen_endpoints を変更する。なお [backend_pool] セクションにも同名の設定があるので間違えないこと。
[ssh]
listen_endpoints = tcp:YYYY:interface=0.0.0.0
cowrieは1024以下のポートを直接リッスンできないので、1024より大きい任意のポート(YYYY)を使う。XX番への接続はiptablesで転送する。
Step 6: iptablesでXX番から委任の番号に転送する
# 僕のユーザーに戻る
exit
# 転送ルールを追加(YYYYはcowrieのリッスンポート)
sudo iptables -t nat -A PREROUTING -p tcp --dport XX -j REDIRECT --to-port YYYY
# 永続化(再起動しても消えないように)
sudo apt install -y iptables-persistent
sudo netfilter-persistent save
Step 7: HetznerのFirewallでXX番を再度開ける
攻撃者が来られるようにXX番を再度開ける。今度はcowrieに誘導するためなので、開けても安全だ。
- Inbound Rules に TCP XX を追加
- Source: Any
Step 8: cowrieを起動する
sudo su - cowrie
cd cowrie
source /home/cowrie/cowrie-env/bin/activate
cowrie start
ログを確認する。
tail -f var/log/cowrie/cowrie.log
攻撃者が来た
起動してすぐ、ログが流れ始めた。
[HoneyPotSSHTransport,0,xx.xxx.xxx.xx] New connection
[SSHChannel] CMD: uname -a
[HoneyPotSSHTransport,0,xx.xxx.xxx.xx] Connection lost after 1.3 seconds
どこかのIPが侵入できたと思い込んでシステム情報を確認するコマンド uname -a を実行していた。cowrieが偽の応答を返して接続を閉じた。攻撃者は自分が偽の環境にいることに気づいていない。
調べてみると、そのIPはMicrosoft Azure(カリフォルニア)のサーバーだった。インターネット上には常に全IPアドレスをスキャンし続けているボットが無数にいて、XX番が開いているのを見つけた瞬間に攻撃を始める。今まではfail2banが弾いていたが、今は偽の環境に招き入れて記録している。
まとめ
最終的なポート構成はこうなった。
| ポート | 用途 |
|---|---|
| XX番 | 攻撃者用(cowrieに転送) |
| XXXX番 | 自分用(本物のSSH) |
| YYYY番 | cowrieが内部でリッスン |
ハニーポットを設置することで、攻撃者の動きを観察できるようになった。セキュリティの学習として、ログを眺めるだけでも攻撃の手口や使われているツールがわかってくる。var/log/cowrie/cowrie.json にはJSON形式でもログが保存されているので、jqで解析するのも面白そうだ。
次は攻撃者のログを深掘りして、何が行われているか分析してみたいと思っている。