By Kurt Seifried [email protected]
Introduction
Network security is a pretty broad topic, so I've broken it down into a
couple of sections. In this area I cover the bottom 4 or so layers (transport,
network, datalink, physical) of the 7 layer OSI protocol stack, the top 3
(application, presentation, session) are in the network server section and so
forth (roughly speaking). I also cover some of the basic network configuration
files, since an explanation is always useful.
Physical protocols
Physical protols such as PPP and Ethernet provide the foundation for TCP-IP.
Before you even begin to think about TCP-IP and network security it is good
to have a grasp of the protocols that sit beneath TCP-IP. The two most common
protocols most people will encounter are PPP, commonly used for dial-up access
and Ethernet, a mainstay of LAN's and the interface that you will see most often
on networking equipment like DSL modems and cable modems.
PPP security
PPP provides TCP-IP, IPX/SPX, and NetBEUI connections over serial lines
(which can, of course, be attached to modems, but can also be direct cable
connections or even done over Ethernet!). It is the primary method most people
use to connect to the Internet (virtually all dial-up accounts are PPP). A PPP
connection essentially consists of two computing devices (a computer, a Palm
Pilot, a terminal server, etc.) connected over a serial link (usually via
modems). Both ends invoke PPP, authentication is handled (by one of several
methods), and the link is brought up. PPP has no real support for encryption, so
if you require a secure link you must invest in some form of VPN software.
Most systems tended to invoke PPP in a rather kludgy way, you "log in" to the
equipment (terminal server, etc.) and then as your login shell PPP is invoked.
This of course means your username and password are sent in clear text over the
line and you must have an account on that piece of equipment. In this case PPP
does not handle the authentication at all. A somewhat safer method of handling
this is to use PAP (Password Authentication Protocol). With PAP the
authentication is handled internally by PPP, so you do not require a "real"
account on the server. However the username and password is still sent in clear
text, but at least the system is somewhat more secure due to the lack of "real"
user accounts.
The third (and best) method for authentication is to use CHAP (Challenge
Handshake Authentication Protocol). Both sides exchange public keys and use them
to encrypt data sent during the authentication sequence. Thus your username and
password are relatively safe from snooping, however actual data transfers are
sent normally. One caveat with CHAP: Microsoft's implementation uses DES instead
of MD5, making it slightly 'broken' if connecting with a Linux client. There are
patches available however to fix this. PPP ships with almost every Linux
distribution as a core part of the OS, the Linux PPP-HOWTO is available at: https://www.linuxdoc.org/HOWTO/PPP-HOWTO/index.html
TCP-IP security
TCP-IP was created in a time and place where security wasn't a very strong
concern. Initially the 'Internet' (then called Arpanet) consisted of very few
hosts, all were academic sites, big corporations or government in nature.
Everyone knew everyone else, and getting on the Internet was a pretty big deal.
The TCP-IP suite of protocol is remarkably robust (it hasn't failed horribly
yet), but unfortunately it has no real provisions for security (i.e.
authentication, verification, encryption and so on). Spoofing packets,
intercepting packets, reading data payloads, and so is remarkably easy in
today's Internet. The most common attacks are denial of service attacks since
they are the easiest to execute and the hardest to defeat, followed by packet
sniffing, port scanning, and other related activities.
Hostnames don't always point at the right IP addresses and IP addresses don't
always reverse lookup to the right hostname. Do not use hostname-based
authentication if possible. Because DNS cache poisoning is relatively easy,
relying on an IP address for authentication reduces the problem to one of
spoofing, which is somewhat more secure but by no means truly secure. There are
no mechanisms in wide spread use to verify who sent data and who is receiving it
except by use of session or IP level encryption (IPSec/IPv6 and other VPN
technologies are starting to gain momentum however).
You can start by denying inbound data that claims to originate from your
network(s), as this data is obviously spoofed. And to prevent your users, or
people who have broken into your network, from launching spoofed attacks you
should block all outbound data that is not from your IP addresses. This is
relatively simple and easy to manage but the vast majority of networks do not do
it (I spent about a year pestering my ISP before they started). If everyone on
the Internet had egress filters (that is restricted outbound traffic to that
which is from their internal IP addresses) spoofing attacks would be impossible,
and thus tracing attackers back to source would be far easier. You should also
block the reserved networks (127.*, 10.*, etc.). I have noticed many attacks
from the Internet with packets labeled as from those IP ranges. if you use
network address translation (like IPMASQ) and do not have it properly firewalled
you could be easily attacked or used to relay an attack to a third party.
If you must communicate securely with people, consider using VPN technology.
The only available technology that has wide acceptance and is slated to become a
the standard (in IPv6) is IPSec, it is an open standard supported by many
vendors and most major vendors have actual working implementations native to
their OS (although some are crippled to comply with US export laws). Please see
Appendix B or the Encrypting Services and Data section for more details.
IPSec
<a href="../vpn/index.html">IPSec is covered in it's own section. I
think it is the future of VPN technology (it's the most commonly supported
standard as of today, and an integral part of IPv6).
IPv6
IPv6 provides no security per se, but it does have built in hooks for future
security enhancements, IPSec support and so on. If used on a network it would of
course make life more difficult for an attacker as IPv6 use is not yet
widespread. If you want to learn more visit: https://www.bieringer.de/linux/IPv6/. Linux currently supports
IPv6 pretty much completely.
Attacking TCP-IP
TCP-IP was not built with security in mind and consequently suffers a wide
variety of problems that can be exploited by attackers. From hijacked
connections to spoofing and sending mangled packets, the limits are endless.
HUNT Project
The HUNT Project is a set of tools for manipulating TCP-IP connections
(typically on an Ethernet LAN), that is it can reset connections, spy on them
and do otherwise "naughty" things. It also includes a variety of ARP based
attacks and other mischievous sources of fun, You can get HUNT at: https://lin.fsid.cvut.cz/~kra/index.html
Basic config files and utilities
/etc/inetd.conf
inetd.conf is responsible for starting services, typically ones that do not
need to run continuously, or are session based (such as telnet, or ftpd). This
is because the overhead of running a service constantly (like telnet) would be
higher then the occasional start up cost (or firing in.telnetd up) when a user
wants to use it. For some services (like DNS) that service many quick
connections, the overhead of starting the service every few seconds would be
higher then constantly running it. Also with services such as DNS and email time
is critical, a few seconds delay starting an ftp session won't hurt much. The
man page for inetd.conf covers the basics ("man inetd.conf"). The service itself
is called inetd and is run at boot time, so you can easily stop/start/reload it
by manipulating the inetd process. Whenever you make changes to inetd.conf you
must restart inetd to make the changes effective, killall -1 inetd will restart
it properly. Lines in inetd.conf can be commented out with a # as usual (this is
a very simple and effective way of disabling services like rexec). It is
advisable to disable as many services in inetd.conf as possible, typically the
only ones in use will be ftp, pop and imap. Telnet and r services should be
replaced with SSH and services like systat/netstat and finger give away far to
much information. Access to programs started by inetd can be easily controlled
by the use of TCP_WRAPPERS.
/etc/services
The services file is a list of port numbers, the protocol and the
corresponding name. The format is:
service-name port/protocol aliases # optional comment
for example:
time 37/udp timserver
rlp 39/udp resource # resource location
name 42/udp nameserver
whois 43/tcp nicname # usually to sri-nic
domain 53/tcp
domain 53/udp
This file is used for example when you run 'netstat -a', and of course not
used when you run 'netstat -an'
For a large services file please see https://seifried.org/security/ports/
TCP_WRAPPERS
Using TCP_WRAPPERS makes securing your servers against outside intrusion is a
lot simpler and painless then you would expect. TCP_WRAPPERS is controlled from
two files:
/etc/hosts.allow
/etc/hosts.deny
hosts.allow is checked first, and the rules are checked from first to last.
If it finds a rule that explicitly allows you in (i.e., a rule allowing your
host, domain, subnet mask, etc.) it lets you connect to the service. If it fails
to find any rules that pertain to you in hosts.allow, it then goes to check
hosts.deny for a rule denying you entry. Again it checks the rules in hosts.deny
from first to last, and the first rule it finds that denies you access (i.e., a
rule disallowing your host, domain, subnet mask, etc.) means it doesn't let you
in. If it fails to find a rule denying you entry it then by default lets you. If
you are paranoid like me the last rule (or only rule if you are going to a
default policy of non-optimistic security) should be:
in hosts.deny:
ALL: 0.0.0.0/0.0.0.0
which means all services, all locations, so any service not explicitly
allowed is then blocked (remember the default is to allow). You might also want
to just default deny access to say telnet and leave ftp wide open to the world.
To do this you would have:
in hosts.allow:
in.telnetd: 10.0.0.0/255.255.255.0 # allow access from my internal network of 10.0.0.*
in.ftpd: 0.0.0.0/0.0.0.0 # allow access from anywhere in the world
in hosts.deny:
in.telnetd: 0.0.0.0/0.0.0.0 # deny access to telnetd from anywhere
or if you wish to be really safe:
ALL: 0.0.0.0/0.0.0.0 # deny access to everything from everywhere
This may affect services such as ssh and nfs, so be careful!
You may wish to simply list all the services you are using separately:
in.telnetd: 0.0.0.0/0.0.0.0
ipop3d: 0.0.0.0/0.0.0.0
If you leave a service on that you shouldn't have in inetd.conf, and DO NOT
have a default deny policy, you could be up the creek. It is safer (and a bit
more work, but in the long run less work then rebuilding the server) to have
default deny rules for firewalling and TCP_WRAPPERS, thus is you leave something
on by accident, by default there will be no access to it. If you install
something that users need access and you forget to put allow rules in, they will
quickly complain that they can't get access and you will be able to rectify the
problem quickly. Erring on the side of caution and accidentally denying
something is a lot safer then leaving it open.
The man pages for TCP_WRAPPERS are very good and available by:
man hosts.allow
man hosts_allow
and/or (they are the same man page):
man hosts.deny
man hosts_deny
One minor caveat with TCP_WRAPPERS that recently popped up on Bugtraq,
TCP_WRAPPERS interprets lines in hosts.allow and hosts.deny in the following
manner:
1) strip off all \'s (line continuations), making all the lines complete
(also note the max length of a line is about 2k, better to use multiple lines in
some cases).
2) strip out lines starting with #'s, i.e. all commented out lines. Thus:
# this is a test
# in.ftpd: 1.1.1.1 \
in.telnetd: 1.1.1.1
this means the "in.telnetd: 1.1.1.1" line would be ignored as well.
What is running and who is it talking to?
You can't start securing services until you know what is running. For this
task ps and netstat are invaluable; ps will tell you what is currently running
(httpd, inetd, etc) and netstat will tell you what the status of ports are (at
this point we're interested in ports that are open and listening, that is
waiting for connections). We can take a look at the various config files that
control network services.
ps
The program ps shows us process status (information available in the /proc
virtual filesystem). The options most commonly used are "ps -xau", which show
pretty much all the information you'd ever want to know. Please note: these
options vary across UNIX systems, Solaris, SCO, etc all behave differently
(which is incredibly annoying). The following is typical output from a machine
(using "ps –xau").
USER PID %CPU %MEM SIZE RSS TTY STAT START TIME COMMAND
bin 320 0.0 0.6 760 380 ? S Feb 12 0:00 portmap
daemon 377 0.0 0.6 784 404 ? S Feb 12 0:00 /usr/sbin/atd
named 2865 0.0 2.1 2120 1368 ? S 01:14 0:01 /usr/sbin/named -u named -g named -t /home/named
nobody 346 0.0 18.6 12728 11796 ? S Feb 12 3:12 squid
nobody 379 0.0 0.8 1012 544 ? S Feb 12 0:00 (dnsserver)
nobody 380 0.0 0.8 1012 540 ? S Feb 12 0:00 (dnsserver)
nobody 383 0.0 0.6 916 416 ? S Feb 12 0:00 (dnsserver)
nobody 385 0.0 0.8 1192 568 ? S Feb 12 0:00 /usr/bin/ftpget -S 1030
nobody 392 0.0 0.3 716 240 ? S Feb 12 0:00 (unlinkd)
nobody 1553 0.0 1.8 1932 1200 ? S Feb 14 0:00 httpd
nobody 1703 0.0 1.8 1932 1200 ? S Feb 14 0:00 httpd
root 1 0.0 0.6 776 404 ? S Feb 12 0:04 init [3]
root 2 0.0 0.0 0 0 ? SW Feb 12 0:00 (kflushd)
root 3 0.0 0.0 0 0 ? SW Feb 12 0:00 (kswapd)
root 4 0.0 0.0 0 0 ? SW Feb 12 0:00 (md_thread)
root 64 0.0 0.5 736 348 ? S Feb 12 0:00 kerneld
root 357 0.0 0.6 800 432 ? S Feb 12 0:05 syslogd
root 366 0.0 1.0 1056 684 ? S Feb 12 0:01 klogd
root 393 0.0 0.7 852 472 ? S Feb 12 0:00 crond
root 427 0.0 0.9 1272 592 ? S Feb 12 0:19 /usr/sbin/sshd
root 438 0.0 1.0 1184 672 ? S Feb 12 0:00 rpc.mountd
root 447 0.0 1.0 1180 644 ? S Feb 12 0:00 rpc.nfsd
root 458 0.0 1.0 1072 680 ? S Feb 12 0:00 /usr/sbin/dhcpd
root 489 0.0 1.7 1884 1096 ? S Feb 12 0:00 httpd
root 503 0.0 0.4 724 296 2 S Feb 12 0:00 /sbin/mingetty tty2
root 505 0.0 0.3 720 228 ? S Feb 12 0:02 update (bdflush)
root 541 0.0 0.4 724 296 1 S Feb 12 0:00 /sbin/mingetty tty1
root 1372 0.0 0.6 772 396 ? S Feb 13 0:00 inetd
root 1473 0.0 1.5 1492 1000 ? S Feb 13 0:00 sendmail: accepting connections on port 25
root 2862 0.0 0.0 188 44 ? S 01:14 0:00 /usr/sbin/holelogd.named /home/named/dev/log
root 3090 0.0 1.9 1864 1232 ? S 12:16 0:02 /usr/sbin/sshd
root 3103 0.0 1.1 1448 728 p1 S 12:16 0:00 su -root 3104 0.0 1.3 1268 864 p1 S 12:16 0:00 -bash
root 3136 0.0 1.9 1836 1212 ? S 12:21 0:04 /usr/sbin/sshd
The interesting ones are: portmap, named, Squid (and it's dnsserver, unlinkd
and ftpget children processes), httpd, syslogd, sshd, rpc.mountd, rpc.nfsd,
dhcpd, inetd, and sendmail (this server appears to be providing gateway
services, email and NFS file sharing). The easiest way to learn how to read ps
output is go over the ps man page and learn what the various fields are (most
are self explanatory, such as %CPU, while some like SIZE are a bit obscure: SIZE
is the number of 4k memory 'pages' a program is using). To figure out what the
running programs are a safe bet is 'man <command_name>'; which almost
always gives you the manual page pertaining to that service (such as httpd). You
will notice that services like telnet, ftpd, identd and several others do not
show up even though they are on. This is because they are run from inetd, the
'superserver'. To find these services look at /etc/inetd.conf or your "netstat
–vat" output.
netstat
netstat tells us pretty much anything network-related that you can imagine.
It is especially good at listing active connections and sockets. Using netstat
we can find which ports on which interfaces are active. The following output is
from a typical server using netstat –vat.
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 24.108.11.200:80 205.253.183.122:3661 ESTABLISHED
tcp 0 0 0.0.0.0:1036 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 10.0.0.10:53 0.0.0.0:* LISTEN
tcp 0 0 28.208.55.254:53 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:139 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:2049 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:635 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
udp 0 0 127.0.0.1:1031 0.0.0.0:*
udp 0 0 0.0.0.0:1029 0.0.0.0:*
udp 0 0 0.0.0.0:800 0.0.0.0:*
udp 0 0 0.0.0.0:1028 0.0.0.0:*
udp 0 0 10.0.0.10:53 0.0.0.0:*
udp 0 0 28.208.55.254:53 0.0.0.0:*
udp 0 0 127.0.0.1:53 0.0.0.0:*
udp 0 0 10.1.0.1:138 0.0.0.0:*
udp 0 0 10.1.0.1:137 0.0.0.0:*
udp 0 0 10.0.0.10:138 0.0.0.0:*
udp 0 0 10.0.0.10:137 0.0.0.0:*
udp 0 0 0.0.0.0:138 0.0.0.0:*
udp 0 0 0.0.0.0:137 0.0.0.0:*
udp 0 0 0.0.0.0:2049 0.0.0.0:*
udp 0 0 0.0.0.0:635 0.0.0.0:*
udp 0 0 0.0.0.0:514 0.0.0.0:*
udp 0 0 0.0.0.0:111 0.0.0.0:*
raw 0 0 0.0.0.0:1 0.0.0.0:*
raw 0 0 0.0.0.0:6 0.0.0.0:*
Numeric output is in my opinion easier to read (once you memorize
/etc/services). The interesting fields for us are the first field, type of
service, the fourth field which is the IP address of the interface and the port,
the foreign address (if not 0.0.0.0.* means someone is actively talking to it),
and the port state. The first line is a remote client talking to the web server
on this machine (port 80). We then see the www server listening on 0.0.0.0:80
which means all interfaces, port 80, followed by the DNS server running on all 3
interfaces, a samba server (139), a mail server (25), an NFS server (2049) and
so on. You will notice the ftp server (21) listed, even though it is run out of
inetd, and not currently in use (i.e. no one is actively ftping in), it is
listed in the netstat output. This makes netstat especially useful for finding
out what is active on a machine, making an inventory of active and inactive
network related software on the server much easier. ****** netstat -p option now
lsof
lsof is a handy program similar in idea to ps, except that it prints out what
files/etc are open, which can include network sockets. Unfortunately your
average lsof puts out a lot of information, so you will need to use grep or
redirect it through less ("lsof | less") to make it easier to read.
squid 9726 root 4u inet 78774 TCP localhost:2074->localhost:2073 (ESTABLISHED)
squid 9726 root 5u inet 78777 TCP localhost:2076->localhost:2075 (ESTABLISHED)
squid 9726 root 6u inet 78780 TCP localhost:2078->localhost:2077 (ESTABLISHED)
squid 9726 root 7w CHR 1,3 6205 /dev/null
squid 9726 root 14u inet 78789 TCP host1:3128 (LISTEN)
squid 9726 root 15u inet 78790 UDP host1:3130
squid 9726 root 16u inet 78791 UDP host1:3130
squid 9726 root 12u inet 167524 TCP host1:3128->host2:3630 (ESTABLISHED)
squid 9726 root 17u inet 167528 TCP host1:3424->www.example.org:http (SYN_SENT)
This example shows that we have Squid running, listening on ports 3128 and
3130, the last two lines show an open connection from an internal host to the
Squid server and the resulting action Squid has taken to fulfill the request
(going to www.example.org). host1 is the Squid server and host2 is the client
machine making the request. This is an invaluable tool for getting a precise
image of what is going on network wise with your server. You can get lsof with
some distributions. Please note that versions of lsof compiled for kernel
version 2.0.x will not work with kernel 2.2.x and vice versa, as there were too
many changes. The primary site for lsof is at: ftp://vic.cc.purdue.edu/pub/tools/unix/lsof/.
Encryption of network traffic (non VPN)
SSL
There are a number of sources for information on SSL. Generally where SSL is
applicable it is in the individual resource (i.e. WWW). For a good FAQ go here:
https://www2.psy.uq.edu.au/~ftp/Crypto/. OpenSSL is an
OpenSource implementation of the SSL libraries that is available form: https://www.openssl.org/.
Routing security
There are a variety of routing software packages available for Linux. Most of
them support the newer routing protocols which have a much higher degree of
security then the older protocols such as RIP.
routed
routed is one of the standard routing packages available for Linux. It
supports RIP (about the oldest routing protocol still in service), and that's
it. RIP is very simple, routers simply broadcast their routing tables to
neighboring routers, resulting (in theory) in a complete routing table that
contains entries for every destination on the Internet. This method is
fundamentally insecure, and very inefficient outside of small secure networks
(in which case it probably is not needed). Securing it is really not possible,
you can firewall ports 520 and 521 which RIP uses to transfer data, however this
can result in routes you want not getting through, and attackers can still spoof
routes. Running this service is a very bad idea.
gated
gated is a more advanced piece of routing software then routed. It supports
RIP versions 1 and 2, DCN HELLO, OSPF version 2, EGP version 2, and BGP versions
2 through 4. Currently the most popular routing protocol seems to be BGP (Border
Gateway Protocol), with OSPF gaining popularity (OSPF has built in security, is
very efficient, and quite a bit more complicated).
MRT
MRT (Multi-threaded Routing Toolkit) is a routing daemon and test toolkit
that can handle IPv4 and IPv6. You can get it at: https://www.mrtd.net/.
Quagga
https://www.quagga.net/
zebra
Zebra has been replaced with Quagga (a fork of the Zebra code which went
stale)
zebra is much more featured then gated, and sports a nice Cisco style command
line interface. It runs as a daemon, and is multi threaded for performance, each
protocol (RIP, OSPF, etc.) has it's own configuration, and you can run multiple
protocols simultaneously (although this could lead to confusion/problems). There
is a master configuration port, and a port for each protocol:
zebrasrv 2600/tcp # zebra service
zebra 2601/tcp # zebra vty
ripd 2602/tcp # RIPd vty
ripngd 2603/tcp # RIPngd vty
ospfd 2604/tcp # OSPFd vty
bgpd 2605/tcp # BGPd vty
ospf6d 2606/tcp # OSPF6d vty
I would advise firewalling these ports. Access is controlled by a login
password, and access to command functions requires another password (using the
same syntax as Cisco, "enable"). You can download zebra from: https://www.zebra.org/.