Skip to content

Changing the SSH Port Safely

Antonios Voulvoulis edited this page Jun 5, 2026 · 4 revisions

Changing the SSH Port Safely

This page is for the common case: you changed your SSH port in /etc/ssh/sshd_config and restarted sshd, and you want to make sure NFTBan lets the new port through — without locking yourself out.

If you are new to NFTBan, read this whole page before you disconnect your current SSH session.

Why one extra step is needed

On a host running NFTBan, two separate systems decide whether your new SSH port works:

  1. sshdlistens on the port. Editing sshd_config and restarting sshd handles this part.
  2. NFTBan's firewall — decides whether traffic to that port is allowed in. If NFTBan does not know about the new port, it drops the connection. The result is confusing: sshd is listening, but the firewall is blocking the door.

NFTBan detects where sshd listens automatically — it reads /etc/ssh/sshd_config and /etc/ssh/sshd_config.d/*.conf, plus the actually-listening sockets. It just needs to be told to re-read and re-apply that, which is one command.

The safe sequence

Keep your current SSH session open the entire time. Do not log out until you have confirmed the new port works in a second session.

# 1. Edit /etc/ssh/sshd_config (and/or drop-ins), then VALIDATE before restart:
sudo sshd -t                                   # see "Best practice" below
#    EL/RHEL only: label the new port for SELinux FIRST (see SELinux section),
#    or sshd won't bind it and you'll get "Connection refused":
#      sudo semanage port -a -t ssh_port_t -p tcp <new-port>
sudo systemctl restart sshd

# 2. Tell NFTBan to re-detect the SSH port and update the firewall:
sudo nftban firewall rebuild

# 3. Confirm the new port is now allowed in:
sudo nftban port status
sudo nft list set ip nftban tcp_ports_in       # must include your new SSH port

# 4. From a NEW terminal, test the new port BEFORE closing the first session:
ssh -p <new-port> youruser@your-server

If the new terminal logs in, you are safe to close the original session. If it does not, you still have your first session open to fix things.

Best practice: validate the config before you restart

The single best habit to avoid a lockout is to test the SSH config for syntax errors before restarting the service. A typo or a broken directive will be caught here — before it takes down sshd.

sudo sshd -t

-t (test mode) checks /etc/ssh/sshd_config and every file under /etc/ssh/sshd_config.d/ for syntax errors and configuration sanity.

  • Silence = success. If the config is valid, the command prints nothing and returns you to a blank prompt.
  • An error prints the exact file, line number, and problem so you can fix it before restarting.

Only run sudo systemctl restart sshd after sudo sshd -t comes back clean.

EL / RHEL-family (SELinux): label the port for sshd first ⚠️

On SELinux-enforcing systems (AlmaLinux, Rocky, CentOS Stream, RHEL), there is an extra step that has nothing to do with NFTBan but will lock you out if you miss it: sshd may only bind to ports labeled ssh_port_t. By default that is only port 22. If you set Port 2222 and restart sshd, SELinux blocks the bind — sshd silently does not listen on 2222, and every connection is refused (even though the firewall allows it).

Symptom: ssh -p 2222Connection refused, and ss -tlnp | grep sshd does not show your new port.

Fix — label the port, then restart sshd:

sudo semanage port -a -t ssh_port_t -p tcp 2222     # one per new port
sudo systemctl restart sshd
ss -tlnp | grep sshd                                 # confirm sshd now listens on it
sudo semanage port -l | grep ssh_port_t              # confirm the label

(If semanage is missing: sudo dnf install policycoreutils-python-utils.)

Do this before removing your old working port, and confirm with a second session. On Debian/Ubuntu (AppArmor) this step is not required — sshd binds any port — but the rest of this page still applies.

What NFTBan detects (multiple ports, drop-ins, ListenAddress)

NFTBan's SSH-port detector takes the sorted-unique union of several sources, so it handles more than a single Port line:

  • Multiple Port lines — all of them.
    Port 2222
    Port 4444
    Port 55000
    
    All three are detected and placed in ssh_ports + tcp_ports_in. NFTBan will not collapse to just the first port (that multi-port lockout was fixed in v1.145).
  • Port in drop-ins — files under /etc/ssh/sshd_config.d/*.conf are scanned too, not only the main config.
  • ListenAddress — only when it includes a port:
    ListenAddress 0.0.0.0:2200     → contributes 2200
    ListenAddress [::]:4400        → contributes 4400
    ListenAddress 0.0.0.0          → contributes nothing (address only)
    ListenAddress ::               → contributes nothing
    
    A bare ListenAddress (or a commented #ListenAddress) only selects which interface to bind; the ports still come from your Port lines.
  • The live listeners — NFTBan also reads what sshd is actually listening on (ss), as a safety net against config/runtime drift.

Commented lines are ignored. #Port 2222 or #ListenAddress :: contribute nothing — only active directives count.

After a rebuild, every active SSH port should show up in both sets:

sudo nft list set ip nftban tcp_ports_in     # e.g. 2222, 4444, 55000 all present
sudo nft list set ip nftban ssh_ports

Where the SSH port lives in the firewall

After a rebuild, your SSH port should appear in two sets:

Set Purpose
tcp_ports_in Reachability — incoming connections to the port are allowed.
ssh_ports The set-driven SSH brute-force rate-limit (tcp dport @ssh_ports). As of v1.145 this is auto-derived from SSH detection and is not user-managed — do not hand-edit it.

Both are filled for you by nftban firewall rebuild. The firewall also checks two safety invariants (Firewall-Anchor-Architecture):

  • INV-F-002 — the SSH port is present in both tcp_ports_in and ssh_ports.
  • INV-F-003 — at least one whitelist entry exists (anti-lockout).

NFTBan also keeps a dedicated SSH "safety port" file at /etc/nftban/ports.d/00-ssh.conf, which is never removed by control-panel integrations, specifically to prevent lockout.

Strongly recommended: whitelist your admin IP

If you administer the server from a fixed IP, whitelist it so a firewall rebuild or a mistake can never lock you out. As of v1.149 there are three explicit tiers:

# Permanent (recommended for a fixed admin IP) — durable + survives rebuild/reload/restart:
sudo nftban whitelist add --static <your-admin-ip>

# Temporary (this session only) — lost on the next firewall rebuild/reload/restart:
sudo nftban whitelist add <your-admin-ip>

# Timed (auto-expires) — e.g. a 1-hour maintenance window:
sudo nftban whitelist add --ttl 1h <your-admin-ip>
  • --static writes a durable entry to whitelist.d/99-manual.conf (no expiry) and applies it live immediately. It survives firewall reload, daemon restart, and reboot. Remove it with sudo nftban whitelist remove --static <ip>.
  • default add is runtime-only (the CLI now warns you of this) — handy for a quick one-off, but it does not survive a rebuild.
  • --ttl <dur> writes a session entry that auto-expires after the duration.

See Security-Operations-Guide.

Do not "test" by port-scanning

NFTBan includes port-scan detection. Rapid connection attempts across several ports — for example, a quick nmap or a burst of retries to a closed/filtered port — can get your own IP auto-banned. To test, make one clean ssh -p <new-port> … attempt, not a scan. If you do get auto-banned, see the recovery steps below. (See Portscan-Detection.)

If you get locked out

Run these from the server console / IPMI / KVM (not over SSH):

# Open everything temporarily:
sudo nft flush table ip nftban
sudo nft flush table ip6 nftban

# Or just whitelist your IP:
sudo nft add element ip nftban whitelist_ipv4 { YOUR_IP }

# Then rebuild the firewall properly:
sudo nftban firewall rebuild

Full recovery and prevention steps: Security-Operations-Guide → "Emergency: Locked Out of SSH".

Quick reference

sudo sshd -t                                 # validate sshd config BEFORE restart
sudo nftban firewall rebuild                 # re-detect + apply SSH port
sudo nftban port status                      # show what ports are exposed/allowed
sudo nft list set ip nftban tcp_ports_in     # confirm the SSH port is allowed
sudo nft list set ip nftban whitelist_ipv4   # confirm your admin IP is whitelisted
sudo nftban whitelist add <your-admin-ip>    # anti-lockout
sudo nftban port help                        # full port command reference

# EL / RHEL only (SELinux) — authorize the port for sshd, then verify:
sudo semanage port -a -t ssh_port_t -p tcp <new-port>   # ("already defined, modifying" is fine)
sudo semanage port -l | grep ssh             # confirm: ssh_port_t  tcp  22, <new-port> ...
sudo ss -tlnp | grep sshd                    # confirm sshd actually listens on <new-port>

See also

Clone this wiki locally