Crisis response for server operators

SSH brute force, and when you lock yourself out

From an SSH brute-force alert, decide whether the banned source is an attacker or one of you, and when you are locked out, tell which mechanism (brute-force guard, allow-list or fail2ban) is blocking and lift it.

  • Level: Basics
  • About 30 min
  • 2026-11-12

#The situation

At 11:37, two messages arrive one after the other

The first is a RoamSwitch alert: "SSH brute force detected, source banned: 10.99.0.3". A few minutes later a colleague writes: "I can't get into the server over SSH. It worked yesterday."

SSH brute force arrives almost every day. Most of it ends with a ban. What the operator has to decide comes after that. Was the banned source an attacker, or one of us? If someone cannot get in, which mechanism is stopping them?

This playbook walks through those decisions and steps, triggered for real inside a disposable VM. The flow is:

StepWhat you doWhat you use
1. TriggerBrute-force from dummy sources inside the VMA network namespace, sshpass
2. LookRead the ban and the alert, and decide: attacker or usSSH brute-force detection and blocking, Notification history, Access log diagnosis (AccessScope)
3. Get back inEnter through a way that is not SSH, tell which mechanism blocks, and lift itunban, Limiting SSH to allowed sources, fail2ban-client
4. UndoClean up the practice setup

The thresholds and the allow-list settings themselves are covered in Configuring SSH protection. How to investigate a login that got in after a brute force is in SSH and remote access.

Practice in a disposable environment

This module changes firewall rules and locks you out on purpose. The VM here is driven with tart exec, which does not use SSH, so you can keep working while SSH is blocked. For a real host, check a way in that is not SSH, such as your cloud console, before you need it. The brute force runs only from the namespace inside the VM; nothing is aimed outside it.

#Prepare the practice setup

A network namespace inside the VM stands in for outside sources, because this host's own addresses are never banned. Four addresses get a role each.

AddressRole
10.99.0.2Your usual workplace
10.99.0.3The attacker
10.99.0.4A colleague who logs in with a key
10.99.0.5You, the next day (your address changed)
Create a test user and outside sources

These steps add a user and network settings (they change the machine). The password is a practice dummy. The undo steps are at the end of the last lab.

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
Output
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.041/0.041/0.041/0.000 ms

In this VM fail2ban guards sshd, so the RoamSwitch guard only detects. For the first half, stop fail2ban so that RoamSwitch does the banning (this changes the machine). The last lab starts fail2ban again.

sudo systemctl stop fail2ban
sudo roamswitch server restart
sudo roamswitch bans | sed -n 5,7p
Excerpt
  State     : detects and bans
  Log       : journal
  Ports     : 22

#Trigger a brute force and read the alert

An attacker's brute force keeps changing user names. Your own typos repeat the same user name. The alert shows the difference.

Try many user names from the attacker

From 10.99.0.3, try eight user names with a wrong password, once each.

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
Excerpt
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

The sixth try, guest, was cut before the refusal came back. After that, connections stopped arriving at all. The packets are dropped with no reply, so the client says "timed out". Look at the alert history.

sudo roamswitch notifications | grep -B1 -A9 "SSH brute force detected"
Output
  2026-11-12T02:37:29.665503529+00:00
  SSH brute force detected, source banned: 10.99.0.3
    Host: ubuntu (IP: 192.168.64.9)
    Source: 10.99.0.3
    Failed logins: 6 within 10 minutes
    User names tried: 6
    Ban: 60 minutes (earlier bans of this source: 0)
    New connections are dropped, and the 1 connection this source already had open to SSH was cut. An authenticated session is never cut.
    If this was your own address, lift the ban with sudo roamswitch server unban 10.99.0.3 and add it to ssh_guard_allow in server.conf.
    Timestamp: 2026-11-12 02:37:29

Three lines carry the decision.

  • User names tried: 6: all six failures used different names. Human typos do not look like this
  • earlier bans of this source: 0: this is the first ban. From the second one on, each ban lasts four times as long
  • Timestamp: UTC. In Japan time (JST) it is 11:25:23

The alert says a connection "was cut" only when the sshd side of it was actually closed at the ban. On this VM, sudo ss -tn state established '( sport = :22 )' showed no connection from 10.99.0.3 after the ban.

The ban list shows the same source.

sudo roamswitch bans | sed -n 9,15p
Output
  Source                                     Kind       Left     Fails  Earlier bans
  10.99.0.3                                  SSH      59m49s         6  0

  Lift: sudo roamswitch unban <IP> / --all

  Recent records:
    2026-11-12T02:37:29  SSH  banned  10.99.0.3  (6)

Stopping one source does not mean nobody else is trying. Read the whole SSH log with the bundled AccessScope. It only reads, and changes no log.

sudo accessscope scan --auto --since 1h
Excerpt
| Overall risk | 0/100 (None) |
| Logs read | Read 2 logs (fail2ban log 1, Authentication log (SSH, sudo, su, PAM) 1) |
| fail2ban | 0 bans (0 IPs), 0 detections, 0 unbans |
| 1 finding | 0 high, 0 medium, 1 low |

## Findings

| # | Severity | Confidence | Finding | Count | Main sources |
|---|---|---|---|---|---|
| 1 | Low | Likely | Suspected SSH brute force | 6 (1 IP) | 10.99.0.3(6) |

Confidence is how sure the tool is that a finding is a real attack. Confirmed: the log shows it. Likely: probably real. Hypothesis: only a suspicion that needs checking.

There is only one source, 10.99.0.3. If a source had logged in after a brute force, AccessScope would also list it under the items to check first, with High severity. Later in this module you will see the same kind of login trigger an alert.

Is the banned source an attacker, or one of us?

Decide from the alert lines and the whole log.

  • Many user names, a source you do not know: an attacker. Leave the ban in place; there is nothing to lift. If the same source comes back after the ban runs out, the next ban is four times longer
  • One user name that is one of your accounts, a source you know: your own typos. Use the next chapter to get back in
  • A successful login after the brute force: look at that session before anything else. The steps are in SSH and remote access

Daily brute force in itself is normal. Turning off password logins and allowing keys only removes the risk of a password being guessed.

#When you have locked yourself out

Now you are the one who gets banned. From your usual place, 10.99.0.2, you keep mistyping the password. No session is open.

Get banned by typos, and lift it from outside SSH

These steps trigger a ban and lift it (they change the machine).

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
Excerpt
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

The seventh try does not arrive. Even with the right password, SSH no longer gets you in. From here on, work through a way in that is not SSH. In this VM that is tart exec. On a real host it is the cloud console, or a screen and keyboard.

sudo roamswitch bans | sed -n 9,17p
Output
  Source                                     Kind       Left     Fails  Earlier bans
  10.99.0.3                                  SSH      59m27s         6  0
  10.99.0.2                                  SSH      59m55s         6  0

  Lift: sudo roamswitch unban <IP> / --all

  Recent records:
    2026-11-12T02:37:57  SSH  banned  10.99.0.2  (6)
    2026-11-12T02:37:29  SSH  banned  10.99.0.3  (6)

Your address is banned next to the attacker's. Try whether a restart clears it.

sudo roamswitch server restart
sudo roamswitch bans | sed -n 9,11p
Excerpt
  ✓ roamswitch-server service successfully restarted.

  Source                                     Kind       Left     Fails  Earlier bans
  10.99.0.3                                  SSH      59m25s         6  0
  10.99.0.2                                  SSH      59m53s         6  0

A restart does not clear it. When the daemon starts, it loads again the bans that have not run out. Lift only your own address with unban, and leave the attacker's 10.99.0.3 in place.

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'
Output
  ✓ Lifted: 10.99.0.2
  Its failure count was cleared too. The count of its earlier bans ("Earlier bans" in sudo roamswitch bans) is kept: if the same source is banned again, the ban is longer by that count (at most ssh_guard_ban_max_secs).
ok from 10.99.0.2 39129 22

unban took effect at once. The failure count is cleared as well. The count of earlier bans stays, so a later ban of the same source is longer.

Lifting a ban with commands that do something else

As shown above, roamswitch server restart does not lift a ban. roamswitch emergency-restore, which lifts isolations, does not lift the SSH bans either. With nothing isolated, it says "Nothing is isolated, and no isolation rule is left, so nothing was removed." Even with --force, it said it had left "roamswitch_sshguard: the SSH brute-force bans. To lift one: sudo roamswitch unban <IP>". Both sources were still in bans afterwards, and 10.99.0.2 still could not get in. --all lifts the attacker's ban too. Lift only your own address with unban.

After lifting it, should the address go into `ssh_guard_allow`?

The alert suggests adding it to ssh_guard_allow in server.conf. An address there is never banned, however many times it fails.

  • A fixed address (your office's exit, a jump host): add it. The key is ssh_guard_allow, comma-separated, and it needs a restart to take effect
  • An address that changes (home, a mobile line): do not. A wide range also stops banning attackers in that range. Use "log in with a key" from the next chapter instead

#Make a lockout less likely

The guard never bans the following sources (per the notes in the example settings file). Two of them matter in day-to-day work.

  • A source that has an authenticated SSH session open right now
  • A source that logged in with a public key within ssh_guard_trust_key_days (30 days by default)
Mistype with a session open, and after a key login

These steps trigger failures (they change the machine).

First, keep one session open from 10.99.0.2. With it open, mistype eight times, then log in with the right password.

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 "login succeeded after"
Output
ok from 10.99.0.2 52183 22
  CRITICAL: SSH login succeeded after a brute-force attempt: 10.99.0.2
    Host: ubuntu (IP: 192.168.64.9)
    Source: 10.99.0.2
    Account logged into: labuser
    Method: password
    Failures before it: 6
    The password may have been guessed. If you do not recognise this login, act now.
    - Check the open sessions with who or last, and cut a suspicious one with loginctl terminate-session
    - Change that account's password and allow key authentication only (PasswordAuthentication no)
    - Look for changes you do not recognise in authorized_keys, cron and the user's systemd services
    The session was not cut.
    This source is one the SSH guard never bans (it has an authenticated SSH session open). The reason dates from before the failures; still check that this login is your own.
    Timestamp: 2026-11-12 02:38:38

You were not banned and got in. In exchange, a critical alert went out. The guard cannot tell you after a typo from an attacker who guessed the password. The end of the alert says the reason the guard never bans this source (an open session) dates from before the failures, and asks you to check that the login is your own. A reason that predates the failures still does not prove the session is not an attacker's. Confirm with who that it is your session, then treat the alert as a record of your own action.

Next, the colleague at 10.99.0.4 logs in with a key, then fails eight times with a password. The key is a practice key made on the spot.

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
Output
key login from 10.99.0.4 33715 22

Look at the ban list and at why nothing was banned. The reason is in the list, and in exempt_reason in the --json output.

sudo roamswitch bans | sed -n 9,17p
sudo roamswitch bans --json | grep '"exempt_reason": "'
Output
  Source                                     Kind       Left     Fails  Earlier bans
  10.99.0.3                                  SSH      58m22s         6  0

  Lift: sudo roamswitch unban <IP> / --all

  Recent records:
    2026-11-12T02:38:56  SSH  exempt (never banned)  10.99.0.4  (6)  reason: it logged in with a public key recently (ssh_guard_trust_key_days)
    2026-11-12T02:38:38  SSH  login after failures   10.99.0.2  (6)
    2026-11-12T02:38:30  SSH  exempt (never banned)  10.99.0.2  (6)  reason: it has an authenticated SSH session open
      "exempt_reason": "it logged in with a public key recently",
      "exempt_reason": "it has an authenticated SSH session open",
  • 10.99.0.2: it had a session open, so it was recorded as "exempt (never banned)"
  • 10.99.0.4: it had logged in with a key recently, so it was exempt too
  • 10.99.0.3: the attacker's ban is still in place
Before the work, set up a state that cannot lock you out

Before you change settings or retype passwords, set up one of these.

  • Keep one session open: that source is not banned. Do not close it until the work is done
  • Log in with a key first: that source is not banned for 30 days. How to turn off password logins is in SSH and remote access

Neither replaces a way in that is not SSH. Check how to reach the console separately.

#When something else is blocking

"I can't get in" is not always the brute-force guard. These are the signs checked in this VM.

What the client seessudo roamswitch bansWhat is blocking
Connection timed outYour address is listedThe brute-force guard
Connection timed outYour address is not listed; ssh-allow status says activeThe source allow-list
Connection refused"detects only", nothing bannedfail2ban (this VM's setting banaction = nftables)

A port mismatch also gives timed out. How to spot that is in the ssh_ports chapter of Configuring SSH protection.

The allow-list does not have the next day's address

These steps turn on the allow-list (they change the machine). The undo step is at the end of this lab.

Put your usual place, 10.99.0.2, in the allow-list and turn it on. The session from the previous lab is still open, so the safety check passes.

The safety check counts only logged-in SSH connections as connected. A banned attacker's connections were closed at the ban. On this VM, sudo ss -tn state established '( sport = :22 )' before turning it on showed only the connection from 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'
Output
  ✓ Saved. (ssh_allow_only_sources = 10.99.0.2)
  ✓ Saved. (ssh_allow_only_enabled = true)
  The daemon loads the rule within 30 seconds. `roamswitch ssh-allow status` shows the result.
  Open connections stay up. To undo: sudo roamswitch ssh-allow disable
ssh: connect to host 10.99.0.1 port 22: Connection timed out

The next day, your address has changed to 10.99.0.5. Even the right password does not get you in. From outside SSH, find out which mechanism it is.

sudo roamswitch bans | sed -n 9,10p
sudo roamswitch ssh-allow status | sed -n 5,8p
sudo nft list tables | grep ssh
Output
  Source                                     Kind       Left     Fails  Earlier bans
  10.99.0.3                                  SSH      57m46s         6  0
  ssh_allow_only_enabled  : true
  ssh_allow_only_sources  : 10.99.0.2
  daemon                  : active — new SSH connections from anything but 1 listed source are refused (ports [22])
  Sources with an SSH session now: 10.99.0.2
nft output
table inet roamswitch_sshguard
table inet roamswitch_sshallow

10.99.0.5 is not in bans. The allow-list is active, and 10.99.0.5 is not on it. The nftables tables are separate too: the brute-force guard (roamswitch_sshguard) and the allow-list (roamswitch_sshallow). Add the new address.

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'
Output
  ✓ Saved. (ssh_allow_only_sources = 10.99.0.2,10.99.0.5)
ok from 10.99.0.5 49191 22

Adding an entry needs no restart; the daemon reads it again every 30 seconds. When it is urgent, use disable. It removes the rule without waiting for the daemon.

sudo roamswitch ssh-allow disable
Output
  ✓ Saved. (ssh_allow_only_enabled = false)
  ✓ The rule was removed.
Locked out by fail2ban

These steps start fail2ban again (they change the machine). At the end of this lab, the practice setup is cleaned up.

Start fail2ban and restart RoamSwitch. The guard goes back to leaving bans to fail2ban.

sudo systemctl start fail2ban
sudo roamswitch server restart
sudo roamswitch bans | sed -n 5,13p
Excerpt
  State     : detects only (does not ban)
  Reason    : fail2ban already guards SSH, so the ban is left to it (ssh_guard_yield_to_fail2ban=true).
  Log       : journal
  Ports     : 22
  The banning is left to fail2ban. The sources the SSH guard never bans (an open SSH session, a recent public-key login, ssh_guard_allow) are not passed on to fail2ban, so add your own addresses to fail2ban's ignoreip (/etc/fail2ban/jail.local) too. What fail2ban bans: sudo fail2ban-client status sshd

  Nothing is banned right now.

  Recent records:

In detect-only mode, RoamSwitch keeps no bans. The attacker's 10.99.0.3 ban is gone too. The new guidance line says that the sources RoamSwitch never bans are not passed on to fail2ban. Now mistype from 10.99.0.5. In this check, the tries began 30 seconds after the restart.

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
Excerpt
labuser@10.99.0.1: Permission denied (publickey,password).
ssh: connect to host 10.99.0.1 port 22: Connection refused
ssh: connect to host 10.99.0.1 port 22: Connection refused

After five failures, the reply turned into Connection refused. Try the RoamSwitch unban, and look at fail2ban's state.

sudo roamswitch unban 10.99.0.5
sudo fail2ban-client status sshd | tail -3
sudo grep "Ban 10" /var/log/fail2ban.log
Output
  No matching ban (neither the SSH guard nor the web guard had one).
  fail2ban (jail: sshd) is banning this source. RoamSwitch does not lift fail2ban's bans. To lift it: 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:40:21,098 fail2ban.actions        [3767]: NOTICE  [sshd] Ban 10.99.0.3
2026-11-12 02:40:21,130 fail2ban.actions        [3767]: NOTICE  [sshd] Ban 10.99.0.2
2026-11-12 02:40:21,138 fail2ban.actions        [3767]: NOTICE  [sshd] Ban 10.99.0.4
2026-11-12 02:41:04,481 fail2ban.actions        [3767]: NOTICE  [sshd] Ban 10.99.0.5

Read it like this.

  • RoamSwitch's unban said it had no ban of its own, that fail2ban is banning this source, and which command lifts it. RoamSwitch does not lift fail2ban's bans
  • fail2ban banned three sources right after it started (02:40:21). It read the failures from before it started back out of the log. That includes 10.99.0.2 and 10.99.0.4, which RoamSwitch had not banned
  • 10.99.0.5 was banned by the failures that followed

RoamSwitch reads fail2ban's log and alerts on its bans. From the ban of 10.99.0.5 to the alert in the history took about 0.5 seconds in one check and about 12 seconds in another. Wait a little before looking.

sleep 15
sudo roamswitch notifications | grep 'fail2ban banned'
Output
  fail2ban banned an SSH source: 10.99.0.5
  fail2ban banned a source the SSH guard never bans: 10.99.0.4
  fail2ban banned an SSH source: 10.99.0.3
  fail2ban banned a source the SSH guard never bans: 10.99.0.2
  • 10.99.0.5: the "fail2ban banned an SSH source" alert carries the command to lift it, sudo fail2ban-client set sshd unbanip 10.99.0.5
  • 10.99.0.2 and 10.99.0.4: bans made right after fail2ban started are alerted too. When fail2ban stops a source the guard never bans (an open session, a recent key login), the title says so, and the alert suggests adding it to fail2ban's ignoreip

Lift a fail2ban ban with 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'
Output
1
ok from 10.99.0.5 51015 22

Finally, clean up the practice setup. Empty the allow-list, and remove the namespace, the user and the key.

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
Excerpt
  ✓ Saved. (ssh_allow_only_sources = )
  ssh_allow_only_enabled  : false
  ssh_allow_only_sources  : -

The practice sources still held by fail2ban drop off when their ban time passes. To remove them at once, use sudo fail2ban-client unban --all.

When you start fail2ban again, mind your own failures

On start, fail2ban also counted failures from a little earlier, read from the log. If you mistyped just before, you are banned the moment it starts. Keep your current session open before you start it, and afterwards check with fail2ban-client status sshd that your address is not listed.

#What you cannot see

What was checked and what was not

In a disposable Ubuntu 24.04 VM, the scope checked is:

  • The steps to get back in assume a way in that is not SSH. This VM used tart exec. Cloud consoles differ by provider and are not covered here
  • The brute-force guard never decides "attacker or us". A person decides from the number of user names, the source and the log. Your own login after typos also raises a critical alert
  • The difference between Connection refused and timed out is what this VM's settings give. Change fail2ban's banaction and the symptom changes too
  • Addresses fail2ban bans do not show in roamswitch bans. Use fail2ban-client status sshd, as its guidance line says
  • A brute force spread over many addresses (a little from each) was not triggered in this module
Check yourself

A colleague says SSH "times out". sudo roamswitch bans does not list their address, and ssh-allow status says active. What do you do?

Show the explanation

It is not in bans, so the brute-force guard is not blocking. An address that is not on the allow-list cannot get in even with the right password. Once added, it works within 30 seconds. When it is urgent, ssh-allow disable removes the rule.

Check yourself

After some typos you get Connection refused and cannot get in. roamswitch bans says "detects only" with nothing banned. Where do you lift it?

Show the explanation

When the guard only detects, fail2ban is doing the banning. RoamSwitch's unban does not lift fail2ban's bans; it prints the fail2ban command to use instead.

#What to learn next

Features covered

Related techniques (ATT&CK): T1110.001

What was verified

Verified on 2026-11-12. Target: Linux 1.17.39. On disposable Ubuntu 24.04 VMs with the published 1.17.39, brute force, typos and key logins were made from a network namespace inside the VM, and the bans and alerts, bans surviving a restart and emergency-restore (including --force), unban, the allow-list, and fail2ban's bans and alerts were run in order in Japanese and English on separate VMs.

Command output varies with the product version and the environment. If yours differs, check the version first.