Skip to main content

Change SSH Port

Changing the SSH port moves the SSH daemon (sshd) from the default TCP port 22 to a different port (for example 2581 or 2222). This reduces background noise from automated scanners and brute-force attempts that primarily target port 22, while keeping SSH available for legitimate administration.

Background and history

SSH standardized on port 22 in the 1990s and became the default remote administration method for Unix-like systems. As internet-exposed servers became common, automated scanners began continuously probing port 22. Port changes emerged as a practical hardening step to reduce low-effort scanning traffic, usually paired with stronger controls such as key-based authentication, restricted firewall access, and rate limiting.

Adoption and where it’s commonly used

Common in:

  • VPS and cloud servers with public IPv4/IPv6 addresses
  • WordPress and web servers that receive constant SSH scanning
  • Small-to-medium fleets where per-host hardening is applied consistently

Maintained by

  • Maintained by the OpenSSH project community (OpenSSH server sshd).

Best when to use

  • SSH is exposed to the internet and logs show persistent scanning attempts.
  • You already enforce SSH keys (preferred) or have strong authentication and monitoring.
  • You can keep a recovery path (cloud console/serial/KVM) in case of lockout.
  • You want a quick noise-reduction step in a hardening baseline.

Not suitable when

  • Automation or integrations assume port 22 and cannot be updated safely.
  • You have no out-of-band recovery option and cannot tolerate any lockout risk.
  • Central policy requires port 22 for standardized access and monitoring.

Compatibility notes

  • OpenSSH config is typically /etc/ssh/sshd_config. Many modern systems also support drop-ins in /etc/ssh/sshd_config.d/*.conf.

  • Service name differs by distro:

    • Debian/Ubuntu: ssh
    • RHEL/Fedora/Rocky/AlmaLinux: sshd
  • If SELinux is enforcing on RHEL-based systems, a custom SSH port may require an SELinux policy update.

  • If you use a cloud/provider firewall (security groups, VPS firewall, edge firewall), you must allow the new port there as well as on the host.

Lockout risk

Follow the order exactly. Keep your existing SSH session open until you have verified a second session can log in using the new port. Validate SSH configuration before reloading. Ensure firewall rules allow the new port before changing sshd settings.

How it works

sshd listens on one or more TCP ports defined by Port directives. Firewalls must allow inbound TCP traffic to that port. When you change the port:

  • sshd must be reloaded/restarted to listen on the new port.
  • Your firewall must allow the new port.
  • Clients must connect using ssh -p <port>.

Prerequisites

  • A working SSH session to the server
  • Root access or a sudo-capable user
  • Host firewall installed and enabled (commonly UFW on Ubuntu/Debian)
  • Optional but strongly recommended: out-of-band access (provider console/serial/KVM)

Safe pre-checks (read-only)

Confirm current SSH listening ports

sudo ss -tulpn | grep -E 'sshd|:22|:2581' || true

Expected if still on default:

  • A LISTEN line containing :22 for sshd

Confirm SSH service status

systemctl status ssh 2>/dev/null || systemctl status sshd

Check firewall state and current SSH rules

UFW example:

sudo ufw status verbose

Step-by-step: change to a new port safely

The example below uses port 2581. Replace it with your chosen port.

Step 1: Choose a port

Recommended rules:

  • Use a port between 1024 and 65535
  • Avoid ports already used by services on your host
  • Keep it consistent across your fleet/runbooks

Check if the port is already in use:

sudo ss -tulpn | grep ':2581' || echo "Port 2581 not currently in use"

Step 2: Allow the new port in the firewall first

UFW (Ubuntu/Debian common)

sudo ufw allow 2581/tcp comment "SSH (new port)"
sudo ufw status numbered

If you restrict SSH to trusted IPs, prefer an allowlist rule instead of allowing from anywhere:

sudo ufw allow from 203.0.113.10 to any port 2581 proto tcp comment "SSH (trusted IP)"
Provider firewall

If your VPS/cloud provider uses a separate firewall/security group, you must allow TCP 2581 there as well. Host firewall rules alone are not sufficient.

Step 3: Update OpenSSH server configuration

Prefer a drop-in file when supported.

sudo install -d -m 0755 /etc/ssh/sshd_config.d
sudo tee /etc/ssh/sshd_config.d/10-custom-port.conf >/dev/null <<'EOF'
Port 2581
EOF

Option B: Edit /etc/ssh/sshd_config directly

Backup first:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

Edit:

sudo nano /etc/ssh/sshd_config

Set (or add) a single Port line:

Port 2581
Duplicate Port lines

If multiple Port lines exist, sshd may listen on multiple ports. Decide whether you want a temporary overlap (22 and 2581) or a single port, and keep the configuration explicit.

Step 4: Validate SSH configuration syntax before reloading

sudo sshd -t

If this prints nothing, the config syntax is valid. If it returns an error, fix the config before continuing.

Step 5: Reload SSH safely

Reload is preferred over restart when supported.

sudo systemctl reload ssh 2>/dev/null || sudo systemctl reload sshd

If reload is not available, restart:

sudo systemctl restart ssh 2>/dev/null || sudo systemctl restart sshd

Step 6: Confirm sshd is listening on the new port

sudo ss -tulpn | grep -E 'sshd.*:2581|:2581.*sshd' || true

You should see LISTEN entries for :2581.

Step 7: Test a new SSH session before closing the old one

From your local machine:

ssh -p 2581 your_username@your_server_ip

Keep the original session open until the new session works.

Step 8: Close port 22 after successful verification (optional)

Only do this after confirming the new port works.

sudo ufw deny 22/tcp comment "Disable default SSH port"
sudo ufw status numbered

SELinux considerations (RHEL-based systems)

If SELinux is enforcing, sshd may fail to bind to a non-standard port even if the firewall is open. Symptoms often include:

  • Port allowed in firewall
  • No sshd listener on the new port
  • Connection attempts time out or are refused

Check SELinux mode:

getenforce 2>/dev/null || true

If enforcing, allow the new SSH port (example for 2581):

sudo semanage port -a -t ssh_port_t -p tcp 2581 2>/dev/null || sudo semanage port -m -t ssh_port_t -p tcp 2581

Then reload SSH and re-check listeners:

sudo systemctl reload sshd 2>/dev/null || sudo systemctl restart sshd
sudo ss -tulpn | grep -E 'sshd.*:2581|:2581.*sshd' || true
semanage availability

If semanage is missing, install the SELinux management utilities package for your distribution (commonly policycoreutils-python-utils or equivalent), then re-run the port command.

Troubleshooting: cannot connect on the new port (example: 2581)

Use these checks in order.

1) Confirm the firewall rule exists (host firewall)

UFW example:

sudo ufw status verbose

You should see an allow rule for 2581/tcp.

2) Confirm sshd is actually listening on the new port

sudo ss -tulpn | grep sshd

If you do not see :2581:

  • The Port 2581 setting was not applied (or is overridden)
  • sshd failed to reload/restart
  • SELinux is blocking the bind (RHEL-based systems)

Check effective config:

sudo sshd -T | grep -i '^port '

This output is authoritative for what sshd will use.

3) Confirm SSH service restarted cleanly

sudo systemctl status ssh 2>/dev/null || sudo systemctl status sshd
sudo journalctl -u ssh -n 200 --no-pager 2>/dev/null || true
sudo journalctl -u sshd -n 200 --no-pager 2>/dev/null || true

4) Confirm your provider firewall/security group allows the port

If the host firewall is correct and sshd is listening on :2581 but you still cannot connect from the internet, the most common cause is an upstream block:

  • Cloud security group/firewall does not allow TCP 2581
  • Provider edge firewall blocks custom ports by policy
  • You are testing from a source network that is restricted

A quick on-server sanity check (local connectivity) can confirm sshd is reachable locally:

# Local connect test (runs on the server itself)
ssh -p 2581 localhost

If localhost works but remote does not, the issue is upstream of sshd (provider firewall, routing, or external network restrictions).

5) Check you used the correct client syntax

Correct:

ssh -p 2581 your_username@your_server_ip

Common mistakes:

  • Swapping flag order or missing -p
  • Connecting to the wrong IP (IPv6 vs IPv4)
  • Connecting as root when root login is disabled

6) Confirm you did not create conflicting rules

If you use allowlisting for SSH, confirm your source IP is permitted. For UFW, numbered rules help with clarity:

sudo ufw status numbered

Recovery and rollback

If you have console/serial/KVM access:

  1. Remove or revert the change.
  2. Validate config.
  3. Reload SSH.
  4. Re-open port 22 temporarily if needed.

Drop-in rollback:

sudo rm -f /etc/ssh/sshd_config.d/10-custom-port.conf
sudo sshd -t
sudo systemctl reload ssh 2>/dev/null || sudo systemctl reload sshd

Re-open port 22 (UFW):

sudo ufw allow 22/tcp comment "SSH recovery"
sudo ufw status verbose

Emergency: disable UFW temporarily (only if necessary)

sudo ufw disable

Re-enable after fixing SSH:

sudo ufw enable
sudo ufw status verbose
Minimize time without a firewall

Disabling the firewall on an internet-exposed server increases risk. Use it only as a short-lived recovery step and restore your rules immediately.

Security notes

Changing the SSH port reduces opportunistic scanning noise but does not replace core hardening:

  • Prefer SSH keys over passwords and disable password authentication where feasible.
  • Disable direct root SSH login and use a sudo-capable admin user.
  • Restrict SSH to trusted IP ranges where possible.
  • Add rate limiting and ban automation (for example, Fail2Ban).
  • Monitor authentication logs and changes to SSH configuration.

Quick reference

Safe change sequence

PhaseCommand
----
Allow new port (UFW)sudo ufw allow 2581/tcp
Set SSH port (drop-in)sudo tee /etc/ssh/sshd_config.d/10-custom-port.conf
Validate configsudo sshd -t
Reload SSHsudo systemctl reload ssh || sudo systemctl reload sshd
Confirm listeningsudo ss -tulpn | grep sshd
Test loginssh -p 2581 user@server
Disable port 22 (optional)sudo ufw deny 22/tcp

Key verification commands

sudo sshd -T | grep -i '^port '
sudo ss -tulpn | grep sshd
sudo ufw status verbose 2>/dev/null || true
systemctl status ssh 2>/dev/null || systemctl status sshd