Changing the Default SSH Port on Mac OS X Server

Photo of Greg
Photo by MyNameMattersNot - http://flic.kr/p/4LeKxH

If you’ve had your server switched on for more than a day or two in a major colocation facility, it’s probably already been targeted by automated attacks via SSH. Changing the port number for SSH will eliminate the set of attacks which always look for the standard port 22.

In addition to enabling the packet filter and adaptive firewall (“Mac OS X Packet Filter and Adaptive Firewall”), you can also cut down on the number of automated brute force attacks against your machine through SSH either by shutting off remote login altogether, which may be inconvenient for administrators, or by moving all SSH traffic to a different port. Note that the latter does nothing to make it harder to break in via SSH, but what it does do is cut out a potentially vast number of automated attacks which simply assume that port 22 is the port to hit.

You can move the port in just a few steps. Start by adding a new service to /etc/services, where you should find these lines already in the list:

#	Jon Postel <postel@isi.edu>
ssh	22/udp # SSH Remote Login Protocol
ssh	22/tcp # SSH Remote Login Protocol
#	Tatu Ylonen <ylo@cs.hut.fi>

Edit the file as root, and copy the ssh lines to the bottom of the file, but change the port number 22 to something else chosen from the list of unassigned ports, and created a new name for your SSH service, so it’s like so:

sshcustomname	12345/udp # SSH Remote Login Protocol
sshcustomname	12345/tcp # SSH Remote Login Protocol

Now you can grab a copy of Apple’s default ssh plist and pop it into /Library/LaunchDaemons:

cp /System/Library/LaunchDaemons/ssh.plist /Library/LaunchDaemons/ssh_your_custom_name.plist

If you open up that copy, you can change the label to match your plist:

<key>Label</key>
<String>ssh_your_custom_name</string>

You can also prevent Bonjour from advertising your new service by deleting these lines:

<key>Bonjour</key>
<array>
	<string>ssh</string>
	<string>sftp-ssh</string>
</array>

Finally, specify the service name so it matches what you added to /etc/services by editing what remains under ‘Sockets’ like so:

<key>Sockets</key>
<dict>
	<key>Listeners</key>
	<dict>
		<key>SockServiceName</key>
		<string>sshcustomname</string>
	</dict>
</dict>

We’re nearly there! You can now load the plist for this new SSH service you’ve created with the usual launchctl:

sudo launchctl load -w /Library/LaunchDaemons/ssh_your_custom_name.plist

Without the -w or -F flag to force the load, you’ll receive an error message saying “nothing found to load”. This is due to the presence of the following at the top of your plist, which enables SSH to be loaded on demand, rather than running all the time:

<key>Disabled</key>
<true/>

Now it’s time to test the service by attempting to connect on the specified port:

ssh -p 12345 -l username example.com

If all is well, you can now shut off the original port 22 service either via launchctl or by unchecking the ‘Remote Login’ box on the Sharing preference pane.

Because this process has done nothing except define a new service on a previously unused port, plus add a plist to engage ssh to handle traffic on that port, everything else continues to work as normal. You can switch remote login on and off as you see fit, enabling or disabling SSH on port 22, and the entirely separate service defined by this procedure will work independently.

Quite a bit more can be done to strengthen your SSH service — such as editing the relevant configuration file to require certificates rather than passwords — but moving to a new port is a good first step to save your server from unnecessary brute force threats.

Once you’ve made the change of SSH port, you’ll need to update any software you already have configured to communicate over SSH — such as SequelPro on the client side or WordPress on the server side — to ensure it points to the new port.

For example, if you use WordPress and have enabled updates and upgrades over SSH, you’ll need to edit your wp-config.php file to specify the new port number rather than 22, with something like the following:

define('FTP_HOST','localhost:12345'); // default is port 22, but we're using custom ssh port

(For more details, I’ve put together a separate article on WordPress SSH upgrades; see “Enabling WordPress to Work with SSH2 Upgrades — Without Extravagant Permissions”.)

All material on this site is carefully reviewed, but its accuracy cannot be guaranteed, and some suggestions offered here might just be silly ideas. For best results, please do your own checking and verifying. This specific article was last reviewed or updated by Greg on .

This site is provided for informational and entertainment purposes only. It is not intended to provide advice of any kind.