Skip to content
macOSHow-To Published Updated 5 min readViews unavailable

Enabling and Hardening Remote Login (SSH) on macOS

Turning on macOS's built-in SSH server correctly, then hardening it beyond the default configuration with key-based authentication and restricted access.

macOS ships with a fully capable OpenSSH server built in, exposed through the “Remote Login” setting rather than requiring any separate installation — but the default configuration once enabled is intentionally permissive, and hardening it beyond the default is worth doing for any Mac you’re actually going to expose to remote SSH access regularly.

Enabling Remote Login

System Settings > General > Sharing > Remote Login

or, from the command line:

sudo systemsetup -setremotelogin on

Once enabled, the Mac accepts SSH connections on port 22 for any user account with login access, authenticated with that account’s regular password by default — which is the first thing worth changing.

Restricting which users can actually connect

The Sharing preference pane lets you restrict Remote Login access to specific user accounts (or groups) rather than leaving it open to every account on the machine, which is worth doing explicitly even on a single-user Mac, since it documents intent clearly rather than relying on there simply not being other accounts to worry about:

System Settings > General > Sharing > Remote Login > select specific users

Switching to key-based authentication

Password authentication over SSH is vulnerable to brute-force attempts against any exposed instance, and switching to public-key authentication removes that entire attack surface. Generate a key pair on the client machine you’ll be connecting from (not the Mac being configured):

ssh-keygen -t ed25519 -C "your-client-identifier"

Copy the public key to the Mac being configured for remote access:

ssh-copy-id username@mac-hostname

Disabling password authentication entirely

Once key-based login is confirmed working, disabling password authentication entirely closes off brute-force attempts against the SSH service completely:

# /etc/ssh/sshd_config.d/hardening.conf
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin no

macOS’s OpenSSH configuration supports drop-in files under /etc/ssh/sshd_config.d/, which is the cleaner way to apply overrides without editing the main sshd_config file directly — keeping your hardening changes isolated and easy to review or revert independently of Apple’s own shipped default configuration.

Restart the SSH service for changes to take effect:

sudo launchctl kickstart -k system/com.openssh.sshd

Changing the default port, if exposing this beyond a local network

If Remote Login needs to be reachable from outside your local network (via router port forwarding, for instance), changing the listening port away from the default 22 meaningfully reduces the volume of automated, opportunistic scanning traffic that constantly probes the default SSH port across the entire internet:

# /etc/ssh/sshd_config.d/hardening.conf
Port 2222

This isn’t a security boundary by itself (anyone doing a targeted, deliberate port scan will still find it), but it does substantially cut down on noise from automated, non-targeted scanning attempts, which is a meaningful practical benefit for reducing log noise and unnecessary connection attempts even if it’s not real security through obscurity.

Verifying the hardened configuration is actually in effect

sudo sshd -T | grep -E 'passwordauthentication|permitrootlogin|port'

sshd -T dumps the actual, fully-resolved effective configuration (after all drop-in files and defaults are combined), which is the reliable way to confirm your hardening changes actually took effect as intended, rather than assuming a config file’s presence alone guarantees its settings are active.

Why this is worth doing even for occasional, infrequent remote access

Even a Mac that’s only remotely accessed occasionally benefits from being hardened by default rather than only when actively expecting a connection — Remote Login, once enabled, remains listening continuously until explicitly disabled, and a machine’s actual usage pattern (frequent versus rare remote access) doesn’t change how continuously exposed the listening SSH service itself actually is to anything that can reach it on the network.

Confirming which specific TCC permissions SSH sessions actually inherit

A user connecting over SSH runs as that same macOS user account, but a non-GUI SSH session doesn’t automatically carry the same TCC privacy grants an interactive Terminal session might already have accumulated — accessing certain protected locations (Full Disk Access-gated paths, for instance) over an SSH session can behave differently than the identical command run locally in Terminal.app, specifically because TCC evaluates grants per requesting process, and sshd’s own spawned shell is a genuinely different process identity than Terminal.app. Granting Full Disk Access explicitly to /usr/sbin/sshd (rather than assuming a grant already made to Terminal.app covers SSH sessions too) is the fix when a script behaving correctly locally fails specifically when run the identical way over SSH.

Using SSH connection logging to see who’s actually connecting

log show --predicate 'process == "sshd"' --last 24h

For a Mac with Remote Login enabled and reachable from outside a trusted local network, periodically reviewing sshd’s own logged connection attempts — successful and failed alike — through the unified logging system gives visibility into actual usage and any concerning patterns (a burst of failed attempts from an unfamiliar address, for instance) rather than assuming the service is behaving as expected purely because you haven’t noticed a problem. This is a genuinely useful habit to build for any Mac with SSH exposed beyond a fully trusted local network, not just something to check reactively after already suspecting a problem.

Considering key-based access for multiple trusted machines

For a Mac you connect to regularly from more than one client device (a laptop and a separate desktop, for instance), adding each device’s own public key to the Mac’s ~/.ssh/authorized_keys file — rather than sharing a single private key across multiple machines — keeps each device’s access independently revocable. Losing one laptop, for instance, means removing just that one specific key from authorized_keys rather than needing to regenerate and redistribute a single shared key pair to every other trusted device that had been using the same one.

Related:

Sources:

Comments