Feb 10 07:07:36 localhost sshd[1078]: Illegal user matt from 210.127.248.158
Feb 10 07:07:38 localhost sshd[1080]: Illegal user test from 210.127.248.158
Feb 10 07:07:40 sshd[1082]: Illegal user operator from 210.127.248.158
Feb 10 07:07:42 sshd[1084]: Illegal user wwwrun from 210.127.248.158
Feb 10 07:07:52 sshd[1096]: Illegal user apache from 210.127.248.158
Feb 10 07:07:59 sshd[1104]: Failed password for root from 210.127.248.158 port 58752 ssh2
Feb 10 07:08:01 sshd[1106]: Failed password for root from 210.127.248.158 port 59136 ssh2
Feb 10 07:08:03 sshd[1108]: Failed password for root from 210.127.248.158 port 59176 ssh2
Feb 10 07:08:15 sshd[1122]: Failed password for root from 210.127.248.158 port 60606 ssh2
....
These entries went on and on and on ... over 100 of them in a three minute time period this morning (notice them hitting the logs every two seconds)! So I loaded the entire system log, which goes back to January 24th. There were nearly 1,000 entries! So clearly, somewhere out there, there's an SSH brute-force exploit script (I run no real "servers" at home, just Remote Login and Personal Web Sharing, but that's blocked at my router). Just from reading the log files, it's pretty obvious that the script is trying common user names, and probably common passwords for the root account. Needless to say, this didn't make me feel very comfortable at all, even though my passwords are secure.
While OS X may not be vulnerable to viruses and malware, it's still quite vulnerable to external attacks from zombied machines running scripts such as this one. So I used the fact that my machine was being probed as an incentive to learn more about increasing the security of my Remote Login sessions. What I found out was that, though SSH is quite secure, there are some simple things you can do to make it even more secure (though there is a downside, as you'll see). Read the rest of the article to see how I hardened my Remote Login setup.
Disclaimer: I am not an expert at this stuff. I'm not even really an amateur. I read various sites, tested stuff, and it all seemed to work and do what I wanted it to do. Your mileage may vary, and I make no guarantees that these changes will 100% secure your Remote Login capabilities ... but I think they're a good start!
I was reasonably confident that my machine wouldn't fall to a username/password brute force attack (I have a secure password and a username that won't be in a standard "first name only" attack). However, the root login attempts concerned me more -- although I have a secure root password as well, I do have root enabled. A longgggg time ago, we ran a hint on how to Disable root access via SSH. At the time (10.0.1!), I had followed the hint and blocked root SSH logins. Somehwere between 10.0.1 and 10.3, including a machine migration, I lost it and had never put it back. This really should be disabled by default, but it's not ... so the first step to further securing Remote Login is to re-block root logins. The instructions in the original hint are still basically true, but somewhat non-detailed, so here's a step-by-step walkthrough.
Open the Terminal, and type cd /etc and press Return. The first thing to do is make a backup of the file we're going to modify, so type:
sudo cp sshd_config sshd_config.bak
Enter your password when prompted, and you'll have created a backup of the sshd_config file. This file contains the settings for the process (sshd) that runs the Remote Login service. The next step is to edit this file; pico is the friendliest editor for Terminal newcomers, as it has a nice menu at the bottom of the screen covering most of the basic functions. You'll need to have root privileges to edit the file, so type sudo pico sshd_config and press Return.
First, as long as you're in the file, find this line:
#Protocol 2,1
Remove the # at the beginning (it's a comment marker), and then remove the ,1 at the end. This will disable the SSH1 version of the SSH protocol -- it's my understanding that version one is less secure than version two (SSH2), so you might as well disable it (most newer operating systems will use SSH2 anyway). Next, find the line that reads:
#PermitRootLogin yes
(You can use Control-W and type Root to search for it.) Again, remove the #, and change yes to no. This will disable root login via SSH. That takes care of one potential hole. Save the file (Control-O, then press Return to confirm), and quit the editor. Open the Sharing panel in System Preferences, then stop and restart Remote Login to restart the sshd server. Presto, one hole closed.
The next thing I did is somewhat more complex. One feature of SSH allows password-free logins. Although this sounds insecure, it's actually a more secure way of making a remote connection, as only machines which have previously given a piece of information to the server will be allowed to connect. The piece of information is called a public key, and it's specific to the machine that generated it. In addition to the public key, your machine (the one that's connecting to the server) has its own private key, which is not shared. The private key generates something called a signature, which can then be paired with your public key to prove you are who you say you are -- only your private key can generate that particular signature. So in essence, when you connect, the server says "Ah, I have your public key. Please send me your signature." Your machine does so, and the server then compares them -- if the signature "checks" agains the public key that it knows, you're confirmed. (Note to technical types: this is my best explanation of the process, and it's probably wrong at some level. Please feel free to clarify.)
So by setting up public key authentication for Remote Login, you can actually create a more secure connection method than passwords -- as there are no passwords to guess, and nobody can fake your signature. The downside is that setting this up is a bit of a pain, as you have to create the public key, and then get it to the machine you wish to connect to. I wrote up a very detailed hint a while back that explained the process. (You can ignore the SSH1 instructions in that hint, assuming you're disabling SSH1 anyway as shown above.) Also read the comments to the hint that discuss some of the security implications -- using my method (no passphrase required), if your machine gets out of your hands, whomever has it will be able to connect to your SSH hosts without any passwords. This hint explains a way to tie this all in to a Keychain password, for some added security.
OK, so you're still here ... the last step in the securing of Remote Login is also the one with the biggest downside. Just because you've enabled public key authorization doesn't mean you've disabled password authorization. In fact, you haven't. You can still easily login with your username and password from any other machine that uses SSH. So the final step is to completely disable password-based Remote Login access. The downside of this is that you will only be able to connect from machines that have previously provided their public keys to the server. This is fine if you're always traveling with your laptop. It's not so great if you've got to use a lab of public machines, or you're renting some computer time in an airport, etc. Personally, I was willing to give up this flexibility for a bit of added security, but you'll have to make this decision for yourself.
To disable password-based logins, re-edit the sshd_config file (using su, as before). This time, you're looking for two lines in one section of the file:
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
Change this section so it looks like this (only two lines changed):
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no
#PermitEmptyPasswords no
# Change to no to disable s/key passwords
ChallengeResponseAuthentication no
Save your changes, quit the editor, and restart Remote Login again. After making these changes, I then tried various SSH connections. First, I asked to connect as root:
$ ssh -l root 10.0.0.10
Permission denied (gssapi,publickey)
On the server (the machine I'm connecting to), the system log (edited for narrowness) showed this:
Feb 10 21:26 xinetd[397]: service ssh, IPV6_ADDRFORM setsockopt() failed:
Protocol not available (errno = 42)
Feb 10 21:26 xinetd[397]: START: ssh pid=1425 from=10.0.0.20
Next, I connected using the public key that I had set up on the server:
$ ssh -l robg 10.0.0.10
Last login: Thu Feb 10 21:15:14 2005 from 10.0.0.20
Welcome to Darwin!
[G5_box]$
Perfect again. The log this time showed this:
Feb 10 21:28 sshd[1427]: Accepted publickey for robg from 10.0.0.20 port 55555 ssh2
Finally, I went to another machine that has not yet shared its public key, and tried to connect:
$ ssh -l root 10.0.0.10
Permission denied (gssapi,publickey)
So I wasn't even allowed to try a password (which will kill the brute force script, since it sends the password after sending a username), and the system log showed the same entry as when I tried to connect as root. There's now no way this script can make a real connection to my machine. I gave up a bit of time (it took more time to write this hint than to modify sshd, actually), and a bit of convenience (as I can no longer use Remote Login from just anywhere). But I will now sleep much better, knowing my machine is safe from this particular script attack.

