ハニーポッド入門でセキュリティを学ぶ

·
#CLI#Terminal#Hetzner#Cloudflare

以前の記事で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で解析するのも面白そうだ。

次は攻撃者のログを深掘りして、何が行われているか分析してみたいと思っている。