On computers that are exposed to the internet, hackers are constantly trying to guess passwords for common usernames. The easiest way to do this for a hacker is to first figure out what type of system you’ve got online, then go through a list of known usernames and the corresponding default passwords. That is the basics, though, and the techniques used are getting more and more refined.

Don’t use passwords, use ssh keys. At least until the day when it is obvious that the private/public key scheme is broken, but we are not there yet.

Owned

I remember an incident some years ago, when I had a fileshare on my test box at home, where I wanted to share data to my X-box (yes, many years ago) and I set up a Samba-user, which required me to also create a linux user. Out of convenience I did so, created a user “xbox” with the fancy password “xbox”. I can’t say that was the most clever thing I had done in a long while.

It took only a couple of days before someone in Romania had passed by my box and guessed the right password. I figured it out by pure chance, disabled the account and reinstalled my system. This happens all the time, just look in your /var/log/auth.log file, and you will see quite a lot of break-in attempts.

Example (on my Ubuntu box):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
MYUSER@MYHOSTNAME:/var/log$ sudo tail -10000 /var/log/auth.log | grep -E "sales|php|mysql" | grep "Failed"
Jan 30 15:35:28 MYHOSTNAME sshd[22370]: Failed password for invalid user mysql from 203.130.49.10 port 38333 ssh2
Jan 30 15:35:34 MYHOSTNAME sshd[22381]: Failed password for invalid user mysql from 203.130.49.10 port 39204 ssh2
Jan 30 15:41:27 MYHOSTNAME sshd[23533]: Failed password for invalid user mysql from 203.130.49.10 port 48675 ssh2
Jan 30 15:41:35 MYHOSTNAME sshd[23535]: Failed password for invalid user mysql from 203.130.49.10 port 49507 ssh2
Jan 30 15:41:42 MYHOSTNAME sshd[23539]: Failed password for invalid user mysql from 203.130.49.10 port 50411 ssh2
Jan 30 16:35:09 MYHOSTNAME sshd[3051]: Failed password for invalid user sales from 203.130.49.10 port 54920 ssh2
Jan 30 16:35:21 MYHOSTNAME sshd[3053]: Failed password for invalid user sales from 203.130.49.10 port 56226 ssh2
Jan 30 16:35:28 MYHOSTNAME sshd[3055]: Failed password for invalid user sales from 203.130.49.10 port 57014 ssh2
Jan 30 17:27:43 MYHOSTNAME sshd[14408]: Failed password for invalid user mysql from 203.130.49.10 port 53484 ssh2
Jan 30 17:27:51 MYHOSTNAME sshd[14410]: Failed password for invalid user sales from 203.130.49.10 port 54622 ssh2
Jan 30 17:28:04 MYHOSTNAME sshd[14412]: Failed password for invalid user sales from 203.130.49.10 port 55982 ssh2
Jan 30 17:43:41 MYHOSTNAME sshd[17905]: Failed password for invalid user php from 203.130.49.10 port 43304 ssh2
Jan 30 17:43:56 MYHOSTNAME sshd[17909]: Failed password for invalid user phpbb from 203.130.49.10 port 44942 ssh2
Jan 30 17:44:09 MYHOSTNAME sshd[17921]: Failed password for invalid user phpBB from 203.130.49.10 port 46286 ssh2
Jan 30 17:44:22 MYHOSTNAME sshd[17932]: Failed password for invalid user phpbb2 from 203.130.49.10 port 47606 ssh2

This is just some random user names I picked from my head. In your log file you will have a good list of attempts (which could be used to discuss the name of your next child if you lack the imagination to come up with your own). In my current log file I could count over 4000 different user names used by someone to try and log in.

1
2
MYUSER@MYHOSTNAME:/var/log$ sudo cat auth.log | cut -d" " -f 11 | sort -u |wc -l
4114

So, what could I have done? Well, using a harder to guess password is one thing, but far from optimal. Nobody really needs a password. Not even a hard to guess password. I usually say “use the key, Luke, use the key”; meaning ssh-keys. As long as you keep your keys safe, you are the only one who can log in (until someone figures out a way to hack that too). But that is not always enough.

If your name is apache, of course you should be allowed to use that as a username.

I mean, a user that is called “oracle”, “apache”, “mysql”, or whatever user name that does not belong to a person, should never even be able to log in. There are also rare cases where you might actually want to have a password set.

The secret here is to lock the user by giving it “/bin/false” as the login shell. In your /etc/password file you have plenty of examples:

1
2
3
4
5
MYUSER@MYHOSTNAME:/var/log$ cat /etc/passwd | grep false
syslog:x:101:103::/home/syslog:/bin/false
messagebus:x:102:105::/var/run/dbus:/bin/false
whoopsie:x:103:106::/nonexistent:/bin/false
...

Making sure that your non-human users has “/bin/false” as their login shell will ensure that nobody can log into your system per ssh. It will also disable the possibility to do a simple “sudo su – USERNAME”.

– But! (someone will say) What if I really need to switch to that user and do some interactive work?

Well, dont. You can do more or less anything with a proper sudo setup. Given an environment where you have locked in a user called “dummy”:

1
2
MYUSER@MYHOSTNAME:/tmp$ grep dummy /etc/passwd
dummy:x:10001:10001:dummy,,,:/:/bin/false

“sudo -u dummy vi your.file” construct will allow you to edit a file as the user “dummy”. And… if you really, really need to work interactively as that user, you can use…

1
sudo su -s /bin/bash - dummy

The “-s” parameter for the “su” command will start that command as the interactive shell.

For those of you with some mileage under your belt: cron

Cron on a decently modern box _will_ run your crontab even if you don’t have a proper login shell.

1
2
3
4
5
6
MYUSER@MYHOSTNAME:/var/log $grep dummy /etc/passwd
dummy:x:10001:10001:dummy,,,:/:/bin/false
MYUSER@MYHOSTNAME:/var/log $sudo crontab -u dummy -l | grep -v "#"
*/1 * * * * echo test >> /tmp/test.file 2>&1
MYUSER@MYHOSTNAME:/var/log $ls -la /tmp/test.file
-rw-r--r-- 1 dummy 10001 10 Jan 30 18:17 /tmp/test.file

There is not much more to it. Lock your anonymous users, and enjoy your increased security.