Securing your Linux box (part 2)
Last
month I talked a bit about securing your machine by commenting out and
eliminating various services. This time around, I'm gonna go through a
couple of proggies and rules that you might want to apply to your machine
in order to lock it down a little more. I'm assuming that the machine
you are going to use is a main machine through which other machines on
your internal LAN use to connect to the Internet. For this article, I'm
using my own home-network as an example, so some of what I might mention
here need not apply to you. I recommend surfing the net and reading up
on any of the tools I'll be mentioning. Alright... enough cock-talk...
lets get to it.
Lets
assume that the machine you're going to be setting up is going to act
as a network management server, here are a few programs that you need
to installed:
1.)
ipfwadm (if you're using kernel 2.0.x. This comes with RedHat 5.x and
most other kernel 2.0.x based linux distributions)
2.)
ipchains (if you're using kernel 2.2.x. This comes with RedHat 6.0, and
most other 2.2.x based linux distributions. As a side note, I would strongly
recommend compiling a fairly new version of kernel 2.2.x, even on your
RedHat 5.2 installation. If you don't know how to do this, just stick
with RedHat's default kernel.
3.)
tcp-wrappers (also known as inetd. This allows us to restrict incoming
access from remote networks). Comes with most distributions. You may take
a serious look at a package called xinetd, as well. It has quite a few
very tasty features (ident lookups on all connections, all in all pretty
good stuff :) etc)
4.) Secure Shell 2.x, which will allow you to make secure connections
to the host system from outside, if you must do so. If you're somewhere
else on the Internet (I.E. at work) and you want access to to your home
network, You will have to make a connection to the host system before
you have access to any other system on your network. I would recommend
further reading of a how to with regards to setting your modem for dial-in
access (a good place to find how-tos would be www.linux.com,
look under the Support section.)
5.)
Some sniffers and analysis tools are nice to have, for troubleshooting
the network. I recommend tcpdump (comes with many distributions) and iptrap
(available all over the web, check around)
6.) Kernel must be compiled with IP Forwarding enabled, masquerade enabled,
etc. I'm not going to quite get into setting up masquerading in the kernel.
Read the IP-Masquerade mini-HOWTO, which is flawless at describing the
basics of setting up masquerade stuff. We'll get around to some changes
you'll make to the examples in a bit.
7.)
I have used the "Deception Finger Daemon" on my home server as it generates
false user reports to people who attempt to finger your system to see
what users are logged on or exist on your network. But I stopped using
it as I prefer not to run fingerd at all. It just isn't worth the possible
risk. If you really must have a finger connection running, "dfingerd"
would make an excellent choice with it's ability to generate syslog entries,
so that you know when you're someone's taking a peek at you as well as
it's fairly easy install, and comprehensive documentation.
Lockdown!
Now
to secure the server... The server is your golden goose. The rest of your
machines are hidden from view from the outside world, and your server
is the only machine that can be seen both by your side of the network
and the rest of the world (Via the Internet connection).
Once your server has been compromised, anyone who knows what they are
doing, will see all your other machines, and potentially attack them,
using your own server's recources! The intruder has the potential to figure
out all the passwords that your users use, they could possibly erase all
the files on open file shares, and maybe even abuse your paper and toner/ink
supply on connected network printers. That's an insult.
The
first thing we're going to do is lock down your open ports with tcp-wrappers. inetd is the tcp-wrapper program that checks for authorization to use
a service. Not all of your services run through inetd (mostly sendmail,
httpd, and secure shell). Inetd protects services such as telnet, finger,
shell, login, auth, etc. When someone attempts to use any of these services,
inetd checks /etc/hosts.allow and /etc/hosts.deny (respectively) for a
line containing an inclusion for the service name (either the daemon executable
name such as "in.telnetd", or "in.fingerd". "ALL" includes all service
names).
My
home server's hosts.allow file allows all the workstations behind the
masquerade to access my hosts full potential, but locks the rest of the
internet out, except for dfingerd, that fake finger daemon I was talking
about earlier.
ALL
: 192.168.1.0/255.255.255.0 dfingerd : ALL
As
soon as anyone connects to my machine, say with telnet, it checks hosts.allow
to see if they have been granted access. If they're on the Internet (not
on my intra-net), they aren't on this list, so it checks to see if they
have been disallowed in hosts.deny. My hosts.deny file is simple: ALL
: ALL This makes sure that only things granted in hosts.allow will make
it to my system. Note that the deny ALL doesn't cover ssh, so I can still
get back in over an encrypted connection if I know my IP address and have
a user/password.
Also
notice if any remote machine tries to use dfingerd, they will be allowed,
because inetd doesn't check hosts.deny if there is a rule in hosts.allow
that applies to that connection. If you're really in for security, I would
advise trying to setup xinetd, which will attempt to find the username of the person who is connecting to the port by making use of their local
machine's ident service (if available, which it is on most UNIXes and
if they have mIRC running at the time, too). It's a little more difficult
to set up, but it still uses the hosts.[allow|deny] convention.
Remember,
anything that starts up outside of "inetd" is not protected by this modification,
so don't put all your hope on it. Some daemons will try to read the hosts.allow/deny
files as well, so there are a few exceptions.
In general, you will want to keep things as closed up as possible, allowing
telnet and ftp from machines on your private Intra-Net. Also, TCP-Wrappers
are all considerably more open to attacks involving spoofed packets, and
it may be possible for someone to make a packet with a source address
of one of your trusted machines, but coming from the outside world.
Since
TCP Wrappers only has support for IP Address restrictions, they can't
tell if the traffic is coming in from your network card on the trusted
side of the firewall, or from a machine on the other end of the ppp connection
through the modem link. This is where packet filters (such as ipfwadm
and ipchains) come in.
Ipchains
and ipfwadm are not the actual filters; but they are programs that control
parts of the running kernel. They tell the kernel what kinds of packets
you wish to let through, and what kinds of packets you wish to deny. Since
filtering takes place at the kernel level, the filtering can potentially
use any aspect of the networking structure to describe what packets to
look for. This means that you can specify not only what addresses to allow
or deny, but also what individual protocols, network interfaces, and many
more things.
This
also means that you can manipulate the kernel into "repeating" or "routing"
traffic between interfaces, allowing you to force the kernel into being
a makeshift router for your home or small business' network. It looks
for traffic that's not meant for any of the local machines, and tries
to push it out over the modem link. If the connection is successful, one
of your networked machines suddenly can access stuff THROUGH the server.
Then, even more machines can do it at the same time, too. You could have
as many connections as you wanted over one modem link (of course after
3 or 4 connections going at once, the link would become very slow). (For
more information on sharing an Internet connection (dial-up) within your
LAN, read my "Setting
up mserver" article)
The
Linux community calls this routing procedure "Masquerading". The *BSD
community calls this "Network Address Translation". Now, we need to use
either ipfwadm or ipchains (Depending on your kernel) to add masqerade
rules. Some people say to add a general policy to masquerade, and that's
bad, because it would allow all sorts of evil stuff to happen, including
maybe someone being able to hide themselves behind your masqerade and
access all of your network resources without authorization. This is also
known as "The Bad Thing".
Also,
I prefer to add masqerade rules on a per-machine basis (as in, one ipfwadm/ipchains
line that tells the kernel to forward packets from workstation 1, workstation
2, etc... instead of telling it to forward from all hosts in 192.168.1.x.
That's
kind of my personal preference, but it's how I would suggest doing things. Ipfwadm or IPChains rules may be typed in at any time, but I would suggest
putting the commands into your /etc/rc.d/rc.local file, which is the closest
equivalent to an "autoexec.bat" for Linux.
If you're using IPChains on your Host Machine (with RedHat 6 or any other
kernel 2.2.x based Linux system), this example should give your machines
with IP Addresses 192.168.168.2 and 192.168.168.8 access to the internet
when you're connected. Just add more "ipchains -A forward -s ..." lines
to /etc/rc.d/rc.local and change the IP Addresses for each machine you
need on the Internet.
ipchains
-P forward DENY
ipchains
-A forward -s 192.168.1.2/32 -j MASQ
ipchains
-A forward -s 192.168.1.8/32 -j MASQ
If
using ipfwadm (as in with RedHat 5.x, or any kernel 2.0.x based linux),
the equivalent to the above ipchains commands, using ipfwadm is:
ipfwadm
-F -p deny
ipfwadm
-F -a m -S 192.168.1.2/32 -D 0.0.0.0/0
ipfwadm
-F -a m -S 192.168.1.8/32 -D 0.0.0.0/0
Again,
these should just go at the end of /etc/rc.d/rc.local, and you can just
add another "ipfwadm -F -a m -S ..." line for each ip you want to forward.
You'll also want to add modules for forwarding "interesting" traffic, where applicable. Strange protocols such as irc, cuseeme, and ftp do not
like masquerading very much.
A
few kernel modules make the masquerade a little more friendly for these
protocols. I just placed lines in rc.local again, using modprobe for the
various modules. These are masq modules from the 2.2.5 kernel. I did not
actually insert all of these modules. The title of them is fairly self-explanatory:
modprobe
ip_masq_autofw.o
modprobe
ip_masq_cuseeme.o
modprobe
ip_masq_ftp.o
modprobe
ip_masq_irc.o
modprobe
ip_masq_mfw.o
modprobe
ip_masq_portfw.o
modprobe
ip_masq_quake.o
modprobe
ip_masq_raudio.o
modprobe
ip_masq_user.o
modprobe
ip_masq_vdolive.o
Advanced firewalling
Sometimes
hosts.allow and hosts.deny just don't cut it. For instance, you already
know it usually only covers stuff that runs through tcp-wrappers. Also,
if someone port-scans your home server, or any linux machine you're running,
even though hosts.deny says not to allow them a connection, they still
see an open port. ipchains and ipfwadm can eliminate the "look" of open
ports on your machine, as well as locking it down even further, as it
just blocks ports.
This
means that any other ports left un-protected by tcp-wrappers (such as
SSH and Sendmail), can be protected as well. Here is a little quick-help
guide to ipchains and ipfwadm I put together a while back. While yer messin
with these rules, I suggest you port-scan the machine you're enforcing
the rules on, to see how they would look from an outside attacker.
The
example that describes denying port to all hosts except the local network
will probably be the most useful for you, just put multiple instances
of ipchains or ipfwadm into rc.local, and change "23" to some other port
that you want to lock down.
The
first step is to scan your box with nmap from any other workstation. My
personal favourite is nmap. Once I had the list of the open ports, there
are the ipchain rules that I entered :
ipchains -A input -p tcp -d 0/0 21 -s ! 192.168.168.1/255.255.255.0 -j
DENY
ipchains -A input -p tcp -d 0/0 23 -s ! 192.168.168.1/255.255.255.0 -j DENY
ipchains -A input -p tcp -d 0/0 79 -s ! 192.168.168.1/255.255.255.0 -j
DENY
ipchains -A input -p tcp -d 0/0 113 -s ! 192.168.168.1/255.255.255.0 -j
DENY
ipchains -A input -p tcp -d 0/0 139 -s ! 192.168.168.1/255.255.255.0 -j
DENY
Examples
of uses:
Deny
port 23 (telnet) from all hosts not on the 192.168.168.xxx network:
ipchains
-A input -p tcp -d 0/0 23 -s ! 192.168.1.0/255.255.255.0 -j DENY
ipfwadm -A in -P tcp -D 0/0 23 -S ! 192.168.1.0/255.255.255.0 -a deny
Make
machine stop responding to ping packets:
ipchains
-A input -p icmp -s 0/0 echo-request -j DENY
ipchains -A input -P icmp -S 0/0 echo-request -a deny
Deny ports 19-23 from the entire 202.160.8.xxx subnet:
ipchains
-A input -p tcp -s 202.160.8.0/255.255.255.0 -d 0/0 19:23 -j DENY
ipfwadm
-A in -P tcp -S 202.160.8.0/255.255.255.0 -D 0/0 19:23 -a deny
Deny all incoming tcp to port 23 if it's coming over interface "ppp0"
ipchains
-A input -p tcp -D 0/0 23 -I ppp0 -j DENY
ipfwadm -A in -P tcp -D 0/0 23 -W ppp0 -a deny
For
the complete list of firewalling rules, I would recommend reading the
ipchains and ipfawdm HOW-TOs located on www.linux.com
(look under Support)
Well
that's about it then. If you have any questions about Linux/*NIX and security,
please send me an e-mail and I shall try to the best of my abilities to
answer your question.
Peace.
-
L33tdawg
1.)
Setting
up mserver -
L33tdawg
2.)
Lockdown
: Securing your Linux box (part 2) -
L33tdawg
3.)
Distributed
Information Gathering -
hybrid
4.)
Aureate's
watching you... -
OB-1
5.)
MPAA's
Letter to 2600.org.au -
2600.org.au
6.)
Hackmount
attack -
r00t