Securing SSH with tcp wrappers

From Sfvlug

(Difference between revisions)
Line 5: Line 5:
To configure <tt>tcp_wrappers</tt>, start with a policy that denies everything by default.
To configure <tt>tcp_wrappers</tt>, start with a policy that denies everything by default.
-
<tt>/etc/hosts.deny</tt>
+
==/etc/hosts.deny==
<pre>
<pre>
Line 13: Line 13:
By setting up a default deny policy in this way, you move all important processing instructions to the <tt>/etc/hosts.allow</tt> file.  It is possible to add deny rules to <tt>hosts.allow</tt> by ending a line with an additional colon and the <tt>DENY</tt> command.  I start by allowing access to localhost and my LAN.  Notice, IPv4 networks must be specified with the full netmask, but IPv6 networks must be designated with CIDR notation.
By setting up a default deny policy in this way, you move all important processing instructions to the <tt>/etc/hosts.allow</tt> file.  It is possible to add deny rules to <tt>hosts.allow</tt> by ending a line with an additional colon and the <tt>DENY</tt> command.  I start by allowing access to localhost and my LAN.  Notice, IPv4 networks must be specified with the full netmask, but IPv6 networks must be designated with CIDR notation.
-
<tt>/etc/hosts.allow</tt>
+
==/etc/hosts.allow==
<pre>
<pre>
Line 25: Line 25:
I have included two rules to govern sshd specifically.  The first denies any address listed in <tt>/etc/hosts.deny.sshd</tt>.  The second only allows addresses listed in <tt>/etc/hosts.allow.sshd</tt>.  The unspoken final rule is in <tt>hosts.deny</tt>, anything that hasn't matched so far will be denied.  The allow line also shows an example of launching a command when the rule is triggered.
I have included two rules to govern sshd specifically.  The first denies any address listed in <tt>/etc/hosts.deny.sshd</tt>.  The second only allows addresses listed in <tt>/etc/hosts.allow.sshd</tt>.  The unspoken final rule is in <tt>hosts.deny</tt>, anything that hasn't matched so far will be denied.  The allow line also shows an example of launching a command when the rule is triggered.
-
<tt>/etc/hosts.allow.sshd</tt>
+
==/etc/hosts.allow.sshd==
I live in the United States.  I work in the United States.  I have never left the United States without knowing it was going to happen at least days in advance.  So the likelihood of finding myself outside my country's borders and suddenly needing to SSH into my server at home is as close to nil as I can imagine.  But, I do travel several times a year within my country's borders, and I don't know what IP I might be coming from.  So within this file, I have listed all the IPs which are assigned inside the US.
I live in the United States.  I work in the United States.  I have never left the United States without knowing it was going to happen at least days in advance.  So the likelihood of finding myself outside my country's borders and suddenly needing to SSH into my server at home is as close to nil as I can imagine.  But, I do travel several times a year within my country's borders, and I don't know what IP I might be coming from.  So within this file, I have listed all the IPs which are assigned inside the US.

Revision as of 08:03, 2 September 2009

Just about everything on a modern Linux distro these days has tcp_wrappers support compiled in. I'll start with some basics on tcp_wrappers configuration. You should definitely also read the hosts_access(5) and hosts_options(5) man pages.

The basic flow of tcp_wrappers is, anything listed in /etc/hosts.allow is allowed. If it isn't found there, processing moves on to /etc/hosts.deny and anything found there is denied. Finally, anything not in either is simply allowed.

To configure tcp_wrappers, start with a policy that denies everything by default.

/etc/hosts.deny

ALL: ALL

By setting up a default deny policy in this way, you move all important processing instructions to the /etc/hosts.allow file. It is possible to add deny rules to hosts.allow by ending a line with an additional colon and the DENY command. I start by allowing access to localhost and my LAN. Notice, IPv4 networks must be specified with the full netmask, but IPv6 networks must be designated with CIDR notation.

/etc/hosts.allow

ALL: localhost 127.0.0.1 ::1
ALL: 192.168.1.0/255.255.255.0 [fe80::]/4

sshd: /etc/hosts.deny.sshd : DENY
sshd: /etc/hosts.allow.sshd : spawn ( denyhosts )

I have included two rules to govern sshd specifically. The first denies any address listed in /etc/hosts.deny.sshd. The second only allows addresses listed in /etc/hosts.allow.sshd. The unspoken final rule is in hosts.deny, anything that hasn't matched so far will be denied. The allow line also shows an example of launching a command when the rule is triggered.

/etc/hosts.allow.sshd

I live in the United States. I work in the United States. I have never left the United States without knowing it was going to happen at least days in advance. So the likelihood of finding myself outside my country's borders and suddenly needing to SSH into my server at home is as close to nil as I can imagine. But, I do travel several times a year within my country's borders, and I don't know what IP I might be coming from. So within this file, I have listed all the IPs which are assigned inside the US.

How do you get this kind of information? I don't know how the people I got it from compiled their list, but there are a few sources on the Internet. I used to get this from a site which seems not to be in service any longer, blackholes.us. A few more sites have stepped up to fill the niche. Currently, I'm using [[1]]. There are other sites that offer this information as well, like [[2]]. If you search for "country by IP address," you will find more.

The files downloaded from countries.nerd.dk are in a format for a particular DNS server. I had to convert them to address/netmask format, one per line. Note that the version of ipcalc I have returns values for use in shell scripts; if I give the command ipcalc -m 10.0.0.0/8 its output is NETMASK=255.0.0.0.

awk 'NR > 1 {print $1}' us.countries.nerd.dk.rbldnsd | while read LINE ; do
eval `ipcalc -m $LINE`
echo ${LINE%%/*}/$NETMASK
done > /etc/hosts.allow.sshd
Personal tools