Home - Teleport Blog - SSH Port 22: Custom Ports, Port Forwarding Security, and Production SSH Hardening
SSH Port 22: Custom Ports, Port Forwarding Security, and Production SSH Hardening

Read this article to learn about:
- Port 22 and its limitations
- Local, remote, and dynamic SSH forwarding and their attack vectors
- KexAlgorithm, cipher, and MAC selections
- Rate limiting and pre-auth defense (PerSourcePenalties, nftables, and PAM)
authorized_keysvs. certificate authorities for SSH
Most Secure Shell (SSH) hardening advice starts and ends with two changes: move off port 22 or disable root login. Both are easy to implement, widely recommended — and almost entirely misunderstood.
However, the real security posture of an SSH deployment is determined elsewhere: by the cryptographic algorithms negotiated during key exchange, the authentication model enforced by sshd_config, forwarding rules that may create unintended access paths, and the presence or absence of connection rate limiting before sshd processes a request.
What is port 22?
Port 22 is the transmission control protocol (TCP) port that accepts the initial SSH handshake. Simply put, port 22 is the standard network entry point where SSH connections land.
Tatu Ylönen, the inventor of SSH, requested port 22 from IANA in 1995, before he submitted the SSH protocol specification as an Internet Draft. He positioned SSH as a secure replacement for Telnet (23) and FTP (21), and chose port 22 because it was available and sat between them. The port number is a historical artifact of that decision — it carries no cryptographic or authentication significance.
What does port 22 do?
Port 22 controls exactly one thing: where the TCP handshake lands. It determines which packets sshd accepts for processing. Once a connection is established, everything that follows (the key exchange algorithm negotiated, the cipher selected, the authentication method, the session authorization) is governed by sshd_config directives and the server's cryptographic configuration. For example, a server running on port 2222 with weak cipher suites and PasswordAuthentication yes has a significantly larger attack surface than one on port 22 with algorithm restrictions and certificate-based authentication.
Port 22 does not control how authentication is performed, which cryptographic algorithms are negotiated, or what a user is allowed to do after connecting. Instead, the argument for changing the default port is noise reduction.
An internet-facing server on port 22 absorbs continuous automated scanning, credential stuffing, and brute-force traffic from botnets that do nothing but probe port 22 across the IPv4 address space. Moving to a non-standard port drops most of that traffic from your logs because those scanners don't prioritize non-standard ports at the same volume, which makes log analysis easier and removes some load from your PAM stack.
A targeted attacker who runs a port scan first will find SSH on any port. Every control in the sections that follow addresses a vulnerability class that port selection leaves intact. Configure the port change if log cleanliness matters to your operations, then move on.
Changing the default SSH port: Key considerations
Changing the SSH listening port is straightforward at the configuration level: you define an alternative port in sshd_config and reload the daemon so it begins accepting connections on the new entry point. What matters more than the port change itself is how it is executed.
The sequencing of this process is critical. The new port must be allowed through the host firewall before the original port is closed — reversing that order can immediately lock you out of the system, especially on remote infrastructure where no out-of-band access exists. This applies regardless of whether the system uses higher-level tools like UFW or direct packet filtering with nftables. You must always ensure the new path is open before removing the old one.
On systems running SELinux in enforcing mode, the port change introduces an additional constraint: SELinux maintains its own policy for which ports SSH is allowed to bind to. If the new port is not explicitly labeled for SSH, the daemon will fail to start on that port even if the configuration is otherwise correct. In practice, this means the service may stop accepting connections entirely if the change is made without updating the SELinux context.
Most operational issues with port changes are not in the daemon itself, but in the surrounding ecosystem. SSH client configurations that assume port 22 will continue to fail silently until updated. This includes ~/.ssh/config entries that omit an explicit port, as well as multi-hop configurations using ProxyJump, where the port must be updated across the entire chain — not just on the final target.
Related Article: How to Use SSH ProxyJump and SSH ProxyCommand
Monitoring and security tooling is another common blind spot. Many SIEM and availability checks assume SSH is reachable on port 22. Once the port changes, those systems may begin reporting hosts as offline or unreachable, even though SSH is functioning normally on the new port. Updating monitoring rules before closing the original port avoids false alerts and unnecessary incident noise.
Changing the SSH port is operationally simple, but it touches multiple layers: firewall policy, mandatory access controls, client configuration, and monitoring assumptions. Treat it as a coordinated change, not a single-line edit.
SSH port forwarding: Local, remote, dynamic, and their specific attack vectors
SSH port forwarding is widely used, and typically safe in practice.
However, port forwarding also introduces a different class of risk. Treating all forwarding capabilities as equivalent in sshd_config ignores how they can be abused in real environments.
Forwarding is achieved by setting the following flags:
- ‘-L’ for Local forwarding
- ‘-R’ for Remote forwarding
- ‘-D’ for Dynamic forwarding
Local forwarding
Local forwarding (-L) binds a port on the client and tunnels traffic to a destination through the SSH connection — commonly used to access a remote database from a local workstation.
Related Article: SSH Tunneling, Explained
By default, the forwarded port binds to the loopback interface, making it accessible only from the client itself. However, if explicitly bound to a broader interface, it can become reachable to other devices on the same network. In those cases, a service that was intended to be accessed locally is effectively exposed to the client’s network environment. Additionally, local forwarding can bypass network-level controls on the remote side by routing traffic through an already authenticated SSH session.
Remote forwarding
Remote forwarding (-R) exposes a port on the remote server that tunnels back to the client. This is useful for making a local service accessible through a remote host, but it also enables reverse tunnel abuse.
For example, a compromised or malicious client can establish an outbound SSH connection and open a reverse tunnel, effectively bypassing NAT (Network Address Translation) and firewall restrictions because the connection originates from inside the network. If GatewayPorts is enabled, the forwarded port may be exposed beyond the remote host itself, increasing the blast radius. In most environments, keeping GatewayPorts disabled reduces unintended exposure.
Related Article: Reverse Proxy: How It Works & Example Architecture
Dynamic forwarding
Dynamic forwarding (-D) turns the SSH server into a SOCKS (SOCKet Secure) proxy, allowing the client to route arbitrary outbound traffic through the SSH connection. This is commonly used for secure browsing or testing from a different network perspective. The risk is reduced visibility: while the SSH session itself is logged, the application-level traffic passing through the SOCKS tunnel is not, making it a potential path for data exfiltration or policy bypass.
Each forwarding mode expands the role of SSH beyond interactive access into a general-purpose tunneling mechanism. Therefore, hardening SSH requires treating forwarding as a controlled capability, rather than a default convenience.
Important considerations for port forwarding
In many environments, forwarding is enabled by default but rarely required. If your SSH usage is limited to interactive access, leaving forwarding capabilities available expands the attack surface without providing operational value.
For those systems, the safer baseline is to disable forwarding explicitly at the server level. OpenSSH provides a single directive for this purpose, with additional options that make the intent unambiguous to anyone reading the configuration.
DisableForwarding yes disables all forwarding types in one setting. This was introduced in OpenSSH 7.3 to simplify what previously required multiple directives. However, versions 7.4 through 9.9 contained a logic error where certain forwarding modes were not consistently disabled in all cases. As a result, explicitly disabling X11, agent, and TCP forwarding alongside it remains a defensible practice.
Related Article: What You Need to Know About X11 Forwarding
While this behavior was corrected in OpenSSH 9.9p2, keeping these explicit directives provides clarity, documents intent, and avoids reliance on version-specific behavior when reviewing or maintaining configurations across mixed environments.
Hardening the cryptographic layer: KexAlgorithms, ciphers, and MACs
OpenSSH negotiates the strongest mutually supported algorithm between client and server. The problem with relying on this behavior alone is that "strongest mutually supported" is bounded by what both sides advertise. A legacy or misconfigured client can force the session down to weaker algorithms if the server allows them. The server defines the floor, but only if it explicitly restricts available algorithms.
KexAlgorithms
KexAlgorithms controls how the initial key exchange is performed.
Modern configurations prioritize algorithms like curve25519-sha256, along with high-strength Diffie-Hellman groups such as group16 and group18 with SHA-512. Older options like diffie-hellman-group1-sha1 and group14-sha1 should be removed due to known weaknesses, including susceptibility to attacks like Logjam (CVE-2015-4000). GSSAPI-based key exchange variants should also be excluded unless the environment explicitly depends on Kerberos.
Curve25519 is preferred in most deployments due to its performance characteristics and reduced risk of implementation flaws compared to older elliptic curve approaches.
Ciphers
Ciphers defines how session data is encrypted after the handshake.
Modern SSH deployments should restrict this list to authenticated encryption modes such as [email protected] and AES-GCM (Galois/Counter Mode) variants. Legacy ciphers like arcfour, 3des-cbc, and other Cipher Block Chaining (CBC) constructions should be excluded. This is because CBC-based modes have historically been associated with padding oracle attacks, including BEAST (CVE-2011-3389) and Lucky13 (CVE-2013-0169), whereas authenticated encryption modes combine confidentiality and integrity in a way that removes those attack classes from the protocol.
MACs
MAC (Message Authentication Code) controls message authentication for algorithms that do not use authenticated encryption.
When MACs are required, encrypt-then-MAC (ETM) variants such as SHA-2-based and UMAC constructions should be preferred. Older options like MD5- or SHA1-based MACs should be removed. Non-ETM constructions have historically been more difficult to analyze securely and were part of the conditions that enabled timing-based attacks like Lucky13. ETM variants authenticate the ciphertext rather than the plaintext, improving resistance to those classes of attacks.
A hardened SSH configuration explicitly restricts key exchange, cipher, and MAC selections to modern, well-analyzed algorithms, rather than relying on default negotiation behavior.
A note on CVE-2024-6387 (regreSSHion): This vulnerability was a signal handler race condition in OpenSSH’s authentication path, affecting versions 8.5p1 through 9.7p1 and enabling unauthenticated remote code execution. The algorithm restrictions above address a different class of risk. Cryptographic hardening mitigates weaknesses in negotiated algorithms, while patching OpenSSH addresses implementation flaws. It’s important to note that both are required — one does not substitute for the other.
Rate limiting and pre-auth defense: PerSourcePenalties, nftables, and PAM
Several sshd configuration parameters (that are often left at their defaults) have a direct impact on how the service behaves under brute-force and connection exhaustion attempts.
Explicitly setting limits on authentication attempts, connection duration, and concurrent unauthenticated sessions establishes a baseline level of protection before introducing external controls. For example, limiting authentication attempts per connection reduces the effectiveness of credential guessing within a single session, while shortening the grace period for unauthenticated connections limits how long an attacker can hold open a connection without completing authentication.
However, controlling the number of concurrent unauthenticated sessions will have the broadest impact: once a defined threshold is reached, sshd begins to probabilistically reject new connection attempts and eventually enforces a hard limit. This prevents connection exhaustion attacks from consuming all available capacity before legitimate users can authenticate.
Recent OpenSSH versions introduce PerSourcePenalties, a mechanism that applies automatic penalties to source addresses exhibiting abusive pre-authentication behavior. This is particularly relevant to vulnerabilities like CVE-2025-26466, where repeated pre-authentication interactions could consume excessive resources. PerSourcePenalties allows sshd to track and penalize abusive sources before the cost of processing each connection accumulates, reducing the impact of repeated malicious attempts. The directive requires OpenSSH 9.9p2 or later and should be configured explicitly rather than assumed to be active by default.
At the network layer, rate limiting can be enforced before sshd processes a connection at all. Packet filtering frameworks such as nftables allow per-source connection limits using connection tracking, ensuring that excessive connection attempts are dropped at the kernel level. This prevents sshd from allocating resources for abusive traffic and reduces log noise generated by repeated connection attempts. Systems that rely on older tooling can achieve similar behavior using iptables modules, though nftables provides a more modern and flexible approach.
Open-source tools like Fail2Ban operate reactively by parsing logs and inserting firewall rules after repeated failures are detected. While effective, they introduce a dependency on user-space monitoring and response. Kernel-level rate limiting enforces decisions at packet ingress, eliminating the delay between detection and enforcement.
For environments that still rely on password-based authentication, PAM modules such as pam_faillock provide account-level protection by locking users after a defined number of failed attempts. This operates after a connection reaches sshd and complements network-level rate limiting. As organizations transition toward certificate-based authentication through tools like Teleport, PAM-based controls remain relevant for any remaining password-authenticated paths and should be treated as part of a layered defense strategy.
authorized_keys vs. certificate authorities for SSH
The limitations of authorized_keys scale with the size of the environment. Each host maintains its own file, and access management becomes a distributed problem. Adding a new engineer requires propagating their key across multiple systems, and revoking access requires finding and removing that key everywhere it exists, with no guarantee that every copy was identified.
From an audit perspective, authorized_keys is equally weak. A successful login produces a key fingerprint, not a human identity tied to a specific authorization decision at a specific point in time. Instead, access is granted based on the presence of a key in a file, not a verified identity or a time-bound policy. At scale, this creates gaps that compliance frameworks such as SOC 2 and PCI-DSS routinely flag.
Certificate authorities address this problem at the model level. Instead of distributing individual keys to every host, systems trust a central authority that signs short-lived certificates. A host only needs to trust the CA once. Users authenticate to that authority, receive a certificate with a defined validity window, and use it to access systems.
Related Article: How to Configure SSH Certificate-Based Authentication
Revocation and expiration become properties of the certificate lifecycle rather than manual file edits on every host, shifting the problem from key distribution to CA lifecycle management. At smaller scales this can be handled manually, but may become a bottleneck at larger scales.
Teleport’s Auth Service builds on this model by operating as a production-grade SSH certificate authority integrated with identity systems. Instead of manually issuing certificates, users authenticate through a centralized identity provider with multi-factor authentication (MFA), and Teleport issues short-lived certificates tied to that verified identity. Access is evaluated at session time using role-based policies rather than relying on keys that were distributed at some point in the past.
Teleport also integrates with existing OpenSSH nodes without requiring replacement of sshd. Hosts trust the Teleport CA, and user access is mediated through the Teleport control plane, which enforces authentication, authorization, and session recording before forwarding connections to the target system. This model removes the need for long-lived SSH keys as the primary access mechanism and replaces it with identity-bound, time-limited credentials. Critically, Teleport also introduces a consistent audit layer where access decisions and session activities are attributed to a human identity and recorded in a centralized system, rather than inferred from distributed log entries.
Once access is fully mediated through Teleport, direct SSH exposure for internal infrastructure can be restricted or removed. Access is no longer defined by which port is open, but by who is allowed to connect and under what conditions.
SSH hardening solves configuration problems — not identity problems
The SSH controls in this article address real weaknesses: weak cryptographic defaults, unbounded connection attempts, permissive forwarding, and the operational risks of exposing SSH directly to the network. Applied together, they will significantly reduce the attack surface of any traditional SSH deployment. But they do not change the underlying SSH model.
Even when hardened, SSH access is still granted based on static credentials, authorization is still defined by what was configured at some point in the past, and revocation depends on configuration changes propagating across systems. Even in a hardened state, SSH remains a system where access is managed indirectly through configuration rather than evaluated directly at connection time.
Moving to certificate-based access shifts SSH from a configuration problem to an identity problem. Instead of trusting keys distributed across hosts, systems trust short-lived credentials issued to verified identities. Access decisions are evaluated at session time, not inferred from configuration state. Expiration, revocation, and scope become properties of the credential itself.
Teleport operationalizes this model. Rather than exposing SSH directly, access is mediated through a control plane that handles authentication, authorization, and session recording before a connection reaches the target system. Certificates are issued on demand, tied to user identity and policy, and expire automatically, ensuring there are no long-lived credentials to rotate or recover.
If you want to see this model in practice, you can try it in your own environment today.
About the author: Matt Keib is a CNAPP implementation consultant, an Azure Cloud Security Engineer, and an unapologetic geek whose life beats in the rhythm of hashing algorithms and cryptographic keys. The one thing he prioritizes more than clean code is privacy — which he believes isn't just a privilege but a right. His playground is among blockchain mysteries and the multilayered world of cybersecurity.
Related articles
→ SSH Hardening Tips to Prevent Brute-Force Attacks
→ 5 Best Practices for Securing SSH
→ Comparing SSH Keys: RSA, DSA, ECDSA, or EdDSA?
→ How to SSH into an EC2 Instance: A Step-by-Step Guide
Table Of Contents
- What is port 22?
- What does port 22 do?
- Changing the default SSH port: Key considerations
- SSH port forwarding: Local, remote, dynamic, and their specific attack vectors
- Hardening the cryptographic layer: KexAlgorithms, ciphers, and MACs
- Rate limiting and pre-auth defense: PerSourcePenalties, nftables, and PAM
- authorized_keys vs. certificate authorities for SSH
- SSH hardening solves configuration problems — not identity problems
- Related articles
Teleport Newsletter
Stay up-to-date with the newest Teleport releases by subscribing to our monthly updates.
Tags
Subscribe to our newsletter

