I try to maintain a reasonably secure webserver.
A webserver is a computer, connected to the public internet, that does things (serves pages, etc.) whenever anyone asks it to. This makes it an easy thing to attack: the first step toward attacking a computer is usually getting it to do your bidding, and a webserver does your bidding every time you click a link.
My system logs show that I get attacked several times a day, like (I imagine) most computers on the Internet. Fortunately, most attacks bounce off — not because I have some magic security-foo, but rather because the software I’m using — specifically publicfile — doesn’t work the way the attackers expect it to.
While I am not so naive or foolish as to say that my server is “secure” — I’m sure it has some exploitable hole, and it runs in a distant facility that probably forgets to lock the doors sometimes — these attacks are of mostly academic interest.
Here’s some data I’ve collected from the past month or so of attacks. I figure this might help someone else detect or prevent an attack in the future.
Interesting HTTP Requests
I monitor all requests for nonexistent pages (404s) on my server. Here are a list of URLs I’ve seen accessed that appear to indicate a casual attack, listed from most common to least.
Notice that the first four aren’t even trying to reach
someone in Brazil has wildly misconfigured their DNS, or this is a virtual host
enumeration attack — where someone is trying to discover what other services
are hosted by a particular server.
The next is fascinating. Look at that big scary URL filled with wildcard characters! That’s the sort of thing that might overflow a buffer, don’t you think?
The rest are relatively boring: attempts to access PHP-based admin consoles. This is exactly the reason why I don’t run scripts — PHP, Ruby, or otherwise — in response to web fetches; bugs in such scripts are a frustratingly common way to break into servers.
If at all possible, don’t run scripts in response to HTTP requests. Obviously sometimes you must (e.g. to search a database), but keep this to a minimum.
Don’t use web admin consoles on your public webserver. Don’t rely on the admin console software to do authentication — use client certificates or HTTP-level authentication over HTTPS.
Use a webserver that is believed to be free of buffer-overflow exploits.
SSH Cracking Attempts
I’ve had repeated, presumably automated, attempts to log into the server using SSH. The usernames are interesting, but there are a lot of them. I’ve posted the complete frequency breakdown on a separate page. Here’s the top of the distribution — all names that were tried at least 100 times.
Over the past month(ish), my server has been attacked 28,889 times using this
method. Over half were attempts to login as
In reviewing the full list, these fall into a few distinct categories.
- Daemon Users. These are the accounts used, not by humans, but by server
wwwall appear in the top 10.
- Common Given Names. Like
donald. In a nice nod to cultural and gender diversity, we also see
zhaowei. The attack seems to be context-free, because there are no variations of either my domain name (
cliffle) or my handle (
- Default Accounts. These accounts may be created during operating system
installation, and often come with a default password.
ubuntuare some examples.
- Funny Names.
- IP Addresses. This is a little weird. If you open the full list and scroll to the end, you’ll see several attempts to login using IP addresses. The thing is, these aren’t my IP address — they’re not even in the same network. Curious.
Consider disabling password authentication on your SSH server entirely — requiring all users to log in using public keys or other authentication methods (such as OTP). I’ve never seen an attack bot try to use anything other than passwords, so this is an easy way to defend against the most common attacks.
Also consider moving the SSH server to a non-standard port. This will give you a bit of obscurity and will fool the simplest of attacks. Fortunately, the most common attacks are the simplest.
Many tutorials suggest binding SSH to a port above 1024. This is not a great idea, because it makes it easier for an attacker to replace your SSH server with a zombie. If the attacker can compromise an unprivileged account, and figure out how to crash — even for an instant — your SSH server, she can bind to the port while the server is down and start collecting all SSH traffic. Ports below 1024 are (by default on Unix) only available to privileged users. Ensure that your SSH server isn’t configured to do anything dumb. Do not trust your operating system vendor to do this for you. Here are some OpenSSH settings that I suggest.
|PermitRootLogin no||No ||NO|
|AllowUsers [list]||Whitelist users||NO|
|AllowGroups [list]||Whitelist groups||NO|
|Protocol 2||Don’t use old protocol||yes|
|UsePrivilegeSeparation yes||Protect against auth exploits||yes|
|StrictModes yes||Prevent login script clobbering||yes|
I recognize that disabling root login over ssh is somewhat controversial. (I’ve
seen at least one post calling it “h*****t”, which I can only assume is some
sort of exponentiation operator I don’t recognize.) I’m recommending it here
root is an incredibly common target for attacks.
As always, disable all SSH protocol options you don’t need.