AI summary
Overview: The article is a practical guide for safely relocating the SSH listening port on Linux servers. It explains differences between service-managed and systemd socket-activated SSH, and outlines the required changes to SSH configuration, systemd socket units, host firewalls, SELinux port labeling, and cloud-provider network controls. It also summarizes validation steps, troubleshooting approaches, client-side configuration updates, and complementary SSH hardening measures.
Core message: Changing SSH to a nonstandard high port can markedly reduce automated attack noise but is not a substitute for strong authentication and access controls. Success depends on following a strict, test-first sequence—leave an active session open, open the new port in all relevant firewalls, validate configuration, restart or reload the appropriate unit, and confirm access from an independent connection—and pairing the port change with key-based auth, intrusion-prevention, and restrictive access policies.
Learn how to change the default SSH port on Linux safely without locking yourself out. This expert guide covers Ubuntu, Debian, Rocky Linux, AlmaLinux, firewalls, SELinux, and modern systemd socket activation, including Ubuntu 24.04 and Debian 13 configurations. Includes troubleshooting tips, security hardening recommendations, and real-world examples for production servers.
How to Change the SSH Port
Audience: Linux system administrators, DevOps engineers, and infrastructure engineers managing internet-facing servers.
Applies to: Ubuntu 22.04/24.04, Debian 12/13, Rocky Linux 8/9, AlmaLinux 8/9, RHEL 8/9, and any systemd-based distribution.
Overview
SSH listens on TCP port 22 by default, a well-known fact that makes it a perpetual target for automated credential-stuffing, dictionary attacks, and opportunistic vulnerability scanners. Relocating SSH to a non-standard high port is a low-effort, high-signal-to-noise hardening measure: it eliminates the overwhelming majority of automated noise without meaningfully impeding legitimate access.
This is a defense-in-depth measure, not a security boundary. A determined attacker running a full port scan (nmap -p-) will discover the service regardless. This technique is most valuable for:
- Drastically reducing brute-force log pollution
- Lowering exposure to exploit attempts targeting zero-days in specific sshd versions
- Providing a secondary layer of obscurity alongside proper cryptographic and authentication hardening
It must be combined with key-based authentication, Fail2Ban or sshguard, disabled password authentication, and ideally IP allowlisting or MFA for administrative access.
Critical Rule Before You Begin
Never close your existing SSH session until the new port is fully validated from a second, independent connection.
A single misstep, a firewall rule applied before an sshd restart, a typo in sshd_config, a missed SELinux label can lock you out of a remote machine. The recovery path from a locked-out VPS varies from painful (console access via provider panel) to catastrophic (no out-of-band access).
Follow this order strictly:
- Keep the current session open
- Open the new port in the firewall first
- Apply the sshd configuration change
- Validate configuration syntax (sshd -t)
- Restart or reload the SSH service/socket
- Test from a second terminal
- Remove the old port 22 rule only after the new session succeeds
Step 1: Choosing a Port
Select a port in the range 1024–65535. Ports below 1024 are privileged and reserved; ports in the 49152–65535 range are designated ephemeral by IANA and may conflict with transient client connections on some systems.
Practical guidance:
- Avoid ports already claimed by well-known services (3306/MySQL, 5432/Postgres, 6379/Redis, 8080/HTTP-alt, etc.)
- Check whether your target port is already in use locally before committing:
ss -tulpn | grep ‘:2222’
- Avoid port 2222 itself it is widely known as the “alternate SSH port” and included in many scan profiles.
- A port in the 10000–50000 range that has no associated IANA service is a reasonable choice.
Step 2: Determine How SSH Is Managed on Your System
This is the most commonly skipped step, and it causes the most confusion. Modern Linux distributions have diverged on how they manage the SSH listening socket:
Traditional Model (ssh.service)
sshd starts at boot, binds to the configured port directly, and manages its own socket lifecycle. The port is determined exclusively by /etc/ssh/sshd_config.
Systemd Socket Activation Model (ssh.socket)
systemd owns and opens the listening socket. sshd is launched on-demand when a connection arrives. The listening port is controlled by the socket unit, not by sshd_config. Modifying sshd_config alone has no effect on which port the system actually accepts connections on.
Ubuntu 22.10+ and Debian 13 have moved toward socket activation by default. Ubuntu 24.04 uses it by default on new installs.
Check which model is active on your system:
systemctl is-active ssh.service
systemctl is-active ssh.socket
Possible states:
| ssh.service | ssh.socket | Model |
| active | inactive | Traditional |
| inactive | active | Socket activation |
| active | active | Transitional/mixed — requires careful handling |

Step 3: Modify the SSH Configuration
Regardless of which model is active, updating sshd_config is good practice — it ensures consistency if the service model ever changes, and it is required for traditional setups.
sudo nano /etc/ssh/sshd_config
Locate the Port directive. It is often commented out, which causes sshd to default to port 22:
#Port 22
Change it to your chosen port:
Port 2222
If you want SSH to listen on multiple ports simultaneously during a migration window (highly recommended for production systems), you can specify multiple Port directives:
Port 22
Port 2222
This lets you validate the new port before removing the old one, without needing two separate sshd processes.
Harden While You’re in the File
Since you have sshd_config open, apply the following hardening settings at the same time:
# Disable direct root login
PermitRootLogin no
# Disable password-based authentication (requires pre-deployed keys)
PasswordAuthentication no
ChallengeResponseAuthentication no
# Restrict which users can authenticate
AllowUsers deployer adminuser
# Reduce authentication timeout and retry limits
LoginGraceTime 30
MaxAuthTries 3
MaxSessions 5
# Disable unused authentication methods
KerberosAuthentication no
GSSAPIAuthentication no
# Restrict to strong key exchange, ciphers, and MACs (modern clients only)
KexAlgorithms curve25519-sha256,[email protected]
Ciphers [email protected],[email protected],[email protected]
MACs [email protected],[email protected]
Note on crypto policy: On RHEL-based systems using system-wide crypto policies (update-crypto-policies), manual cipher/kex overrides in sshd_config may conflict. Either configure via the policy subsystem or set CRYPTO_POLICY= in /etc/sysconfig/sshd to opt out.
Step 4: Validate the Configuration
Before touching any service, validate the configuration syntax. This catches errors that would otherwise cause sshd to fail to start, locking you out:
sudo sshd -t
No output means the configuration is syntactically valid. If errors are reported, fix them before proceeding.
For a more detailed parse of the effective configuration (including defaults and includes):
sudo sshd -T | grep -E ‘^(port|permitrootlogin|passwordauthentication|allowusers)’
Step 5: Configure the Firewall
The firewall must be updated before restarting SSH. Opening the new port first ensures you have a path in via the new port, even if something goes wrong during the service restart.
UFW (Ubuntu/Debian)
# Open the new port
sudo ufw allow 2222/tcp comment ‘SSH custom port’
# Verify it is listed
sudo ufw status verbose
# Only remove port 22 after successful validation
sudo ufw delete allow 22/tcp
sudo ufw delete allow OpenSSH
ufw rules are persistent across reboots by default. No additional step needed.
firewalld (Rocky Linux, AlmaLinux, RHEL, Fedora)
# Add the new port permanently
sudo firewall-cmd –permanent –add-port=2222/tcp
# Apply the permanent configuration to the running state
sudo firewall-cmd –reload
# Verify
sudo firewall-cmd –list-ports
# Remove port 22 after validation
sudo firewall-cmd –permanent –remove-service=ssh
sudo firewall-cmd –reload
A common mistake is running firewall-cmd without –permanent. This opens the port in the running configuration only; it is lost on the next reboot or firewall-cmd –reload.
iptables (Legacy Systems)
sudo iptables -A INPUT -p tcp –dport 2222 -j ACCEPT
sudo iptables -D INPUT -p tcp –dport 22 -j ACCEPT
# Persist (Debian/Ubuntu)
sudo iptables-save > /etc/iptables/rules.v4
# Persist (RHEL-based)
sudo service iptables save

Step 6: Configure SELinux (RHEL-Based Systems Only)
On systems with SELinux enforcing, the SSH daemon is constrained by the ssh_port_t type label. Even with a correct sshd_config and an open firewall rule, sshd will silently fail to bind to an unlabeled port it will either fall back to port 22 or refuse to start.
This step is mandatory on Rocky Linux, AlmaLinux, RHEL, CentOS Stream, and Fedora.
Check Whether SELinux Is Enforcing
getenforce
If the output is Enforcing, proceed. If Permissive or Disabled, this step is not required (but permissive mode still logs denials — check with ausearch -m avc).
Label the New Port
sudo semanage port -a -t ssh_port_t -p tcp 2222
If semanage is not available:
sudo dnf install -y policycoreutils-python-utils
Verify the Label
sudo semanage port -l | grep ssh_port_t
Expected output:
ssh_port_t tcp 2222, 22
Verify No Denials After Restart
sudo ausearch -m avc -ts recent | grep sshd
If you see AVC denials related to the new port, the label was not applied correctly.
Step 7: Apply the Change — Traditional Mode
For systems running ssh.service (no socket activation):
# Reload configuration without dropping connections (preferred for production)
sudo systemctl reload ssh # Debian/Ubuntu
sudo systemctl reload sshd # RHEL-based
# Or do a full restart if reload is not supported
sudo systemctl restart ssh
sudo systemctl restart sshd
# Check service status
sudo systemctl status ssh
Confirm the port is now listening:
ss -lntp | grep sshd
Step 8: Apply the Change — Socket Activation Mode
On systems where ssh.socket is active (Ubuntu 22.10+, Ubuntu 24.04, Debian 13), sshd_config changes to Port do not affect the actual listening port. systemd owns the socket and passes it to sshd via socket activation. You must configure the socket unit directly.
Create a Systemd Override
sudo systemctl edit ssh.socket
This opens a drop-in override file at /etc/systemd/system/ssh.socket.d/override.conf. Add:
[Socket]
ListenStream=
ListenStream=2222
The first ListenStream= (empty) clears the inherited default value. The second sets the new port. Without the empty line, the new port is added to the existing ones rather than replacing them.
For dual-stack systems (both IPv4 and IPv6):
[Socket]
ListenStream=
ListenStream=0.0.0.0:2222
ListenStream=[::]:2222
Reload and Restart the Socket
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
Verify the Socket Is Listening
sudo systemctl status ssh.socket
ss -lntp | grep 2222
Handling Mixed ssh.service + ssh.socket
Some systems in a partially-migrated state may have both active simultaneously. The socket unit takes precedence for incoming connections, but the service may still hold port 22 open independently. If you see SSH listening on both ports from different processes:
# Identify what owns each port
ss -lntpe | grep -E ‘(:22|:2222)’
# Disable and stop the legacy service unit if socket activation is the target
sudo systemctl disable –now ssh.service
Step 9: Validate From a Second Terminal
Do not close your original session yet. Open a new terminal window and test:
ssh -p 2222 -v user@server-ip
The -v flag enables verbose output. If the connection fails, the output will identify whether the problem is network-level (connection refused/timeout), authentication, or host key verification.
Confirm no unexpected ports remain open:
ss -lntp | grep -E ‘(sshd|ssh)’
At this point you may remove the port 22 firewall rule (see Step 5) and optionally remove the Port 22 line from sshd_config if you had it set for dual-port testing.
Troubleshooting
SSH Still Listening on Port 22
Possible causes:
- ssh.socket is active and was not reconfigured (the ListenStream override was not applied)
- Both ssh.service and ssh.socket are running; the service is binding port 22 independently
- A stale sshd process is still running (check with ps aux | grep sshd)
- The systemctl daemon-reload step was skipped after editing the socket unit
Diagnostic commands:
# What process owns port 22?
ss -lntpe | grep ‘:22’
# Is the socket unit using the override?
systemctl cat ssh.socket
# Are there any lingering processes?
ps aux | grep ‘[s]shd’
Connection Refused on New Port
Work through the stack from bottom to top:
# 1. Is sshd actually listening?
ss -lntp | grep 2222
# 2. Is the firewall passing the traffic?
sudo ufw status # or
sudo firewall-cmd –list-all
# 3. Is SELinux blocking the bind? (RHEL-based)
sudo ausearch -m avc -ts recent | grep sshd
# 4. What does the SSH daemon log show?
journalctl -u ssh -xe –since “5 minutes ago”
journalctl -u ssh.socket -xe –since “5 minutes ago”
Cloud Provider / External Firewalls
The OS-level firewall is only one layer. Many VPS and cloud providers operate external security groups or network ACLs that are entirely independent of the guest OS:
| Provider | Console Location |
| AWS | EC2 → Security Groups |
| GCP | VPC → Firewall Rules |
| Azure | Network Security Groups |
| Hetzner | Cloud Firewall (project level) |
| DigitalOcean | Networking → Firewalls |
| Linode/Akamai | Cloud Firewalls |
You must open the new SSH port in the provider’s control plane, in addition to the OS firewall, before the connection can reach sshd.
Updating Your SSH Client Configuration

To avoid typing -p 2222 on every connection, update ~/.ssh/config on your client machines:
Host myserver
HostName 203.0.113.10
User adminuser
Port 2222
IdentityFile ~/.ssh/id_ed25519
Pre-Removal Checklist
Before removing port 22 from both the firewall and sshd_config, verify every item:
- [ ] New port accepts connections from a second terminal
- [ ] ss -lntp confirms SSH is only listening on the new port
- [ ] OS-level firewall rule for port 22 removed
- [ ] Cloud/provider-level firewall updated
- [ ] SELinux labels verified (RHEL-based)
- [ ] sshd -t passes with the final configuration
- [ ] ~/.ssh/config on all client machines updated
- [ ] Runbooks, monitoring alerts, and bastion host configs updated to reference the new port
- [ ] Any CI/CD pipelines or deployment tools updated
Additional SSH Hardening Recommendations
Changing the port is one layer. A properly hardened sshd_config should also include:
# Never permit root login directly
PermitRootLogin no
# Disable all password-based authentication
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes
# Restrict to specific users or groups
AllowUsers deployer
# AllowGroups sshusers
# Short grace period for unauthenticated connections
LoginGraceTime 30
# Limit retry attempts to reduce brute-force window
MaxAuthTries 3
# Prevent X11 and agent forwarding unless explicitly needed
X11Forwarding no
AllowAgentForwarding no
# Disable TCP forwarding if not required
AllowTcpForwarding no
# Log verbosely for audit trail
LogLevel VERBOSE
# Drop idle sessions after inactivity
ClientAliveInterval 300
ClientAliveCountMax 2
# Restrict SSH protocol features to reduce attack surface
PermitEmptyPasswords no
PermitUserEnvironment no
Pair this with:
- Fail2Ban with aggressive jails on the new port
- Port knocking (knockd) or Single Packet Authorization (fwknop) for maximum obscurity
- WireGuard or a VPN as the primary administrative access path, with SSH only exposed on the VPN interface
- Ed25519 keys for all authentication (smaller, faster, and based on better math than RSA-2048)
- Key rotation policy and revocation via authorized_keys management or a secrets manager
Secure Your Infrastructure with Advanced Hosting
Whether you manage a single VPS or an enterprise infrastructure, secure remote access is foundational to Linux server security.
Advanced Hosting provides:
- High-performance VPS and dedicated servers
- Enterprise-grade DDoS protection
- Advanced networking and firewall options
- Bare metal infrastructure
- Managed hosting solutions
- Low-latency global deployments
If you need reliable infrastructure for production Linux workloads, container platforms, virtualization, or secure SSH administration at scale, explore the solutions available at Advanced Hosting.
Does changing the SSH port actually improve security?
Changing the port does not harden SSH cryptographically, but it significantly reduces exposure to automated scanning and low-effort brute-force attacks targeting port 22. Most internet-wide attacks are opportunistic and focus on default configurations.
However, moving SSH to another port should always be combined with:
- SSH key authentication
- Fail2Ban or rate limiting
- Disabling password authentication
- Restricting login users
- IP allowlists where possible
Think of it as reducing attack surface noise rather than replacing real authentication security.
What is the best port number for SSH?
There is no universally “best” SSH port.
Recommended practice:
- Use a high, unassigned TCP port
- Stay within 1024–65535
- Avoid ports used by databases, web services, or orchestration systems
Good examples:
- 2222
- 22222
- 50222
Avoid:
- Common alternative SSH ports heavily scanned by bots
- Ports already used by Docker, Kubernetes, game servers, or monitoring systems
Can changing the SSH port affect automation tools?
Yes. Any automation or orchestration platform that connects through SSH must be updated after the port change.
Common affected systems:
- Ansible
- Terraform provisioners
- Jenkins agents
- Git deployment hooks
- Backup systems
- Monitoring agents
- CI/CD pipelines
For Ansible, specify the port in inventory:
ansible_host=server_ip ansible_port=2222
Should I completely disable port 22 afterward?
In most production environments, yes, after verifying the new port works correctly.
Leaving both ports active:
- increases exposure
- creates configuration ambiguity
- weakens the purpose of the migration
However, temporary dual-port operation can be useful during staged migrations or infrastructure automation rollouts.
Can I run SSH on multiple ports simultaneously?
Yes.
OpenSSH supports multiple Port directives:
Port 22
Port 2222
This is commonly used during:
- migration periods
- phased firewall updates
- temporary compatibility windows
Be aware that every exposed port increases the visible attack surface.
Does changing the SSH port affect SCP or SFTP?
Yes. SCP and SFTP both rely on SSH transport.
You must explicitly specify the custom port.
SCP example:
scp -P 2222 file.txt user@server:/tmp
SFTP example:
sftp -P 2222 user@server
Note that SCP uses uppercase -P, while SSH uses lowercase -p.