Musings on Network Security

As a sysadmin, I have always thought simplicity should be a key
guideline when securing Linux or Unix servers. That sounds rather
meaningless by itself, so an example is in order. Anyone who spends
time looking at the log files on an internet-facing server or
firewall will notice the almost constant barrage of SSH brute-force
attacks. SSH is indispensable as a remote administration tool, so it
is likely to be installed on every such Linux or Unix system. Some
admins like to install automatic analysis and blocking tools (e.g.,
fail2ban), but I dislike such tools because they are just another
way of "enumerating badness" [1]. So I secure SSH with a set of
simple changes:

* Move sshd to a random high port: Sure, this is security-through-
obscurity, but it is simple (a one-line change in the sshd config
file), and remarkably effective in avoiding the vast majority of
brute-force attacks. It is also part of a larger, layered security
effort.

* Disable password authentication and root login: A nice side-
effect of this is that you also get to disable PAM and challenge-
response authentication.

* Enable key-based authentication: Use keys with strong passphrases
and agents for convenience on the client side.

* Hash known hosts files so that IP addresses of target servers are
not displayed in the clear.

* Add a host-based firewall that allows SSH only from certain IP
addresses, or configure authorized_keys host and user restrictions.

* Render authorized_keys files immutable (Linux chattr +i).

Many admins balk at only allowing SSH from static IP addresses,
especially with the prevalence of 'pseudo-static' IP addresses
assigned to home cable or DSL modems. But it's not as limiting as
you may imagine. Cheap VPS (SDF [2], Linode or AWS) systems
routinely come with static IPs, and shell services like SDF offer
login servers with static IPs. Agent- forwarding [3] can help make
login through intermediate hosts convenient. If you must allow login
from anywhere, configure a default-drop firewall and use
single-packet authorization (SPA) [4] instead.

Each of these in isolation might not be very effective against a
determined attack. But taken together, they provide a very secure
environment for SSH. That doesn't preclude a server being
compromised through some other network-accessible application, but
with these changes SSH itself is quite secure. The idea, of course,
is to secure all of your internet facing applications in similar,
simple ways and if possible with a default-drop mindset. Web or
Internet applications meant for public consumption are the one
exception where default drop just isn't possible. Particularly in
those cases, I add outbound filtering to host-based firewall rules.
That way, if your shiny new wordpress install is ever compromised
(when, not if), you can at least contain the damage.

Speaking of disabling PAM authentication, this quote from Patrick
Volkerding, the creator of Slackware Linux is a great example of
choosing simplicity:

"If you see a security problem reported which depends on PAM, you
can be glad you run Slackware. I think a better name for PAM might
be SCAM, for Swiss Cheese Authentication Modules, and have never
felt that the small amount of convenience it provides is worth the
great loss of system security. We miss out on half a dozen security
problems a year by not using PAM, but you can always install it
yourself if you feel that you're missing out on the fun. (No, don't
do that)" [5]

It is notable that even today, PAM is not used in Slackware.

[1] http://www.ranum.com/security/computer_security/editorials/dumb/
[2] http://sdf.org
[3] http://unixwiz.net/techtips/ssh-agent-forwarding.html
[4] http://cypherdyne.org/fwknop
[5] ftp://ftp.slackware.com/pub/slackware/slackware-8.1/ChangeLog.txt