サーバー運用者の危機対応

SSH への総当たりと、自分が締め出されたとき

SSH の総当たりの通知から、遮断した相手が攻撃者か自分かを決め、締め出されたときに止めている仕組み(総当たりガード・許可リスト・fail2ban)を見分けて解きます。

  • レベル: 基礎
  • 約30分
  • 2026-11-12

#状況

午前 11 時 31 分、2つの連絡が続けて届きました

1つ目は RoamSwitch の通知です。「SSH 総当たりを検知し、接続元を遮断: 10.99.0.3」。数分後、同僚から2つ目が届きます。「サーバーに SSH で入れません。昨日までは入れました。」

SSH の総当たりは、毎日のように来ます。ほとんどは遮断で終わります。運用者が迷うのは、その先です。遮断したのは攻撃者か、自分たちか。入れないのは、どの仕組みが止めているからか。

この講座は、その判断と手順を、使い捨ての VM の中で、実際に起こして確かめる手順書です。流れは次のとおりです。

順番すること使うもの
1. 起こすVM の中のダミーの接続元から、総当たりをかけるネットワーク名前空間、sshpass
2. 見る遮断と通知を読み、攻撃者か自分かを決めるSSH 総当たりの検知と遮断、通知の履歴、アクセスログの診断(AccessScope)
3. 入り直すSSH 以外の入り口から入り、止めている仕組みを見分けて解くunban、SSH の接続元の限定、fail2ban-client
4. 元に戻す練習の場を片付ける

しきい値や許可リストの設定そのものは、SSH の保護の設定 で扱いました。総当たりのあとに入られたときの調べ方は、SSH とリモートアクセス にあります。

練習は、使い捨ての環境で

この講座は、ファイアウォールの規則を変え、わざと自分を締め出します。この講座の VM は tart exec で操作します。SSH を通らないので、SSH が遮断されても作業を続けられます。実機で同じことが起きたときに備えて、クラウドのコンソールのような、SSH 以外の入り口を先に確かめておきます。総当たりは、VM の中の名前空間からだけかけ、VM の外には向けません。

#練習の場を用意する

VM の中にネットワーク名前空間を作り、外の接続元に見立てます。このホスト自身のアドレスは遮断されないためです。4つのアドレスに、役を割り当てます。

アドレス役
10.99.0.2いつもの自分の作業場所
10.99.0.3攻撃者
10.99.0.4鍵でログインしている同僚
10.99.0.5次の日の自分(アドレスが変わった)
テスト用のユーザーと、外の接続元を作る

ユーザーを作り、ネットワークの設定を足す操作です(変更を伴う操作です)。パスワードは練習用のダミーです。戻し方は、最後の演習の終わりにあります。

sudo useradd -m -s /bin/bash labuser
echo 'labuser:Practice-Pass-123' | sudo chpasswd
sudo install -d -m 700 -o labuser -g labuser /home/labuser/.ssh
sudo apt install -y sshpass
sudo ip netns add outside
sudo ip link add veth-host type veth peer name veth-out
sudo ip link set veth-out netns outside
sudo ip addr add 10.99.0.1/24 dev veth-host
sudo ip link set veth-host up
for a in 2 3 4 5; do sudo ip netns exec outside ip addr add 10.99.0.$a/24 dev veth-out; done
sudo ip netns exec outside ip link set veth-out up
sudo ip netns exec outside ping -c1 -W2 10.99.0.1 | tail -2
実行結果
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.047/0.047/0.047/0.000 ms

この VM では fail2ban が sshd を見ていて、RoamSwitch のガードは検知だけをします。前半は、遮断を RoamSwitch に任せるため、fail2ban を止めます(変更を伴う操作です)。最後の演習で、fail2ban を戻します。

sudo systemctl stop fail2ban
sudo roamswitch server restart
sudo roamswitch bans | sed -n 5,7p
出力の抜粋
  状態      : 検知して遮断
  ログ      : journal
  ポート    : 22

#総当たりを起こし、通知を読む

攻撃者の総当たりは、ユーザー名を次々に変えてきます。自分の打ち間違いは、同じユーザー名で続きます。この違いが、通知に出ます。

攻撃者から、ユーザー名を変えて試す

10.99.0.3 から、8つのユーザー名で、間違ったパスワードを1回ずつ試します。

F="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PubkeyAuthentication=no -o NumberOfPasswordPrompts=1 -o LogLevel=ERROR -o ConnectTimeout=5"
for u in root admin test oracle ubuntu guest deploy postgres; do
  sudo ip netns exec outside sshpass -p wrong-pass ssh $F -b 10.99.0.3 $u@10.99.0.1 true; echo "$u: exit $?"
done
出力の抜粋
oracle@10.99.0.1: Permission denied (publickey,password).
oracle: exit 255
ubuntu@10.99.0.1: Permission denied (publickey,password).
ubuntu: exit 255
guest: exit 255
ssh: connect to host 10.99.0.1 port 22: Connection timed out
deploy: exit 255
ssh: connect to host 10.99.0.1 port 22: Connection timed out
postgres: exit 255

6 回目の guest は、断りの返事が届く前に接続が切れました。そのあとは、接続そのものが届きません。断る返事を返さず、パケットを捨てるため、「timed out」になります。通知の履歴を見ます。

sudo roamswitch notifications | grep -B1 -A9 "SSH 総当たりを検知"
実行結果
  2026-11-12T02:31:33.593623786+00:00
  SSH 総当たりを検知し、接続元を遮断: 10.99.0.3
    ホスト: ubuntu (IP: 192.168.64.4)
    接続元: 10.99.0.3
    失敗したログイン: 6 回(10 分以内)
    試されたユーザー名: 6 種類
    遮断時間: 60 分(この接続元のこれまでの遮断: 0 回)
    新しい接続を止め、この接続元が SSH に張っていた 1 本の接続も切りました。認証済みのセッションは切りません。
    自分の接続元だった場合は、sudo roamswitch server unban 10.99.0.3 で解除し、server.conf の ssh_guard_allow に加えてください。
    時刻: 2026-11-12 02:31:33

判断に使う行は、次の3つです。

  • 試されたユーザー名: 6 種類: 6 回の失敗が、すべて別の名前でした。人の打ち間違いでは、こうなりません
  • これまでの遮断: 0 回: 初めての遮断です。2 度目からは、遮断時間が 4 倍ずつ延びます
  • 時刻: UTC です。日本時間では 11:31:33 です

「1 本の接続も切りました」は、遮断のときに sshd の側の接続を実際に閉じたときだけ書かれます。この VM では、遮断のあと sudo ss -tn state established '( sport = :22 )' に 10.99.0.3 の接続は残っていませんでした。

遮断の一覧でも、同じ接続元が見えます。

sudo roamswitch bans | sed -n 9,15p
実行結果
  接続元                                     種類       残り      失敗  これまでの遮断
  10.99.0.3                                  SSH      59m49s         6  0

  解除: sudo roamswitch unban <IP> / --all

  最近の記録:
    2026-11-12T02:31:33  SSH  遮断  10.99.0.3  (6)

1つの接続元を止めても、ほかの接続元から来ていることがあります。同梱の AccessScope で、SSH のログ全体を見ます。読むだけで、ログを変えません。

sudo accessscope scan --auto --since 1h
出力の抜粋
| 総合リスク | 0/100 (なし) |
| 読んだログ | 2 個のログを読みました(fail2ban のログ 1、認証ログ(SSH・sudo・su・PAM) 1) |
| fail2ban | 遮断 0 回(0 個の IP)、検出 0 回、遮断の解除 0 回 |
| 検知 1 件 | 高 0 件、中 0 件、低 1 件 |

## 検知

| # | 深刻度 | 確度 | 検知 | 件数 | 主な送信元 |
|---|---|---|---|---|---|
| 1 | 低 | 中 | SSH 総当たりの疑い | 6 (1 IP) | 10.99.0.3(6) |

確度は、その検知が本当の攻撃である可能性の高さです。高: ログに証拠があります。中: 可能性が高いです。低: 疑いの段階なので、確認が必要です。

送信元は 10.99.0.3 の1つだけです。総当たりのあとにログインが成功した接続元があると、「最初に確認すること」の表に、深刻度「高」で出ます。この講座の後半で、同じ種類のログインに通知が出る場面を見ます。

遮断した相手は、攻撃者か、自分たちか

通知の行と、ログの全体から決めます。

  • ユーザー名が何種類もある、接続元に覚えがない: 攻撃者です。遮断はそのまま残します。解除は要りません。遮断が切れたあと同じ接続元が戻れば、次は 4 倍の時間で止まります
  • ユーザー名が1種類で、自分たちのアカウント名、接続元に覚えがある: 自分たちの打ち間違いです。次の章の手順で入り直します
  • 総当たりのあとに成功したログインがある: 遮断より先に、そのセッションを調べます。手順は SSH とリモートアクセス にあります

総当たりが毎日来ること自体は、ふつうです。パスワードのログインを止めて鍵だけにすると、当てられる心配がなくなります。

#自分が締め出されたとき

次は、自分が遮断される側です。いつもの場所 10.99.0.2 から、パスワードを打ち間違え続けます。開いているセッションはありません。

打ち間違いで遮断され、SSH 以外の入り口から解く

遮断を起こし、解除する操作です(変更を伴う操作です)。

for i in 1 2 3 4 5 6 7; do sudo ip netns exec outside sshpass -p Practice-Pass-12 ssh $F -b 10.99.0.2 labuser@10.99.0.1 true; done
出力の抜粋
labuser@10.99.0.1: Permission denied (publickey,password).
labuser@10.99.0.1: Permission denied (publickey,password).
ssh: connect to host 10.99.0.1 port 22: Connection timed out

7 回目は届きません。正しいパスワードを思い出しても、もう SSH では入れません。ここからは、SSH 以外の入り口で作業します。この VM では tart exec です。実機なら、クラウドのコンソールや、つないだ画面とキーボードです。

sudo roamswitch bans | sed -n 9,17p
実行結果
  接続元                                     種類       残り      失敗  これまでの遮断
  10.99.0.3                                  SSH      59m29s         6  0
  10.99.0.2                                  SSH      59m55s         6  0

  解除: sudo roamswitch unban <IP> / --all

  最近の記録:
    2026-11-12T02:31:59  SSH  遮断  10.99.0.2  (6)
    2026-11-12T02:31:33  SSH  遮断  10.99.0.3  (6)

自分のアドレスが、攻撃者と並んで遮断されています。再起動で解けるかを試します。

sudo roamswitch server restart
sudo roamswitch bans | sed -n 9,11p
出力の抜粋
  ✓ roamswitch-server サービスを正常に再起動しました。

  接続元                                     種類       残り      失敗  これまでの遮断
  10.99.0.3                                  SSH      59m27s         6  0
  10.99.0.2                                  SSH      59m53s         6  0

再起動では解けません。デーモンは起動のとき、切れていない遮断を読み込み直します。自分のアドレスだけを、unban で解きます。攻撃者の 10.99.0.3 は残します。

sudo roamswitch unban 10.99.0.2
sudo ip netns exec outside sshpass -p Practice-Pass-123 ssh $F -b 10.99.0.2 labuser@10.99.0.1 'echo ok from $SSH_CLIENT'
実行結果
  ✓ 解除しました: 10.99.0.2
  失敗の回数も消しました。遮断の回数の記録(sudo roamswitch bans の「これまでの遮断」)は残ります。同じ接続元がまた遮断されると、この回数に応じて長く遮断されます(上限は ssh_guard_ban_max_secs)。
ok from 10.99.0.2 37527 22

unban は、すぐに効きました。失敗の回数も消えます。「これまでの遮断」の回数は残るので、同じ接続元が次に遮断されると、時間が長くなります。

遮断を解くために、関係のない操作をする

roamswitch server restart では、上のとおり遮断は解けません。隔離を解く roamswitch emergency-restore も、SSH の遮断を解きません。隔離がないときは「隔離はされていません。隔離の規則も残っていないので、何も外していません。」と出て終わります。--force を付けても、総当たりの遮断の表(roamswitch_sshguard)は残しました。この VM でも、実行のあとに bans に2つの接続元が残り、10.99.0.2 からは入れませんでした。--all での一括解除は、攻撃者の遮断まで消します。自分のアドレスだけを unban で解きます。

解いたあと、`ssh_guard_allow` に入れるか

通知は「server.conf の ssh_guard_allow に加えてください」と勧めます。入れたアドレスは、何回失敗しても遮断されません。

  • 固定のアドレス(会社の出口、踏み台): 入れます。キーは ssh_guard_allow、カンマ区切りで、反映には再起動が要ります
  • 変わるアドレス(自宅、モバイル回線): 入れません。広い範囲を入れると、同じ範囲の攻撃者も遮断されなくなります。代わりに、次の章の「鍵でログインしておく」を使います

#締め出されにくくしておく

ガードは、次の接続元を遮断しません(設定ファイルの例の注記)。運用で効くのは、このうちの2つです。

  • 認証済みの SSH セッションを、いま開いている接続元
  • ssh_guard_trust_key_days(既定 30 日)以内に、公開鍵でログインした接続元
セッションを開いたまま、鍵でログインしたあとに、打ち間違える

遮断を起こす操作です(変更を伴う操作です)。

まず、10.99.0.2 からセッションを1本開いたままにします。その状態で 8 回打ち間違え、最後に正しいパスワードで入ります。

sudo ip netns exec outside setsid sshpass -p Practice-Pass-123 ssh $F -b 10.99.0.2 -N labuser@10.99.0.1 </dev/null >/dev/null 2>&1 &
for i in 1 2 3 4 5 6 7 8; do sudo ip netns exec outside sshpass -p Practice-Pass-12 ssh $F -b 10.99.0.2 labuser@10.99.0.1 true 2>/dev/null; done
sudo ip netns exec outside sshpass -p Practice-Pass-123 ssh $F -b 10.99.0.2 labuser@10.99.0.1 'echo ok from $SSH_CLIENT'
sudo roamswitch notifications | grep -A12 "ログインが成功"
実行結果
ok from 10.99.0.2 42655 22
  【重大】SSH 総当たりのあとにログインが成功: 10.99.0.2
    ホスト: ubuntu (IP: 192.168.64.4)
    接続元: 10.99.0.2
    ログインしたアカウント: labuser
    認証方法: password
    その前の失敗: 6 回
    パスワードが推測された可能性があります。心当たりがなければ、すぐに確認してください。
    ・who や last で今のセッションを確かめ、不審なら loginctl terminate-session で切ってください
    ・そのアカウントのパスワードを変え、鍵認証だけにしてください(PasswordAuthentication no)
    ・authorized_keys、cron、systemd のユーザーサービスに、見覚えのない変更がないか確かめてください
    セッションは切っていません。
    この接続元は、SSH ガードが遮断しない接続元です(ログイン済みの SSH のセッションを開いている)。失敗の前から続く理由ですが、このログインが自分のものかを確かめてください。
    時刻: 2026-11-12 02:32:44

遮断はされず、入れました。そのかわり、重大の通知が出ました。ガードには、打ち間違いのあとの自分と、パスワードを当てた攻撃者の区別がつかないためです。通知の終わりには、遮断しない理由(セッションを開いている)が失敗の前から続いていることと、このログインが自分のものかを確かめるように、と書かれます。理由が前からあっても、攻撃者のセッションでないとは言えないためです。who で、自分のセッションだと確かめてから、自分の操作の記録として扱います。

次に、同僚の 10.99.0.4 が鍵でログインし、そのあとパスワードで 8 回失敗します。鍵は、この場で作る練習用のものです。

ssh-keygen -q -t ed25519 -N "" -C lab-dummy-key -f /tmp/lab_key
cat /tmp/lab_key.pub | sudo tee -a /home/labuser/.ssh/authorized_keys >/dev/null
sudo chown labuser:labuser /home/labuser/.ssh/authorized_keys
K="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR -o ConnectTimeout=5 -o BatchMode=yes"
sudo ip netns exec outside ssh $K -i /tmp/lab_key -b 10.99.0.4 labuser@10.99.0.1 'echo key login from $SSH_CLIENT'
for i in 1 2 3 4 5 6 7 8; do sudo ip netns exec outside sshpass -p Practice-Pass-12 ssh $F -b 10.99.0.4 labuser@10.99.0.1 true 2>/dev/null; done
実行結果
key login from 10.99.0.4 47099 22

遮断の一覧と、遮断しなかった理由を見ます。理由は一覧の「理由」の欄と、--json の exempt_reason(英語)に出ます。

sudo roamswitch bans | sed -n 9,17p
sudo roamswitch bans --json | grep '"exempt_reason": "'
実行結果
  接続元                                     種類       残り      失敗  これまでの遮断
  10.99.0.3                                  SSH      58m16s         6  0

  解除: sudo roamswitch unban <IP> / --all

  最近の記録:
    2026-11-12T02:33:04  SSH  除外(遮断しない)          10.99.0.4  (6)  理由: 最近、公開鍵でログインした(ssh_guard_trust_key_days)
    2026-11-12T02:32:44  SSH  失敗のあとのログイン成功  10.99.0.2  (6)
    2026-11-12T02:32:35  SSH  除外(遮断しない)          10.99.0.2  (6)  理由: ログイン済みの SSH のセッションを開いている
      "exempt_reason": "it logged in with a public key recently",
      "exempt_reason": "it has an authenticated SSH session open",
  • 10.99.0.2: セッションを開いていたので、「除外(遮断しない)」と記録されました
  • 10.99.0.4: 最近、鍵でログインしていたので、同じく「除外(遮断しない)」でした
  • 10.99.0.3: 攻撃者の遮断は、そのまま残っています
作業の前に、締め出されない状態を作る

設定を変える作業や、パスワードを入れ直す作業の前に、次のどちらかを作っておきます。

  • セッションを1本開いたままにする: その接続元は遮断されません。作業が終わるまで閉じません
  • 鍵でログインしておく: 30 日のあいだ、その接続元は遮断されません。パスワードのログインを止める手順は、SSH とリモートアクセス にあります

どちらも、SSH 以外の入り口の代わりにはなりません。コンソールの入り方は、別に確かめておきます。

#止めているのが、別の仕組みのとき

「入れない」の原因は、総当たりガードだけではありません。この VM で確かめた見分け方は、次のとおりです。

手元の症状sudo roamswitch bans止めている仕組み
Connection timed out自分のアドレスがある総当たりガード
Connection timed out自分のアドレスがない。ssh-allow status が「有効」接続元の許可リスト
Connection refused「検知のみ」で、遮断はないfail2ban(この VM の設定 banaction = nftables)

ポートの設定の食い違いでも、timed out になります。その見分け方は、SSH の保護の設定 の ssh_ports の章にあります。

許可リストに、次の日のアドレスがない

許可リストを有効にする操作です(変更を伴う操作です)。戻し方は、この演習の最後にあります。

いつもの場所 10.99.0.2 を許可リストに入れて、有効にします。前の演習のセッションが開いているので、安全装置は通ります。

安全装置が「つながっている」と数えるのは、ログイン済みの SSH の接続だけです。遮断した攻撃者の接続は、遮断のときに閉じられています。この VM では、有効にする前の sudo ss -tn state established '( sport = :22 )' に、10.99.0.2 の接続だけが出ました。

sudo roamswitch ssh-allow add 10.99.0.2
sudo roamswitch ssh-allow enable
sleep 30
sudo ip netns exec outside sshpass -p Practice-Pass-123 ssh $F -b 10.99.0.5 labuser@10.99.0.1 'echo ok from $SSH_CLIENT'
実行結果
  ✓ 保存しました。 (ssh_allow_only_sources = 10.99.0.2)
  ✓ 保存しました。 (ssh_allow_only_enabled = true)
  30 秒以内にデーモンが規則を読み込みます。結果は `roamswitch ssh-allow status` で確かめられます。
  確立済みの接続は切れません。戻すには: sudo roamswitch ssh-allow disable
ssh: connect to host 10.99.0.1 port 22: Connection timed out

次の日、自分のアドレスが 10.99.0.5 に変わりました。正しいパスワードでも入れません。SSH 以外の入り口から、どの仕組みかを見ます。

sudo roamswitch bans | sed -n 9,10p
sudo roamswitch ssh-allow status | sed -n 5,8p
sudo nft list tables | grep ssh
実行結果
  接続元                                     種類       残り      失敗  これまでの遮断
  10.99.0.3                                  SSH      57m41s         6  0
  ssh_allow_only_enabled  : true
  ssh_allow_only_sources  : 10.99.0.2
  デーモンの状態          : 有効 — 1 件の接続元以外からの新しい SSH 接続を断っています(ポート [22])
  いま SSH でつながっている接続元: 10.99.0.2
nft の出力
table inet roamswitch_sshguard
table inet roamswitch_sshallow

bans に 10.99.0.5 はありません。許可リストが有効で、リストに 10.99.0.5 がありません。nftables の表も、総当たりガード(roamswitch_sshguard)と許可リスト(roamswitch_sshallow)で分かれています。新しいアドレスを足します。

sudo roamswitch ssh-allow add 10.99.0.5
sleep 30
sudo ip netns exec outside sshpass -p Practice-Pass-123 ssh $F -b 10.99.0.5 labuser@10.99.0.1 'echo ok from $SSH_CLIENT'
実行結果
  ✓ 保存しました。 (ssh_allow_only_sources = 10.99.0.2,10.99.0.5)
ok from 10.99.0.5 51327 22

足すだけなら、再起動は要りません。デーモンが 30 秒ごとに読み直します。急ぐときは disable を使います。デーモンを待たずに、規則を外します。

sudo roamswitch ssh-allow disable
実行結果
  ✓ 保存しました。 (ssh_allow_only_enabled = false)
  ✓ 規則を外しました。
fail2ban に締め出される

fail2ban を戻す操作です(変更を伴う操作です)。この演習の最後に、練習の場を片付けます。

fail2ban を起動し、RoamSwitch を再起動します。ガードは、遮断を fail2ban に任せる状態に戻ります。

sudo systemctl start fail2ban
sudo roamswitch server restart
sudo roamswitch bans | sed -n 5,13p
出力の抜粋
  状態      : 検知のみ(遮断しない)
  理由      : fail2ban が SSH を防御しているため、遮断はそちらに任せています(ssh_guard_yield_to_fail2ban=true)。
  ログ      : journal
  ポート    : 22
  遮断は fail2ban に任せています。SSH ガードが遮断しない接続元(開いている SSH のセッション、最近の公開鍵のログイン、ssh_guard_allow)は、fail2ban には伝わりません。自分の接続元は、fail2ban の ignoreip(/etc/fail2ban/jail.local)にも加えてください。fail2ban が遮断している接続元: sudo fail2ban-client status sshd

  遮断中の接続元はありません。

  最近の記録:

検知のみに戻ると、RoamSwitch の遮断は残りません。攻撃者の 10.99.0.3 の遮断も消えました。新しい案内の行は、RoamSwitch が遮断しない接続元が fail2ban には伝わらないことを知らせています。10.99.0.5 から、打ち間違えます。この確認では、再起動から 30 秒待ってから試しました。

sleep 30
for i in 1 2 3 4 5 6 7; do sudo ip netns exec outside sshpass -p Practice-Pass-12 ssh $F -b 10.99.0.5 labuser@10.99.0.1 true; done
出力の抜粋
labuser@10.99.0.1: Permission denied (publickey,password).
labuser@10.99.0.1: Permission denied (publickey,password).
ssh: connect to host 10.99.0.1 port 22: Connection refused

6 回の失敗のあと、Connection refused に変わりました。RoamSwitch の unban を試し、fail2ban の状態を見ます。

sudo roamswitch unban 10.99.0.5
sudo fail2ban-client status sshd | tail -3
sudo grep "Ban 10" /var/log/fail2ban.log
実行結果
  該当する遮断はありませんでした(SSH ガードにも、Web アクセスガードにも)。
  この接続元は、fail2ban(jail: sshd)が遮断しています。RoamSwitch は fail2ban の遮断を解除しません。解除するには: sudo fail2ban-client set sshd unbanip 10.99.0.5
   |- Currently banned:	4
   |- Total banned:	4
   `- Banned IP list:	10.99.0.3 10.99.0.2 10.99.0.4 10.99.0.5
2026-11-12 02:34:30,258 fail2ban.actions        [3676]: NOTICE  [sshd] Ban 10.99.0.3
2026-11-12 02:34:30,292 fail2ban.actions        [3676]: NOTICE  [sshd] Ban 10.99.0.2
2026-11-12 02:34:30,301 fail2ban.actions        [3676]: NOTICE  [sshd] Ban 10.99.0.4
2026-11-12 02:35:14,665 fail2ban.actions        [3676]: NOTICE  [sshd] Ban 10.99.0.5

読み方は次のとおりです。

  • RoamSwitch の unban は、自分の遮断はないと答え、fail2ban が遮断していることと、解除のコマンドを示しました。fail2ban の遮断を、RoamSwitch は解きません
  • fail2ban は、起動した直後(02:34:30)に3つを遮断しました。起動する前の失敗を、ログから読み直したためです。RoamSwitch が遮断しなかった 10.99.0.2 と 10.99.0.4 も含まれます
  • 10.99.0.5 は、そのあとの失敗で遮断されました

fail2ban の遮断は、RoamSwitch が fail2ban のログを読んで通知します。10.99.0.5 の遮断から通知の履歴に入るまでは、2 回の確認で約 0.5 秒と約 12 秒でした。少し待ってから見ます。

sleep 15
sudo roamswitch notifications | grep 'fail2ban が'
実行結果
  fail2ban が SSH の接続元を遮断: 10.99.0.5
    fail2ban が SSH を防御しているため、遮断はそちらに任せています(ssh_guard_yield_to_fail2ban=true)。
  fail2ban が、SSH ガードでは遮断しない接続元を遮断: 10.99.0.4
  fail2ban が SSH の接続元を遮断: 10.99.0.3
  fail2ban が、SSH ガードでは遮断しない接続元を遮断: 10.99.0.2
  • 10.99.0.5: 「fail2ban が SSH の接続元を遮断」の通知に、解除のコマンド sudo fail2ban-client set sshd unbanip 10.99.0.5 が書かれます。2行目は、その少し前の「SSH 総当たりを検知(遮断なし)」の通知の1行です
  • 10.99.0.2 と 10.99.0.4: 起動の直後の遮断も通知されます。ガードが遮断しない接続元(セッションを開いている、最近の鍵のログイン)を fail2ban が止めたときは、見出しが「SSH ガードでは遮断しない接続元を遮断」になり、fail2ban の ignoreip に加えるよう勧めます

fail2ban の遮断は、fail2ban で解きます。

sudo fail2ban-client set sshd unbanip 10.99.0.5
sudo ip netns exec outside sshpass -p Practice-Pass-123 ssh $F -b 10.99.0.5 labuser@10.99.0.1 'echo ok from $SSH_CLIENT'
実行結果
1
ok from 10.99.0.5 43887 22

最後に、練習の場を片付けます。許可リストの中身を消し、名前空間とユーザーと鍵を消します。

sudo roamswitch unban --all
sudo roamswitch ssh-allow remove 10.99.0.2 10.99.0.5
sudo ip netns del outside
sudo pkill -u labuser
sleep 1
sudo userdel -r labuser
rm -f /tmp/lab_key /tmp/lab_key.pub
sudo roamswitch ssh-allow status | sed -n 5,6p
出力の抜粋
  ✓ 保存しました。 (ssh_allow_only_sources = )
  ssh_allow_only_enabled  : false
  ssh_allow_only_sources  : -

fail2ban に残っている練習の接続元は、遮断の時間が過ぎると外れます。すぐ外すときは、sudo fail2ban-client unban --all を使います。

fail2ban を戻すときは、自分の失敗に注意する

fail2ban は、起動したときに、少し前の失敗もログから数えました。直前に自分が打ち間違えていると、起動と同時に自分が遮断されます。戻す前に、いまのセッションを閉じないでおき、戻したあとに fail2ban-client status sshd で、自分のアドレスがないかを見ます。

#見えない部分

確かめたこと・確かめていないこと

使い捨ての Ubuntu 24.04 の VM で確かめた範囲は、次のとおりです。

  • 入り直す手順は、SSH 以外の入り口がある前提です。この VM では tart exec を使いました。クラウドのコンソールの入り方は、事業者ごとに違うので、この講座では扱っていません
  • 総当たりガードが「攻撃者か自分か」を決めることはありません。通知のユーザー名の種類、接続元、ログを見て、人が決めます。打ち間違いのあとの自分のログインにも、重大の通知が出ます
  • Connection refused と timed out の違いは、この VM の設定での結果です。fail2ban の banaction を変えると、症状も変わります
  • fail2ban が遮断したアドレスは、roamswitch bans に出ません。案内の行のとおり、fail2ban-client status sshd で見ます
  • アドレスを分けた総当たり(多数の接続元から少しずつ)は、この講座では起こしていません
確認問題

同僚が「timed out で入れない」と言います。sudo roamswitch bans に同僚のアドレスはなく、ssh-allow status は「有効」でした。何をしますか

解説を見る

bans に出ていないので、総当たりガードは止めていません。許可リストにないアドレスは、正しいパスワードでも入れません。足せば、30 秒以内に効きます。急ぐときは ssh-allow disable で外します。

確認問題

打ち間違えたあと Connection refused が出て入れません。roamswitch bans は「検知のみ」で、遮断はありません。どこで解きますか

解説を見る

ガードが検知のみのときは、遮断しているのは fail2ban です。RoamSwitch の unban は、fail2ban の遮断を解かず、代わりに使う fail2ban のコマンドを示します。

#次に学ぶこと

扱う機能

対応する攻撃手法 (ATT&CK): T1110.001

確認した内容

2026-11-12に確認しました。対象は Linux 1.17.39 です。公開版 1.17.39 の入った使い捨ての Ubuntu 24.04 の VM で、VM の中のネットワーク名前空間から総当たり・打ち間違い・鍵のログインを起こし、遮断と通知、再起動と emergency-restore(--force を含む)で遮断が残ること、unban、許可リスト、fail2ban の遮断と通知までを、日本語と英語で別の VM で上から順に実行しました。

コマンドの出力は、製品の版や環境によって変わります。違いが出たら、まず製品の版を確かめてください。