The Hidden SSH Port macOS Doesn't Tell You About

The hidden port: macOS Remote Login controls port 22, but a custom LaunchDaemon on port 2222 operates completely independently.
The Assumption Everyone Makes
If you disable Remote Login in macOS System Settings, SSH is off. That is the reasonable assumption. Apple's UI presents a single toggle, and when it is off, port 22 closes. Most administrators stop there.
We almost did too.
During a red team audit of our own infrastructure, we discovered something that should concern anyone running custom SSH services on macOS: a LaunchDaemon-based sshd on port 2222 continues to accept connections even when Remote Login is completely disabled. macOS has no awareness of it. There is no indicator in System Settings. No warning in the sharing panel. The port stays open, silently.
com.openssh.sshd on port 22. Any custom LaunchDaemon running sshd on another port operates with complete independence. Disabling one has zero effect on the other.Why Custom SSH Ports Are Invisible to macOS
macOS manages SSH through a LaunchDaemon called com.openssh.sshd. When you toggle Remote Login on or off, macOS loads or unloads that specific daemon. It listens on port 22 and is the only SSH service the operating system knows about.
But macOS has no registry of "all SSH services." Any process can open a TCP listener on any port. If you install a second LaunchDaemon that runs sshd on port 2222 — as we did for our hardware-authenticated vault sync — macOS treats it like any other background service. It has no concept that this is also an SSH server.
The Two Independent Paths
Path A: System SSH (Port 22)
Controlled by: System Settings → General → Sharing → Remote Login
LaunchDaemon: com.openssh.sshd
Behavior: Toggle ON = port 22 opens. Toggle OFF = port 22 closes.
Visibility: Full. macOS knows about this service.
Path B: Custom SSH (Port 2222)
Controlled by: Nothing in the macOS UI
LaunchDaemon: com.opendlp.gate-sshd (custom)
Behavior: Loaded at boot via launchctl. Persists regardless of Remote Login state.
Visibility: None. macOS has no awareness this port is open.
This is not a vulnerability in macOS. It is an architectural reality. But it creates a dangerous assumption gap: an administrator who disables Remote Login believing they have closed all SSH access is wrong.
The macOS Tahoe sshd-session Bug
While investigating port 2222, we discovered a second, more severe problem: SSH is fundamentally broken on macOS Tahoe.
OpenSSH 10.2, which ships with macOS Tahoe, splits the SSH server into two binaries. The listener (sshd) accepts connections and then hands each one off to a per-connection handler (sshd-session) via fork() + exec(). The problem is that the socket file descriptor is not properly inherited across the exec() boundary.

The broken handoff: sshd-session loses the socket file descriptor after exec(), killing every connection.
The Failure Chain
Every Mode Fails
All sshd configurations tested — all broken
- inetd mode (sshd-keygen-wrapper) — Broken pipe
- Standalone daemon (
sshd -D -p 2222) — Broken pipe - Standalone + no PAM (
sshd -D -p 2222 -o UsePAM=no) — Broken pipe - Standard port 22 (system
com.openssh.sshd) — Broken pipe
This is a system-wide macOS issue, not specific to custom configurations.
The Security Audit: 7 Gaps Found
With port 2222 operating outside macOS's awareness, we conducted a full security audit of the gate sshd configuration. The results were sobering — even with hardware YubiKey authentication in place, we found seven gaps that could weaken the overall security posture.

Defense in depth: seven layers between an attacker and the gate, each independently enforceable.
1. No Firewall Rule for Non-LAN Traffic
Gap: Murus (macOS PF firewall) had default-deny inbound, but no explicit block for non-LAN sources targeting port 2222.
Fix: Added PF rules — block drop in log quick proto tcp from ! 192.168.5.0/24 to any port 2222 — persisted in /etc/murus/murus.custom.
2. Gate User Had a Real Shell
Gap: The opendlp-gate user's shell was /bin/bash. If ForceCommand were ever bypassed (sshd bug, config error), an attacker would land in a real interactive shell.
Fix: Changed shell to /usr/bin/false. Even a ForceCommand bypass now yields nothing.
3. Keyboard-Interactive Authentication Left Default
Gap: While PasswordAuthentication was disabled, KbdInteractiveAuthentication was not explicitly set — leaving a potential authentication vector open.
Fix: Explicitly set KbdInteractiveAuthentication no.
4. No Session or Auth Attempt Limits
Gap: No MaxAuthTries or MaxSessions set — an attacker could attempt unlimited authentication cycles or open unlimited sessions.
Fix: Added MaxAuthTries 3 and MaxSessions 2.
5. Port Forwarding Not Fully Restricted
Gap: AllowTcpForwarding no was set, but PermitOpen and PermitListen were not — leaving potential tunnel abuse vectors.
Fix: Added PermitOpen none and PermitListen none.
6. Loopback IP in Device ACL
Gap: The YubiKey device ACL listed 127.0.0.1 as a known IP — meaning a loopback-source-spoofing attack could bypass the IP binding check.
Fix: Changed to the actual LAN IP (192.168.5.47).
7. User Environment Injection
Gap: PermitUserEnvironment was not explicitly disabled — theoretically allowing environment variable injection via ~/.ssh/environment.
Fix: Explicitly set PermitUserEnvironment no.
What Was Already Strong
The audit was not all gaps. Several layers of protection were already in place and validated during testing.
Existing Protections (Pre-Audit)
- YubiKey challenge-response — Hardware PIV cryptographic signature required for every connection. No password or SSH key alone is sufficient.
- ForceCommand (double-enforced) — Both the sshd Match block and
authorized_keys command=directive restrict the connection to a single controlled entry point. - PubkeyAuthentication only — No password, no keyboard-interactive, no host-based auth.
- E5 crypto hardening — AEAD ciphers only (ChaCha20-Poly1305, AES-256-GCM), post-quantum key exchange (sntrup761x25519), no SHA-1 MACs, no CBC mode.
- Hidden system user — The gate user is not visible in the login window or standard user listings.
- Append-only audit logs —
chflags uappndon all gate and verifier log files. Even root cannot delete entries without clearing the flag. - Nonce-based replay protection — Each authentication challenge uses a single-use nonce that is deleted immediately after verification.
E5: Crypto Hardening Profile
As part of the audit, we deployed a restrictive cryptographic configuration for the gate sshd. This eliminates legacy algorithms that are technically supported by OpenSSH but offer no benefit on a modern network.
What This Eliminates
- CBC ciphers — Vulnerable to padding oracle attacks
- SHA-1 MACs — Collision attacks demonstrated since 2017
- umac-64 — Insufficient MAC length for high-security contexts
- Weak KEX — Removed diffie-hellman-group-exchange and group14 variants
The configuration validates cleanly with sshd -t and will take effect once the macOS Tahoe sshd-session bug is resolved.
Designing the Fix: A User-Facing Toggle
The root UX problem is clear: enabling or disabling the gate SSH listener requires terminal commands that no end user should need to run. If we are building security software that operates a hidden port, we have a responsibility to make that port controllable.

Proposed UX: a simple toggle with Touch ID authentication, auto-disable timer, and clear status indication.
Current State (Unacceptable)
Proposed Design
Remote Vault Sync Toggle
- Label: "Allow Remote Vault Sync" — not "SSH," because users don't need to know the protocol
- Authentication: Touch ID or admin password required before enabling (this is a privileged operation)
- Status indicator: Green dot = listening on port 2222, Gray = off
- Port display: Shows "Port 2222 (LAN only)" when enabled
- Auto-disable: Optional timer — "Turn off after 1h / 4h / 8h / Never" — prevents forgotten open ports
- Independence: Does NOT require macOS Remote Login to be enabled
- PF integration: Toggle also manages the PF firewall rule (LAN-only restriction)
Architecture
The toggle communicates with a privileged XPC helper running as root. The helper manages both the LaunchDaemon lifecycle (launchctl bootstrap/bootout) and the PF firewall anchor. This keeps the user-facing app in userspace while the privileged operations happen through a controlled, audited channel.
Fix Options for the sshd-session Bug
The macOS Tahoe sshd-session bug blocks all SSH-based features. We evaluated four approaches:
Option A: Wait for Apple
Approach: Apple patches sshd-session socket inheritance in a future macOS update.
Pro: Zero effort. Con: Unknown timeline; blocks all SSH testing indefinitely.
Option B: Homebrew OpenSSH (Recommended)
Approach: Install via brew install openssh. Use /opt/homebrew/sbin/sshd, which ships a single binary without the sshd-session split.
Pro: Known working, decouples from Apple's build, version control. Con: Extra dependency, needs own host keys.
Option C: Dropbear
Approach: Lightweight SSH server with no sshd-session split.
Pro: Simple, no Apple dependencies. Con: Different config format, no ForceCommand support.
Option D: Enable Remote Login via GUI
Approach: System Settings → Sharing → Remote Login.
Pro: May fix sshd-keygen-wrapper path. Con: Did not work in testing — same broken pipe.
Current Live State
Here is exactly where things stand as of this writing. The security hardening is deployed and validated, but the transport layer is blocked by the macOS bug.
What IS Running
- ESF extension (v99) — All 15 AUTH + 9 NOTIFY subscriptions active, full vault protection
- NE extension (v8) — DNS monitoring, DoH detection, exfil correlation
- E5 crypto config — Deployed, validates with
sshd -t - F5 authorized_keys —
restrict,pty,command=enforced
What's Waiting on the sshd Fix
- A6 session reaper — Script and plist ready, no sessions to reap
- PF firewall rule — No port to protect until sshd works
- E5 live verification — Can't test cipher negotiation without connections
- UX toggle — Designed, awaiting working transport
What This Means for You
If you are running any custom SSH service on macOS — whether it is a development server, a remote management tool, or a security gate — you should assume that macOS has no awareness of it. The Remote Login toggle in System Settings controls only the system sshd on port 22. Everything else is invisible.
The most dangerous security assumption is the one that feels obvious. "I turned off SSH" feels definitive. On macOS, it might only be half true.
• Audit your LaunchDaemons for any custom sshd instances:
sudo launchctl list | grep ssh• Check for listeners on non-standard ports:
sudo lsof -iTCP -sTCP:LISTEN -P | grep ssh• If you find custom SSH ports, add explicit PF firewall rules to restrict source IPs
• Harden sshd configs: disable password auth, set session limits, restrict forwarding
• If on macOS Tahoe: test that SSH actually works — the sshd-session bug may affect you
• Consider Homebrew OpenSSH as a workaround until Apple patches the socket inheritance issue
We are publishing this because security findings have more value when shared. The port 2222 independence issue is not a macOS vulnerability — it is an architectural behavior. But it is one that creates a false sense of security, and that makes it worth documenting.
If you assume disabling Remote Login closes all SSH access on your Mac, verify that assumption today.