LDP/LDP/howto/docbook/Security-Quickstart-HOWTO.sgml

8544 lines
280 KiB
Plaintext

<!DOCTYPE Article PUBLIC "-//OASIS//DTD DocBook V3.1//EN"
[<!entity % redhat "INCLUDE"> <!entity % linuxall "IGNORE">]
>
<!--
Note that this doc can build either a generic Linux version (linuxall), or a
slightly modified Redhat specific version (redhat) by toggling the 'entity' in
the DTD header. The below (poor) Makefile will build both versions with
'make all'
###########################################################################
# Half-ass Makefile for the Security-Quickstart HOWTO
#
# This builds txt and html versions of this doc for either
# the generic version, the Redhat version, or both (make all).
#
BASE = Security-Quickstart
DIR = QUICKSTART
TMP_DIR = _makefile.tmp
TMP_SGML = _tmp.sgml
TEXT = _tmp.txt
RH = Redhat
## targets
all: redhat linuxall
redhat:
perl -pe 's/\[<!entity.*/[<!entity % redhat "INCLUDE"> <!entity % linuxall "IGNORE">]/' $(BASE).sgml >\
$(TMP_SGML)
[ -d $(DIR)-$(RH) ] && rm -fr $(DIR)-$(RH) || true
mkdir -p $(DIR)-$(RH) $(TMP_DIR) && mv *.html $(TMP_DIR) || true
jade -t sgml -ihtml -d /usr/lib/sgml/stylesheets/ldp.dsl\#html $(TMP_SGML) ||\
( mv -f $(TMP_DIR)/*.html . && rm -rf $(TMP_DIR) $(TMP_SGML) && false)
mv -f *.html $(DIR)-$(RH)
mv -f $(TMP_DIR)/*.html . || true
make txt && mv -f $(TEXT).gz $(BASE)-$(RH).txt.gz
rm -rf $(TMP_DIR) $(TMP_SGML)
linuxall:
perl -pe 's/\[<!entity.*/[<!entity % redhat "IGNORE"> <!entity % linuxall "INCLUDE">]/' $(BASE).sgml >\
$(TMP_SGML)
[ -d $(DIR) ] && rm -fr $(DIR) || true
mkdir -p $(DIR) $(TMP_DIR) && mv -f *.html $(TMP_DIR) || true
jade -t sgml -ihtml -d /usr/lib/sgml/stylesheets/ldp.dsl\#html $(TMP_SGML) ||\
( mv -f $(TMP_DIR)/*.html . && rm -rf $(TMP_DIR) $(TMP_SGML) && false)
mv -f *.html $(DIR)
mv -f $(TMP_DIR)/*.html . || true
make txt && mv -f $(TEXT).gz $(BASE).txt.gz
rm -rf $(TMP_DIR) $(TMP_SGML)
# This is called by Redhat and linuxall...do not invoke directly.
txt:
jade -t sgml -i html -d /usr/lib/sgml/stylesheets/ldp.dsl\#html -V nochunks $(TMP_SGML) >\
_$(TEXT).html
lynx -dump _$(TEXT).html > $(TEXT) && gzip -f $(TEXT) && rm -f _$(TEXT).html
clean:
rm -rf $(TMP_DIR) $(TMP_SGML) $(DIR)* *~
## eof #############################################################
Hal Burgiss 09/30/01
-->
<article id="index">
<artheader>
<title>Security Quick-Start HOWTO for <![%redhat;[ Red Hat ]]> Linux</title>
<pubdate>v. 1.2, 2002-07-21</pubdate>
<authorgroup>
<author>
<firstname>Hal</firstname>
<surname>Burgiss</surname>
<affiliation>
<address>
<email>hal@foobox.net</email>
</address>
</affiliation>
</author>
</authorgroup>
<revhistory>
<revision>
<revnumber>v. 1.2</revnumber>
<date>2002-07-21</date>
<authorinitials>hb</authorinitials>
<revremark>
A few small additions, and fix the usual broken links.
</revremark>
</revision>
<revision>
<revnumber>v. 1.1</revnumber>
<date>2002-02-06</date>
<authorinitials>hb</authorinitials>
<revremark>
A few fixes, some additions and many touch-ups from the original.
</revremark>
</revision>
<revision>
<revnumber>v. 1.0</revnumber>
<date>2001-11-07</date>
<authorinitials>hb</authorinitials>
<revremark>
Initial Release.
</revremark>
</revision>
</revhistory>
<keywordset>
<keyword>Secure</keyword>
<keyword>Security</keyword>
<keyword>Services</keyword>
<keyword>Firewall</keyword>
<keyword>Intrusion</keyword>
<keyword>Hacker</keyword>
<keyword>Hacked</keyword>
<keyword>Cracker</keyword>
<keyword>Cracked</keyword>
<keyword>owned</keyword>
<keyword>Firewall</keyword>
<keyword>ipchains</keyword>
<keyword>iptables</keyword>
<keyword>tcpwrappers</keyword>
<keyword>portsentry</keyword>
<keyword>virus</keyword>
<keyword>trojan</keyword>
</keywordset>
<abstract>
<![%redhat;[
<para>
<comment>
This is here to keep vim syntax file from breaking :/
If I knew enough to fix it, I would.
DO NOT REMOVE!
</comment>
</para>
]]>
<para>
<comment>
$cvs get LDP/howto/docbook/Security-Quickstart-HOWTO.sgml
upload...
$ cvs commit Security-Quickstart-HOWTO.sgml !!!!!!!!!!!!!!!!
(from the LDP/howto/docbook/ dir)
check here: http://cvs.pld.org.pl/LDP/howto/docbook/Security-Quickstart-HOWTO.sgml
aspell -H -c Security-Quickstart.sgml
ldp-review@lupercalia.org
submit@tldp.org
http://feenix.burgiss.net/ldp/quickstart/Security-Quickstart.sgml.gz
====================================================================
v1.2pre
CHANGES
Minor changes to Have I Been Hacked
Explicit path for ipchains and iptables (missed in first set of scripts)
Further note on what is being protected by scripts.
Add note on ZA type apps in General questions.
More on chattr, and Bill S's tip for checking immutables.
MySQL server port added.
TODO
Submitted v1.1 Wed 02/06/02 07:44:50 PM
CHANGES
Various minor corrections per Bill S. 11/12/01
Fixed Redhat typos. RED HAT, doh!
rpcinfo blurb.
A few additional credits.
Added suggestions from Jacco de Leeuw (jacco2@dds.nl)
for smb.conf, cupsd.conf and xdm/inittab.
chattr mentioned per Bill S. 11/21/01
Re-check with netstat after updating packages.
Other doc formats referenced at ldp.org
Small blurb on tcpwrappers. 12/02/01
Added note on Bastille/Debian
A little more on passwords
rc.inet2 on Slack 12/17/01
re-did blacklist in scripts
cat /proc/*/stat |awk '{print $1,$2}' (PIDs and names)
ports 1-19, 6010 added to port info section
note on scripts presented as examples 12/29/01
Additional explanation on RPC services re: portmap 01/06/02
Added Remote X Apps HOWTO to links.
iptables mini-me 01/27/02
nmap/udp
Run servers on non-standard ports 2x
principles to guide us by (intro)
note on DSL and cable staying updated! 02/01/02
fixed netfilter URLs (changed)
logcheck is now logsentry 02/01/02
02/06/02 -- end 1.1
TODO
There is no one single thing that constitutes good security....
ftp://ftp.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.2/capfaq-0.2.txt
http://www.linuxsecurity.com/feature_stories/kernel-24-security.html
http://www.cert.org/tech_tips/AUSCERT_checklist2.0.html
Version 1.0 submitted 11-7-01
11/01/01 - seawall and shorewall added to Links.
A few minor changes.
Begin .99 07/10/01
TODO
ls -l /proc/31873/exe (command that started process).
for x in `ls /proc | grep '^[0-9]*$'`; do cat /proc/$x/cmdline; echo; done
perl -pe '' /etc/passwd
perl -pe '' /etc/shadow
</comment>
</para>
<para>
This document is a an overview of the basic steps required to
secure a Linux installation from intrusion. It is intended to be an
introduction. <![%redhat;[ This is a Red Hat specific version of this
document. ]]>
</para>
</abstract>
</artheader>
<!-- ~ End section ~ -->
<!-- ~~~~~~~~ New section Header ~~~~~~~~~ -->
<sect1 id="intro">
<title>Introduction</title>
<!-- ~~~~~ New section ~~~~~ -->
<sect2>
<title>Why me?</title>
<para>
Who should be reading this document and why should the average Linux user
care about security? Those new to Linux, or unfamiliar with the inherent
security issues of connecting a Linux system to large networks like Internet
should be reading. <Quote>Security</Quote> is a broad subject with many
facets, and is covered in much more depth in other documents, books, and on
various sites on the Web. This document is intended to be an introduction to
the most basic concepts as they relate to <![%redhat;[Red Hat]]> Linux, and as
a starting point only.
</para>
<Para>
<Literal>
<MSGText>
<LiteralLayout>
Iptables Weekly Log Summary from Jul 15 04:24:13 to Jul 22 04:06:00
Blocked Connection Attempts:
Rejected tcp packets by destination port
port count
111 19
53 12
21 9
515 9
27374 8
443 6
1080 2
1138 1
Rejected udp packets by destination port
port count
137 34
22 1
</LiteralLayout>
</MSGText>
</Literal>
</Para>
<para>
The above is real, live data from a one week period for my home LAN.
Much of the above would seem to be specifically targeted at Linux systems.
Many of the targeted <quote>destination</quote> ports are used by well known
Linux and Unix services, and all may be installed, and possibly
even running, on your system.
</para>
<para>
The focus here will be on threats that are shared by all Linux users, whether
a dual boot home user, or large commercial site. And we will take a few,
relatively quick and easy steps that will make a typical home Desktop system
or small office system running <![%redhat;[Red Hat]]> Linux reasonably safe
from the majority of outside threats. For those responsible for Linux systems
in a larger or more complex environment, you'd be well advised to read this,
and then follow up with additional reading suitable to your particular
situation. Actually, this is probably good advice for everybody.
</para>
<para>
We will assume the reader knows little about Linux, networking, TCP/IP,
and the finer points of running a server Operating System like Linux. We
will also assume, for the sake of this document, that all local users are
<quote>trusted</quote> users, and won't address physical or local network
security issues in any detail. Again, if this is not the case, further
reading is strongly recommended.
</para>
<para>
The principles that will guide us in our quest are:
</para>
<para>
<itemizedlist>
<listitem>
<para>
There is no <application>magic bullet</application>. There is no one
<emphasis role="bold">single</emphasis> thing we can do to make us secure. It is not that simple.
</para>
</listitem>
<listitem>
<para>
Security is a process that requires maintenance, not an objective to
be reached.
</para>
</listitem>
<listitem>
<para>
There is no 100% safe program, package or distribution. Just varying
degrees of insecurity.
</para>
</listitem>
</itemizedlist>
</para>
<para>
The steps we will be taking to get there are:
</para>
<para>
<itemizedlist>
<listitem>
<para>
Step 1: Turn off, and perhaps uninstall, any and all unnecessary services.
</para>
</listitem>
<listitem>
<para>
Step 2: Make sure that any services that are installed are updated and
patched to the current, safe version -- <emphasis>and then stay that
way</emphasis>. Every server application has potential exploits. Some have
just not been found yet.
</para>
</listitem>
<listitem>
<para>
Step 3: Limit connections to us from outside sources by implementing a
firewall and/or other restrictive policies. The goal is to allow only the
minimum traffic necessary for whatever our individual situation may be.
</para>
</listitem>
<listitem>
<para>
Awareness. Know your system, and how to properly maintain and secure it.
New vulnerabilities are found, and exploited, all the time. Today's
secure system may have tomorrow's as yet unfound weaknesses.
</para>
</listitem>
</itemizedlist>
</para>
<para>
If you don't have time to read everything, concentrate on Steps 1, 2, and 3.
This is where the meat of the subject matter is. The <link
linkend="appendix">Appendix</link> has a lot of supporting information, which
may be helpful, but may not be necessary for all readers.
</para>
</sect2>
<!-- ~ End section ~ -->
<![%redhat;[
<!-- ~~~~~ New section ~~~~~ -->
<sect2>
<title>Notes</title>
<para>
This is a Red Hat specific version of this document. The included examples
are compatible with Red Hat 7.0 and later. Actually, most examples should
work with earlier versions of Red Hat as well. Also, this document should be
applicable to other distributions that are Red Hat derivatives, such as
Mandrake, Conectiva, etc.
</para>
<para>
Overwhelmingly, the content of this document is not peculiar to Red Hat. The
same rules and methodologies apply to other Linuxes. And indeed, to other
Operating Systems as well. But each may have their own way of doing things --
the file names and locations may differ, as may the system utilities that
we rely on. It is these differences that make this document a
<quote>Red Hat</quote> version.
</para>
</sect2>
<!-- ~ End section ~ -->
]]>
<!-- ~~~~~ New section ~~~~~ -->
<sect2>
<title>Copyright</title>
<para>
Security-Quickstart HOWTO for <![%redhat;[Red Hat]]> Linux
</para>
<para>
Copyright &copy; 2001 Hal Burgiss.
</para>
<para>
This document is free; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
</para>
<para>
This document is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
</para>
<para>
You can get a copy of the GNU GPL at <ulink
URL="http://www.gnu.org/copyleft/gpl.html">http://www.gnu.org/copyleft/gpl.html</ulink>.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2>
<title>Credits</title>
<para>
Many thanks to those who helped with the production of this document.
</para>
<para>
<itemizedlist>
<listitem>
<para>
Bill Staehle, who has done a little bit of everything: ideas, editing,
encouragement, and suggestions, many of which have been incorporated.
Bill helped greatly with the content of this document.
</para>
</listitem>
<listitem>
<para>
Others who have contributed in one way or another: Dave Wreski, Ian
Jones, Jacco de Leeuw, and Indulis Bernsteins.
</para>
</listitem>
<listitem>
<para>
Various posters on comp.os.linux.security, a great place to learn about
Linux and security.
</para>
</listitem>
<listitem>
<para>
The Netfilter Development team for their work on
<application>iptables</application> and connection tracking, state of the
art tools with which to protect our systems.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="disclaimer">
<title>Disclaimer</title>
<para>
The author accepts no liability for the contents of this document. Use the
concepts, examples and other content at your own risk. As this is a new
document, there may be errors and inaccuracies. Hopefully these are few and
far between. Corrections and suggestions are welcomed.
</para>
<para>
This document is intended to give the new user a starting point for securing
their system while it is connected to the Internet. Please understand that
there is no intention whatsoever of claiming that the contents of this
document will necessarily result in an ultimately secure and worry-free
computing environment. Security is a complex topic. This document just
addresses some of the most basic issues that inexperienced users should be
aware of.
</para>
<para>
The reader is encouraged to read other security related documentation and
articles. And to stay abreast of security issues as they evolve. Security is
not an objective, but an ongoing process.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2>
<title>New Versions and Changelog</title>
<![%linuxall;[
<para>
The current official version can always be found at <ulink
url="http://www.tldp.org/HOWTO/Security-Quickstart-HOWTO/">http://www.tldp.org/HOWTO/Security-Quickstart-HOWTO/</ulink>.
Pre-release versions can be found at <ulink
URL="http://feenix.burgiss.net/ldp/quickstart/">http://feenix.burgiss.net/ldp/quickstart/</ulink>.
</para>
]]>
<![%redhat;[
<para>
The current official version can always be found at <ulink
url="http://www.tldp.org/HOWTO/Security-Quickstart-Redhat-HOWTO/">http://www.tldp.org/HOWTO/Security-Quickstart-Redhat-HOWTO/</ulink>.
Pre-release versions can be found at <ulink
URL="http://feenix.burgiss.net/ldp/quickstart-rh/">http://feenix.burgiss.net/ldp/quickstart-rh/</ulink>.
</para>
]]>
<para>
Other formats, including PDF, PS, single page HTML, may be found at
the Linux Documentation HOWTO index page: <ulink
url="http://tldp.org/docs.html#howto">http://tldp.org/docs.html#howto</ulink>.
</para>
<para>
Changelog:
</para>
<para>
Version 1.2: Clarifications on example firewall scripts, and small additions
to 'Have I been Hacked'. Note on Zonealarm type applications. More on the use
of <quote>chattr</quote> by script kiddies, and how to check for this. Other
small additions and clarifications.
</para>
<para>
Version 1.1: Various corrections, amplifications and numerous mostly small
additions. Too many to list. Oh yea, learn to spell Red Hat correctly ;-)
</para>
<para>
Version 1.0: This is the initial release of this document. Comments
welcomed.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2>
<title>Feedback</title>
<para>
Any and all comments on this document are most welcomed. Please make sure you have
the most current version before submitting corrections or suggestions! These
can be sent to <email>hal@foobox.net</email>.
</para>
</sect2>
</sect1>
<!-- ~ End section ~ -->
<!-- ~~~~~~~~ New section Header ~~~~~~~~~ -->
<sect1 id="foreword">
<title>Foreword</title>
<para>
Before getting into specifics, let's try to briefly answer some questions
about why we need to be concerned about security in the first place.
</para>
<para>
It is easy to see why an e-commerce site, an on-line bank, or a government
agency with sensitive documents would be concerned about security. But what
about the average user? Why should even a Linux home Desktop user worry about
security?
</para>
<para>
Anyone connected to the Internet is a target, plain and simple. It
makes little difference whether you have a part-time dialup connection, or a
full-time connection, though full-time connections make for bigger targets.
Larger sites make for bigger targets too, but this does not let small users
off the hook since the <quote>small user</quote> may be less skilled and thus
an easier victim.
<![%redhat;[ Red Hat, and Red Hat based distributions, tend to make for bigger
targets as well, since the installed user base is so large.]]>
</para>
<para>
There are those out there that are scanning just for easy
victims all the time. If you start logging unwanted connection attempts,
you will see this soon enough. There is little doubt that many of these
attempts are maliciously motivated and the attacker, in some cases, is
looking for Linux boxes to crack. Does someone on the other side of the globe
really want to borrow my printer?
</para>
<para>
What do they want? Often, they just may want your computer, your IP
address, and your bandwidth. Then they use you to either attack others, or
possibly commit crimes or mischief and are hiding their true identity behind
you. This is an all too common scenario. Commercial and high-profile sites
are targeted more directly and have bigger worries, but we all face this type
of common threat.
</para>
<para>
With a few reasonable precautions, <![%redhat;[Red Hat ]]>Linux can be very
secure, and with all the available tools, makes for a fantastically fun and
powerful Internet connection or server. Most successful break-ins are the
result of ignorance or carelessness.
</para>
<para>
The bottom line is:
</para>
<para>
<itemizedlist>
<listitem>
<para>
Do you want control of your own system or not?
</para>
</listitem>
<listitem>
<para>
Do you want to unwittingly participate in criminal activity?
</para>
</listitem>
<listitem>
<para>
Do you want to be used by someone else?
</para>
</listitem>
<listitem>
<para>
Do you want to risk losing your Internet connection?
</para>
</listitem>
<listitem>
<para>
Do you want to have to go through the time consuming steps of reclaiming
your system?
</para>
</listitem>
<listitem>
<para>
Do you want to chance the loss of data on your system?
</para>
</listitem>
</itemizedlist>
</para>
<para>
These are all real possibilities, unless we take the appropriate
precautions.
</para>
<Warning>
<Para>
If you are reading this because you have already been broken into, or
suspect that you have, you cannot trust any of your system utilities to
provide reliable information. And the suggestions made in the next several
sections will not help you recover your system. Please jump straight to the
<link linkend="hacked">Have I been Hacked?</link> section, and read that
first.
</Para>
</Warning>
<!-- ~~~~~ New section ~~~~~ -->
<!--
<sect2>
<title>Preamble</title>
<para>
First, there is no such thing as a 100% guaranteed safe Internet connection.
No matter how many steps you take, there is always someone willing to do you
one better, and undo all your work. The only absolutely safe connection is
one that is unplugged. That being said, it is not difficult to greatly
minimize the risk from many of these inherent threats.
</para>
<para>
Secondly, networks are designed explicitly such that computers in different
locations can connect to each other, and exchange data. Linux is a network
Operating System from the ground up, and generally comes with a wide array
of <Quote>server</Quote> applications installed and ready for action. Mail
servers, web servers, ftp servers, telnet servers, print servers - to name
just a few. While this is a good thing in many respects, it also makes Linux
an inviting target for those with less than honorable intentions. A common
modus operandi for <Quote>hackers</Quote> is to find a weakness in a given
server (e.g. <application>ftp</application> server), and then let themselves
in by exploiting that weakness. One step we will take here will be to decide
which, if any, servers we really need to be running on our own systems. Then,
we'll make sure that any we do really need to be running, are running the
latest patched version.
</para>
<para>
Contrary to popular opinion, a <Quote>hacker</Quote> does not much
care about any sensitive or personal data (like bank account number) you may
have tucked away. Not to say this is not a concern for businesses, commercial
sites and others with valuable secrets or data. But what he really wants in
many cases is your IP address, your bandwidth, and the free reign of your
system. That's all. This way he is hidden, and whatever attacks or mischief
he may undertake, utilizes your resources, and it looks like it is coming
from you. So if I wanted to break into CIA Headquarters, I surely wouldn't do
it from home. Well, not my home anyway. First I break into someone else's
system, and do it from their home. Anyway, you are a target just because you
are connected to the Internet - nothing more, nothing less.
</para>
<para>
Lastly, is every connection attempt, an attempted break-in? No, of course
not. There is a number of innocent explanations why you might find someone
knocking at your door so to speak. But how to tell the difference? You can't
really, but we do know for a fact that many of these attempts are indeed
either attempts to find out more about your system as a precursor to
<quote>something</quote>, or possibly are an actual entry attempt. So better
safe than sorry as they say.
</para>
</sect2>
-->
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2>
<title>The Optimum Configuration</title>
<para>
Ideally, we would want one computer as a dedicated firewall and router. This
would be a bare bones installation, with <emphasis>no</emphasis> servers
running, and only the required services and components installed. The rest of
our systems would connect via this dedicated router/firewall system. If we
wanted publicly accessible servers (web, mail, etc), these would be in a
<quote>DMZ</quote> (De-militarized Zone). The router/firewall allows
connections from outside to whatever services are running in the DMZ by
<quote>forwarding</quote> these requests, but it is segregated from the rest
of the internal network (aka LAN) otherwise. This leaves the rest of the
internal network in fairly secure isolation, and relative safety. The
<quote>danger zone</quote> is confined to the DMZ.
</para>
<para>
But not everyone has the hardware to dedicate to this kind of installation.
This would require a minimum of two computers. Or three, if you would be
running any publicly available servers (not a good idea initially). Or maybe
you are just new to Linux, and don't know your way around well enough yet. So
if we can't do the ideal installation, we will do the next best thing.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2>
<title>Before We Start</title>
<para>
Before we get to the actual configuration sections, a couple of notes.
</para>
<para>
<![%linuxall;[
First, one of the interesting aspects of Linux, is the different
distributions like Caldera, Red Hat, SuSE, and Debian. While these are all
<quote>Linux</quote>, and may share certain features, there is surely some
differences as to what utilities they may install as defaults. Most Linux
distributions will write their own system configuration tools as well. And with
Linux, there is always more than one way to skin a cat. But for the purposes
of our discussion, we will have to use as generic set of tools as we can.
Unfortunately, GUI tools don't lend themselves to this type of documentation.
We will be using text based, command line tools for the most part. If you
are familiar with your distribution's utilities, feel free to substitute
those in appropriate places. And if not, you should learn them or suitable
alternatives.
]]>
<![%redhat;[ With Linux, there is always more than one way to perform any
task. For the purposes of our discussion, we will have to use as generic set
of tools as we can. Unfortunately, GUI tools don't lend themselves to this
type of documentation. So we will be using text based, command line tools for
the most part. Red Hat does provide various GUI utilities, feel free to
substitute those in appropriate places.
]]>
</para>
<para>
The next several sections have been written such that you can perform the
recommended procedures as you read along. This is the
<quote>Quick Start</quote> in the document title!
</para>
<para>
To get ready, what you will need for the configuration sections below:
</para>
<para>
<ItemizedList>
<ListItem>
<para>
A text editor. There are many available. If you use a file manager
application <![%redhat;[ like <application>gmc</application> or
<application>nautilus</application>]]>, it probably has a built in editor.
This will be fine. <command>pico</command> and <command>mcedit</command>
are two relatively easy to use editors if you don't already have a
favorite. There is a quick guide to <link linkend="text">Text
editors</link> in the Appendix that might help you get started. It is
always a good idea to make a back up copy, before editing system
configuration files.
</para>
</ListItem>
<ListItem>
<para>
For non-GUI editors and some of the commands, you will also need a
terminal window opened. <command>xterm,</command>
<command>rxvt,</command> and <command>gnome-terminal</command> all will
work, as well as others.
</para>
</ListItem>
<![%linuxall;[
<ListItem>
<para>
You should also be familiar with your distribution's method of stopping
services from running on each boot. Also, how they install (and uninstall)
packages (<command>rpm</command>, <command>deb</command>, etc). And where
to find the updates for your release. This information is available in
your release's documentation, or on your vendor's web site.
</para>
</ListItem>
]]>
</ItemizedList>
</para>
<para>
We'll be using a hypothetical system here for examples with the hostname
<quote>bigcat</quote>. Bigcat is a Linux desktop with a fresh install of the
latest/greatest <![%linuxall;[ Linux distro ]]> <![%redhat;[ Red Hat
]]> running. Bigcat has a full-time, direct Internet connection. Even if your
installation is not so <quote>fresh</quote>, don't be deterred. Better late
than never.
</para>
</sect2>
</sect1>
<!-- ~ End section ~ -->
<!-- ~~~~~~~~ New section Header ~~~~~~~~~ -->
<sect1 id="services">
<title>Step 1: Which services do we really need?</title>
<para>
In this section we will see which services are running on our freshly installed
system, decide which we really need, and do away with the rest. If you are
not familiar with how servers and TCP connections work, you may want to read
the section on <link linkend="serversetc">servers and ports</link> in the
Appendix first. If not familiar with the <command>netstat</command> utility,
you may want to read a quick <link linkend="netstat">overview</link> of it
beforehand. There is also a section in the Appendix on <link
linkend="ports">ports</link>, and corresponding services. You may want to
look that over too.
</para>
<!--
<para>
Historically many Linux distributions either enabled many unnecessary
services, or perhaps just made it too easy to wind up with services running
that might be unnecessary, and even potentially dangerous. And sometimes it
is not so obvious that these are indeed running. Or that they may be
potentially security risks.
</para>
<para>
Newer Linux releases seem to be more security conscious, making it less
likely to have unnecessary services running. This is good. But we can't be
sure unless we know how to verify this for ourselves.
</para>
-->
<para>
Our goal is to turn off as many services as possible. If we can turn them
all off, or at least off to outside connections, so much the better. Some
rules of thumb we will use to guide us:
</para>
<para>
<itemizedlist>
<listitem>
<para>
It is perfectly possible to have a fully functional Internet connection
with no servers running that are accessible to outside connections. Not
only possible, but desirable in many cases. The principle here is that
you will never be successfully broken into via a port that is not opened
because no server is listening on it. No server == no port open == not
vulnerable. At least to outside connections.
</para>
</listitem>
<listitem>
<para>
If you don't recognize a particular service, chances are good you don't
really need it. We will assume that and so we'll turn it off. This may
sound dangerous, but is a good rule of thumb to go by.
</para>
</listitem>
<listitem>
<para>
Some services are just not intended to be run over the Internet -- even
if you decide it is something you really do need. We'll flag these
as dangerous, and address these in later sections, should you decide
you do really need them, and there is no good alternative.
</para>
</listitem>
</itemizedlist>
</para>
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="audit">
<title>System Audit</title>
<para>
So what is really running on our system anyway? Let's not take anything for
granted about what <quote>should</quote> be running, or what we
<quote>think</quote> is running.
</para>
<![%linuxall;[
<para>
Unfortunately, there is no such things as a standard Linux installation. The
wide variety of servers available, coupled with each particular distribution's
installation options, make providing a ready made list impossible. The best
that can be done is show you how to list all running services, and point you
in the right general direction.
</para>
]]>
<![%redhat;[
<para>
Which services get installed and started will vary greatly depending on
which version of Red Hat, and which installation options were chosen.
Earlier releases were very much prone to start many services and then let
the user figure out which ones were needed, and which ones weren't. Recent
versions are much more cautious. But this makes providing a ready made list
of likely services impossible. Not to worry, as we shouldn't trust what is
<emphasis>supposed</emphasis> to be running anyway. What we need to do
is list for ourselves all running services.
</para>
]]>
<para>
Now open an <command>xterm</command>, and <command>su</command> to root.
You'll need to widen the window wide so the lines do not wrap. Use this
command: <literal>netstat -tap |grep LISTEN</literal>. This will give us a
list of all currently running servers as indicated by the keyword
<literal>LISTEN</literal>, along with the <quote>PID</quote> and
<quote>Program Name</quote> that started each particular service.
</para>
<para>
<screen>
# netstat -tap |grep LISTEN
*:exec *:* LISTEN 988/inetd
*:login *:* LISTEN 988/inetd
*:shell *:* LISTEN 988/inetd
*:printer *:* LISTEN 988/inetd
*:time *:* LISTEN 988/inetd
*:x11 *:* LISTEN 1462/X
*:http *:* LISTEN 1078/httpd
bigcat:domain *:* LISTEN 956/named
bigcat:domain *:* LISTEN 956/named
*:ssh *:* LISTEN 972/sshd
*:auth *:* LISTEN 388/in.identd
*:telnet *:* LISTEN 988/inetd
*:finger *:* LISTEN 988/inetd
*:sunrpc *:* LISTEN 1290/portmap
*:ftp *:* LISTEN 988/inetd
*:smtp *:* LISTEN 1738/sendmail: accepting connections
*:1694 *:* LISTEN 1319/rpc.mountd
*:netbios-ssn *:* LISTEN 422/smbd
</screen>
</para>
<para>
<![%redhat;[ Red Hat 7.x and Mandrake 8.x and later users will have
<literal>xinetd</literal> in place of <literal>inetd</literal>.]]> Note the
first three columns are cropped above for readability. If your list is as
long as the example, you have some work ahead of you! It is highly unlikely
that you really need anywhere near this number of servers running.
</para>
<para>
Please be aware that the example above is just one of many, many possible
system configurations. Yours probably does look very different.
</para>
<para>
You don't understand what any of this is telling you? Hopefully then, you've
read the <command>netstat</command> <link linkend="netstat">tutorial</link>
in the Appendix, and understand how it works. Understanding exactly what each
server is in the above example, and what it does, is beyond the scope of this
document. You will have to check your system's documentation (e.g.
Installation Guide, man pages, etc) if that service is important to you. For
example, does <quote>exec</quote>, <quote>login</quote>, and <quote>shell</quote>
sound important? Yes, but these are not what they may sound like. They
are actually <command>rexec</command>, <command>rlogin</command>, and
<command>rsh</command>, the <quote>r</quote> (for remote) commands. These are
antiquated, unnecessary, and in fact, are very dangerous if exposed to the
Internet.
</para>
<para>
Let's make a few quick assumptions about what is necessary and unnecessary,
and therefore what goes and what stays on bigcat. Since we are running a
desktop on bigcat, <application>X11</application> of course needs to stay. If
bigcat were a dedicated server of some kind, then X11 would be unnecessary. If
there is a printer physically attached, the printer (lp) daemon should stay.
Otherwise, it goes. Print servers may sound harmless, but are potential
targets too since they can hold ports open. If we plan on logging
<emphasis>in to</emphasis> bigcat <emphasis>from</emphasis> other hosts,
sshd (Secure SHell Daemon) would be necessary. If we have Microsoft hosts on
our LAN, we probably want <application>Samba</application>, so
<application>smbd</application> should stay. Otherwise, it is completely
unnecessary. Everything else in this example is optional and not required for
a normally functioning system, and should probably go. See anything that you
don't recognize? Not sure about? It goes!
</para>
<para>
To sum up: since bigcat is a desktop with a printer attached, we will
need <quote>x11</quote>, <quote>printer</quote>. bigcat is on a LAN with
MS hosts, and shares files and printing with them, so
<quote>netbios-ssn</quote> (<command>smbd</command>) is desired. We will also
need <quote>ssh</quote> so we can login from other machines. Everything else
is unnecessary for this particular case.
</para>
<para>
Nervous about this? If you want, you can make notes of any changes you make
or save the list of servers you got from <command>netstat</command>, with
this command: <literal>netstat -tap |grep LISTEN > ~/services.lst</literal>.
That will save it your home directory with the name of
<quote>services.lst</quote> for future reference.
</para>
<para>
This is to not say that the ones we have decided to keep are inherently safe.
Just that we probably need these. So we will have to deal with these via
firewalling or other means (addressed below).
</para>
<para>
It is worth noting that the <command>telnet</command> and
<command>ftp</command> daemons in the above example are
<emphasis>servers</emphasis>, aka <quote>listeners</quote>. These accept
incoming connections to you. You do not need, or want, these just to use
<command>ftp</command> or <command>telnet</command>
<emphasis>clients</emphasis>. For instance, you can download files from an
FTP site with just an <command>ftp</command> client. Running an
<application>ftp</application> server on your end is not required at all, and
has serious security implications.
</para>
<para>
There may be individual situations where it is desirable to make exceptions
to the conclusions reached above. See <link linkend="exceptions">below</link>.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="danger">
<title>The Danger Zone (or r00t m3 pl34s3)</title>
<para>
The following is a list of services that should <emphasis>not</emphasis> be
run over the Internet. Either disable these (see below), uninstall, or if you
really do need these services running locally, make sure they are the
current, patched versions <emphasis>and</emphasis> that they are effectively
firewalled. And if you don't have a firewall in place now, turn them off
until it is up and verified to be working properly. These are potentially
insecure by their very nature, and as such are prime cracker targets.
</para>
<para>
<itemizedlist>
<listitem>
<para>
<application>NFS</application> (Network File System) and related services,
including <application>nfsd</application>,
<application>lockd</application>, <application>mountd</application>,
<application>statd</application>, <application>portmapper</application>,
etc. NFS is the standard Unix service for sharing file systems across a
network. Great system for LAN usage, but dangerous over the Internet.
And its completely unnecessary on a stand alone system.
</para>
</listitem>
<listitem>
<para>
rpc.* services, Remote Procedure Call.*, typically NFS and NIS related (see
above).
</para>
</listitem>
<listitem>
<para>
Printer services (<application>lpd</application>).
</para>
</listitem>
<listitem>
<para>
The so-called r* (for <quote>remote</quote>, i.e. Remote SHell) services:
<application>rsh</application>, <application>rlogin</application>,
<application>rexec</application>, <application>rcp</application> etc.
Unnecessary, insecure and potentially dangerous, and better utilities are
available if these capabilities are needed. <application>ssh</application>
will do everything these command do, and in a much more sane way. See the
man pages for each if curious. These will probably show in
<command>netstat</command> output without the <quote>r</quote>:
<command>rlogin</command> will be just <quote>login</quote>, etc.
</para>
</listitem>
<listitem>
<para>
<application>telnet</application> server. There is no reason for this
anymore. Use <application>sshd</application> instead.
</para>
</listitem>
<listitem>
<para>
<application>ftp</application> server. There are better, safer ways for
most systems to exchange files like <command>scp</command> or
via <command>http</command> (see below). <application>ftp</application> is a
proper protocol only for someone who is running a dedicated ftp server, and
who has the time and skill to keep it buttoned down. For everyone else, it is
potentially big trouble.
</para>
</listitem>
<listitem>
<para>
<application>BIND</application> (<command>named</command>), DNS server
package. With some work, this can be done without great risk, but is not
necessary in many situations, and requires special handling no matter
how you do it. See the sections on <link
linkend="exceptions">Exceptions</link> and special handling for <link
linkend="indapps">individual applications</link>.
</para>
</listitem>
<listitem>
<para>
Mail Transport Agent, aka <quote>MTA</quote>
(<application>sendmail</application>, <application>exim</application>,
<application>postfix</application>, <application>qmail</application>).
Most installations on single computers will not really need this. If you are not
going to be directly receiving mail from Internet hosts (as a designated MX
box), but will rather use the POP server of your ISP, then it is not
needed. You may however need this if you are receiving mail
<emphasis>directly</emphasis> from other hosts on your LAN, but initially
it's safer to disable this. Later, you can enable it over the local
interface once your firewall and access policies have been implemented.
</para>
</listitem>
</itemizedlist>
</para>
<para>
This is not necessarily a definitive list. Just some common services that
are sometimes started on default <![%redhat;[ Red Hat ]]> <![%linuxall;[ Linux
]]> installations. And conversely, this does not imply that other
services are inherently safe.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="stopservices">
<title>Stopping Services</title>
<para>
The next step is to find where each server on our kill list is being started.
If it is not obvious from the <command>netstat</command> output, use
<command>ps</command>, <command>find</command>, <command>grep</command> or
<command>locate</command> to find more information from the <quote>Program
name</quote> or <quote>PID</quote> info in the last column. There is examples
of this in the <link linkend="pid">Process Owner</link> section in the
<command>netstat</command> Tutorial of the Appendix. If the service name or
port number do not look familiar to you, you might get a real brief
explanation in your <filename>/etc/services</filename> file.
</para>
<![%redhat;[
<para>
<command>chkconfig</command> is a very useful command for controlling
services that are started via init scripts (see example below). Also, where
<application>xinetd</application> is used, it can control those services as
well. <command>chkconfig</command> can tell us what services the system is
configured to run, but not necessarily all services that are indeed actually
running. Or what services may be started by other means, e.g. from
<filename>rc.local</filename>. It is a configuration tool, more than a
real time system auditing too.
</para>
]]>
<para>
Skeptical that we are going to break your system, and the pieces won't go
back together again? If so, take this approach: turn off everything listed
above in <quote>The Danger Zone</quote>, and run your system for a while. OK?
Try stopping one of the ones we found to be <quote>unnecessary</quote> above.
Then, run the system for a while. Keep repeating this process, until you get
to the bare minimum. If this works, then make the changes permanent (see
below).
</para>
<para>
The ultimate objective is not just to stop the service now, but to make sure
it is stopped permanently! So whatever steps you take here, be sure to check
after your next reboot.
</para>
<para>
There are various places and ways to start system services. Let's look at the
most common ways this is done, and is probably how your system works. System
services are typically either started by <quote>init</quote> scripts, or by
<command>inetd</command> (or its replacement <command>xinetd</command>) on
most distributions. <![%linuxall;[ (The location of the init scripts may vary
from distribution to distribution.) ]]>
</para>
<!-- ~~~~~ New section ~~~~~ -->
<sect3 id="inits">
<title>Stopping Init Services</title>
<para>
Init services are typically started automatically during the boot process, or
during a runlevel change. There is a naming scheme that uses symlinks to
determine which services are to be started, or stopped, at any given
runlevel. The scripts themselves should be in
<filename>/etc/init.d/</filename> (or possibly
<filename>/etc/rc.d/init.d/</filename> <![%redhat;[ for older versions of
Red Hat]]>). <![%linuxall;[ This init style is used by Red Hat,
SuSE, Mandrake, Debian, Conectiva, and most Linuxes. Slackware is one notable
exception (though recent versions have an option for this)! Typically
on Slackware system services are all configured in one file:
<filename>/etc/rc.d/rc.inet2</filename>.]]>
</para>
<para>
You can get a listing of these scripts:
</para>
<para>
<screen>
<![%linuxall;[ # ls -l /etc/init.d/ | less ]]>
<![%redhat;[ # ls -l /etc/rc.d/init.d/ | less ]]>
</screen>
</para>
<![%linuxall;[
<para>
Or use whichever tools your distribution provides for this.
</para>
]]>
<para>
To stop a running service now, as root<![%linuxall;[ (on SysVinit style systems,
which is pretty much everybody)]]>:
</para>
<para>
<screen>
# /etc/init.d/&lt;$SERVICE_NAME&gt; stop
</screen>
</para>
<para>
Where <quote>$SERVICE_NAME</quote> is the name of the init script, which is
often, but not always, the same as the service name itself. <![%linuxall;[
This should do the trick on <emphasis>most</emphasis> distributions.]]> Older
Red Hat versions may use the path <filename>/etc/rc.d/init.d/</filename>
instead.
</para>
<para>
This only stops this particular service now. It will restart again on the
next reboot, or runlevel change, unless additional steps are taken. So this is
really a two step process for init type services.
</para>
<![%linuxall;[
<para>
Your distribution will have utilities available for controlling which services
are started at various runlevels. Debian based systems have
<command>update-rc.d</command> for this, and Red Hat based systems have
<command>chkconfig</command>. If you are familiar with these tools,
do it now, and then check again after the next reboot. If you are not
familiar with these tools, see the man pages and learn it now! This is
something that you need to know. For Debian (where
<literal>$SERVICE_NAME</literal> is the init script name):
</para>
<para>
<screen>
# update-rc.d -f $SERVICE_NAME remove
</screen>
</para>
<para>
And Red Hat:
</para>
<para>
<screen>
# chkconfig $SERVICE_NAME off
</screen>
</para>
]]>
<![%redhat;[
<para>
<command>chkconfig</command> can be used to see what services are
started at each runlevel, and to turn off any unneeded services. To view
<emphasis>all services</emphasis> under its control, type this command
in an <application>xterm</application>:
</para>
<para>
<screen>
# chkconfig --list | less
</screen>
</para>
<para>
To view only the ones that are <quote>on</quote>:
</para>
<para>
<screen>
# chkconfig --list | grep "\bon\b" | less
</screen>
</para>
<para>
The first column is the service name, and the remaining columns are the various
runlevels. We need generally only worry about runlevels 3 (boot
to text console login) and 5 (boot straight to X11 login).
<application>xinetd</application> services won't have columns, since that
aspect would be controlled by <application>xinetd</application> itself.
</para>
<para>
Examples of commands to turn services <quote>off</quote>:
</para>
<para>
<screen>
# chkconfig portmapper off
# chkconfig nfs off
# chkconfig telnet off
# chkconfig rlogin off
</screen>
</para>
<para>
Note that the last two are <application>xinetd</application> services.
A very easy and nifty tool to use! Red Hat also includes <command>ntsysv</command>
and <command>tksysv</command> (GUI) for runlevel and service configuration.
See the man pages for additional command line options.
</para>
]]>
<!--
<para>
If you are not sure how to go about this and are really, really desperate,
run this command:
</para>
<screen>
# rm -frv /etc/init.d/S*
</screen>
WOWSER!!!!!!!!! Killing me softly, with his rm.
<para>
Warning! This is an extreme approach, but will stop any init services from
restarting. Please learn your distribution's method of doing this the
<quote>right way
</quote>.
</para>
-->
<para>
Another option here is to uninstall a package if you know you do not need it.
This is a pretty sure-fire, permanent fix. This also alleviates the
potential problem of keeping all installed packages updated and current (Step
2). <![%linuxall;[ And, package management systems like
<application>RPM</application> or <application>DEB</application> make it very
easy to re-install a package should you change your mind.]]><![%redhat;[
<application>RPM</application> makes it very easy to re-install a package
should you change your mind.]]>
</para>
<![%redhat;[
<para>
To uninstall packages with <application>RPM</application>:
</para>
<para>
<screen>
# rpm -ev telnet-server rsh rsh-server
</screen>
</para>
<para>
The above command would uninstall the <quote>telnet server</quote> package
(but not telnet client!), <quote>rsh</quote> client and <quote>rsh
server</quote> packages in one command. Red Hat also includes
<application>gnorpm</application>, a GUI <application>RPM</application>
management utility which can do this as well.
</para>
]]>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3 id="inetd">
<title>Inetd</title>
<para>
<application>Inetd</application> is called a <quote>super-daemon</quote>
because it is used to spawn sub-daemons. <command>inetd</command> itself will
generally be started via init scripts, and will <quote>listen</quote> on the
various ports as determined by which services are enable in its configuration
file, <filename>/etc/inetd.conf</filename>. Any service listed here will be
under the control of <command>inetd</command>. Likewise, any of the listening
servers in <command>netstat</command> output that list <quote>inetd</quote>
in the last column under <quote>Program Name</quote>, will have been started
by <command>inetd</command>. You will have to adjust the
<command>inetd</command> configuration to stop these services.
<command>xinetd</command> is an enhanced <command>inetd</command> replacement,
and is configured differently (see next section below).
</para>
<para>
Below is a partial snippet from a typical <filename>inetd.conf</filename>. Any
service with a <quote>#</quote> at the beginning of the line is
<quote>commented out</quote>, and thus ignored by <command>inetd</command>,
and consequently disabled.
</para>
<para>
<screen>
#
# inetd.conf This file describes the services that will be available
# through the INETD TCP/IP super server. To re-configure
# the running INETD process, edit this file, then send the
# INETD process a SIGHUP signal.
#
# Version: @(#)/etc/inetd.conf 3.10 05/27/93
#
# Authors: Original taken from BSD UNIX 4.3/TAHOE.
# Fred N. van Kempen, &lt;waltje@uwalt.nl.mugnet.org&gt;
#
# Modified for Debian Linux by Ian A. Murdock &lt;imurdock@shell.portal.com&gt;
#
# Echo, discard, daytime, and chargen are used primarily for testing.
#
# To re-read this file after changes, just do a 'killall -HUP inetd'
#
#echo stream tcp nowait root internal
#echo dgram udp wait root internal
#discard stream tcp nowait root internal
#discard dgram udp wait root internal
#daytime stream tcp nowait root internal
#daytime dgram udp wait root internal
#chargen stream tcp nowait root internal
#chargen dgram udp wait root internal
time stream tcp nowait root internal
#
# These are standard services.
#
#ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd -l -a
#telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd
#
# Shell, login, exec, comsat and talk are BSD protocols.
#
#shell stream tcp nowait root /usr/sbin/tcpd in.rshd
#login stream tcp nowait root /usr/sbin/tcpd in.rlogind
#exec stream tcp nowait root /usr/sbin/tcpd in.rexecd
#comsat dgram udp wait root /usr/sbin/tcpd in.comsat
#talk dgram udp wait root /usr/sbin/tcpd in.talkd
#ntalk dgram udp wait root /usr/sbin/tcpd in.ntalkd
#dtalk stream tcp wait nobody /usr/sbin/tcpd in.dtalkd
#
# Pop and imap mail services et al
#
#pop-2 stream tcp nowait root /usr/sbin/tcpd ipop2d
pop-3 stream tcp nowait root /usr/sbin/tcpd ipop3d
#imap stream tcp nowait root /usr/sbin/tcpd imapd
#
# The Internet UUCP service.
#
#uucp stream tcp nowait uucp /usr/sbin/tcpd /usr/lib/uucp/uucico -l
#
&lt;snip&gt;
</screen>
</para>
<para>
The above example has two services enabled: <command>time</command> and
<command>pop3</command>. To disable these, all we need is to open the
file with a text editor, comment out the two services with a
<quote>#</quote>, save the file, and then restart <command>inetd</command>
(as root):
</para>
<para>
<screen>
<![%linuxall;[ # /etc/init.d/inetd restart ]]>
<![%redhat;[ # /etc/rc.d/init.d/inetd restart ]]>
</screen>
</para>
<para>
Check your logs for errors, and run <command>netstat</command> again to
verify all went well.
</para>
<para>
A quicker way of getting the same information, using <command>grep</command>:
</para>
<para>
<screen>
$ grep -v '^#' /etc/inetd.conf
time stream tcp nowait root internal
pop-3 stream tcp nowait root /usr/sbin/tcpd ipop3d
</screen>
</para>
<para>
Again, do you see anything there that you don't know what it is? Then in
all likelihood you are not using it, and it should be disabled.
</para>
<para>
Unlike the init services configuration, this is a lasting change so only
the one step is required.
</para>
<para>
Let's expose one myth that gets tossed around: you shouldn't disable a
service by commenting out, or removing, entries from
<filename>/etc/services</filename>. This may have the desired effect
in some cases, but is not the right way to do it, and may interfere
with the normal operation of other system utilities.
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3 id="xinetd">
<title>Xinetd</title>
<para>
<application>xinetd</application> is an <application>inetd</application> replacement with
enhancements. <![%redhat;[ Red Hat includes <application>xinetd</application> with
7.0 and later releases. ]]> It essentially serves the same purpose as
<application>inetd</application>, but the
configuration is different. The configuration can be in the file
<filename>/etc/xinetd.conf</filename>, or individual files in the directory
<filename>/etc/xinetd.d/</filename>.
<![%redhat;[ Configuration of individual services will be in the individual
files under <filename>/etc/xinetd.d/*</filename>.]]> Turning off
<application>xinetd</application> services is done by either deleting the
corresponding configuration section, or file. Or by using your text editor and
simply setting <literal>disable = yes </literal> for the appropriate service.
<![%redhat;[ Or by using <command>chkconfig</command>. ]]> Then,
<application>xinetd</application> will need to be restarted. See <literal>man
xinetd</literal> and <literal>man xinetd.conf</literal> for syntax and
configuration options. A sample <command>xinetd</command> configuration:
</para>
<para>
<screen>
# default: on
# description: The wu-ftpd FTP server serves FTP connections. It uses \
# normal, unencrypted usernames and passwords for authentication.
service ftp
{
disable = no
socket_type = stream
wait = no
user = root
server = /usr/sbin/in.ftpd
server_args = -l -a
log_on_success += DURATION USERID
log_on_failure += USERID
nice = 10
}
</screen>
</para>
<para>
You can get a quick list of enabled services:
</para>
<para>
<screen>
$ grep disable /etc/xinetd.d/* |grep no
/etc/xinetd.d/finger: disable = no
/etc/xinetd.d/rexec: disable = no
/etc/xinetd.d/rlogin: disable = no
/etc/xinetd.d/rsh: disable = no
/etc/xinetd.d/telnet: disable = no
/etc/xinetd.d/wu-ftpd: disable = no
</screen>
</para>
<para>
At this point, the above output should raise some red flags. In the
overwhelming majority of systems, all the above can be disabled without any
adverse impact. Not sure? Try it without that service. After disabling
unnecessary services, then restart <command>xinetd</command>:
</para>
<para>
<screen>
<![%linuxall;[ # /etc/init.d/xinetd restart ]]>
<![%redhat;[ # /etc/rc.d/init.d/xinetd restart ]]>
</screen>
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3>
<title>When All Else Fails</title>
<para>
OK, if you can't find the <quote>right</quote> way to stop a service,
or maybe a service is being started and you can't find how or where,
you can <quote>kill</quote> the process. To do this, you will need to know
the PID (Process I.D.). This can be found with <command>ps</command>,
<command>top</command>, <command>fuser</command> or other system utilities.
For <command>top</command> and <command>ps</command>, this will be the number
in the first column. See the <link linkend="pid">Port and Process Owner</link>
section in the Appendix for examples.
</para>
<para>
Example (as root):
</para>
<para>
<screen>
# kill 1163
</screen>
</para>
<para>
Then run <command>top</command> or <command>ps</command> again to verify
that the process is gone. If not, then:
</para>
<para>
<screen>
# kill -KILL 1163
</screen>
</para>
<para>
Note the second <quote>KILL</quote> in there. This must be done either
by the user who owns the process, or root. Now go find where and how this
process got started ;-)
</para>
<para>
The <filename>/proc</filename> filesystem can also be used to find out
more information about each process. Armed with the PID, we can find
the path to a mysterious process:
</para>
<para>
<screen>
$ /bin/ps ax|grep tcpgate
921 ? S 0:00 tcpgate
</screen>
</para>
<para>
<screen>
# ls -l /proc/921/exe
lrwxrwxrwx 1 root root 0 July 21 12:11 /proc/921/exe -> /usr/local/bin/tcpgate
</screen>
</para>
</sect3>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="exceptions">
<title>Exceptions</title>
<para>
Above we used the criteria of turning off <emphasis>all</emphasis> unnecessary
services. Sometimes that is not so obvious. And sometimes what may be
required for one person's configuration is not the same for another's.
Let's look at a few common services that fall in this category.
</para>
<para>
Again, our rule of thumb is if we don't need it, we won't run it. It's that
simple. If we do need any of these, they are prime candidates for some
kind of restrictive policies via firewall rules or other mechanisms (see
below).
</para>
<para>
<itemizedlist>
<listitem>
<para>
<application>identd</application> - This is a protocol that has been
around for ages, and is often installed and running by default. It is used
to provide a minimal amount of information about who is connecting to a
server. But, it is not necessary in many cases. Where might you need it?
Most IRC servers require it. Many mail servers use it, but don't really
require it. Try your mail setup without it. If
<application>identd</application> is going to be a problem, it will
be because there is a time out before the server starts sending or
receiving mail. So mail should work fine without it, but may be slower. A
few <application>ftp</application> servers may require it. Most don't
though.
<![%redhat;[ Older versions of Red Hat started
<application>identd</application> via <application>inetd</application>.
Recent versions start this via init scripts.]]>
</para>
<para>
If <application>identd</application> is required, there are some
configuration options that can greatly reduce the information that is
revealed:
</para>
<para>
<screen>
/usr/sbin/in.identd in.identd -l -e -o -n -N
</screen>
</para>
<para>
The <literal>-o</literal> flag tells <application>identd</application> to
not reveal the operating system type it is run on and to instead always
return <quote>OTHER</quote>. The <literal>-e</literal> flag tells identd
to always return <quote>UNKNOWN-ERROR</quote> instead of the
<quote>NO-USER</quote> or <quote>INVALID-PORT</quote> errors. The
<literal>-n</literal> flag tells identd to always return user numbers
instead of user names, if you wish to keep the user names a secret. The
<literal>-N</literal> flag makes identd check for the file
<filename>.noident</filename> in the user's home directory for which the
daemon is about to return a user name. It that file exists then the
daemon will give the error <quote>HIDDEN-USER</quote> instead of the
normal <quote>USERID</quote> response.
</para>
</listitem>
<listitem>
<para>
Mail server (MTA's like <application>sendmail</application>,
<application>qmail</application>, etc) - Often a fully functional mail
server like <application>sendmail</application> is installed by default.
The only time that this is actually required is if you are hosting a
domain, and receiving incoming mail directly. Or possibly, for exchanging
mail on a LAN, in which case it does not need Internet exposure and can
be safely firewalled. For your ISP's POP mail access, you don't need it
even though this is a common configuration. One alternative here is to
use <application>fetchmail</application> for POP mail retrieval with the
<literal>-m</literal> option to specify a local delivery agent:
<literal>fetchmail -m procmail</literal> for instance works with no
sendmail daemon running at all. Sendmail, can be handy to have running,
but the point is, it is not required in many situations, and can be
disabled, or firewalled safely.
</para>
</listitem>
<listitem>
<para>
<application>BIND</application> (named) - This often is installed by
default, but is only really needed if you are an authoritative name server
for a domain. If you are not sure what this means, then you definitely
don't need it. BIND is probably the number one crack target on the
Internet. <application>BIND</application> is often used though in a
<quote>caching</quote> only mode. This can be quite useful, but does not
require full exposure to the Internet. In other words, it should be
restricted or firewalled. See special handling of <link linkend="indapps">individual applications</link> below.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="conclusions">
<title>Summary and Conclusions for Step 1</title>
<para>
In this section we learned how to identify which services are running
on our system, and were given some tips on how to determine which
services may be necessary. Then we learned how to find where the services
were being started, and how to stop them. If this has not made sense,
now is a good time to re-read the above.
</para>
<para>
Hopefully you've already taken the above steps. Be sure to test your results
with <command>netstat</command> again, just to verify the desired end has
been achieved, and only the services that are really required are running.
</para>
<para>
It would also be wise to do this after the next reboot, anytime you upgrade
a package (to make sure a new configuration does not sneak in), and after
every system upgrade or new install.
</para>
</sect2>
</sect1>
<!-- ~ End section ~ -->
<!-- ~~~~~~~~ New section Header ~~~~~~~~~ -->
<sect1 id="updates">
<title>Step 2: Updating</title>
<para>
OK, this section should be comparatively short, simple and straightforward
compared to the above, but no less important.
</para>
<para>
The very first thing after a new install you should check <![%linuxall;[ your
distribution's updates and security notices and apply all patches]]>
<![%redhat;[ the errata notices at <ulink
url="http://redhat.com/errata/">http://redhat.com/apps/errata/</ulink>,
and apply all relevant updates]]>. Only a year old you say? That's a long
time actually, and not current enough to be safe. Only a few months or few
weeks? Check anyway. A day or two? Better safe than sorry. It is quite
possible that security updates have been released during the pre-release
phase of the development and release cycle. If you can't take this step,
disable any publicly accessible services until you can.
</para>
<para>
Linux distributions are not static entities. They are updated with new,
patched packages as the need arises. The updates are just as important
as the original installation. Even more so, since they are fixes. Sometimes
these updates are bug fixes, but quite often they are security fixes because
some hole has been discovered. Such <quote>holes</quote> are
<emphasis>immediately</emphasis> known to the cracker community, and they are
quick to exploit them on a large scale. Once the hole is known, it is quite
simple to get in through it, and there will be many out there looking for it.
And Linux developers are also equally quick to provide fixes. Sometimes the
same day as the hole has become known!
</para>
<para>
Keeping <emphasis>all</emphasis> installed packages current with your release
is one of the most important steps you can take in maintaining a secure
system. It can not be emphasized enough that all installed packages should be
kept updated -- not just the ones you use. If this is burdensome, consider
uninstalling any unused packages. Actually this is a good idea anyway.
</para>
<para>
But where to get this information in a timely fashion? There are a number of
web sites that offer the latest security news. There are also a number of
mailing lists dedicated to this topic. <![%linuxall;[ In fact, your vendor
most likely has such a list where vulnerabilities and the corresponding fix
is announced. ]]> <![%redhat;[ In fact, Red Hat has the <quote>watch</quote>
list, just for this purpose at <ulink
url="https://listman.redhat.com/mailman/listinfo/redhat-watch-list">https://listman.redhat.com/mailman/listinfo/redhat-watch-list</ulink>. This is a very low
volume list by the way. ]]> This is an excellent way to stay abreast of
issues effecting your release, and is <emphasis>highly
recommended</emphasis>. <ulink
url="http://linuxsecurity.com">http://linuxsecurity.com</ulink> is a good
site for Linux only issues. They also have weekly newsletters available:
<ulink
url="http://www.linuxsecurity.com/general/newsletter.html">http://www.linuxsecurity.com/general/newsletter.html</ulink>.
</para>
<para>
<![%linuxall;[ Also, many distributions have utilities that will automatically update your
installed packages via ftp. This can be run as a
<application>cron</application> job on a regular basis and is a painless
way to go if you have ready Internet access. ]]>
<![%redhat;[ Red Hat also has the <application>up2date</application> utility
for automatically keeping your system(s) up to date ;-). See the man page
for details.]]>
</para>
<!--
<para>
If you are running public services over the Internet, you can further stay
ahead of the curve, by running the latest version of these packages, whether
they are an official update to your distribution or not.
</para>
-->
<para>
This is not a one time process -- it is ongoing. It is important to stay
current. So watch those security notices. And subscribe to
<![%linuxall;[ your vendor's ]]> <![%redhat;[ that ]]>
security mailing list today! If you have cable modem, DSL, or other
full time connection, there is no excuse not to do this religiously.
All distributions make this easy enough!
</para>
<para>
One last note: any time a new package is installed, there is also a
chance that a new or revised configuration has been installed as well.
Which means that if this package is a server of some kind, it may be
enabled as a result of the update. This is bad manners, but it can
happen, so be sure to run <application>netstat</application> or
comparable to verify your system is where you want it after any
updates or system changes. In fact, do it periodically even if there are no
such changes.
</para>
<!-- ~~~~~ New section ~~~~~ -->
<sect2>
<title>Summary and Conclusions for Step 2</title>
<para>
It is very simple: make sure your Linux installation is current. Check
<![%linuxall;[ with your vendor ]]> <![%redhat;[ the Red Hat errata ]]>
for what updated packages may be available. There is nothing
wrong with running an older release, just so the packages in it are
updated according to what <![%linuxall;[ your vendor ]]> <![%redhat;[ Red Hat ]]>
has made available since the initial release. At least as long as
<![%linuxall;[ your vendor ]]> <![%redhat;[ Red Hat ]]> is still supporting
the release and updates are still being provided. <![%redhat;[ For instance,
Red Hat has stopped providing updates for 5.0 and 5.1, but still does for
5.2.]]>
</para>
</sect2>
</sect1>
<!-- ~ End section ~ -->
<!-- ~~~~~~~~ New section Header ~~~~~~~~~ -->
<sect1 id="firewalls">
<title>Step 3: Firewalls and Setting Access Policies</title>
<para>
So what is a <quote>firewall</quote>? It's a vague term that can mean
anything that acts as a protective barrier between us and the outside world.
This can be a dedicated system, or a specific application that provides this
functionality. Or it can be a combination of components, including various
combinations of hardware and software. Firewalls are built from
<quote>rules</quote> that are used to define what is allowed to enter and
exit a given system or network. Let's look at some of the possible components
that are readily available for Linux, and how we might implement a reasonably
safe firewalling strategy.
</para>
<para>
In Step 1 above, we have turned off all services we don't need. In our
example, there were a few we still needed to have running. In this
section, we will take the next step here and decide which we need to leave
open to the world. And which we might be able to restrict in some way. If we can
block them all, so much the better, but this is not always practical.
</para>
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="strategy">
<title>Strategy</title>
<para>
What we want to do now is restrict connections and traffic so that we only
allow the minimum necessary for whatever our particular situation is. In
some cases we may want to block all incoming <quote>new</quote> connection
attempts. Example: we want to run <application>X</application>, but don't
want anyone from outside to access it, so we'll block it completely from
outside connections. In other situations, we may want to limit, or restrict,
incoming connections to trusted sources only. The more restrictive, the
better. Example: we want to <command>ssh</command> into our system from
outside, but we only ever do this from our workplace. So we'll limit
<command>sshd</command> connections to our workplace address range. There are
various ways to do this, and we'll look at the most common ones.
</para>
<para>
We also will not want to limit our firewall to any one application. There is
nothing wrong with a <quote>layered</quote> defense-in-depth approach. Our
front line protection will be a packet filter -- either
<application>ipchains</application> or <application>iptables</application>
(see below). Then we can use additional tools and mechanisms to reinforce
our firewall.
</para>
<para>
We will include some brief examples. Our rule of thumb will be to deny
everything as the default policy, then open up just what we need. We'll try
to keep this as simple as possible since it can be an involved and complex
topic, and just stick to some of the most basic concepts. See the
<link linkend="links">Links section</link> for further reading on this
topic.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="filters">
<title>Packet Filters -- Ipchains and Iptables</title>
<para>
<quote>Packet filters</quote> (like <application>ipchains</application>)
have the ability to look at individual packets, and make decisions based
on what they find. These can be used for many purposes. One common purpose
is to implement a firewall.
</para>
<para>
Common packet filters on Linux are <application>ipchains</application> which
is standard with 2.2 kernels, and <application>iptables</application> which
is available with the more recent 2.4 kernels.
<application>iptables</application> has more advanced packet filtering
capabilities and is recommended for anyone running a 2.4 kernel. But either
can be effective for our purposes. <application>ipfwadm</application> is
a similar utility for 2.0 kernels (not discussed here).
</para>
<para>
If constructing your own <application>ipchains</application> or
<application>iptables</application> firewall rules seems a bit daunting,
there are various sites that can automate the process. See the
<link linkend="links">Links section</link>. Also the included examples may be
used as a starting point.
<![%linuxall;[ And your distribution may be including a
utility of some kind for generating a firewall script. ]]>
<![%redhat;[ As of Red Hat 7.1, Red Hat is providing init scripts
for <application>ipchains</application> and <application>iptables</application>,
and <application>gnome-lokkit</application> for generating a very basic
set of firewall rules (<link linkend="lokkit">see below</link>). ]]> This may be
adequate, but it is still recommended to know the proper syntax and
how the various mechanisms work as such tools rarely do more than a
few very simple rules.
</para>
<note>
<para>
Various examples are given below. These are presented for illustrative
purposes to demonstrate some of the concepts being discussed here.
While they might also be useful as a starting point for your own
script, please note that they are not meant to be all encompassing.
You are strongly encouraged to understand how the scripts work, so
you can create something even more tailored for your own situation.
</para>
<para>
The example scripts are just protecting inbound connections to one interface
(the one connected to the Internet). This may be adequate for many simple
home type situations, but, conversely, this approach is not adequate for
<emphasis>all</emphasis> situations!
</para>
</note>
<!-- ~~~~~ New section ~~~~~ -->
<sect3 id="ipchains">
<title>ipchains</title>
<para>
<application>ipchains</application> can be used with either 2.2 or 2.4
kernels. When <application>ipchains</application> is in place, it checks
every packet that moves through the system. The packets move across different
<quote>chains</quote>, depending where they originate and where they are
going. Think of <quote>chains</quote> as rule sets. In advanced
configurations, we could define our own custom chains. The three default
built-in chains are <literal>input</literal>, which is incoming traffic,
<literal>output</literal>, which is outgoing traffic, and
<literal>forward</literal>, which is traffic being forwarded from one
interface to another (typically used for <quote>masquerading</quote>).
Chains can be manipulated in various ways to control the flow of traffic in
and out of our system. Rules can be added at our discretion to achieve
the desired result.
</para>
<para>
At the end of every <quote>chain</quote> is a <quote>target</quote>. The
target is specified with the <literal>-j</literal> option to the command. The
target is what decides the fate of the packet and essentially terminates that
particular chain. The most common targets are mostly self-explanatory:
<literal>ACCEPT</literal>, <literal>DENY</literal>,
<literal>REJECT</literal>, and <literal>MASQ</literal>.
<literal>MASQ</literal> is for <quote>ipmasquerading</quote>.
<literal>DENY</literal> and <literal>REJECT</literal> essentially do the
same thing, though in different ways. Is one better than the other? That is
the subject of much debate, and depends on other factors that are beyond the
scope of this document. For our purposes, either should suffice.
</para>
<para>
<application>ipchains</application> has a very flexible configuration. Port
(or port ranges), interfaces, destination address, source address can be
specified, as well as various other options. The man page explains these
details well enough that we won't get into specifics here.
</para>
<para>
Traffic entering our system from the Internet, enters via the
<literal>input</literal> chain. This is the one that we need as tight as we
can make it.
</para>
<para>
Below is a brief example script for a hypothetical system. We'll let the
comments explain what this script does. Anything starting with a
<quote>#</quote> is a comment. <application>ipchains</application> rules
are generally incorporated into shell scripts, using shell variables to
help implement the firewalling logic.
</para>
<para>
<programlisting>
#!/bin/sh
#
# ipchains.sh
#
# An example of a simple ipchains configuration.
#
# This script allows ALL outbound traffic, and denies
# ALL inbound connection attempts from the outside.
#
###################################################################
# Begin variable declarations and user configuration options ######
#
IPCHAINS=/sbin/ipchains
# This is the WAN interface, that is our link to the outside world.
# For pppd and pppoe users.
# WAN_IFACE="ppp0"
WAN_IFACE="eth0"
## end user configuration options #################################
###################################################################
# The high ports used mostly for connections we initiate and return
# traffic.
LOCAL_PORTS=`cat /proc/sys/net/ipv4/ip_local_port_range |cut -f1`:\
`cat /proc/sys/net/ipv4/ip_local_port_range |cut -f2`
# Any and all addresses from anywhere.
ANYWHERE="0/0"
# Let's start clean and flush all chains to an empty state.
$IPCHAINS -F
# Set the default policies of the built-in chains. If no match for any
# of the rules below, these will be the defaults that ipchains uses.
$IPCHAINS -P forward DENY
$IPCHAINS -P output ACCEPT
$IPCHAINS -P input DENY
# Accept localhost/loopback traffic.
$IPCHAINS -A input -i lo -j ACCEPT
# Get our dynamic IP now from the Inet interface. WAN_IP will be our
# IP address we are protecting from the outside world. Put this
# here, so default policy gets set, even if interface is not up
# yet.
WAN_IP=`ifconfig $WAN_IFACE |grep inet |cut -d : -f 2 |cut -d \ -f 1`
# Bail out with error message if no IP available! Default policy is
# already set, so all is not lost here.
[ -z "$WAN_IP" ] && echo "$WAN_IFACE not configured, aborting." && exit 1
# Accept non-SYN TCP, and UDP connections to LOCAL_PORTS. These are
# the high, unprivileged ports (1024 to 4999 by default). This will
# allow return connection traffic for connections that we initiate
# to outside sources. TCP connections are opened with 'SYN' packets.
$IPCHAINS -A input -p tcp -s $ANYWHERE -d $WAN_IP $LOCAL_PORTS ! -y -j ACCEPT
# We can't be so selective with UDP since that protocol does not
# know about SYNs.
$IPCHAINS -A input -p udp -s $ANYWHERE -d $WAN_IP $LOCAL_PORTS -j ACCEPT
## ICMP (ping)
#
# ICMP rules, allow the bare essential types of ICMP only. Ping
# request is blocked, ie we won't respond to someone else's pings,
# but can still ping out.
$IPCHAINS -A input -p icmp --icmp-type echo-reply \
-s $ANYWHERE -i $WAN_IFACE -j ACCEPT
$IPCHAINS -A input -p icmp --icmp-type destination-unreachable \
-s $ANYWHERE -i $WAN_IFACE -j ACCEPT
$IPCHAINS -A input -p icmp --icmp-type time-exceeded \
-s $ANYWHERE -i $WAN_IFACE -j ACCEPT
###################################################################
# Set the catchall, default rule to DENY, and log it all. All other
# traffic not allowed by the rules above, winds up here, where it is
# blocked and logged. This is the default policy for this chain
# anyway, so we are just adding the logging ability here with '-l'.
# Outgoing traffic is allowed as the default policy for the 'output'
# chain. There are no restrictions on that.
$IPCHAINS -A input -l -j DENY
echo "Ipchains firewall is up `date`."
##-- eof ipchains.sh
</programlisting>
</para>
<para>
To use the above script would require that it is executable (i.e.
<literal>chmod +x ipchains.sh</literal>), and run by root to build the
chains, and hence the firewall.
</para>
<para>
To summarize what this example did was to start by setting some shell
variables in the top section, to be used later in the script. Then we set
the default rules (ipchains calls these <quote>policies</quote>) of denying
all inbound and forwarded traffic, and of allowing all our own outbound
traffic. We had to open some holes in the high, unprivileged ports so
that we could have return traffic from connections that bigcat initiates to
outside addresses. If we connect to someone's web server, we want that HTML
data to be able to get back to us, for instance. The same applies to other
network traffic. We then allowed a few specific types of the ICMP protocol
(most are still blocked). We are also logging any inbound traffic that
violates any of our rules so we know who is doing what. Notice that we are
only using IP address here, not hostnames of any kind. This is so that
our firewall works, even in situation where there may be DNS failures.
Also, to prevent any kind of DNS spoofing.
</para>
<para>
See the <application>ipchains</application> man page for a full explanation
of syntax. The important ones we used here are:
</para>
<blockquote>
<simplelist>
<member>
&nbsp;<literal>-A input</literal>: Adds a rule to the
<quote>input</quote> chain. The default chains are input, output, and forward.
</member>
</simplelist>
<simplelist>
<member>
&nbsp;<literal>-p udp</literal>: This rule only applies to the
<quote>UDP</quote> <quote>protocol</quote>. The <literal>-p</literal>
option can be used with tcp, udp or icmp protocols.
</member>
</simplelist>
<simplelist>
<member>
&nbsp;<literal>-i $WAN_IFACE</literal>: This rule applies to the specified
interface only, and applies to whatever chain is referenced (input, output,
or forward).
</member>
</simplelist>
<simplelist>
<member>
&nbsp;<literal>-s &lt;IP address&gt;</literal> [port]: This rule only
applies to the source address as specified. It can optionally have a port
(e.g. 22) immediately afterward, or port range, e.g. 1023:4999.
</member>
</simplelist>
<simplelist>
<member>
&nbsp;<literal>-d &lt;IP address&gt;</literal> [port]: This rule only
applies to the destination address as specified. Also, it may include port or
port range.
</member>
</simplelist>
<simplelist>
<member>
&nbsp;<literal>-l</literal> : Any packet that hits a rule with this option
is logged (lower case <quote>L</quote>).
</member>
</simplelist>
<simplelist>
<member>
&nbsp;<literal>-j ACCEPT</literal>: Jumps to the <quote>ACCEPT</quote>
<quote>target</quote>. This effectively terminates this chain
and decides the ultimate fate for this particular packet, which in this
example is to <quote>ACCEPT</quote> it. The same is
true for other <literal>-j</literal> targets like <literal>DENY</literal>.
</member>
</simplelist>
</blockquote>
<para>
By and large, the order in which command line options are specified is not
significant. The chain name (e.g. <literal>input</literal>) must come first
though.
</para>
<para>
Remember in Step 1 when we ran <command>netstat</command>, we had
both X and print servers running among other things. We don't want these
exposed to the Internet, even in a limited way. These are still happily
running on bigcat, but are now safe and sound behind our
<application>ipchains</application> based firewall. You probably have other
services that fall in this category as well.
</para>
<para>
The above example is a simplistic all or none approach. We allow all our own
outbound traffic (not necessarily a good idea), and block all inbound
connection attempts from outside. It is only protecting one interface, and
really just the inbound side of that interface. It would more than likely
require a bit of fine tuning to make it work for you. For a more advanced set
of rules, see the <link linkend="pfilters">Appendix</link>. And you might
want to read <ulink
url="http://tldp.org/HOWTO/IPCHAINS-HOWTO.html">http://tldp.org/HOWTO/IPCHAINS-HOWTO.html</ulink>.
</para>
<para>
Whenever you have made changes to your firewall, you should verify its
integrity. One step to make sure your rules seem to be doing what you
intended, is to see how <application>ipchains</application> has interpreted
your script. You can do this by opening your <application>xterm</application>
very wide, and issuing the following command:
</para>
<para>
<screen>
# ipchains -L -n -v | less
</screen>
</para>
<para>
The output is grouped according to chain. You should also find a way to scan
yourself (see the <link linkend="verify">Verifying section</link> below). And
then keep an eye on your logs to make sure you are blocking what is
intended.
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3 id="iptables">
<title>iptables</title>
<para>
<application>iptables</application> is the next generation packet filter for
Linux, and requires a 2.4 kernel. It can do everything
<application>ipchains</application> can, but has a number of noteworthy
enhancements. The syntax is similar to <application>ipchains</application> in
many respects. See the man page for details.
</para>
<para>
The most noteworthy enhancement is <quote>connection tracking</quote>, also
known as <quote>stateful inspection</quote>. This gives
<application>iptables</application> more knowledge of the state of each
packet. Not only does it know if the packet is a TCP or UDP packet, or
whether it has the SYN or ACK flags set, but also if it is part of an existing
connection, or related somehow to an existing connection. The implications
for firewalling should be obvious.
</para>
<para>
The bottom line is that it is easier to get a tight firewall with
<application>iptables</application>, than with
<application>ipchains</application>. So this is the recommended way to go.
</para>
<para>
Here is the same script as above, revised for
<application>iptables</application>:
</para>
<para>
<programlisting>
#!/bin/sh
#
# iptables.sh
#
# An example of a simple iptables configuration.
#
# This script allows ALL outbound traffic, and denies
# ALL inbound connection attempts from the Internet interface only.
#
###################################################################
# Begin variable declarations and user configuration options ######
#
IPTABLES=/sbin/iptables
# Local Interfaces
# This is the WAN interface that is our link to the outside world.
# For pppd and pppoe users.
# WAN_IFACE="ppp0"
WAN_IFACE="eth0"
#
## end user configuration options #################################
###################################################################
# Any and all addresses from anywhere.
ANYWHERE="0/0"
# This module may need to be loaded:
modprobe ip_conntrack_ftp
# Start building chains and rules #################################
#
# Let's start clean and flush all chains to an empty state.
$IPTABLES -F
# Set the default policies of the built-in chains. If no match for any
# of the rules below, these will be the defaults that IPTABLES uses.
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P INPUT DROP
# Accept localhost/loopback traffic.
$IPTABLES -A INPUT -i lo -j ACCEPT
## ICMP (ping)
#
# ICMP rules, allow the bare essential types of ICMP only. Ping
# request is blocked, ie we won't respond to someone else's pings,
# but can still ping out.
$IPTABLES -A INPUT -p icmp --icmp-type echo-reply \
-s $ANYWHERE -i $WAN_IFACE -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type destination-unreachable \
-s $ANYWHERE -i $WAN_IFACE -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type time-exceeded \
-s $ANYWHERE -i $WAN_IFACE -j ACCEPT
###################################################################
# Set the catchall, default rule to DENY, and log it all. All other
# traffic not allowed by the rules above, winds up here, where it is
# blocked and logged. This is the default policy for this chain
# anyway, so we are just adding the logging ability here with '-j
# LOG'. Outgoing traffic is allowed as the default policy for the
# 'output' chain. There are no restrictions on that.
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A INPUT -m state --state NEW -i ! $WAN_IFACE -j ACCEPT
$IPTABLES -A INPUT -j LOG -m limit --limit 30/minute --log-prefix "Dropping: "
echo "Iptables firewall is up `date`."
##-- eof iptables.sh
</programlisting>
</para>
<para>
The same script logic is used here, and thus this does pretty much the same
exact thing as the <application>ipchains</application> script in the
previous section. There are some subtle differences as to syntax. Note the
case difference in the chain names for one (e.g. INPUT vs input). Logging is
handled differently too. It has its own <quote>target</quote> now
(<literal>-j LOG</literal>), and is much more flexible.
</para>
<para>
There are some very fundamental differences as well, that might not be so
obvious. Remember this section from the <application>ipchains</application>
script:
</para>
<para>
<programlisting>
# Accept non-SYN TCP, and UDP connections to LOCAL_PORTS. These are the high,
# unprivileged ports (1024 to 4999 by default). This will allow return
# connection traffic for connections that we initiate to outside sources.
# TCP connections are opened with 'SYN' packets. We have already opened
# those services that need to accept SYNs for, so other SYNs are excluded here
# for everything else.
$IPCHAINS -A input -p tcp -s $ANYWHERE -d $WAN_IP $LOCAL_PORTS ! -y -j ACCEPT
# We can't be so selective with UDP since that protocol does not know
# about SYNs.
$IPCHAINS -A input -p udp -s $ANYWHERE -d $WAN_IP $LOCAL_PORTS -j ACCEPT
</programlisting>
</para>
<para>
We jumped through hoops here with <application>ipchains</application> so
that we could restrict unwanted, incoming connections as much as possible. A
bit of a kludge, actually.
</para>
<para>
That section is missing from the <application>iptables</application> version.
It is not needed as connection tracking handles this quite nicely, and then
some. This is due to the <quote>statefulness</quote> of
<application>iptables</application>. It knows more about each packet than
<application>ipchains</application>. For instance, it knows whether the
packet is part of a <quote>new</quote> connection, or an
<quote>established</quote> connection, or a <quote>related</quote>
connection. This is the so-called <quote>stateful inspection</quote> of
connection tracking.
</para>
<!--
<para>
To show another brief example and just how much work connection tracking can
do for us, here is an short and sweet example from the Netfilter
Packet-Filtering HOWTO:
</para>
<para>
This very succinct example shows the use of a user defined chain -
<quote>block</quote> here, which is jumped to from the only
<literal>INPUT</literal> and <literal>FORWARD</literal> rules there at the
end. This essentially allows all outbound traffic (since
<literal>OUTPUT</literal> is not defined here and that is the default
behavior). And then any connections that are <literal>ESTABLISHED</literal>
or <literal>RELATED</literal> to those <literal>OUTPUT</literal> connections
that we generate. So <quote>connection tracking</quote> is doing the lion's
share of the work here.
</para>
-->
<para>
There are many, many features of <application>iptables</application> that
are not touched on here. For more reading on the Netfilter project and
<application>iptables</application>, see <ulink
url="http://netfilter.samba.org">http://netfilter.samba.org</ulink>.
And for a more advanced set of rules, see the <link
linkend="pfilters">Appendix</link>.
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<![%redhat;[
<sect3 id="lokkit">
<title>Red Hat Firewall Configuration Tools</title>
<para>
Red Hat has not included firewall configuration tools until 7.1, when
the GUI utility <command>gnome-lokkit</command> started being bundled.
<command>gnome-lokkit</command> does a minimalist set of rules for
<application>ipchains</application> only. Explicit support for
<application>iptables</application> configuration is not an option, despite
the fact that the default kernel is 2.4.
</para>
<para>
<command>gnome-lokkit</command> is an option on non-upgrade installs, and
can also be run as a stand-alone app any time after installation. It will ask
a few simple questions, and dump the resulting rule-set into
<filename>/etc/sysconfig/ipchains</filename>.
</para>
<para>
As mentioned, this is a fairly minimalist set of rules, and possibly a
sufficient starting point. An example
<filename>/etc/sysconfig/ipchains</filename> created by
<command>gnome-lokkit</command>:
</para>
<para>
<programlisting>
# Firewall configuration written by lokkit
# Manual customization of this file is not recommended.
# Note: ifup-post will punch the current nameservers through the
# firewall; such entries will *not* be listed here.
:input ACCEPT
:forward ACCEPT
:output ACCEPT
-A input -s 0/0 -d 0/0 80 -p tcp -y -j ACCEPT
-A input -s 0/0 -d 0/0 25 -p tcp -y -j ACCEPT
-A input -s 0/0 -d 0/0 22 -p tcp -y -j ACCEPT
-A input -s 0/0 -d 0/0 23 -p tcp -y -j ACCEPT
-A input -s 0/0 -d 0/0 -i lo -j ACCEPT
-A input -s 0/0 -d 0/0 -i eth1 -j ACCEPT
-A input -s 127.0.0.1 53 -d 0/0 -p udp -j ACCEPT
-A input -s 0/0 -d 0/0 -p tcp -y -j REJECT
-A input -s 0/0 -d 0/0 -p udp -j REJECT
</programlisting>
</para>
<para>
This is in a format that can be read by the
<application>ipchains</application> command
<command>ipchains-restore</command>. Consequently, a new or modified set or
rules can be generated with the <command>ipchains-save</command>, and
redirecting the output to this file. <command>ipchains-restore</command> is
indeed how the <application>ipchains</application> init script processes
this file. So for this to work, the <application>ipchains</application>
service must be activated:
</para>
<para>
<screen>
# chkconfig ipchains on
</screen>
</para>
<para>
Conversely, if you want to roll your own <application>iptables</application>
rules instead, you should make sure the <application>ipchains</application>
init service is disabled. There is also an
<application>iptables</application> init script, that works much the same as
the <application>ipchains</application> version. There is just no support
from <command>gnome-lokkit</command> at this time.
</para>
</sect3>
]]>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="tcpwrappers">
<title>Tcpwrappers (libwrap)</title>
<para>
<application>Tcpwrappers</application> provides much the same desired results
as <application>ipchains</application> and
<application>iptables</application> above, though works quite differently.
<application>Tcpwrappers</application> actually intercepts the connection
attempt, then examines its configurations files, and decides whether to
accept or reject the request. <application>Tcpwrappers</application>
controls access at the application level, rather than the socket level
like <application>iptables</application> and <application>ipchains</application>.
This can be quite effective, and is a standard component on most Linux
systems.
</para>
<para>
<application>Tcpwrappers</application> consists of the configuration
files <filename>/etc/hosts.allow</filename> and
<filename>/etc/hosts.deny</filename>. The functionality is provided by the
<application>libwrap</application> library.
</para>
<para>
<application>Tcpwrappers</application> first looks to see if access is
permitted in <filename>/etc/hosts.allow</filename>, and if so, access is
granted. If not in <filename>/etc/hosts.allow</filename>, the file
<filename>/etc/hosts.deny</filename> is then checked to see if access is
<emphasis>not</emphasis> allowed. If so, access is denied. Else,
<emphasis>access is granted</emphasis>. For this reason,
<filename>/etc/hosts.deny</filename> should contain only one uncommented
line, and that is: <literal>ALL: ALL</literal>. Access should then be
permitted through entries in <filename>/etc/hosts.allow</filename>, where
specific services are listed, along with the specific host addresses allowed
to access these services. While hostnames can be used here, use of hostnames
opens the limited possibility for name spoofing.
</para>
<para>
<application>Tcpwrappers</application> is commonly used to protect services
that are started via <application>inetd</application> (or
<application>xinetd</application>). But also any program
that has been compiled with <application>libwrap</application> support, can
take advantage of it. Just don't assume that all programs have built in
<application>libwrap</application> support -- they do not. In fact, most
probably don't. So we will only use it in our examples here to protect
services start via <application>inetd</application>. And then rely on our
packet filtering firewall, or other mechanism, to protect non-(x)inetd
services.
</para>
<para>
Below is a small snippet from a typical <filename>inetd.conf</filename> file:
</para>
<para>
<screen>
# Pop and imap mail services et al
#
#pop-2 stream tcp nowait root /usr/sbin/tcpd ipop2d
#pop-3 stream tcp nowait root /usr/sbin/tcpd ipop3d
#imap stream tcp nowait root /usr/sbin/tcpd imapd
#
</screen>
</para>
<para>
The second to last column is the <application>tcpwrappers</application>
daemon -- <command>/usr/sbin/tcpd</command>. Immediately after is the daemon
it is protecting. In this case, <application>POP</application> and
<application>IMAP</application> mail servers. Your distro probably has
already done this part for you. For the few applications that have built-in
support for <application>tcpwrappers</application> via the
<application>libwrap</application> library, specifying the daemon as above
is not necessary.
</para>
<para>
We will use the same principles here: default policy is to deny everything,
then open holes to allow the minimal amount of traffic necessary.
</para>
<para>
So now with your text editor, <command>su</command> to root and open
<filename>/etc/hosts.deny</filename>. If it does not exist, then create
it. It is just a plain text file. We want the following line:
</para>
<para>
<screen>
ALL: ALL
</screen>
</para>
<para>
If it is there already, fine. If not, add it in and then save and close file.
Easy enough. <quote>ALL</quote> is one of the keywords that
<application>tcpwrappers</application> understands. The format is
<literal>$SERVICE_NAME : $WHO</literal>, so we are denying all connections to
all services here. At least all services that are using
<application>tcpwrappers</application>. Remember, this will primarily be
<application>inetd</application> services. See <literal>man 5
hosts_access</literal> for details on the syntax of these files. Note the
<quote>5</quote> there!
</para>
<para>
Now let's open up just the services we need, as restrictively as we can,
with a brief example:
</para>
<para>
<screen>
ALL: 127.0.0.1
sshd,ipop3d: 192.168.1.
sshd: .myworkplace.com, hostess.mymomshouse.com
</screen>
</para>
<para>
The first line allows all <quote>localhost</quote> connections.
You will need this. The second
allows connections to the <application>sshd</application> and
<application>ipop3d</application> services from IP addresses that start with
<literal>192.168.1.</literal>, in this case the private address range for
our hypothetical home LAN. Note the trailing <quote>.</quote>. It's
important. The third line allows connections to only our
<application>sshd</application> daemon from any host associated with
<literal>.myworkplace.com</literal>. Note the leading <quote>.</quote> in
this example. And then also, the single host
<literal>hostess.mymomshouse.com</literal>. In summary, localhost and all
our LAN connections have access to any and all tcpwrappered services on
bigcat. But only our workplace addresses, and our mother can use
<application>sshd</application> on bigcat from outside connections. Everybody
else is denied by the default policy in <filename>/etc/hosts.deny</filename>.
</para>
<para>
The types of wild cards above (<literal>.myworkplace.com</literal> and
<literal>192.168.1.</literal>) are not supported by
<application>ipchains</application> and <application>iptables</application>,
or most other Linux applications for that matter. Also,
<application>tcpwrappers</application> can use hostnames in place of
IP addresses which is quite handy in some situations. This does
not work with <application>ipchains</application> and
<application>iptables</application>.
</para>
<para>
You can test your <application>tcpwrappers</application> configuration
with the included <command>tcpdchk</command> utility (see the man page). Note
that at this time this does not work with <application>xinetd</application>,
and may not even be included in this case.
</para>
<para>
There is nothing wrong with using both <application>tcpwrappers</application>
and a packet filtering firewall like <application>ipchains</application>. In
fact, it is recommended to use a <quote>layered</quote> approach. This
helps guard against accidental misconfigurations. In this case, each
connection will be tested by the packet filter rules first, then
<application>tcpwrappers</application>.
</para>
<para>
Remember to make backup copies before editing system configuration files,
restart the daemon afterward, and then check the logs for error messages.
</para>
<!-- ~~~~~ New section ~~~~~ -->
<sect3 id="xinetd2">
<title>xinetd</title>
<para>
As mentioned, <ulink url="http://www.xinetd.org">xinetd</ulink> is an
enhanced <application>inetd</application> <![%redhat;[, and replaces
<application>inetd</application> as of Red Hat 7.0]]>. It has much of the
same functionality, with some notable enhancements. One is that
<application>tcpwrappers</application> support <![%linuxall;[ can ]]> be
<![%redhat;[ is ]]> compiled in, eliminating the need for explicit references to
<command>tcpd</command>. Which means <filename>/etc/hosts.allow</filename>
and <filename>/etc/hosts.deny</filename> are automatically in effect.
<![%linuxall;[ Don't
assume this is the case though. A little testing, then viewing the logs
should be able to tell you whether <application>tcpwrappers</application>
support is automatic or not. ]]>
</para>
<para>
Some of <application>xinetd's</application> other enhancements: specify
IP address to listen on, which is a very effective method of access control;
limit the rate of incoming connections and the total number of simultaneous
connections; limit services to specific times of day. See the
<application>xinetd</application> and <application>xinetd.conf</application>
man pages for more details.
</para>
<para>
The syntax is quite different though. An example from
<filename>/etc/xinetd.d/tftp</filename>:
</para>
<para>
<screen>
service tftp
{
socket_type = dgram
bind = 192.168.1.1
instances = 2
protocol = udp
wait = yes
user = nobody
only_from = 192.168.1.0
server = /usr/sbin/in.tftpd
server_args = /tftpboot
disable = no
}
</screen>
</para>
<para>
Notice the <literal>bind</literal> statement. We are only listening on,
or <quote>binding</quote> to, the private, LAN interface here. No outside
connections can be made since the outside port is not even opened. We are
also only accepting connections from <literal>192.168.1.0</literal>, our LAN.
For <application>xinetd's</application> purposes, this denotes any IP
address beginning with <quote>192.168.1</quote>. Note that the syntax is different
from <application>inetd</application>. The <literal>server</literal>
statement in this case is the <command>tftp</command> daemon,
<command>in.tftpd</command>. Again, this assumes that
<application>libwrap/tcpwrappers</application> support is compiled into
<application>xinetd</application>. The <literal>user</literal> running the
daemon will be <quote>nobody</quote>. Yes, there is a user account called
<quote>nobody</quote>, and it is wise to run such daemons as non-root users
whenever possible. Lastly, the <literal>disable</literal> statement is
<application>xinetd's</application> way of turning services on or off. In
this case, it is <quote>on</quote>. This is on here only as an example. Do
NOT run <application>tftp</application> as a public service as it is unsafe.
</para>
</sect3>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="portsentry">
<title>PortSentry</title>
<para>
<ulink url="http://www.psionic.org/products/portsentry.html">Portsentry</ulink>
works quite differently than the other tools discussed so far.
<application>Portsentry</application> does what its name implies --
it guards ports. <application>Portsentry</application> is configured with the
<filename>/etc/portsentry/portsentry.conf</filename> file.
</para>
<para>
Unlike the other applications discussed above, it does this by actually
becoming the listening server on those ports. Kind of like baiting a trap.
Running <literal>netstat -taup</literal> as root while
<application>portsentry</application> is running, will show
<application>portsentry</application> as the <literal>LISTENER</literal> on
whatever ports <application>portsentry</application> is configured for. If
<application>portsentry</application> senses a connection attempt, it blocks
it completely. And then goes a step further and blocks the route to that host
to stop all further traffic. Alternately, <application>ipchains</application>
or <application>iptables</application> can be used to block the host
completely. So it makes an excellent tool to stop port scanning of a range of
ports.
</para>
<para>
But <application>portsentry</application> has limited flexibility as to
whether it allows a given connection. It is pretty much all or nothing. You
can define specific IP addresses that it will ignore in
<filename>/etc/portsentry/portsentry.ignore</filename>. But you cannot allow
selective access to individual ports. This is because only one server can
bind to a particular port at the same time, and in this case that is
<application>portsentry</application> itself. So it has limited usefulness as a
stand-alone firewall. As part of an overall firewall strategy, yes, it can
be quite useful. For most of us, it should not be our first line of defense,
and we should only use it in conjunction with other tools.
</para>
<para>
Suggestion on when <application>portsentry</application> might be useful:
</para>
<ItemizedList>
<listitem>
<para>
As a second layer of defense, behind either
<application>ipchains</application> or <application>iptables</application>.
Packet filtering will catch the packets first, so that anything that gets
to <application>portsentry</application> would indicate a misconfiguration.
Do not use in conjunction with <application>inetd</application> services --
it won't work. They will butt heads.
</para>
</listitem>
<listitem>
<para>
As a way to catch full range ports scans. Open a pinhole or two in the
packet filter, and let <application>portsentry</application> catch these
and re-act accordingly.
</para>
</listitem>
<listitem>
<para>
If you are <emphasis>very sure</emphasis> you have no exposed public servers
at all, and you just want to know who is up to what. But do not assume
anything about what <application>portsentry</application> is protecting.
By default it does not watch all ports, and may even leave some very
commonly probed ports open. So make sure you configure it accordingly.
And make sure you have tested and verified your set up first, and that
nothing is exposed.
</para>
</listitem>
</ItemizedList>
<para>
All in all, the packet filters make for a better firewall.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="proxies">
<title>Proxies</title>
<para>
The dictionary defines <quote>proxy</quote> as <quote>the authority or power
to act on behalf of another</quote>. This pretty well describes software proxies as
well. It is an intermediary in the connection path. As an example, if we
were using a web proxy like <quote>squid</quote> (<ulink
url="http://www.squid-cache.org/">http://www.squid-cache.org/</ulink>),
every time we browse to a web site, we
would actually be connecting to our locally running <application>squid</application> server.
Squid in turn, would relay our request to the ultimate, real destination. And
then <application>squid</application> would relay the web pages back to us. It is
a go-between. Like <quote>firewalls</quote>, a <quote>proxy</quote> can refer
to either a specific application, or a dedicated server which runs a proxy
application.
</para>
<para>
Proxies can perform various duties, not all of which have much to do with
security. But the fact that they are an intermediary, makes them a good place
to enforce access control policies, limit direct connections through a
firewall, and control how the network behind the proxy looks to the Internet.
So this makes them strong candidates to be part of an overall firewall
strategy. And, in fact, are sometimes used instead of packet filtering
firewalls. Proxy based firewalls probably make more sense where many users
are behind the same firewall. And it probably is not high on the list of
components necessary for home based systems.
</para>
<para>
Configuring and administering proxies can be complex, and is beyond the scope of
this document. The Firewall and Proxy Server HOWTO, <ulink url="http://tldp.org/HOWTO/Firewall-HOWTO.html
">http://tldp.org/HOWTO/Firewall-HOWTO.html</ulink>, has examples
of setting up proxy firewalls. Squid usage is discussed at
<ulink url="http://squid-docs.sourceforge.net/latest/html/book1.htm">http://squid-docs.sourceforge.net/latest/html/book1.htm</ulink>
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="indapps">
<title>Individual Applications</title>
<para>
Some servers may have their own access control features. You should check
this for each server application you run. We'll only look at a few of the
common ones in this section. Man pages, and other application specific
documentation, is your friend here. This should be done whether you have
confidence in your firewall or not. Again, <application>layers</application>
of protection is always best.
</para>
<para>
<itemizedlist>
<listitem>
<para>
<application>BIND</application> - a very common package that provides name
server functionality. The daemon itself is <quote>named</quote>. This only
requires full exposure to the Internet if you are providing DNS look ups
for one or more domains to the rest of the world. If you are not sure what
this means, <emphasis>you do not need, or want</emphasis>, it exposed. For
the overwhelming majority of us this is the case. It is a very common
crack target.
</para>
<para>
But it may be installed, and can be useful in a caching only mode. This
does not require full exposure to the Internet. Limit the interfaces
on which it <quote>listens</quote> by editing
<filename>/etc/named.conf</filename> (random example shown):
</para>
<para>
<screen>
options {
directory "/var/named";
listen-on { 127.0.0.1; 192.168.1.1; };
version "N/A";
};
</screen>
</para>
<para>
The <quote>listen-on</quote> statement is what limits where named
listens for DNS queries. In this example, only on localhost and bigcat's
LAN interface. There is no port open for the rest of the world. It just
is not there. Restart <command>named</command> after making changes.
</para>
</listitem>
<listitem>
<para>
X11 can be told not to allow TCP connections by using the
<literal>-nolisten tcp</literal> command line option. If using
<command>startx</command>, you can make this automatic by placing
<literal>alias startx="startx -- -nolisten tcp"</literal> in your
<filename>~/.bashrc</filename>, or the system-wide file,
<filename>/etc/bashrc</filename>, with your text editor. If using
<application>xdm</application> (or variants such as
<application>gdm</application>, <application>kdm</application>, etc),
this option would be specified in
<application>/etc/X11/xdm/Xservers</application> (or comparable) as
<literal>:0 local /usr/bin/X11/X -nolisten tcp</literal>.
<application>gdm</application> actually uses
<filename>/etc/X11/gdm/gdm.conf</filename>.
</para>
<para>
If using <application>xdm</application> (or comparable) to start X
automatically at boot, <filename>/etc/inittab</filename> can
be modified as: <literal>xdm -udpPort 0</literal>, to further
restrict connections. This is typically near the bottom of
<filename>/etc/inittab</filename>.
</para>
</listitem>
<listitem>
<para>
Recent versions of <application>sendmail</application> can be told to
listen only on specified addresses:
</para>
<para>
<screen>
# SMTP daemon options
O DaemonPortOptions=Port=smtp,Addr=127.0.0.1, Name=MTA
</screen>
</para>
<para>
The above excerpt is from <filename>/etc/sendmail.cf</filename> which can
be carefully added with your text editor. The
<filename>sendmail.mc</filename> directive is:
</para>
<para>
<screen>
dnl This changes sendmail to only listen on the loopback device 127.0.0.1
dnl and not on any other network devices.
DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')
</screen>
</para>
<para>
In case you would prefer to build a new <filename>sendmail.cf</filename>,
rather than edit the existing one. Other mail server daemons likely have
similar configuration options. Check your local documentation.
<![%redhat;[ As of Red Hat 7.1, <application>sendmail</application> has
compiled in support for <application>tcpwrappers</application> as well.]]>
</para>
</listitem>
<listitem>
<para>
<application>SAMBA</application> connections can be restricted in
<filename>smb.conf</filename>:
</para>
<para>
<screen>
bind interfaces = true
interfaces = 192.168.1. 127.
hosts allow = 192.168.1. 127.
</screen>
</para>
<para>
This will only open, and allow, connections from localhost (127.0.0.1),
and the local LAN address range. Adjust the LAN address as needed.
</para>
</listitem>
<listitem>
<para>
The <application>CUPS</application> print daemon can be told where
to listen for connections. Add to <filename>/etc/cups/cupsd.conf</filename>:
</para>
<para>
<screen>
Listen 192.168.1.1:631
</screen>
</para>
<para>
This will only open a port at the specified address and port number.
</para>
</listitem>
<listitem>
<para>
<application>xinetd</application> can force daemons to listen only
on a specified address with its <quote>bind</quote> configuration
directive. For instance, an internal LAN interface address.
See <literal>man xinetd.conf</literal> for this and other syntax.
There are various other control mechanisms as well.
</para>
</listitem>
</itemizedlist>
</para>
<para>
As always, anytime you make system changes, backup the configuration file
first, restart the appropriate daemon afterward, and then check the
appropriate logs for error messages.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="verify">
<title>Verifying</title>
<para>
The final step after getting your firewall in place, is to verify that it
is doing what you intended. You would be wise to do this anytime you make
even minor changes to your system configuration.
</para>
<para>
So how to do this? There are several things you can do.
</para>
<para>
For our packet filters like <application>ipchains</application> and
<application>iptables</application>, we can list all our rules, chains,
and associated activity with <literal>iptables -nvL | less</literal>
(substitute <command>ipchains</command> if appropriate). Open
your xterm as wide as possible to avoid wrapping long lines.
</para>
<para>
This should give you an idea if your chains are doing what you think they
should. You may want to perform some of the on-line tasks you normally do
first: open a few web pages, send and retrieve mail, etc. This will, of
course, not give you any information on <application>tcpwrappers</application> or
<application>portsentry</application>. <command>tcpdchk</command> can
be used to verify <application>tcpwrappers</application> configuration
(except with <application>xinetd</application>).
</para>
<para>
And then, scan yourself. <application>nmap</application> is the scanning
tool of choice and <![%linuxall;[ may be available via your distribution]]>
<![%redhat;[ is included with recent Red Hat releases]]>, or from
<ulink url="http://www.insecure.org/nmap/nmap_download.html">http://www.insecure.org/nmap/nmap_download.html</ulink>. <application>nmap</application> is very
flexible, and essentially is a <quote>port prober</quote>. In other words,
it looks for open ports, among other things. See the
<application>nmap</application> man page for details.
</para>
<para>
If you do run <application>nmap</application> against yourself (e.g.
<literal>nmap localhost</literal>), this should tell you what ports are
open -- and <emphasis>visible locally</emphasis> only! Which hopefully by now, is
quite different from what can be seen from the outside. So, scan yourself,
and then find a trusted friend, or site (see the <link linkend="links">Links
section</link>), to scan you from the outside. Make sure you are not
violating your ISPs Terms of Service by port scanning. It may not be allowed,
even if the intentions are honorable. Scanning from outside is the best way
to know how the rest of the world sees you. This should tell you how well
that firewall is working. See the <link linkend="nmap">nmap</link> section in
the Appendix for some examples on <application>nmap</application> usage.
</para>
<para>
One caveat on this: some ISPs may filter some ports, and you will not know
for sure how well your firewall is working. Conversely, they make it look
like certain ports are open by using web, or other, proxies. The scanner
may see the web proxy at port 80 and mis-report it as an open port on your
system.
</para>
<para>
Another option is to find a website that offers <emphasis>full
range</emphasis> testing. <ulink
url="http://www.hackerwhacker.com">http://www.hackerwhacker.com</ulink> is
one such site. Make sure that any such site is not just scanning a relatively
few well known ports.
</para>
<para>
Repeat this procedure with every firewall change, every system upgrade or new
install, and when any key components of your system changes.
</para>
<para>
You may also want to enable logging all the denied traffic. At least
temporarily. Once the firewall is verified to be doing what you think it
should, and if the logs are hopelessly overwhelming, you may want to disable
logging.
</para>
<para>
If relying on <application>portsentry</application> at all, please read the
documentation. Depending on your configuration it will either drop the
route to the scanner, or implement a
<application>ipchains</application>/<application>iptables</application> rule
doing the same thing. Also, since it <quote>listens</quote> on the
specified ports, all those ports will show as <quote>open</quote>. A false
alarm in this case.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="logging">
<title>Logging</title>
<para>
Linux does a lot of logging. Usually to more than one file. It is not always
obvious what to make of all these entries -- good, bad or indifferent? Firewall
logs tend to generate a fair amount of each. Of course, you are wanting to
stop only the <quote>bad</quote>, but you will undoubtedly catch some
harmless traffic as well. The 'net has a lot of background noise.
</para>
<para>
In many cases, knowing the intentions of an incoming packet are almost
impossible. Attempted intrusion? Misbehaved protocol? Mis-typed IP address?
Conclusions can be drawn based on factors such as destination port, source
port, protocol, and many other variables. But there is no substitute for
experience in interpreting firewall logs. It is a black art in many cases.
</para>
<para>
So do we really need to log? And how much should we be trying to log? Logging
is good in that it tells us that the firewall is functional. Even if we
don't understand much of it, we know it is doing <quote>something</quote>.
And if we have to, we can dig into those logs and find whatever data might be
called for.
</para>
<para>
On the other hand, logging can be bad if it is so excessive, it is difficult
to find pertinent data, or worse, fills up a partition. Or if we over re-act
and take every last entry as an all out assault. Some perspective is a great
benefit, but something that new users lack almost by definition. Again, once
your firewall is verified, and you are perplexed or overwhelmed, home
desktop users may want to disable as much logging as possible. Anyone with
greater responsibilities should log, and then find ways to extract the
pertinent data from the logs by filtering out extraneous information.
</para>
<para>
Not sure where to look for log data? <![%linuxall;[ This could conceivably be
many places depending on how your distribution configured the various daemons
and <command>syslogd</command>. Most logging is done in
<filename>/var/log/*</filename>. Check that directory with <literal>ls -l
/var/log/</literal> and see if you can tell the most active logs by size and
timestamp. Also, look at <filename>/etc/syslog.conf</filename> to see where
the default logs are. <filename>/var/log/messages</filename> is a good place
to look for starters.]]> <![%redhat;[ The two logs to keep an eye on are
<filename>/var/log/messages</filename> and <filename>/var/log/secure</filename>.
There may be other application specific logs, depending on what you have
installed, or using. <application>FTP</application>, for instance, logs
to <filename>/var/log/xfer</filename> on Red Hat.]]>
</para>
<para>
<application>Portsentry</application> and <application>tcpwrappers</application>
do a certain amount of logging that is not adjustable.
<application>xinetd</application> has logging enhancements that can be turned
on. Both <application>ipchains</application> and
<application>iptables</application>, on the other hand, are very flexible as
to what is logged.
</para>
<para>
For <application>ipchains</application> the <literal>-l</literal> option can
be added to any rule. <application>iptables</application> uses the
<literal>-j LOG</literal> target, and requires its own, separate rule instead.
<application>iptables</application> goes a few steps further and allows
customized log entries, and rate limiting. See the man page. Presumably, we
are more interested in logging blocked traffic, so we'd confine logging to
only our <literal>DENY</literal> and <literal>REJECT</literal> rules.
</para>
<para>
So whether you log, and how much you log, and what you do with the logs, is
an individual decision, and probably will require some trial and error so
that it is manageable. A few auditing and analytical tools can be quite
helpful:
</para>
<para>
Some tools that will monitor your logs for you and notify you when necessary.
These likely will require some configuration, and trial and error, to make
the most out of them:
</para>
<para>
<itemizedlist>
<listitem>
<para>
A nice log entry analyzer for <application>ipchains</application> and
<application>iptables</application> from Manfred Bartz: <ulink
url="http://www.logi.cc/linux/NetfilterLogAnalyzer.php3">http://www.logi.cc/linux/NetfilterLogAnalyzer.php3</ulink>.
What does all that stuff mean anyway?
</para>
</listitem>
<listitem>
<para>
<application>LogSentry</application> (formerly <application>logcheck</application>) is available from
<ulink url="http://www.psionic.org/products/logsentry.html">http://www.psionic.org/products/logsentry.html</ulink>,
the same group that is responsible for
<application>portsentry</application>. <application>LogSentry</application>
is an all purpose log monitoring tool with a flexible configuration, that
handles multiple logs.
</para>
</listitem>
<listitem>
<para>
<ulink
url="http://freshmeat.net/projects/firelogd/">http://freshmeat.net/projects/firelogd/</ulink>, the Firewall Log Daemon from Ian Jones, is designed to
watch, and send alerts on <application>iptables</application> or
<application>ipchains</application> logs data.
</para>
</listitem>
<listitem>
<para>
<ulink
url="http://freshmeat.net/projects/fwlogwatch/">http://freshmeat.net/projects/fwlogwatch/</ulink> by Boris Wesslowski, is a similar idea, but supports
more log formats.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="wheretostart">
<title>Where to Start</title>
<para>
Let's take a quick look at where to run our firewall scripts from.
</para>
<para>
<application>Portsentry</application> can be run as an init process, like
other system services. It is not so important when this is done.
<application>Tcpwrappers</application> will be automatically be invoked by
<application>inetd</application> or <application>xinetd</application>, so not
to worry there either.
</para>
<para>
But the packet filtering scripts will have to be started somewhere. And many
scripts will have logic that uses the local IP address. This will mean that
the script must be started after the interface has come up and been assigned
an IP address. Ideally, this should be immediately after the interface is up.
So this depends on how you connect to the Internet. Also, for protocols like
<application>PPP</application> or <application>DHCP</application> that may
be dynamic, and get different IP's on each re-connect, it is best to have
the scripts run by the appropriate daemon.
</para>
<para>
<![%linuxall;[
For <application>PPP</application>, you probably have an
<filename>/etc/ppp/ip-up</filename> file. This will be executed every
time there is a connect or re-connect. You should put the full path to your
firewall script here. Check the local documentation for the correct
location. Debian use files in <filename>/etc/ppp/ip-up.d/</filename>, so
either put the script itself there, or a symlink to it.]]> Red Hat uses
<filename>/etc/ppp/ip-up.local</filename> for any user defined, local
PPP configuration. <![%redhat;[ If this file does not exist, create it, and
make it executable (<literal>chmod +x</literal>). Then with your text editor,
add a reference to your firewall script.]]>
</para>
<para>
For <application>DHCP</application>, it depends on which client.
<command>dhcpcd</command> will execute
<command>/etc/dhcpcd/dhcpcd-&lt;interface&gt;.exe</command> (e.g.
dhcpcd-eth0.exe) whenever a lease is obtained or renewed. So this is where to
put a reference to your firewall script. For
<command>pump</command><![%redhat;[ (the default on Red Hat)]]>, the main
configuration file is <filename>/etc/pump.conf</filename>.
<command>Pump</command> will run whatever script is defined by the
<quote>script</quote> statement any time there is a new or renewed lease:
</para>
<para>
<programlisting>
script /usr/local/bin/ipchains.sh
</programlisting>
</para>
<para>
If you have a static IP address (i.e. it never changes), the placement is not
so important and should be <emphasis>before</emphasis> the interface comes
up!
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="summary3">
<title>Summary and Conclusions for Step 3</title>
<para>
In this section we looked at various components that might be used to
construct a <quote>firewall</quote>. And learned that a firewall is as
much a strategy and combination of components, as it is any one particular
application or component. We looked at a few of the most commonly available
applications that can be found on most, if not all, Linux systems. This is
not a definitive list.
</para>
<para>
This is a lot of information to digest at all at one time and expect anyone
to understand it all. Hopefully this can used as a starting point, and
used for future reference as well. The packet filter firewall examples can be
used as starting points as well. Just use your text editor, cut and paste
into a file with an appropriate name, and then run <literal>chmod
+x</literal> against it to make it executable. Some minor editing of the
variables may be necessary. Also look at the <link
linkend="links">Links</link> section for sites and utilities that can be
used to generate a custom script. This may be a little less daunting.
</para>
<para>
Now we are done with Steps 1, 2 and 3. Hopefully by now you have already
instituted some basic measures to protect your system(s) from the various and
sundry threats that lurk on networks. If you haven't implemented any of the
above steps yet, now is a good time to take a break, go back to the top, and
have at it. The most important steps are the ones above.
</para>
<para>
A few quick conclusions...
</para>
<para>
<quote>What is best <application>iptables</application>,
<application>ipchains</application>, <application>tcpwrappers</application>,
or <application>portsentry</application>?</quote> The quick answer is that
<application>iptables</application> can do more than any of the others. So
if you are using a 2.4 kernel, use
<application>iptables</application>. Then,
<application>ipchains</application> if using a 2.2 kernel. The long answer is
<quote>it just depends on what you are doing and what the objective
is</quote>. Sorry. The other tools all have some merit in any given
situation, and all can be effective in the right situation.
</para>
<para>
<quote>Do I really need all these packages?</quote> No, but please combine
more than one approach, and please follow all the above recommendations.
<application>iptables</application> by itself is good, but in conjunction
with some of the other approaches, we are even stronger. Do not rely on any
single mechanism to provide a security blanket. <quote>Layers</quote> of
protection is always best. As is sound administrative practices. The best
<application>iptables</application> script in the world is but one piece of
the puzzle, and should not be used to hide other system weaknesses.
</para>
<para>
<quote>If I have a small home LAN, do I need to have a firewall on each
computer?</quote> No, not necessary as long as the LAN gateway has a properly
configured firewall. Unwanted traffic should be stopped at that point. And as
long as this is working as intended, there should be no unwanted traffic on
the LAN. But, by the same token, doing this certainly does no harm. And on
larger LANs that might be mixed platform, or with untrusted users, it would
be advisable.
</para>
</sect2>
</sect1>
<!-- ~ End section ~ -->
<!-- ~~~~~~~~ New section Header ~~~~~~~~~ -->
<sect1 id="intrusion">
<title>Intrusion Detection</title>
<para>
This section will deal with how to get early warning, how to be alerted
after the fact, and how to clean up from intrusion attempts.
</para>
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="ids">
<title>Intrusion Detection Systems (IDS)</title>
<para>
Intrusion Detection Systems (IDS for short) are designed to catch what might
have gotten past the firewall. They can either be designed to catch an
active break-in attempt in progress, or to detect a successful break-in
after the fact. In the latter case, it is too late to prevent any damage, but
at least we have early awareness of a problem. There are two basic types of
IDS: those protecting networks, and those protecting individual hosts.
</para>
<para>
For host based IDS, this is done with utilities that monitor the filesystem
for changes. System files that have changed in some way, but should not
change -- unless we did it -- are a dead give away that something is amiss.
Anyone who gets in, and gets root, will presumably make changes to the system
somewhere. This is usually the very first thing done. Either so he can get
back in through a backdoor, or to launch an attack against someone else. In
which case, he has to change or add files to the system.
</para>
<para>
This is where tools like tripwire (<ulink
url="http://www.tripwire.org">http://www.tripwire.org</ulink>) play a role.
<![%redhat;[ Tripwire is included beginning with Red Hat 7.0. ]]>
Such tools monitor various aspects of the filesystem, and compare them against a
stored database. And can be configured to send an alert if
<emphasis>any</emphasis> changes are detected. Such tools should only be
installed on a known <quote>clean</quote> system.
</para>
<para>
For home desktops and home LANs, this is probably not an absolutely necessary
component of an overall security strategy. But it does give peace of mind, and
certainly does have its place. So as to priorities, make sure the Steps 1, 2
and 3 above are implemented and verified to be sound, before delving into
this.
</para>
<para>
<![%linuxall;[<application>RPM</application> users]]><![%redhat;[We]]> can
get somewhat the same results with <literal>rpm -Va</literal>, which will
verify all packages, but without all the same functionality. For instance, it
will not notice new files added to most directories. Nor will it detect
files that have had the extended attributes changed (e.g. <literal>chattr +i</literal>,
man <command>chattr</command> and man <command>lsattr</command>). For this to
be helpful, it needs to be done after a clean install, and then each time any
packages are upgraded or added. Example:
</para>
<para>
<screen>
# rpm -Va > /root/system.checked
</screen>
</para>
<para>
Then we have a stored system snapshot that we can refer back to.
</para>
<![%linuxall;[
<para>
Debian users have a similar tool with <command>debsums</command>.
</para>
<para>
<screen>
# debsums -s > /root/system.checked
</screen>
</para>
]]>
<para>
Another idea is to run <command>chkrootkit</command>
(<ulink url="http://www.chkrootkit.org/">http://www.chkrootkit.org/</ulink>)
as a weekly cron job. This will detect common <quote>rootkits</quote>.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="hacked">
<title>Have I Been Hacked?</title>
<para>
Maybe you are reading this because you've noticed something <quote>odd</quote>
about your system, and are suspicious that someone was gotten in? This can be
a clue.
</para>
<para>
The first thing an intruder typically does is install a <quote>rootkit</quote>.
There are many prepackaged rootkits available on the Internet.
The rootkit is essentially a script, or set of scripts, that makes quick work
of modifying the system so the intruder is in control, and he is well hidden.
He does this by installing modified binaries of common system utilities and
tampering with log files. Or by using special kernel modules that achieve
similar results. So common commands like <command>ls</command> may be
modified so as to not show where he has his files stored. Clever!
</para>
<para>
A well designed rootkit can be quite effective. Nothing on the system can
really be trusted to provide accurate feedback. Nothing! But sometimes the
modifications are not as smooth as intended and give hints that something is
not right. Some things that <emphasis>might</emphasis> be warning signs:
</para>
<para>
<itemizedlist>
<listitem>
<para>
<command>Login</command> acts weird. Maybe no one can login. Or only
root can login. Any <command>login</command> weirdness at all should be
suspicious. Similarly, any weirdness with adding or changing passwords.
</para>
<para>
Wierdness with other system commands (e.g. <command>top</command> or
<command>ps</command>) should be cause for concern as well.
</para>
</listitem>
<listitem>
<para>
System utilities are slower, or awkward, or show strange and unexpected
results. Common utilities that might be modified are: <command>ls</command>,
<command>find</command>, <command>who</command>, <command>w</command>,
<command>last</command>, <command>netstat</command>,
<command>login</command>, <command>ps</command>, <command>top</command>.
This is not a definitive list!
</para>
</listitem>
<listitem>
<para>
Files or directories named <quote>...</quote> or <quote>.. </quote>
(dot dot space). A sure bet in this case. Files with haxor looking
names like <quote>r00t-something</quote>.
</para>
</listitem>
<listitem>
<para>
Unexplained bandwidth usage, or connections. Script kiddies have a fondness
for IRC, so such connections should raise a red flag.
</para>
</listitem>
<listitem>
<para>
Logs that are missing completely, or missing large sections. Or a sudden
change in <command>syslog</command> behavior.
</para>
</listitem>
<listitem>
<para>
Mysterious open ports, or processes.
</para>
</listitem>
<listitem>
<para>
Files that cannot be deleted or moved. Some rootkits use
<command>chattr</command> to make files <quote>immutable</quote>,
or not changable. This kind of change will not show up with
<command>ls</command>, or <command>rpm -V</command>, so the files look
normal at first glance. See the man pages for <command>chattr</command>
and <command>lsattr</command> on how to reverse this. Then see the next
section below on restoring your system as the jig is up at this point.
</para>
<para>
This is becoming a more and more common script kiddie trick. In fact, one
quick test to run on a suspected system (as root):
</para>
<screen>
/usr/bin/lsattr `echo $PATH | tr ':' ' '` | grep i--
</screen>
<para>
This will look for any <quote>immutable</quote> files in root's
<literal>PATH</literal>, which is almost surely a sign of trouble since
no standard distributions ship files in this state. If the above command
turns up <emphasis>anything at all</emphasis>, then plan on completely
restoring the system (see below). A quick sanity check:
</para>
<screen>
# chattr +i /bin/ps
# /usr/bin/lsattr `echo $PATH | tr ':' ' '` | grep "i--"
---i---------- /bin/ps
# chattr -i /bin/ps
</screen>
<para>
This is just to verify the system is not tampered with to the point that
<command>lsattr</command> is completely unreliable. The third line is
<emphasis>exactly</emphasis> what you should see.
</para>
</listitem>
<listitem>
<para>
Indications of a <quote>sniffer</quote>, such as log messages of an
interface entering <quote>promiscuous</quote> mode.
</para>
</listitem>
<listitem>
<para>
Modifications to <filename>/etc/inetd.conf</filename>,
<filename>rc.local</filename>, <filename>rc.sysint</filename> or
<filename>/etc/passwd</filename>. Especially, any additions. Try
using <command>cat</command> or <command>tail</command> to view these
files. Additions will most likely be appended to the end. Remember though
such changes may not be <quote>visible</quote> to any system tools.
</para>
</listitem>
</itemizedlist>
</para>
<para>
Sometimes the intruder is not so smart and forgets about root's
<filename>.bash_history</filename>, or cleaning up log entries, or even
leaves strange, leftover files in <filename>/tmp</filename>. So these should
always be checked too. Just don't necessarily expect them to be accurate.
Often such left behind files, or log entries, will have obvious
script kiddie sounding names, e.g. <quote>r00t.sh</quote>.
</para>
<para>
Packet sniffers, like <application>tcpdump</application>
(<ulink url="http://www.tcpdump.org">http://www.tcpdump.org</ulink>), might
be useful in finding any uninvited traffic. Interpreting sniffer output is
probably beyond the grasp of the average new user. <application>snort</application>
(<ulink url="http://www.snort.org">http://www.snort.org</ulink>), and
<application>ethereal</application>
(<ulink url="http://www.ethereal.com">http://www.ethereal.com</ulink>), are
also good. <application>Ethereal</application> has a GUI.
</para>
<para>
As mentioned, a compromised system will undoubtedly have altered system
binaries, and the output of system utilities is not to be trusted. Nothing on
the system can be relied upon to be telling you the whole truth. Re-installing
individual packages may or may not help since it could be system libraries
or kernel modules that are doing the dirty work. The point here is that there
is no way to know with absolute certainty exactly what components have been
altered.
</para>
<para>
<![%linuxall;[<application>RPM</application> users]]> <![%redhat;[We]]> can
use <literal>rpm -Va |less</literal> to attempt to verify the integrity all
packages. But again there is no assurance that <application>rpm</application>
itself has not been tampered with, or the system components that
<application>RPM</application> relies on.
</para>
<para>
If you have <command>pstree</command> on your system, try this instead
of the standard <command>ps</command>. Sometimes the script kiddies forget
about this one. No guarantees though that this is accurate either.
</para>
<para>
You can also try querying the <filename>/proc</filename> filesystem,
which contains everything the kernel knows about processes that are
running:
</para>
<para>
<screen>
# cat /proc/*/stat | awk '{print $1,$2}'
</screen>
</para>
<para>
This will provide a list of all processes and PID numbers (assuming
a malicious kernel module is not hiding this).
</para>
<para>
Another approach is to visit <ulink
url="http://www.chkrootkit.org">http://www.chkrootkit.org</ulink>, download
their rootkit checker, and see what it says.
</para>
<para>
Some interesting discussions on issues surrounding forensics can be found at <ulink
url="http://www.fish.com/security/">http://www.fish.com/security/</ulink>.
There is also a collection of tools available, aptly called
<quote>The Coroner's Toolkit</quote> (TCT).
</para>
<para>
Read below for steps on recovering from an intrusion.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="reclaim">
<title>Reclaiming a Compromised System</title>
<para>
So now you've confirmed a break-in, and know that someone else has root
access, and quite likely one or more hidden backdoors to your system. You've
lost control. How to clean up and regain control?
</para>
<para>
There is no sure fire way of doing this short of a complete re-install. There
is no way to find with assurance all the modified files and backdoors that
may have been left. Trying to patch up a compromised system risks a false
sense of security and may actually aggravate an already bad situation.
</para>
<para>
The steps to take, in this order:
</para>
<para>
<itemizedlist>
<listitem>
<para>
Pull the plug and disconnect the machine. You may be unwittingly
participating in criminal activity, and doing to others what has been done
to you.
</para>
</listitem>
<listitem>
<para>
Depending on the needs of the situation and time available to restore the
system, it is advantageous to learn as much as you can about how the
attacker got in, and what was done in order to plug the hole and avoid a
recurrence. This could conceivably be time consuming, and is not always
feasible. And it may require more expertise than the typical user
possesses.
</para>
</listitem>
<listitem>
<para>
Backup important data. Do <emphasis>not</emphasis> include any system files
in the backup, and system configuration files like
<filename>inetd.conf</filename>. Limit the backup to personal data files
only! You don't want to backup, then restore something that might open
a backdoor or other hole.
</para>
</listitem>
<listitem>
<para>
Re-install from scratch, and reformat the drive during the installation
(<command>mke2fs</command>) to make sure no remnants are hiding. Actually,
replacing the drive is not a bad idea. Especially, if you want to keep
the compromised data available for further analysis.
</para>
</listitem>
<listitem>
<para>
Restore from backups. After a clean install is the best time to install
an IDS (Intrusion Detection System) such as <application>tripwire</application>
(<ulink url="http://www.tripwire.org">http://www.tripewire.org</ulink>).
</para>
</listitem>
<listitem>
<para>
Apply all updates<![%linuxall;[ or patches for your distribution. Check
your vendor's web site for security related notices.]]> <![%redhat;[ from
<ulink url="ftp://updates.redhat.com">ftp://updates.redhat.com</ulink>.]]>
</para>
</listitem>
<listitem>
<para>
Re-examine your system for unnecessary services. Re-examine your firewall and
access policies, and tighten all holes. <emphasis>Use new
passwords</emphasis>, as these were stolen in all likelihood.
</para>
</listitem>
<listitem>
<para>
Re-connect system ;-)
</para>
</listitem>
</itemizedlist>
</para>
<para>
At this time, any rootkit cleanup tools that may be available on-line are not
recommended. They probably do work just fine most of the time. But again,
how to be absolutely sure that all is well and all vestiges of the intrusion
are gone?
</para>
</sect2>
</sect1>
<!-- ~ End section ~ -->
<!-- ~~~~~~~~ New section Header ~~~~~~~~~ -->
<sect1 id="general">
<title>General Tips</title>
<para>
This section will quickly address some general concepts for maintaining a
more secure and reliable system or network. Let's emphasize
<quote>maintaining</quote> here since computer systems change daily, as does
the environment around them. As mentioned before, there isn't any one thing
that makes a system secure. There are too many variables. Security is an
approach and an attitude more than it is a reliance on any particular
product, application or specific policy.
</para>
<para>
<itemizedlist>
<listitem>
<para>
Do not allow remote root logins. This may be controlled by a configuration
file such as <filename>/etc/securetty</filename>. Remove any lines
that begin <quote>pts</quote>. This is one big security hole.
</para>
</listitem>
<listitem>
<para>
In fact, don't log in as root at all. Period. Log in on your user account
and <command>su</command> to root when needed. Whether the login is remote
or local. Or use <command>sudo</command>, which can run individual commands
with root privileges.
<![%linuxall;[(There should be a <command>sudo</command> package
available from your vendor.) ]]>
<![%redhat;[(Red hat includes a <command>sudo</command> package. )]]>
This takes some getting used to, but it is
the <quote>right</quote> way to do things. And the safest. And will become
more a more natural way of doing this as time goes on.
</para>
<para>
I know someone is saying right now <quote>but that is so much trouble, I am
root, and it is my system</quote>. True, but root is a specialized account that
was not ever meant to be used as a regular user account. Root has access to
everything, even hardware devices. The system <quote>trusts</quote> root.
It believes that you know what you are doing. If you make a mistook, it
assumes that you meant that, and will do it's best to do what you told it
to do...even if that destroys the system!
</para>
<para>
As an example, let's say you start X as root, open
<application>Netscape</application>, and visit a web site. The web page has
badly behaved java script. And conceivably now that badly written java
script might have access to much more of your system than if you had done
it the <quote>right</quote> way.
</para>
</listitem>
<listitem>
<para>
Take passwords seriously. Don't give them out to anyone. Don't use the same
one for everything. Don't use root's password for anything else -- except
root's password! Never sign up or register on line, using any of your
system passwords. Passwords should be a combination of mixed case letters,
numbers and/or punctuation and a reasonable length (eight characters or
longer). Don't use so-called <quote>dictionary</quote> words that are easy
to guess like <quote>cat</quote> or <quote>dog</quote>. Don't incorporate
personal information like names or dates or hostnames. Don't write down
system passwords -- memorize them.
<!--
From FBI-NIPC (excerpt)
Password Protection 101
Remembering long passwords can be difficult, but there are some basic
techniques users can employ to lessen the pain. First, choose a phrase that
you will remember. As an example, we will use the phrase "The pearl in the
river." You can then take a number that you are familiar with, such as a
birthday. For this example we will use 7/4/01. Next, you can take the first
letter of your phrase and interlace it with the chosen date to make
something similar to t7p4i0t1r. This method creates a password that won't be
found in any dictionary and is unique to the person who created it.
t p i t r =t7p4i0t1r
7 4 0 1
-->
</para>
<para>
Use the more secure <quote>shadow</quote> passwords. <![%linuxall;[This
should be the default for any recent Linux distribution now.]]>
<![%redhat;[This has been the default on Red Hat for some time now.]]> If
the file <filename>/etc/shadow</filename> exists, then it is enabled
already. The commands <command>pwconv</command> and
<command>grpconv</command>, can be used to convert password and group files
to shadow format if available.
</para>
</listitem>
<listitem>
<para>
Avoid using programs that require clear text logins over untrusted networks
like the Internet. <command>Telnet</command> is a prime example.
<command>ssh</command> is much better. If there is any support for
SSL (Secure Socket Layers), use it. For instance, does your ISP offer POP
or IMAP mail via SSL? Recent <![%linuxall;[ distributions should include ]]>
<![%redhat;[ Red Hat releases do include ]]> <application><ulink
url="http://www.openssl.org/">openssl</ulink></application>, and many
Linux applications can use SSL where support is available.
</para>
</listitem>
<listitem>
<para>
Set resource limits. There are various ways to do this. The need for
this probably increases with the number of users accessing a given system.
Not only does setting limits on such things as disk space prevent
intentional mischief, it can also help with unintentionally misbehaved
applications or processes. <command>quota</command> (<literal>man
quota</literal>) can be used to set disk space limits.
<application>Bash</application> includes the <command>ulimit</command>
command (<literal>man ulimit</literal> or <literal>man bash</literal>),
that can limit various functions on a per user basis.
</para>
<para>
Also, not discussed here at any length, but <application>PAM</application>
(Pluggable Authentication Modules) has a very sophisticated approach to
controlling various system functions and resources. See <literal>man
pam</literal> to get started. <application>PAM</application> is configured
via either <filename>/etc/pam.conf</filename> or
<filename>/etc/pam.d/*</filename>. Also files in
<filename>/etc/security/*</filename>, including
<filename>/etc/security/limits.conf</filename>, where again various sane
limits can be imposed. An in depth look at <application>PAM</application>
is beyond the scope of this document. The
User-Authentication HOWTO (<ulink url="http://tldp.org/HOWTO/User-Authentication-HOWTO/index.html">http://tldp.org/HOWTO/User-Authentication-HOWTO/index.html</ulink>) has more on this.
</para>
</listitem>
<listitem>
<para>
Make sure someone with a clue is getting root's mail. This can be done with an
<quote>alias</quote>. Typically, the mail server will have a file such
as <filename>/etc/aliases</filename> where this can defined. This can
conceivably be an account on another machine if need be:
</para>
<para>
<screen>
# Person who should get root's mail. This alias
# must exist.
# CHANGE THIS LINE to an account of a HUMAN
root: hal@bigcat
</screen>
</para>
<para>
Remember to run <command>newaliases</command> (or equivalent) afterward.
</para>
</listitem>
<listitem>
<para>
Be careful where you get software. Use trusted sources. How well do you
trust complete strangers? Check <![%linuxall;[your vendor]]>
<![%redhat;[ Red Hat's ftp site (or mirrors)]]> first if looking for a
specific package. It will probably be best suited for your system any way.
Or, the original package's project site is good as well. Installing from raw
source (either tarball or src.rpm) at least gives you the ability to
examine the code. Even if you don't understand it ;-) While this does not
seem to be a wide spread problem with Linux software sites, it is very
trivial for someone to add a very few lines of code, turning that harmless
looking binary into a <quote>Trojan horse</quote> that opens a backdoor to
your system. Then the jig is up.
</para>
</listitem>
<listitem>
<para>
So someone has scanned you, probed you, or otherwise seems to want into
your system? Don't retaliate. There is a good chance that the source IP
address is a compromised system, and the owner is a victim already. Also,
you may be violating someone's Terms of Service, and have trouble with
your own ISP. The best you can do is to send your logs to the abuse
department of the source IP's ISP, or owner. This is often
something like <quote>abuse@someisp.com</quote>. Just don't expect to
hear much back. Generally speaking, such activity is not legally
criminal, unless an actual break-in has taken place. Furthermore,
even if criminal, it will never be prosecuted unless significant
damage (read: big dollars) can be shown.
</para>
</listitem>
<listitem>
<para>
Red Hat<![%linuxall;[,Mandrake and Debian]]> users can install the <quote>Bastille
Hardening System</quote>, <ulink
url="http://www.bastille-linux.org/">http://www.bastille-linux.org/</ulink>.
This is a multi-purpose system for <quote>hardening</quote> Red Hat and
Mandrake system security. It has a GUI interface which can be used to
construct firewall scripts from scratch and configure
<application>PAM</application> among many other things. Debian support
is new.
</para>
</listitem>
<listitem>
<para>
So you have a full-time Internet connection via cable-modem or DSL. But
do you always use it, or always need it? There's an old saying that
<quote>the only truly secure system, is a disconnected system</quote>.
Well, that's certainly one option. So take that interface down, or stop the
controlling daemon (<command>dhcpcd</command>, <command>pppoed</command>,
etc). Or possibly even set up <application>cron</application> jobs to bring your
connection up and down according to your normal schedule and usage.
</para>
</listitem>
<listitem>
<para>
What about cable and DSL routers that are often promoted as
<quote>firewalls</quote>? The lower priced units are mostly equating
NAT (Network Address Translation), together with the ability to open holes
for ports through it, as a firewall. While NAT itself does provide a fair
degree of security for the systems behind the NAT gateway, this does not
constitute anything but a very rudimentary firewall. And if holes are
opened, there is still exposure. Also, you are relying on the router's
firmware and implementation not to be flawed. It is wise to have some kind
of additional protection behind such routers.
</para>
</listitem>
<listitem>
<para>
What about wireless network cards and hubs? Insecure, despite what
the manufacturers may claim. Treat these connections just as you would an
Internet connection. Use secure protocols like <application>ssh</application>
only! Even if it is just one LAN box to another.
</para>
</listitem>
<listitem>
<para>
If you find you need to run a particular service, and it is for just you,
or maybe a relatively small number of people, use a non-standard port. Most
server daemons support this. For instance, <command>sshd</command> runs on
port 22 by default. All worms and script kiddies will expect it there, and
look for it there. So, run it on another port! See the <command>sshd</command>
man page.
</para>
</listitem>
<listitem>
<para>
What about firewalls that block Internet connections according to the
application (like <application>ZoneAlarm</application> from Windowsdom)?
These were designed with this feature primarily because of the plethora
of virii and trojans that are so common with MS operating systems. This
is really not a problem on Linux. So, really no such application exists
on Linux at this time. And there does not seem to be enough demand for it
that someone has taken the time to implement it. A better firewall can be
had on Linux, by following the other suggestions in this document.
</para>
</listitem>
<listitem>
<para>
Lastly, know your system! Let's face it, if you are new to Linux, you can't
already know something you have never used. Understood. But in the process
of learning, learn how to do things the right way, not the easiest way.
There is several decades of history behind <quote>the right way</quote> of
doing things. This has stood the test of time. What may seem unnecessary or
burdensome now, will make sense in due time.
</para>
<para>
Be familiar with whatever services you are running, and the implications
these services might have to the overall health of your system if
something does go wrong. Read what you can, and ask questions. Don't run
something as a service <quote>just because I can</quote>, or because the
installer put it there. You can't start out being an experienced System
Administrator clearly. But you can work to learn enough about your own
system, that you are in control. This is one thing that separates *nix from
MS systems: we can never be in complete control with MS, but we can with
*nix. Conversely, if something bad happens, we often have no one else to
blame.
</para>
</listitem>
<!--
And neither a borrower nor lender be...in a pear tree :/
-->
</itemizedlist>
</para>
</sect1>
<!-- ~ End section ~ -->
<!-- ~~~~~~~~ New section Header ~~~~~~~~~ -->
<sect1 id="appendix">
<title>Appendix</title>
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="serversetc">
<title>Servers, Ports, and Packets</title>
<para>
Let's take a quick, non-technical look at some networking concepts, and how
they can potentially impact our own security. We don't need to know much
about networking, but a general idea of how things work is certainly going to
help us with firewalls and other related issues.
</para>
<para>
As you may have noticed Linux is a very network oriented Operating System.
Much is done by connecting to <quote>servers</quote> of one type or another
-- X servers, font servers, print servers, etc.
</para>
<para>
Servers provide <quote>services</quote>, which provide various capabilities,
both to the local system and potentially other remote systems. The same
server generally provides both functionalities. Some servers
work quietly behind the scenes, and others are more interactive by nature. We
may only be aware of a print server when we need to print something, but it
is there running, listening, and waiting for connection requests whether we
ever use it or not (assuming of course we have it enabled). A typical Linux
installation will have many, many types of servers available to it. Default
installations often will turn some of these <quote>on</quote>.
</para>
<para>
And even if we are not connected to a real network all the time, we are still
<quote>networked</quote> so to speak. Take our friendly local X server for
instance. We may tend to think of this as just providing a GUI interface,
which is only true to a point. It does this by <quote>serving</quote> to
client applications, and thus is truly a server. But X Windows is also
capable of serving remote clients over a network -- even large networks like
the Internet. Though we probably don't really want to be doing this ;-)
</para>
<para>
And yes, if you are not running a firewall or have not taken other
precautions, and are connected to the Internet, it is quite possible that
someone -- anyone -- could connect to your X server. X11
<quote>listens</quote> on TCP <quote>port</quote> 6000 by default. This
principle applies to most other servers as well -- they can be easily
connected to, unless something is done to restrict or prevent connections.
</para>
<para>
In TCP/IP (Transmission Control Protocol/Internet Protocol) networks like we
are talking about with Linux and the Internet, every connected computer
has a unique <quote>IP Address</quote>. Think of this like a phone number.
You have a phone number, and in order to call someone else, you have to know
that phone number, and then dial it. The phone numbers have to be unique for
the system to work. IP address are generally expressed as <quote>dotted
quad</quote> notation, e.g. 152.19.254.81.
</para>
<para>
On this type of network, servers are said to <quote>listen</quote>. This
means that they have a <quote>port</quote> opened, and are awaiting incoming
connections to that port. Connections may be local, as is typically the case
with our X server, or remote -- meaning from another computer
<quote>somewhere</quote>. So servers <quote>listen</quote> on a specific
<quote>port</quote> for incoming connections. Most servers have a default
port, such as port 80 for web servers. Or 6000 for X11. See
<filename>/etc/services</filename> for a list of common ports and their
associated service.
</para>
<para>
The <quote>port</quote> is actually just an address in the kernel's
networking stack, and is a method that TCP, and other protocols, use to
organize connections and the exchange of data between computers. There are
total of 65,536 TCP and UDP ports available, though usually only a relatively
few of these are used at any one time. These are classified as
<quote>privileged</quote>, those ports below 1024, and
<quote>unprivileged</quote>, 1024 and above. Most servers use the privileged
ports.
</para>
<para>
Only one server may listen on, or <quote>bind</quote> to, a port at a time.
Though that server may well be able to open multiple connections via that one
port. Computers talk to each other via these <quote>port</quote> connections.
One computer will open a connection to a <quote>port</quote> on another
computer, and thus be able to exchange data via the connection that has been
established between their respective ports.
</para>
<para>
Getting back to the phone analogy, and stretching it a bit, think of calling
a large organization with a complex phone system. The organization has many
<quote>departments</quote>: sales, shipping, billing, receiving, customer
service, R&amp;D, etc. Each department has it's own <quote>extension</quote>
number. So the shipping department might be extension 21, the sales might be
department 80 and so on. The main phone number is the IP Address, and the
department's extension is the port in this analogy. The
<quote>department's</quote> number is always the same when we call. And
generally they can handle many simultaneous incoming calls.
</para>
<para>
The data itself is contained in <quote>packets</quote>, which are small
chunks of data, generally 1500 bytes or less each. Packets are used to
control and organize the connection, as well as carry data. There are
different types of packets. Some are specifically used for controlling the
connection, and then some packets carry our data as their payload. If
there is a lot of data, it will be broken up into multiple packets which is
almost always how it works. The packets will be transmitted one at a time,
and then <quote>re-assembled</quote> at the other end. One web page for
instance, will take many packets to transmit -- maybe hundreds or even
thousands. This all happens very quickly and transparently.
</para>
<para>
We can see a typical connection between two computers in this one line
excerpt from <command>netstat</command> output:
</para>
<para>
<screen>
tcp 30 0 169.254.179.139:1359 18.29.1.67:21 CLOSE_WAIT
</screen>
</para>
<para>
The interesting part is the IP addresses and ports in the fourth and fifth
columns. The port is the number just to the right of the colon. The left side
of the colon is the IP address of each computer. The fourth column is the
local address, or our end of the connection. In the example, 169.254.179.139
is the IP address assigned by my ISP. It is connected to port 21
(FTP) on 18.29.1.67, which is rpmfind.net. This is just after an FTP download
from rpmfind.net. Note that while I am connected to their FTP server on their
port 21, the port on my end that is used by my FTP client is 1359. This is a
randomly assigned <quote>unprivileged</quote> port, used for my end of the
two-way <quote>conversation</quote>. The data moves in both directions:
me:port#1359 &lt;-&gt; them:port#21. The FTP protocol is actually a little
more complicated than this, but we won't delve into the finer points here.
The <literal>CLOSE_WAIT</literal> is the TCP state of the connection at this
particular point in time. Eventually the connection will close completely on
both ends, and <application>netstat</application> will not show anything for
this.
</para>
<para>
The <quote>unprivileged</quote> port that is used for my end of the
connection, is temporary and is not associated with a locally running server.
It will be closed by the kernel when the connection is terminated. This is
quite different than the ports that are kept open by <quote>listening</quote>
servers, which are permanent and remain <quote>open</quote> even after a
remote connection is terminated.
</para>
<para>
So to summarize using the above example, we have client (me) connecting
to a server (rpmfind.net), and the connection is defined and controlled by
the respective ports on either end. The data is transmitted and controlled by
packets. The server is using a <quote>privileged</quote> port (i.e. a port
below number 1024) which stays open listening for connections. The
<quote>unprivileged</quote> port used on my end by my client application is
temporary, is only opened for the duration of the connection, and only
responds to the server's port at the other end of the connection. This type
of port is not vulnerable to attacks or break-ins generally speaking. The
server's port is vulnerable since it remains open. The administrator of the
FTP server will need to take appropriate precautions that his server is
secure. Other Internet connections, such as to web servers or mail servers,
work similar to the above example, though the server ports are different.
SMTP mail servers use port 25, and web servers typically use port 80.
See the <link linkend="ports">Ports section</link> for other commonly used
ports and services.
</para>
<para>
One more point on ports: ports are only accessible if there is something
listening on that port. No one can force a port open if there is no service
or daemon listening there, ready to handle incoming connection requests.
A closed port is a totally safe port.
</para>
<para>
And a final point on the distinction between clients and servers. The example
above did not have a <command>telnet</command> or <command>ftp</command>
server in the <literal>LISTENER</literal> section in the
<command>netstat</command> example above. In other words, no such servers
were running locally. You do not need to run a <command>telnet</command> or
<command>ftp</command> server daemon in order to connect to
<emphasis>somebody else's</emphasis> <command>telnet</command> or
<command>ftp</command> server. These are only for providing these services
to others that would be making connections to you. Which you don't really
want to be doing in most cases. This in no way effects the ability to use
<command>telnet</command> and <command>ftp</command> client software.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="ports">
<title>Common Ports</title>
<para>
A quick run down of some commonly seen and used ports, with the commonly
associated service name, and risk factor. All have <emphasis>some</emphasis>
risk. It is just that some have historically had more exploits than others.
That is how they are evaluated below, and not necessarily to be interpreted
as whether any given service is safe or not.
</para>
<para>
<simplelist>
<member>
1-19, assorted protocols, many of which are antiquated, and probably
none of which are needed on a modern system. If you don't know what
any of these are, then you definitely don't need them.
The <application>echo</application> service (port 7) should not be
confused with the common <command>ping</command> program. Leave all these
off.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
20 - FTP-DATA. <quote>Active</quote> FTP connections use two
ports: 21 is the control port, and 20 is where the data comes through.
Passive FTP does not use port 20 at all. Low risk, but see below.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
21 - FTP server port, aka File Transfer Protocol. A well entrenched protocol
for transferring files between systems. Very high risk, and maybe the number
one crack target.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
22 - SSH (Secure Shell), or sometimes PCAnywhere. Low to moderate
risk (yes there are exploits even against so called <quote>secure</quote>
services).
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
23 - Telnet server. For LAN use only. Use <application>ssh</application>
instead in non-secure environments. Moderate risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
25 - SMTP, Simple Mail Transfer Protocol, or mail server port, used for
sending outgoing mail, and transferring mail from one place to another.
Moderate risk. This has had a bad history of exploits, but has improved
lately.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
37 - Time service. This is the built-in
<application>inetd</application> time service. Low risk. For LAN use
only.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
53 - DNS, or Domain Name Server port. Name servers listen on this port,
and answer queries for resolving host names to IP addresses. High Risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
67 (UDP) - BOOTP, or DHCP, server port. Low risk. If using DHCP on your
LAN, this does not need to be exposed to the Internet.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
68 (UDP) - BOOTP, or DHCP, client port. Low risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
69 - tftp, or Trivial File Transfer Protocol. Extremely insecure. LAN
only, if really, really needed.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
79 - Finger, used to provide information about the system, and logged
in users. Low risk as a crack target, but gives out way too much
information and should not be run.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
80 - WWW or HTTP standard web server port. The most commonly used service
on the Internet. Low risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
98 - Linuxconf web access administrative port. LAN only, if really needed
at all.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
110 - POP3, aka Post Office Protocol, mail server port. POP mail is mail
that the user retrieves from a remote system. Low risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
111 - sunrpc (Sun Remote Procedure Call), or portmapper port. Used by NFS
(Network File System), NIS (Network Information Service), and various related
services. Sounds dangerous and is high risk. LAN use only. A favorite crack
target.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
113 - identd, or auth, server port. Used, and sometimes required, by some
older style services (like SMTP and IRC) to validate the connection.
Probably not needed in most cases. Low risk, but could give an attacker
too much information about your system.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
119 -- nntp or news server port. Low risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
123 - Network Time Protocol for synchronizing with time servers where a
high degree of accuracy is required. Low risk, but probably not required
for most users. <application>rdate</application> makes an easier and more
secure way of updating the system clock. And then
<application>inetd's</application> built in time service for synchronizing
LAN systems is another option.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
137-139 - NetBios (SMB) services. Mostly a Windows thing. Low risk on
Linux, but LAN use only. 137 is a very commonly seen port attempt. A
rather obnoxious protocol from Redmond that generates a lot of
<quote>noise</quote>, much of which is harmless.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
143 - IMAP, Interim Mail Access Protocol. Another mail retrieval protocol.
Low to moderate risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
161 - SNMP, Simple Network Management Protocol. More commonly used in
routers and switches to monitor statistics and vital signs. Not needed
for most of us, and low risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
177 - XDMCP, the X Display Management Control Protocol for remote connections
to X servers. Low risk, but LAN only is recommended.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
443 - HTTPS, a secure HTTP (WWW) protocol in fairly wide use. Low risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
465 - SMTP over SSL, secure mail server protocol. Low risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
512 (TCP) - exec is how it shows in <application>netstat</application>.
Actually the proper name is <command>rexec,</command> for Remote
Execution. Sounds dangerous, and is. High risk, LAN only if at all.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
512 (UDP) - biff, a mail notification protocol. Low risk, LAN only.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
513 - login, actually <command>rlogin</command>, aka Remote Login. No
relation to the standard <command>/bin/login</command> that we use
every time we log in. Sounds dangerous, and is. High risk, and LAN only if
really needed.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
514 (TCP) - shell is the nickname, and how <application>netstat</application>
shows it. Actually, <command>rsh</command> is the application for
<quote>Remote Shell</quote>. Like all the <quote>r</quote> commands, this
is a throw back to kindler, gentler times. Very insecure, so high risk, and
LAN only usage, if at all.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
514 (UDP) - syslog daemon port, only used for remote logging purposes. The
average user does not need this. Probably low risk, but definitely LAN
only if really required.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
515 - lp or print server port. High risk, and LAN only of course. Someone
on the other side of the world does not want to use your printer for it's
intended purpose!
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
587 - MSA, or <quote>submission</quote>, the Mail Submission Agent
protocol. A new mail handling protocol supported by most MTA's (mail
servers). Low risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
631 - the CUPS (print daemon) web management port. LAN only, low risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
635 - mountd, part of NFS. LAN use only.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
901 - SWAT, Samba Web Administration Tool port. LAN only.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
993 - IMAP over SSL, secure IMAP mail service. Very low risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
995 - POP over SSL, secure POP mail service. Very low risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
1024 - This is the first <quote>unprivileged</quote> port, which is
dynamically assigned by the kernel to whatever application requests
it. This can be almost anything. Ditto for ports just above this.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
1080 - Socks Proxy server. A favorite crack target.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
1243 - SubSeven Trojan. Windows only problem.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
1433 - MS SQL server port. A sometimes target. N/A on Linux.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
2049 - nfsd, Network File Service Daemon port. High risk, and LAN
usage only is recommended.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
3128 - Squid proxy server port. Low risk, but for most should be
LAN only.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
3306 - MySQL server port. Low risk, but for most should be
LAN only.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
5432 - PostgreSQL server port. LAN only, relatively low risk.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
5631 (TCP), 5632 (UDP) - PCAnywhere ports. Windows only. PCAnywhere
can be quite <quote>noisy</quote>, and broadcast wide address ranges.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
6000 - X11 TCP port for remote connections. Low to moderate risk, but
again, this should be LAN only. Actually, this can include ports
6000-6009 since X can support multiple displays and each display would
have its own port. <application>ssh's</application> X11Forwarding will
start using ports at 6010.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
6346 - gnutella.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
6667 - ircd, Internet Relay Chat Daemon.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
6699 - napster.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
7100-7101 - Some font servers use these ports. Low risk, but LAN only.
</member>
</simplelist>
</para>
<!--
<para>
<simplelist>
<member>
7070 (UDP) - Realplayer.
</member>
</simplelist>
</para>
-->
<para>
<simplelist>
<member>
8000 and 8080 - common web cache and proxy server ports. LAN only.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
10000 - webmin, a web based system administration utility. Low risk at this
point.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
27374 - SubSeven, a commonly probed for Windows only Trojan. Also, 1243.
</member>
</simplelist>
</para>
<para>
<simplelist>
<member>
31337 - Back Orifice, another commonly probed for Windows only Trojan.
</member>
</simplelist>
</para>
<para>
More services and corresponding port numbers can be found in
<filename>/etc/services</filename>. Also, the <quote>official</quote>
list is <ulink url="http://www.iana.org/assignments/port-numbers">http://www.iana.org/assignments/port-numbers</ulink>.
</para>
<para>
A great analysis of what probes to these and other ports might mean
from Robert Graham: <ulink url="http://www.linuxsecurity.com/resource_files/firewalls/firewall-seen.html">http://www.linuxsecurity.com/resource_files/firewalls/firewall-seen.html</ulink>. A very good reference.
</para>
<para>
Another point here, these are the <emphasis>standard</emphasis> port
designations. There is no law that says any service has to run on a
specific port. Usually they do, but certainly they don't always have to.
</para>
<para>
Just a reminder that when you see these types of ports in your firewall logs,
it is not anything to go off the deep end about. Not if you have followed
Steps 1-3 above, and verified your firewall works. You are fairly safe. Much
of this traffic may be <quote>stray bullets</quote> too -- Internet
background noise, misconfigured clients or routers, noisy Windows stuff, etc.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="netstat">
<title>Netstat Tutorial</title>
<!-- ~~~~~ New section ~~~~~ -->
<sect3>
<title>Overview</title>
<para>
<command>netstat</command> is a very useful utility for viewing
the current state of your network status -- what servers are listening for
incoming connections, what interfaces they listen on, who is connected to us,
who we are connect to, and so on. Take a look at the man page for some of the
many command line options. We'll just use a relative few options here.
</para>
<para>
As an example, let's check all currently listening servers and active
connections for both TCP and UDP on our hypothetical host,
bigcat. bigcat is a home desktop installation, with a DSL
Internet connection in this example. bigcat has two ethernet cards: one for
the external connection to the ISP, and one for a small LAN with an address
of 192.168.1.1.
</para>
<para>
<screen>
$ netstat -tua
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 *:printer *:* LISTEN
tcp 0 0 bigcat:8000 *:* LISTEN
tcp 0 0 *:time *:* LISTEN
tcp 0 0 *:x11 *:* LISTEN
tcp 0 0 *:http *:* LISTEN
tcp 0 0 bigcat:domain *:* LISTEN
tcp 0 0 bigcat:domain *:* LISTEN
tcp 0 0 *:ssh *:* LISTEN
tcp 0 0 *:631 *:* LISTEN
tcp 0 0 *:smtp *:* LISTEN
tcp 0 1 dsl-78-199-139.s:1174 64.152.100.93:nntp SYN_SENT
tcp 0 1 dsl-78-199-139.s:1175 64.152.100.93:nntp SYN_SENT
tcp 0 1 dsl-78-199-139.s:1173 64.152.100.93:nntp SYN_SENT
tcp 0 0 dsl-78-199-139.s:1172 207.153.203.114:http ESTABLISHED
tcp 1 0 dsl-78-199-139.s:1199 www.xodiax.com:http CLOSE_WAIT
tcp 0 0 dsl-78-199-139.sd:http 63.236.92.144:34197 TIME_WAIT
tcp 400 0 bigcat:1152 bigcat:8000 CLOSE_WAIT
tcp 6648 0 bigcat:1162 bigcat:8000 CLOSE_WAIT
tcp 553 0 bigcat:1164 bigcat:8000 CLOSE_WAIT
udp 0 0 *:32768 *:*
udp 0 0 bigcat:domain *:*
udp 0 0 bigcat:domain *:*
udp 0 0 *:631 *:*
</screen>
</para>
<para>
This output probably looks very different from what you get on your own
system. Notice the distinction between <quote>Local Address</quote> and
<quote>Foreign Address</quote>, and how each includes a corresponding port
number (or service name if available) after the colon. <quote>Local
Address</quote> is our end of the connection. The first group with
<literal>LISTEN</literal> in the far right hand column are services that are
running on this system. These are servers that are running in the background
on bigcat, and <quote>listen</quote> for incoming connections. So they
have a port opened, and this is where they <quote>listen</quote>. These
connections might come from the local system (i.e. bigcat itself), or remote
systems. This is very important information to have! The others just below
this are connections that have been established from this system to other
systems. The respective connections are in varying states as indicated by the
key words in the last column. Those with no key word in the last column at
the end are servers responding to UDP connections. UDP is a different
protocol from TCP altogether, but is used for some types of low priority
network traffic.
</para>
<para>
Now, the same thing with the <quote>-n</quote> flag to suppress converting to
<quote>names</quote> so we can actually see the port numbers:
</para>
<para>
<screen>
$ netstat -taun
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:515 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:37 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 192.168.1.1: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:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:631 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN
tcp 0 1 169.254.179.139:1174 64.152.100.93:119 SYN_SENT
tcp 0 1 169.254.179.139:1175 64.152.100.93:119 SYN_SENT
tcp 0 1 169.254.179.139:1173 64.152.100.93:119 SYN_SENT
tcp 0 0 169.254.179.139:1172 207.153.203.114:80 ESTABLISHED
tcp 1 0 169.254.179.139:1199 216.26.129.136:80 CLOSE_WAIT
tcp 0 0 169.254.179.139:80 63.236.92.144:34197 TIME_WAIT
tcp 400 0 127.0.0.1:1152 127.0.0.1:8000 CLOSE_WAIT
tcp 6648 0 127.0.0.1:1162 127.0.0.1:8000 CLOSE_WAIT
tcp 553 0 127.0.0.1:1164 127.0.0.1:8000 CLOSE_WAIT
udp 0 0 0.0.0.0:32768 0.0.0.0:*
udp 0 0 192.168.1.1:53 0.0.0.0:*
udp 0 0 127.0.0.1:53 0.0.0.0:*
udp 0 0 0.0.0.0:631 0.0.0.0:*
</screen>
</para>
<para>
Let's look at the first few lines of this in detail. On line one,
</para>
<para>
<screen>
tcp 0 0 0.0.0.0:515 0.0.0.0:* LISTEN
</screen>
</para>
<para>
<quote>Local Address</quote> is <literal>0.0.0.0</literal>, meaning
<quote>all</quote> interfaces that are available. The local port is 515, or the
standard print server port, usually owned by the lpd daemon. You can find a
listing of common service names and corresponding ports in the file
<filename>/etc/services</filename>.
</para>
<para>
The fact that it is listening on all interfaces is significant. In this case,
that would be lo (localhost), eth0, and eth1. Printer connections could
conceivably be made over any of these interfaces. Should a user on this system
bring up a PPP connection, then the print daemon would be listening on that
interface (ppp0) as well. The <quote>Foreign Address</quote> is also
<literal>0.0.0.0</literal>, meaning from <quote>anywhere</quote>.
</para>
<para>
It is also worth noting here, that even though this server is telling the
kernel to listen on all interfaces, the <command>netstat</command> output
does not reflect whether there may be a firewall in place that may be
filtering incoming connections. We just can't tell that at this point.
Obviously, for certain servers, this is very desirable. Nobody outside your
own LAN has any reason whatsoever to connect to your print server port for
instance.
</para>
<para>
Line two is a little different:
</para>
<para>
<screen>
tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN
</screen>
</para>
<para>
Notice the <quote>Local Address</quote> this time is localhost's address
of <literal>127.0.0.1</literal>. This is very significant as only connections
local to this machine will be accepted. So only bigcat can connect to
bigcat's TCP port 8000. The security implications should be obvious. Not all
servers have configuration options that allow this kind of restriction, but
it is a very useful feature for those that do. Port 8000 in this example,
is owned by the web proxy <application>Junkbuster</application>.
</para>
<para>
With the next three entries, we are back to listening on all available
interfaces:
</para>
<para>
<screen>
tcp 0 0 0.0.0.0:37 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
</screen>
</para>
<para>
Looking at <filename>/etc/services</fileName>, we can tell that port 37
is a <quote>time</quote> service, which is a time server.
6000 is <application>X11</application>, and 80 is the standard port for HTTP
servers like <application>Apache</application>. There is nothing really
unusual here as these are all readily available services on Linux.
</para>
<para>
The first two above are definitely not the kind of services you'd want just
anyone to connect to. These should be firewalled so that all outside
connections are refused. Again, we can't tell from this output whether any
firewall is in place, much less how effectively implemented it may be.
</para>
<para>
The web server on port 80 is not a huge security risk by itself. HTTP is a
protocol that is often open to all comers. For instance, if we wanted to host
our own home page, <application>Apache</application> can certainly do this
for us. It is also possible to firewall this off, so that it is for use only
to our LAN clients as part of an Intranet. Obviously too, if you do not have
a good justification for running a web server, then it should be disabled
completely.
</para>
<para>
The next two lines are interesting:
</para>
<para>
<screen>
tcp 0 0 192.168.1.1:53 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN
</screen>
</para>
<para>
Again notice the <quote>Local Address</quote> is not <literal>0.0.0.0</literal>.
This is good! The port this time is 53, or the DNS port used by nameserver
daemons like <command>named.</command> But we see the nameserver
daemon is only listening on the lo interface (localhost), and the interface
that connects bigcat to the LAN. So the kernel only allows connections from
localhost, and the LAN. There will be no port 53 available to outside
connections at all. This is a good example of how individual applications
can sometimes be securely configured. In this case, we are probably looking
at a caching DNS server since a real nameserver that is responsible for
handling DNS queries would have to have port 53 open to the world. This
is a security risk and requires special handling.
</para>
<para>
The last three <literal>LISTENER</literal> entries:
</para>
<para>
<screen>
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:631 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN
</screen>
</para>
<para>
These are back to listening on all available interfaces. Port 22 is
<application>sshd</application>, the Secure Shell server daemon. This is a good
sign! Notice that the service for port 631 does not have a service name if we
look at the output in the first example. This might be a clue that something
unusual is going on here. (See the next section for the answer to this
riddle.) And lastly, port 25, the standard port for the SMTP mail daemon.
Most Linux installations probably will have an SMTP daemon running, so this
is not necessarily unusual. But is it necessary?
</para>
<para>
The next grouping is established connections. For our purposes the state of
the connection as indicated by the last column is not so important. This is
well explained in the man page.
</para>
<para>
<screen>
tcp 0 1 169.254.179.139:1174 64.152.100.93:119 SYN_SENT
tcp 0 1 169.254.179.139:1175 64.152.100.93:119 SYN_SENT
tcp 0 1 169.254.179.139:1173 64.152.100.93:119 SYN_SENT
tcp 0 0 169.254.179.139:1172 207.153.203.114:80 ESTABLISHED
tcp 1 0 169.254.179.139:1199 216.26.129.136:80 CLOSE_WAIT
tcp 0 0 169.254.179.139:80 63.236.92.144:34197 TIME_WAIT
tcp 400 0 127.0.0.1:1152 127.0.0.1:8000 CLOSE_WAIT
tcp 6648 0 127.0.0.1:1162 127.0.0.1:8000 CLOSE_WAIT
tcp 553 0 127.0.0.1:1164 127.0.0.1:8000 CLOSE_WAIT
</screen>
</para>
<para>
There are nine total connections here. The first three is our external
interface connecting to a remote host on their port 119, the standard NNTP (News)
port. There are three connections here to the same news server. Apparently
the application is multi-threaded, as it is trying to open multiple
connections to the news server. The next two entries are connections to a
remote web server as indicated by the port 80 after the colon in the fifth
column. Probably a pretty common looking entry for most of us. But the one
just after is reversed and has the port 80 in the fourth column, so this is
someone that has connected to bigcat's web server via its external,
Internet-side interface. The last three entries are all connections from
localhost to localhost. So we are connecting to ourselves here. Remembering
from above that port 8000 is bigcat's web proxy, this is a web browser that
is connected to the locally running proxy. The proxy then will open an
external connection of its own, which probably is what is going on with lines
four and five.
</para>
<para>
Since we gave <command>netstat</command> both the <literal>-t</literal> and
<literal>-u</literal> options, we are getting both the TCP and UDP listening
servers. The last few lines are the UDP ones:
</para>
<para>
<screen>
udp 0 0 0.0.0.0:32768 0.0.0.0:*
udp 0 0 192.168.1.1:53 0.0.0.0:*
udp 0 0 127.0.0.1:53 0.0.0.0:*
udp 0 0 0.0.0.0:631 0.0.0.0:*
</screen>
</para>
<para>
The last three entries have ports that are familiar from the above
discussion. These are servers that are listening for both TCP and UDP
connections. Same servers in this case, just using two different protocols.
The first one on local port 32768 is new, and does not have a service name
available to it in <filename>/etc/services</filename>. So at first glance
this should be suspicious and pique our curiosity. See the next section for
the explanation.
</para>
<para>
Can we draw any conclusions from this hypothetical situation? For
the most part, these look to be pretty normal looking network services and
connections for Linux. There does not seem to be an unduly high number of
servers running here, but that by itself does not mean much since we don't
know if all these servers are really required or not. We know that
<command>netstat</command> can not tell us if any of these are effectively
firewalled, so there is no way to say how secure all this might be. We also
don't really know if all the listening services are really required by the
owner here. That is something that varies widely from installation to
installation. Does bigcat even have a printer attached for instance?
Presumably it does, or this is a completely unnecessary risk.
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3 id="pid">
<title>Port and Process Owners</title>
<para>
We've learned a lot about what is going on with bigcat's networking from
the above section. But suppose we see something we don't recognize and
want to know what started that particular service? Or we want to stop a
particular server and it is not obvious from the above output?
</para>
<para>
The <literal>-p</literal> option should give us the process's PID and the
program name that started the process in the last column. Let's look at the
TCP servers again (with first three columns cropped for spacing). We'll have
to run this as root to get all the available information:
</para>
<para>
<screen>
# netstat -tap
Active Internet connections (servers and established)
Local Address Foreign Address State PID/Program name
*:printer *:* LISTEN 988/inetd
bigcat:8000 *:* LISTEN 1064/junkbuster
*:time *:* LISTEN 988/inetd
*:x11 *:* LISTEN 1462/X
*:http *:* LISTEN 1078/httpd
bigcat:domain *:* LISTEN 956/named
bigcat:domain *:* LISTEN 956/named
*:ssh *:* LISTEN 972/sshd
*:631 *:* LISTEN 1315/cupsd
*:smtp *:* LISTEN 1051/master
</screen>
</para>
<para>
Some of these we already know about. But we see now that the printer daemon
on port 515 is being started via <command>inetd</command> with a
PID of <quote>988</quote>. <command>inetd</command> is a special situation.
<command>inetd</command> is often called the <quote>super server</quote>,
since it's main role is to spawn sub-services. <![%redhat;[
<application>xinetd</application> replaces <application>inetd</application>
as of Red Hat 7.0. ]]> If we look at the first line, <command>inetd</command>
is listening on port 515 for printer services. If a connection comes for this
port, <command>inetd</command> intercepts it, and then will spawn the
appropriate daemon, i.e. the print daemon in this case. The configuration of
how <command>inetd</command> handles this is typically done in
<filename>/etc/inetd.conf</filename>. This should tell us that if we want to
stop an <command>inetd</command> controlled server on a permanent basis, then
we will have to dig into the <command>inetd</command> (or perhaps
<command>xinetd</command>) configuration. Also the time service above is
started via <command>inetd</command> as well. This should also tell us that
these two services can be further protected by
<application>tcpwrappers</application> (discussed in Step 3 above). This is
one benefit of using <command>inetd</command> to control certain system
services.
</para>
<para>
We weren't sure about the service on port 631 above since it did not have
a standard service name, which means it is something maybe unusual or off
the beaten path. Now we see it is owned by <command>cupsd</command>
<![%redhat;[ (not included with Red Hat by the way)]]>, which is one of
several print daemons available under Linux. This happens to be the web
interface for controlling the printer service. Something
<command>cupsd</command> does that is indeed a little different than other
print servers.
</para>
<para>
The last entry above is the SMTP mail server on bigcat. Often, this is
<command>sendmail</command><![%linuxall;[ with many distributions]]>. But
not in this case. The command is <quote>master</quote>, which may not ring
any bells. Armed with the program name we could go searching the filesystem
with tools like the <command>locate</command> or <command>find</command>
commands. After we found it, we could then probably discern what package it
belonged to. But with the PID available now, we can look at
<command>ps</command> output, and see if that helps us any:
</para>
<para>
<screen>
$ /bin/ps ax |grep 1051 |grep -v grep
1051 ? S 0:24 /usr/libexec/postfix/master
</screen>
</para>
<para>
We took a shortcut here by combining <command>ps</command> with
<command>grep</command>. It looks like that this file belongs to
<command>postfix</command>, which is indeed a mail server package
comparable to <command>sendmail</command><![%redhat;[ ( and is
included with Powertools, not the base distribution)]]>.
</para>
<para>
Running <command>ps</command> with the <literal>--forest</literal> flag
(<literal>-f</literal> for short) can be helpful in determining what
processes are parent or child process or another process. An edited example:
</para>
<para>
<screen>
$ /bin/ps -axf
956 ? S 0:00 named -u named
957 ? S 0:00 \_ named -u named
958 ? S 0:46 \_ named -u named
959 ? S 0:47 \_ named -u named
960 ? S 0:00 \_ named -u named
961 ? S 0:11 \_ named -u named
1051 ? S 0:30 /usr/libexec/postfix/master
1703 ? S 0:00 \_ tlsmgr -l -t fifo -u -c
1704 ? S 0:00 \_ qmgr -l -t fifo -u -c
1955 ? S 0:00 \_ pickup -l -t fifo -c
1863 ? S 0:00 \_ trivial-rewrite -n rewrite -t unix -u -c
2043 ? S 0:00 \_ cleanup -t unix -u -c
2049 ? S 0:00 \_ local -t unix
2062 ? S 0:00 \_ smtpd -n smtp -t inet -u -c
</screen>
</para>
<para>
A couple of things to note here. We have two by now familiar daemons here:
<command>named</command> and <command>postfix (smtpd)</command>. Both
are spawning sub-processes. In the case of <command>named</command>, what we are
seeing is threads, various sub-processes that it always spawns.
<command>Postfix</command> is also spawning sub-processes, but not as
<quote>threads</quote>. Each sub-process has its own specific task. It is
worth noting that child processes are dependent on the parent process.
So killing the parent PID, will in turn kill all child processes.
</para>
<para>
If all this has not shed any light, we might also try <command>locate</command>:
</para>
<para>
<screen>
$ locate /master
/etc/postfix/master.cf
/var/spool/postfix/pid/master.pid
/usr/libexec/postfix/master
/usr/share/vim/syntax/master.vim
/usr/share/vim/vim60z/syntax/master.vim
/usr/share/doc/postfix-20010202/html/master.8.html
/usr/share/doc/postfix-20010202/master.cf
/usr/share/man/man8/master.8.gz
</screen>
</para>
<para>
<command>find</command> is perhaps the most flexible file finding utility,
but doesn't use a database the way <command>locate</command> does, so is
much slower:
</para>
<para>
<screen>
$ find / -name master
/usr/libexec/postfix/master
</screen>
</para>
<para>
If <command>lsof</command> is installed, it is another command that is useful
for finding who owns processes or ports:
</para>
<para>
<screen>
# lsof -i :631
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
cupsd 1315 root 0u IPv4 3734 TCP *:631 (LISTEN)
</screen>
</para>
<para>
This is again telling us that the <command>cupsd</command> print daemon is
the owner of port 631. Just a different way of getting at it. Yet one more
way to get at this is with <command>fuser</command>, which should be
installed:
</para>
<para>
<screen>
# fuser -v -n tcp 631
USER PID ACCESS COMMAND
631/tcp root 1315 f.... cupsd
</screen>
</para>
<para>
See the man pages for <command>fuser</command> and <command>lsof</command>
command syntax.
</para>
<para>
Another place to look for where a service is started, is in the
<filename>init.d</filename> directory, where the actual init scripts
live<![%linuxall;[ (for SysVinit systems)]]>. Something like <literal>ls -l
/etc/<![%redhat;[rc.d/]]>init.d/</literal>, should give us a list of these.
Often the script name itself gives a hint as to which service(s) it starts,
though it may not necessarily exactly match the <quote>Program Name</quote>
as provided by <command>netstat</command>. Or we can use
<command>grep</command> to search inside files and match a search pattern.
Need to find where <command>rpc.statd</command> is being started, and we
don't see a script by this name?
</para>
<para>
<screen>
# grep rpc.statd /etc/init.d/*
/etc/init.d/nfslock: [ -x /sbin/rpc.statd ] || exit 0
/etc/init.d/nfslock: daemon rpc.statd
/etc/init.d/nfslock: killproc rpc.statd
/etc/init.d/nfslock: status rpc.statd
/etc/init.d/nfslock: /sbin/pidof rpc.statd &gt;/dev/null 2>&amp;1; STATD="$?"
</screen>
</para>
<para>
We didn't really need all that information, but at least we see now
exactly which script is starting it. Remember too that not all services
are started this way. Some may be started via <application>inetd</application>,
or <application>xinetd</application>.
</para>
<para>
The <filename>/proc</filename> filesystem also keeps everything we want
to know about processes that are running. We can query this to find out
more information about each process. Do you need to know the full path of the
command that started a process?
</para>
<para>
<screen>
# ls -l /proc/1315/exe
lrwxrwxrwx 1 root root 0 July 4 19:41 /proc/1315/exe -> /usr/sbin/cupsd
</screen>
</para>
<para>
Finally, we had a loose end or two in the UDP listening services. Remember we
had a strange looking port number 32768, that also had no service name
associated with it:
</para>
<para>
<screen>
# netstat -aup
Active Internet connections (servers and established)
Local Address Foreign Address State PID/Program name
*:32768 *:* 956/named
bigcat:domain *:* 956/named
bigcat:domain *:* 956/named
*:631 *:* 1315/cupsd
</screen>
</para>
<para>
Now by including the <quote>PID/Program name</quote>
option with the <literal>-p</literal> flag, we see this also belongs to
<command>named</command>, the nameserver daemon. Recent versions of
<application>BIND</application> use an unprivileged port for some types
of traffic. In this case, this is <application>BIND 9.x</application>.
So no real alarms here either. The unprivileged port here is the one
<command>named</command> uses to talk to other nameservers for name
and address lookups, and should not be firewalled.
</para>
<para>
So we found no big surprises in this hypothetical situation.
</para>
<para>
If all else fails, and you can't find a process owner for an open port,
suspect that it may be an RPC (Remote Procedure Call) service of some kind.
These use randomly assigned ports without any seeming logic or consistency,
and are typically controlled by the <command>portmap</command> daemon.
In some cases, these may not reveal the process owner to
<command>netstat</command> or <command>lsof</command>. Try stopping
<command>portmap</command>, and then see if the mystery service goes away. Or
you can use <command>rpcinfo -p localhost</command> to see what RPC services
may be running (<command>portmap</command> must be running for this to
work).
</para>
<warning>
<para>
If you suspect you have been broken into, <emphasis>do not trust</emphasis>
<command>netstat</command> or <command>ps</command> output. There is a good
chance that they, and other system components, has been tampered with in
such a way that the output is not reliable.
</para>
</warning>
</sect3>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="threats">
<title>Attacks and Threats</title>
<para>
In this section, we will take a quick look at some of the common threats
and techniques that are out there, and attempt to put them into some
perspective.
</para>
<para>
The corporate world, government agencies and high profile Internet sites have
to be concerned with a much more diverse and challenging set of threats than
the typical home desktop user. There are many reasons someone may want to
break in to someone else's computer. It may be just for kicks, or any number
of malicious reasons. They may just want a base from which to attack
someone else. This is a very common motivation.
</para>
<para>
The most common <quote>attack</quote> for most of us is from already
compromised systems. The Internet is littered with computers that have been
broken into, and are now doing their master's bidding blindly, in zombie-like
fashion. They are programmed to scan massively large address ranges, probing
each individual IP address as they go. Looking for one or more open ports,
and then probing for known weaknesses if they get the chance. Very
impersonal. Very methodical. And very effective. We are all in the path of
such robotic scans. All because those responsible for these systems fail to
do what you are doing now - taking steps to protect their system(s), and
avoid being r00ted.
</para>
<para>
These scans do not look at login banners that may be presented on connection.
It will do little good to change your <filename>/etc/issue.net</filename> to
pretend that you are running some obscure operating system. If they find
something listening, they will try all of the exploits appropriate to that
port, without regard to any indications your system may give. If it works,
they are in -- if not, they will move on.
</para>
<!-- ~~~~~ New section ~~~~~ -->
<sect3 id="scans">
<title>Port Scans and Probes</title>
<para>
First, let's define <quote>scan</quote> and <quote>probe</quote> since these
terms come up quite a bit. A <quote>probe</quote> implies testing if a given
port is open or closed, and possibly what might be listening on that port. A
<quote>scan</quote> implies either <quote>probing</quote> multiple ports on
one or more systems. Or individual ports on multiple systems. So you might
<quote>scan</quote> all ports on your own system for instance. Or a
cracker might <quote>scan</quote> the 216.78.*.* address range to see who
has port 111 open.
</para>
<para>
Black hats can use scan and probe information to know what services are
running on a given system, and then they might know what exploits to try.
They may even be able to tell what Operating System is running, and even
kernel version, and thus get even more information. <quote>Worms</quote>, on
the other hand, are automated and scan blindly, generally just looking for
open ports, and then a susceptible victim. They are not trying to
<quote>learn</quote> anything, the way a cracker might.
</para>
<para>
The distinction between <quote>scan</quote> and <quote>probe</quote>is often
blurred. Both can used in good ways, or in bad ways, depending on who is
doing it, and why. You might ask a friend to scan you, for instance, to see
how well your firewall is working. This is a legitimate use of scanning tools
such as <application>nmap</application>. But what if someone you don't know
does this? What is their intent? If it's your ISP, they may be trying to
enforce their Terms of Service Agreement. Or maybe, it is someone just
playing, and seeing who is <quote>out there</quote>. But more than likely it
is someone or something with not such good intentions.
</para>
<para>
Full range port scans (meaning probing of many ports on the same machine)
seem to be a not so common threat for home based networks. But certainly,
scanning individual ports across numerous systems is a very, very common
occurrence.
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3>
<title>Rootkits</title>
<para>
A <quote>rootkit</quote> is the script kiddie's stock in trade. When a
successful intrusion takes place, the first thing that is often done, is to
download and install such <quote>rootkits</quote>. The rootkit is a set of
scripts designed to take control of the system, and then hide the intrusion.
Rootkits are readily available on the web for various Operating Systems.
</para>
<para>
A rootkit will typically replace critical system files such as
<command>ls</command>, <command>ps</command>, <command>netstat</command>,
<command>login</command> and others. Passwords may be added, hidden
daemons started, logs tampered with, and surely one of more backdoors are
opened. The hidden backdoors allow easy access any time the attacker wants
back in. And often the vulnerability itself may even be fixed so that the new
<quote>owner</quote> has the system all to himself. The entire process is
scripted so it happens very quickly. The rightful owners of these compromised
systems generally have no idea what is going on, and are victims themselves.
A well designed rootkit can be very difficult to detect.
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3>
<title>Worms and Zombies</title>
<para>
A <quote>worm</quote> is a self replicating exploit. It infects a system,
then attempts to spread itself typically via the same vulnerability. Various
<quote>worms</quote> are weaving their way through the entire Internet
address space constantly, spreading themselves as they go.
</para>
<para>
But somewhere behind the zombie, there is a controller. Someone launched
the worm, and they will be informed after a successful intrusion. It is
then up to them how the system will be used.
</para>
<para>
Many of these are Linux systems, looking for other Linux systems to
<quote>infect</quote> via a number of exploits. But most Operating Systems
share in this threat. Once a vulnerable system is found, the actual entry
and take over is quick, and may be difficult to detect after the fact. The
first thing an intruder (whether human or <quote>worm</quote>) will do is
attempt to cover their tracks. A <quote>rootkit</quote> is downloaded and
installed. This trend has been exacerbated by the growing popularity of cable
modems and DSL. The number of full time Internet connections is growing
rapidly, and this makes fertile ground for such exploits since often
these aren't as well secured as larger sites.
</para>
<para>
While this may sound ominous, a few simple precautions can effectively
deter this type of attack. With so many easy victims out there, why waste much
effort breaking into <Emphasis>your</Emphasis> system? There is no incentive
to really try very hard. Just scan, look, try, move on if unsuccessful. There
is always more IPs to be scanned. If your firewall is effectively bouncing
this kind of thing, it is no threat to you at all. Take comfort in that,
and don't over re-act.
</para>
<para>
It is worth noting, that these worms cannot <quote>force</quote> their way
in. They need an open and accessible port, <emphasis>and</emphasis> a known
vulnerability. If you remember the <quote>Iptables Weekly Log Summary</quote>
in the opening section above, many of those may have all been the result of
this type of scan. If you've followed the steps in this HOWTO, you should be
reasonably safe here. This one is easy enough to deflect.
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3>
<title>Script Kiddies</title>
<para>
A <quote>script kiddie</quote> is a <quote>cracker</quote> wanna be who
doesn't know enough to come up with his/her own exploits, but instead
relies on <quote>scripts</quote> and exploits that have been developed by
others. Like <quote>worms</quote>, they are looking for easy victims,
and may similarly scan large address ranges looking for specific ports
with known vulnerabilities. Often, the actual scanning is done from
already comprised systems so that it is difficult to trace it back to them.
</para>
<para>
The script kiddie has a bag of ready made tricks at his disposal, including
an arsenal of <quote>rootkits</quote> for various Operating Systems. Finding
susceptible victims is not so hard, given enough time and address space to
probe. The motives are a mixed bag as well. Simple mischief, defacement
of web sites, stolen credit card numbers, and the latest craze,
<quote>Denial of Service</quote> attacks (see below). They collect
zombies like trophies and use them to carry out whatever their objective is.
</para>
<para>
Again, the key here is that they are following a <quote>script</quote>, and
looking for easy prey. Like the worm threat above, a functional firewall
and a few very basic precautions, should be sufficient to deflect any
threat here. By now, you should be relatively safe from this nuisance.
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3>
<title>Spoofed IPs</title>
<para>
How easy is it to spoof an IP address? With the right tools, very easy. How
much of a threat is this? Not much, for most of us, and is over-hyped as a
threat.
</para>
<para>
Because of the way TCP/IP works, each packet must carry both the source and
destination IP addresses. Any return traffic is based on this information. So
a spoofed IP can never return any useful information to an attacker who is
sending out spoofed packets. The traffic would go back to wherever that
spoofed IP address was pointed. The attacker gets nothing back at all.
</para>
<para>
This does have potential for <quote>DoS</quote> attacks (see below) where
learning something about the targeted system is not important. And may be
used for some general mischief making as well.
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3>
<title>Targeted Attacks</title>
<para>
The worm and wide ranging address type scans, are impersonal. They are just
looking for any vulnerable system. It makes no difference whether it is a top
secret government facility, or your mother's Window's box. But there are
<quote>black hats</quote> that will spend a great deal of effort to get into
a system or network. We'll call these <quote>targeted</quote> attacks since
there has been a deliberate decision made to break in to a specific system
or network.
</para>
<para>
In this case, the attacker will look the system over for weaknesses. And
possibly make many different kinds of attempts, until he finds a crack to
wiggle through. Or gives up. This is more difficult to defend against. The
attacker is armed and dangerous, so to speak, and is stalking his prey.
</para>
<para>
Again, this scenario is very unlikely for a typical home system. There just
generally isn't any incentive to take the time and effort when there are
bigger fish to fry. For those who may be targets, the best defense here
includes many of things we've discussed. Vigilance is probably more important
than ever. Good logging practices and an IDS (Intrusion Detection System)
should be in place. And subscribing to one or more security related mailing
lists like BUGTRAQ. And of course, reading those alerts daily, and taking
the appropriate actions, etc.
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3 id="dos">
<title>Denial of Service (DoS)</title>
<para>
<quote>DoS</quote> is another type of <quote>attack</quote> in which the
intention is to disrupt or overwhelm the targeted system or network in such a
way that it cannot function normally. DoS can take many forms. On the
Internet, this often means overwhelming the victim's bandwidth or TCP/IP
stack, by sending floods of packets and thus effectively disabling the
connection. We are talking about many, many packets per second. Thousands in
some cases. Or perhaps, the objective is to crash a server.
</para>
<para>
This is much more likely to be targeted at organizations or high profile
sites, than home users. And can be quite challenging to stop depending
on the technique. And it generally requires the co-operation of
networks between the source(s) and the target, so that the floods are
stopped, or minimized, before they reach the targeted destination. Once they
hit the destination, there is no good way to completely ignore them.
</para>
<para>
<quote>DDoS</quote>, Distributed Denial of Service, is where multiple sources
are used to maximize the impact. Again, not likely to be directly targeted at
home users. These are <quote>slaves</quote> that are <quote>owned</quote>
by a cracker, or script kiddie, that are woken up and are targeted at the
victim. There may be many computers involved in the attack.
</para>
<para>
If you are home user, and with a dynamic IP address, you might find
disconnecting, then re-connecting to get a new IP, an effective way out
if you are the target. Maybe.
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3>
<title>Brute Force</title>
<para>
<quote>Brute force</quote> attacks are where the attacker makes repetitive
attempts at the same perceived weakness(es). Like a battering ram. A classic
example would be where someone tries to access a
<application>telnet</application> server simply by continually throwing
passwords at it, hoping that one will eventually work. Or maybe crash the
server. This doesn't require much imagination, and is not a commonly used
tactic against home systems.
</para>
<para>
By the way, this is one good argument against allowing remote root logins.
The root account exists on all systems. It is probably the only one that this
is true of. You'd like to make a potential attacker guess both the login
name <emphasis>and</emphasis> password. But if root is allowed remote logins,
then the attacker only needs to guess the password!
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3 id="viruses">
<title>Viruses</title>
<para>
And now something <emphasis>not</emphasis> to worry about. Viruses seem to be
primarily a Microsoft problem. For various reasons, viruses
are not a significant threat to Linux users. This is not to say that it will
always be this way, but the current virus explosion that plagues Microsoft
systems, can not spread to Linux (or Unix) based systems. In fact, the
various methods and practices that enable this phenomena, are not exploitable
on Linux. So Anti-Virus software is not recommended as part of our arsenal.
At least for the time being with Linux only networks.
</para>
</sect3>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="links">
<title>Links</title>
<para>
Some references for further reading are listed below. Not listed is your
distribution's site, security page or ftp download site. You will
have to find these on your own. Then you should bookmark them!
</para>
<para>
<itemizedlist>
<![%redhat;[
<listitem>
<para>
Redhat sites of interest:
</para>
<simplelist>
<member>
The Redhat watch/security mailing list: <ulink
url="https://listman.redhat.com/mailman/listinfo/redhat-watch-list">https://listman.redhat.com/mailman/listinfo/redhat-watch-list</ulink>
</member>
</simplelist>
<simplelist>
<member>
Red Hat errata and security notices:
<ulink url="http://redhat.com/errata/">http://redhat.com/errata/</ulink>
</member>
</simplelist>
<simplelist>
<member>
The Red Hat update FTP site:
<ulink url="ftp://updates.redhat.com/">ftp://updates.redhat.com/</ulink>
</member>
</simplelist>
</listitem> ]]>
<listitem>
<para>
Other relevant documents available from the Linux Documentation Project:
</para>
<simplelist>
<member>
Security HOWTO: <ulink url="http://tldp.org/HOWTO/Security-HOWTO.html
">http://tldp.org/HOWTO/Security-HOWTO.html
</ulink>
</member>
</simplelist>
<simplelist>
<member>
Firewall HOWTO: <ulink url="http://tldp.org/HOWTO/Firewall-HOWTO.html">http://tldp.org/HOWTO/Firewall-HOWTO.html</ulink>
</member>
</simplelist>
<simplelist>
<member>
Ipchains HOWTO: <ulink url="http://tldp.org/HOWTO/IPCHAINS-HOWTO.html
">http://tldp.org/HOWTO/IPCHAINS-HOWTO.html
</ulink>
</member>
</simplelist>
<simplelist>
<member>
User Authentication: <ulink
url="http://tldp.org/HOWTO/User-Authentication-HOWTO/index.html">http://tldp.org/HOWTO/User-Authentication-HOWTO/index.html</ulink>, includes a
nice discussion on PAM.
</member>
</simplelist>
<simplelist>
<member>
VPN (Virtual Private Network): <ulink
url="http://tldp.org/HOWTO/VPN-HOWTO.html">http://tldp.org/HOWTO/VPN-HOWTO.html</ulink>
and <ulink
url="http://tldp.org/HOWTO/VPN-Masquerade-HOWTO.html">http://tldp.org/HOWTO/VPN-Masquerade-HOWTO.html</ulink>
</member>
</simplelist>
<simplelist>
<member>
The Remote X Apps Mini HOWTO,
<ulink url="http://www.tldp.org/HOWTO/mini/Remote-X-Apps.html">http://www.tldp.org/HOWTO/mini/Remote-X-Apps.html</ulink>,
includes excellent discussions on the security implications of running
X Windows.
</member>
</simplelist>
<simplelist>
<member>
The Linux Network Administrators Guide:
<ulink
url="http://tldp.org/LDP/nag2/index.html">http://tldp.org/LDP/nag2/index.html</ulink>, includes a good overview of networking and TCP/IP, and
firewalling.
</member>
</simplelist>
<simplelist>
<member>
The Linux Administrator's Security Guide:
<ulink
url="http://www.seifried.org/lasg/"> http://www.seifried.org/lasg/</ulink>,
includes many obvious topics of interest, including firewalling,
passwords and authentication, PAM, and more.
</member>
</simplelist>
<simplelist>
<member>
Securing Red Hat:
<ulink
url="http://tldp.org/LDP/solrhe/Securing-Optimizing-Linux-RH-Edition-v1.3/index.html">http://tldp.org/LDP/solrhe/Securing-Optimizing-Linux-RH-Edition-v1.3/index.html</ulink>
</member>
</simplelist>
</listitem>
<listitem>
<para>
Tools for creating custom <application>ipchains</application> and
<application>iptables</application> firewall scripts:
</para>
<!--
<simplelist>
<member>
PMFirewall: <ulink
url="http://www.pmfirewall.com/PMFirewall/">http://www.pmfirewall.com/PMFirewall/</ulink>
</member>
</simplelist>
-->
<simplelist>
<member>
Firestarter: <ulink
url="http://firestarter.sourceforge.net">http://firestarter.sourceforge.net</ulink>
</member>
</simplelist>
<simplelist>
<member>
Two related projects: <ulink url="http://seawall.sourceforge.net/">http://seawall.sourceforge.net/</ulink> for ipchains,
and <ulink url="http://shorewall.sourceforge.net/"></ulink> for iptables.
</member>
</simplelist>
</listitem>
<listitem>
<para>
Netfilter and iptables documentation from the netfilter developers
(available in many other languages as well):
</para>
<simplelist>
<member>
FAQ: <ulink
url="http://netfilter.samba.org/documentation/FAQ/netfilter-faq.html">http://netfilter.samba.org/documentation/FAQ/netfilter-faq.html</ulink>
</member>
<member>
Packet filtering: <ulink
url="http://netfilter.samba.org/documentation/HOWTO/packet-filtering-HOWTO.html">http://netfilter.samba.org/documentation/HOWTO/packet-filtering-HOWTO.html</ulink>
</member>
<member>
Networking: <ulink
url="http://netfilter.samba.org/documentation/HOWTO/networking-concepts-HOWTO.html">http://netfilter.samba.org/documentation/HOWTO/networking-concepts-HOWTO.html</ulink>
</member>
<member>
NAT/masquerading: <ulink
url="http://netfilter.samba.org/documentation/HOWTO/NAT-HOWTO.html">http://netfilter.samba.org/documentation/HOWTO/NAT-HOWTO.html</ulink>
</member>
</simplelist>
</listitem>
<listitem>
<para>
Port number assignments, and what that scanner may be scanning for:
</para>
<simplelist>
<member>
<ulink
url="http://www.linuxsecurity.com/resource_files/firewalls/firewall-seen.html">http://www.linuxsecurity.com/resource_files/firewalls/firewall-seen.html</ulink>
</member>
</simplelist>
<simplelist>
<member>
<ulink
url="http://www.sans.org/newlook/resources/IDFAQ/oddports.htm">http://www.sans.org/newlook/resources/IDFAQ/oddports.htm</ulink>
</member>
</simplelist>
<simplelist>
<member>
<ulink url="http://www.iana.org/assignments/port-numbers">http://www.iana.org/assignments/port-numbers</ulink>, the official assignments.
</member>
</simplelist>
</listitem>
<listitem>
<para>
General security sites. These all have areas on documentation, alerts,
newsletters, mailing lists, and other resources.
</para>
<simplelist>
<member>
Linux Security.com: <ulink url="http://www.linuxsecurity.com">http://www.linuxsecurity.com</ulink>, loaded with good info, and Linux specific.
Lots of good docs: <ulink url="http://www.linuxsecurity.com/docs/">http://www.linuxsecurity.com/docs/</ulink>
</member>
</simplelist>
<simplelist>
<member>
CERT, <ulink url="http://www.cert.org">http://www.cert.org</ulink>
</member>
</simplelist>
<simplelist>
<member>
The SANS Institute: <ulink
url="http://www.sans.org/">http://www.sans.org/</ulink>
</member>
</simplelist>
<simplelist>
<member>
The Coroner's Toolkit (TCT): <ulink
url="http://www.fish.com/security/">http://www.fish.com/security/</ulink>,
discussions and tools for dealing with post break-in issues (and
preventing them in the first place).
</member>
</simplelist>
</listitem>
<listitem>
<para>
Privacy:
</para>
<simplelist>
<member>
Junkbuster: <ulink
url="http://www.junkbuster.com">http://www.junkbuster.com</ulink>, a
web proxy and cookie manager.
</member>
</simplelist>
<simplelist>
<member>
PGP: <ulink url="http://www.gnupg.org/">http://www.gnupg.org/</ulink>
</member>
</simplelist>
</listitem>
<listitem>
<para>
Other documentation and reference sites:
</para>
<simplelist>
<member>
Linux Security.com: <ulink
url="http://www.linuxsecurity.com/docs/">http://www.linuxsecurity.com/docs/</ulink>
</member>
</simplelist>
<simplelist>
<member>
Linux Newbie: <ulink
url="http://www.linuxnewbie.org/nhf/intel/security/index.html">http://www.linuxnewbie.org/nhf/intel/security/index.html</ulink>
</member>
</simplelist>
<simplelist>
<member>
The comp.os.linux.security FAQ: <ulink
url="http://www.linuxsecurity.com/docs/colsfaq.html">http://www.linuxsecurity.com/docs/colsfaq.html</ulink>
</member>
</simplelist>
<simplelist>
<member>
The Internet Firewall FAQ: <ulink
url="http://www.interhack.net/pubs/fwfaq/">http://www.interhack.net/pubs/fwfaq/</ulink>
</member>
</simplelist>
<simplelist>
<member>
The Site Security Handbook RFC: <ulink
url="http://www.ietf.org/rfc/rfc2196.txt">http://www.ietf.org/rfc/rfc2196.txt</ulink>
</member>
</simplelist>
</listitem>
<listitem>
<para>
Miscellaneous sites of interest:
</para>
<simplelist>
<member>
<ulink url="http://www.bastille-linux.org">http://www.bastille-linux.org</ulink>, for Mandrake and Red Hat only.
</member>
</simplelist>
<simplelist>
<member>
SAINT: <ulink
url="http://www.wwdsi.com/saint/">http://www.wwdsi.com/saint/</ulink>,
system security analysis.
</member>
</simplelist>
<simplelist>
<member>
SSL: <ulink url="http://www.openssl.org/">http://www.openssl.org/</ulink>
</member>
</simplelist>
<simplelist>
<member>
SSH: <ulink url="http://www.openssh.org/">http://www.openssh.org/</ulink>
</member>
</simplelist>
<simplelist>
<member>
Scan yourself: <ulink
url="http://www.hackerwhacker.com">http://www.hackerwhacker.com</ulink>
</member>
</simplelist>
<simplelist>
<member>
PAM: <ulink
url="http://www.kernel.org/pub/linux/libs/pam/index.html">http://www.kernel.org/pub/linux/libs/pam/index.html</ulink>
</member>
</simplelist>
<simplelist>
<member>
Detecting Trojaned Linux Kernel Modules: <ulink
url="http://members.prestige.net/tmiller12/papers/lkm.htm">http://members.prestige.net/tmiller12/papers/lkm.htm</ulink>
</member>
</simplelist>
<simplelist>
<member>
Rootkit checker: <ulink
url="http://www.chkrootkit.org">http://www.chkrootkit.org</ulink>
</member>
</simplelist>
<simplelist>
<member>
Port scanning tool <application>nmap's</application> home page: <ulink
url="http://www.insecure.org">http://www.insecure.org</ulink>
</member>
</simplelist>
<simplelist>
<member>
Nessus, more than just a port scanner: <ulink
url="http://www.nessus.org">http://www.nessus.org</ulink>
</member>
</simplelist>
<simplelist>
<member>
Tripwire, intrusion detection:
<ulink url="http://www.tripwire.org">http://www.tripwire.org</ulink>
</member>
</simplelist>
<simplelist>
<member>
Snort, sniffer and more: <ulink
url="http://www.snort.org">http://www.snort.org</ulink>
</member>
</simplelist>
<simplelist>
<member>
<ulink url="http://www.mynetwatchman.com">http://www.mynetwatchman.com</ulink>
and <ulink url="http://dshield.org">http://dshield.org</ulink> are
<quote>Distributed Intrusion Detection Systems</quote>. They collect
log data from subscribing <quote>agents</quote>, and collate the
data to find and report malicious activity. If you want to fight back,
check these out.
</member>
</simplelist>
</listitem>
</itemizedlist>
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="text">
<title>Editing Text Files</title>
<para>
By Bill Staehle
</para>
<para>
All the world is a file.
</para>
<para>
There are a great many types of files, but I'm going to stretch it here,
and class them into two really broad families:
</para>
<Para>
<Literal>
<MSGText>
<LiteralLayout>
Text files are just that.
Binary files are not.
</LiteralLayout>
</MSGText>
</Literal>
</Para>
<para>
Binary files are meant to be read by machines, text files can be easily
edited, and are generally read by people. But text files can be (and
frequently are) read by machines. Examples of this would be configuration
files, and scripts.
</para>
<para>
There are a number of different text editors available in *nix. A few
are found on every system. That would be '/bin/ed' and '/bin/vi'. 'vi' is
almost always a clone such as 'vim' due to license problems. The problem with
'vi' and 'ed' is that they are terribly user unfriendly. Another common editor
that is not always installed by default is 'emacs'. It has a lot more features
and capability, and is not easy to learn either.
</para>
<para>
As to 'user friendly' editors, 'mcedit' and 'pico' are good choices to start
with. These are often much easier for those new to *nix.
</para>
<para>
The first things to learn are how to exit an editing session, how to save
changes to the file, and then how to avoid breaking long lines that should
not be broken (wrapped).
</para>
<para>
The 'vi' editor
</para>
<para>
'vi' is one of the most common text editors in the Unix world, and it's
nearly always found on any *nix system. Actually, due to license problems,
the '/bin/vi' on a Linux system is always a 'clone', such as 'elvis',
'nvi', or 'vim' (there are others). These clones can act exactly like
the original 'vi', but usually have additional features that make it
slightly less impossible to use.
</para>
<para>
So, if it's so terrible, why learn about it? Two reasons. First, as
noted, it's almost guaranteed to be installed, and other (more user
friendly) editors may not be installed by default. Second, many of the
'commands' work in other applications (such as the pager 'less' which is
also used to view man pages). In 'less', accidentally pressing the 'v' key
starts 'vi' in most installations.
</para>
<para>
'vi' has two modes. The first is 'command mode', and keystrokes are
interpreted as commands. The other mode is 'insert' mode, where nearly all
keystrokes are interpreted as text to be inserted.
</para>
<para>
==> Emergency exit from 'vi'
1. press the &lt;esc&gt; key up to three times, until the computer beeps, or the
screen flashes.
2. press the keys :q! &lt;Enter&gt;
</para>
<para>
That is: colon, the letter Q, and then the exclamation point, followed by
the Enter key.
</para>
<para>
'vi' commands are as follows. All of these are in 'command' mode:
</para>
<Para>
<Literal>
<MSGText>
<LiteralLayout>
a Enter insertion mode after the cursor.
A Enter insertion mode at the end of the current line.
i Enter insertion mode before the cursor.
o Enter insertion mode opening a new line BELOW current line.
O Enter insertion mode opening a new line ABOVE current line.
h move cursor left one character.
l move cursor right one character.
j move cursor down one line.
k move cursor up one line.
/mumble move cursor forward to next occurrence of 'mumble' in
the text
?mumble move cursor backward to next occurrence of 'mumble'
in the text
n repeat last search (? or / without 'mumble' to search for
will do the same thing)
u undo last change made
^B Scroll back one window.
^F Scroll forward one window.
^U Scroll up one half window.
^D Scroll down one half window.
:w Write to file.
:wq Write to file, and quit.
:q quit.
:q! Quit without saving.
&lt;esc&gt; Leave insertion mode.
</LiteralLayout>
</MSGText>
</Literal>
</Para>
<para>
NOTE: The four 'arrow' keys almost always work in 'command' or 'insert'
mode.
</para>
<para>
The 'ed' editor.
</para>
<para>
The 'ed' editor is a line editor. Other than the fact that it is virtually
guaranteed to be on any *nix computer, it has no socially redeeming
features, although some applications may need it. A _lot_ of things have
been offered to replace this 'thing' from 1975.
</para>
<para>
==> Emergency exit from 'ed'
</para>
<para>
1. type a period on a line by itself, and press &lt;Enter&gt; This gets you to
the command mode or prints a line of text if you were in command mode.
2. type q and press &lt;Enter&gt;. If there were no changes to the file,
this action quits ed. If you then see a '?' this means that the file had
changed, and 'ed' is asking if you want to save the changes. Press q and
&lt;Enter&gt; a second time to confirm that you want out.
</para>
<para>
The 'pico' editor.
</para>
<para>
'pico' is a part of the Pine mail/news package from the University of
Washington (state, USA). It is a very friendly editor, with one minor
failing. It silently inserts a line feed character and wraps the line when
it exceeds (generally) 74 characters. While this is fine while creating
mail, news articles, and text notes, it is often fatal when editing system
files. The solution to this problem is simple. Call the program with the
-w option, like this:
</para>
<para>
pico -w file_2_edit
</para>
<para>
Pico is so user friendly, no further instructions are needed. It _should_
be obvious (look at the bottom of the screen for commands). There is an
extensive help function. Pico is available with nearly all distributions,
although it _may_ not be installed by default.
</para>
<para>
==> Emergency exit from 'pico'
</para>
<para>
Press and hold the &lt;Ctrl&gt; key, and press the letter x. If no changes
had been made to the file, this will quit pico. If changes had been made,
it will ask if you want to save the changes. Pressing n will then exit.
</para>
<para>
The 'mcedit' editor.
</para>
<para>
'mcedit' is part of the Midnight Commander shell program, a full featured
visual shell for Unix-like systems. It can be accessed directly from the
command line ( mcedit file_2_edit ) or as part of 'mc' (use the arrow keys
to highlight the file to be edited, then press the F4 key).
</para>
<para>
mcedit is probably the most intuitive editor available, and comes with
extensive help. "commands" are accessed through the F* keys. Midnight
Commander is available with nearly all distributions, although it _may_ not
be installed by default.
</para>
<para>
==> Emergency exit from 'mcedit'
</para>
<para>
Press the F10 key. If no changes have been made to the file, this will
quit mcedit. If changes had been made, it will ask if you want to Cancel
this action. Pressing n will then exit.
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="nmap">
<title>nmap</title>
<para>
Let's look at a few quick examples of what <command>nmap</command> scans
look like. The intent here is to show how to use <command>nmap</command>
to verify our firewalling, and system integrity. <command>nmap</command>
has other uses that we don't need to get into. Do NOT use
<command>nmap</command> on systems other than your own, unless you have
permission from the owner, and you know it is not a violation of anyone's
Terms of Service. This kind of thing <emphasis>will</emphasis> be taken as
hostile by most people.
</para>
<para>
As mentioned previously, <command>nmap</command> is a sophisticated
port scanning tool. It tries to see if a host is <quote>there</quote>,
and what ports might be open. Barring that, what states those ports
might be in. <command>nmap</command> has a complex command line and
can do many types of <quote>scans</quote>. See the man page for all
the nitty gritty.
</para>
<para>
A couple of words of warning first. If using
<application>portsentry</application>, turn it off. It will drop the route
to wherever the scan is coming from. You might want to turn off any logging
also, or at least be aware that you might get copious logs if doing multiple
scans.
</para>
<para>
A simple, default scan of <quote>localhost</quote>:
</para>
<para>
<screen>
# nmap localhost
Starting nmap V. 2.53 by fyodor@insecure.org ( www.insecure.org/nmap/ )
Interesting ports on bigcat (127.0.0.1):
(The 1507 ports scanned but not shown below are in state: closed)
Port State Service
22/tcp open ssh
25/tcp open smtp
37/tcp open time
53/tcp open domain
80/tcp open http
3000/tcp open ppp
Nmap run completed -- 1 IP address (1 host up) scanned in 2 seconds
</screen>
</para>
<para>
If you've read most of this document, you should be familiar with
these services by now. These are some of the same ports we've seen in other
examples. Some things to note on this scan: it only did 1500+
<quote>interesting</quote> ports -- not all ports. This can be configured
differently if more is desirable (see man page). It only did TCP ports too.
Again, configurable. It only picks up <quote>listening</quote> services,
unlike <command>netstat</command> that shows all open ports -- listening or
otherwise. Note the last <quote>open</quote> port here is 3000 is identified
as <quote>PPP</quote>. Wrong! That is just an educated guess by nmap based on
what is contained in <filename>/etc/services</filename> for this port number.
Actually in this case it is <application>ntop</application> (a network
traffic monitor). Take the service names with a grain of salt. There is no
way for <command>nmap</command> to really know what is on that port. Matching
port numbers with service names can at times be risky. Many do have standard
ports, but there is nothing to say they have to use the commonly associated
port numbers.
</para>
<para>
Notice that in all our <command>netstat</command> examples, we had two classes
of open ports: listening servers, and then established connections that we
initiated to other remote hosts (e.g. a web server somewhere).
<command>nmap</command> only sees the first group -- the listening servers!
The other ports connecting us to remote servers are not visible, and thus
not vulnerable. These ports are <quote>private</quote> to that single
connection, and will be closed when the connection is terminated.
</para>
<para>
So we have open and closed ports here. Simple enough, and gives a pretty good
idea what is running on bigcat -- but not necessarily what we look like to
the outside world since this was done from localhost, and wouldn't reflect
any firewalling or other access control mechanisms.
</para>
<para>
Let's do a little more intensive scan. Let's check all ports -- TCP and UDP.
</para>
<para>
<screen>
# nmap -sT -sU -p 1-65535 localhost
Starting nmap V. 2.53 by fyodor@insecure.org ( www.insecure.org/nmap/ )
Interesting ports on bigcat (127.0.0.1):
(The 131050 ports scanned but not shown below are in state: closed)
Port State Service
22/tcp open ssh
25/tcp open smtp
37/tcp open time
53/tcp open domain
53/udp open domain
80/tcp open http
3000/tcp open ppp
8000/tcp open unknown
32768/udp open unknown
Nmap run completed -- 1 IP address (1 host up) scanned in 385 seconds
</screen>
</para>
<para>
This is more than just <quote>interesting</quote> ports -- it is everything.
We picked up a couple of new ones in the process too. We've seen these before
with <command>netstat</command>, so we know what they are. That is the
<command>Junkbuster</command> web proxy on port 8000/tcp and
<command>named</command> on 32768/udp. This scan takes much, much longer, but it
is the only way to see all ports.
</para>
<para>
So now we have a pretty good idea of what is open on bigcat. Since
we are scanning localhost from localhost, everything should be visible.
We still don't know how the outside world sees us though. Now I'll
<command>ssh</command> to another host on the same LAN, and try again.
</para>
<para>
<screen>
# nmap bigcat
Starting nmap V. 2.53 by fyodor@insecure.org ( www.insecure.org/nmap/ )
Interesting ports on bigcat (192.168.1.1):
(The 1520 ports scanned but not shown below are in state: closed)
Port State Service
22/tcp open ssh
3000/tcp open ppp
Nmap run completed -- 1 IP address (1 host up) scanned in 1 second
</screen>
</para>
<para>
I confess to tampering with the <application>iptables</application> rules
here to make a point. Only two visible ports on this scan. Everything
else is <quote>closed</quote>. So says <application>nmap</application>.
Once again:
</para>
<para>
<screen>
# nmap bigcat
Starting nmap V. 2.53 by fyodor@insecure.org ( www.insecure.org/nmap/ )
Note: Host seems down. If it is really up, but blocking our ping probes, try -P0
Nmap run completed -- 1 IP address (0 hosts up) scanned in 30 seconds
</screen>
</para>
<para>
Oops, I blocked ICMP (ping) while I was at it this time. One more time:
</para>
<para>
<screen>
# nmap -P0 bigcat
Starting nmap V. 2.53 by fyodor@insecure.org ( www.insecure.org/nmap/ )
All 1523 scanned ports on bigcat (192.168.1.1) are: filtered
Nmap run completed -- 1 IP address (1 host up) scanned in 1643 seconds
</screen>
</para>
<para>
That's it. Notice how long that took. Notice ports are now
<quote>filtered</quote> instead of <quote>closed</quote>. How does
<command>nmap</command> know that? Well for one, <quote>closed</quote> means
bigcat sent a packet back saying <quote>nothing running here</quote>, i.e.
port is closed. In this last example, the <application>iptables</application>
rules were changed to not allow ICMP (ping), and to <quote>DROP</quote> all
incoming packets. In other words, no response at all. A subtle difference
since <command>nmap</command> seems to still know there was a host there,
even though no response was given. One lesson here, is if you want to slow a
scanner down, <quote>DROP</quote> (or <quote>DENY</quote>) the packets. This
forces a TCP time out for the remote end on each port probe. Anyway, if your
scans look like this, that is probably as well as can be expected, and your
firewall is doing its job.
</para>
<para>
A brief note on UDP: <command>nmap</command> can not accurately determine
the status of these ports if they are <quote>filtered</quote>. You probably
will get a false-positive <quote>open</quote> condition. This has to do with
UDP being a connectionless protocol. If <command>nmap</command> gets no
answer (e.g. due to a <quote>DROP</quote>), it assumes the packets reached
the target, and thus the port will be reported as <quote>open</quote>.
This is <quote>normal</quote> for <command>nmap</command>.
</para>
<para>
We can play with firewall rules in a LAN set up to try to simulate how the
outside world sees us, and if we are smart, and know what we are doing,
and don't have a brain fart, we probably will have a pretty good picture. But
it is still best to try to find a way to do it from outside if possible.
Again, make sure you are not violating any ISP rules of conduct. Do you have
a friend on the same ISP?
</para>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="sysctl">
<title>Sysctl Options</title>
<para>
The <quote>sysctl</quote> options are kernel parameters that can be
configured via the <filename>/proc</filename> filesystem. These can
be dynamically adjusted at run-time. Typically these options are off
if set to <quote>0</quote>, and on if set to <quote>1</quote>.
</para>
<para>
Some of these have security implications, and thus is why we are here ;-)
We'll just list the ones we think are relevant. Feel free to cut and
paste these into a firewall script, or other file that is run during boot
(like <filename>/etc/rc.local</filename>). <![%linuxall;[ Or your
distribution may have their own way of tuning this. ]]>
<![%redhat;[ Red Hat provides the <command>sysctl</command> command for
dynamically adjusting these values (see man page). Or they can permanently be
set in <filename>/etc/sysctl.conf</filename> with your text editor of choice.
<command>sysctl</command> is executed during init, and uses these values.]]>
You can read up on what these mean in
<filename>/usr/src/linux/Documentation/sysctl/README</filename> and other
files in the kernel Documentation directories.
<!--
# ???????
net.ipv4.tcp_rfc1337 = 1
net.ipv4.ip_no_pmtu_disc = 0
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_timestamps = 1
-->
</para>
<![%redhat;[
<para>
The traditional method:
</para>
]]>
<para>
<programlisting>
#!/bin/sh
#
# Configure kernel sysctl run-time options.
#
###################################################################
# Anti-spoofing blocks
for i in /proc/sys/net/ipv4/conf/*/rp_filter;
do
echo 1 > $i
done
# Ensure source routing is OFF
for i in /proc/sys/net/ipv4/conf/*/accept_source_route;
do
echo 0 > $i
done
# Ensure TCP SYN cookies protection is enabled
[ -e /proc/sys/net/ipv4/tcp_syncookies ] &&\
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
# Ensure ICMP redirects are disabled
for i in /proc/sys/net/ipv4/conf/*/accept_redirects;
do
echo 0 > $i
done
# Ensure oddball addresses are logged
[ -e /proc/sys/net/ipv4/conf/all/log_martians ] &&\
echo 1 > /proc/sys/net/ipv4/conf/all/log_martians
[ -e /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts ] &&\
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
[ -e /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses ] &&\
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
## Optional from here on down, depending on your situation. ############
# Ensure ip-forwarding is enabled if
# we want to do forwarding or masquerading.
[ -e /proc/sys/net/ipv4/ip_forward ] &&\
echo 1 > /proc/sys/net/ipv4/ip_forward
# On if your IP is dynamic (or you don't know).
[ -e /proc/sys/net/ipv4/ip_dynaddr ] &&\
echo 1 > /proc/sys/net/ipv4/ip_dynaddr
# eof
</programlisting>
</para>
<![%redhat;[
<para>
The same effect by using <filename>/etc/sysctl.conf</filename> instead:
</para>
<para>
<programlisting>
#
# Add to existing sysctl.conf
#
# Anti-spoofing blocks
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
# Ensure source routing is OFF
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_source_route = 0
# Ensure TCP SYN cookies protection is enabled
net.ipv4.tcp_syncookies = 1
# Ensure ICMP redirects are disabled
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
# Ensure oddball addresses are logged
net.ipv4.conf.default.log_martians = 1
net.ipv4.conf.all.log_martians = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
## Optional from here on down, depending on your situation. ############
# Ensure ip-forwarding is enabled if
# we want to do forwarding or masquerading.
net.ipv4.ip_forward = 1
# On if your IP is dynamic (or you don't know).
net.ipv4.ip_dynaddr = 1
# end of example
</programlisting>
</para>
]]>
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="securealt">
<title>Secure Alternatives</title>
<para>
This section will give a brief run down on secure alternatives to
potentially insecure methods. This will be a hodge podge of clients
and servers.
</para>
<para>
<itemizedlist>
<listitem>
<para>
telnet, rsh - ssh
</para>
</listitem>
<listitem>
<para>
ftp, rcp - scp or sftp. Both are part of ssh packages. Also, files
can easily be transfered via HTTP if Apache is already running
anyway. Apache can be buttoned down even more by using SSL (HTTPS).
</para>
</listitem>
<listitem>
<para>
sendmail - postfix, qmail. Not to imply that current versions of
<application>sendmail</application> are insecure. Just that there
is some bad history there, and just because it is so widely used
that it makes an inviting crack target.
</para>
<para>
As noted above, Linux installations often include a fully functional
mail server. While this may have some advantages, it is not necessary
in many cases for simply sending mail, or retrieving mail. This can all
be done without a <quote>mail server daemon</quote> running locally.
</para>
</listitem>
<listitem>
<para>
POP3 - SPOP3, POP3 over SSL. If you really need to run your own
POP server, this is the way to do it. If retrieving your mail from
your ISP's server, then you are at their mercy as to what they provide.
</para>
</listitem>
<listitem>
<para>
IMAP - IMAPS, same as above.
</para>
</listitem>
<listitem>
<para>
If you find you need a particular service, and it is for just you or a few
friends, consider running it on a non-standard port. Most server daemons
support this, and is not a problem as long as those who will be
connecting, know about it. For instance, the standard port for
<command>sshd</command> is 22. Any worm or scan will probe for this port
number. So run it on a randomly chosen port. See the <command>sshd</command>
man page.
</para>
</listitem>
</itemizedlist>
</para>
<!--
<simplelist>
<member>
</member>
</simplelist>
-->
</sect2>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect2 id="pfilters">
<title>Ipchains and Iptables Redux</title>
<para>
This section offers a little more advanced look at some of things that
<application>ipchains</application> and <application>iptables</application>
can do. These are basically the same scripts as in Step 3 above, just
with some more advanced configuration options added. These will provide
<quote>masquerading</quote>, <quote>port forwarding</quote>, allow access to
some user definable services, and a few other things. Read the comments for
explanations.
</para>
<!-- ~~~~~ New section ~~~~~ -->
<sect3>
<title>ipchains II</title>
<para>
<programlisting>
#!/bin/sh
#
# ipchains.sh
#
# An example of a simple ipchains configuration. This script
# can enable 'masquerading' and will open user definable ports.
#
###################################################################
# Begin variable declarations and user configuration options ######
#
# Set the location of ipchains (default).
IPCHAINS=/sbin/ipchains
# Local Interfaces
#
# This is the WAN interface, that is our link to the outside world.
# For pppd and pppoe users.
# WAN_IFACE="ppp0"
WAN_IFACE="eth0"
#
# Local Area Network (LAN) interface.
#LAN_IFACE="eth0"
LAN_IFACE="eth1"
# Our private LAN address(es), for masquerading.
LAN_NET="192.168.1.0/24"
# For static IP, set it here!
#WAN_IP="1.2.3.4"
# Set a list of public server port numbers here...not too many!
# These will be open to the world, so use caution. The example is
# sshd, and HTTP (www). Any services included here should be the
# latest version available from your vendor. Comment out to disable
# all PUBLIC services.
#PUBLIC_PORTS="22 80 443"
PUBLIC_PORTS="22"
# If we want to do port forwarding, this is the host
# that will be forwarded to.
#FORWARD_HOST="192.168.1.3"
# A list of ports that are to be forwarded.
#FORWARD_PORTS="25 80"
# If you get your public IP address via DHCP, set this.
DHCP_SERVER=66.21.184.66
# If you need identd for a mail server, set this.
MAIL_SERVER=
# A list of unwelcome hosts or nets. These will be denied access
# to everything, even our 'PUBLIC' services. Provide your own list.
#BLACKLIST="11.22.33.44 55.66.77.88"
# A list of "trusted" hosts and/or nets. These will have access to
# ALL protocols, and ALL open ports. Be selective here.
#TRUSTED="1.2.3.4/8 5.6.7.8"
## end user configuration options #################################
###################################################################
# The high ports used mostly for connections we initiate and return
# traffic.
LOCAL_PORTS=`cat /proc/sys/net/ipv4/ip_local_port_range |cut -f1`:\
`cat /proc/sys/net/ipv4/ip_local_port_range |cut -f2`
# Any and all addresses from anywhere.
ANYWHERE="0/0"
# Start building chains and rules #################################
#
# Let's start clean and flush all chains to an empty state.
$IPCHAINS -F
# Set the default policies of the built-in chains. If no match for any
# of the rules below, these will be the defaults that ipchains uses.
$IPCHAINS -P forward DENY
$IPCHAINS -P output ACCEPT
$IPCHAINS -P input DENY
# Accept localhost/loopback traffic.
$IPCHAINS -A input -i lo -j ACCEPT
# Get our dynamic IP now from the Inet interface. WAN_IP will be our
# IP address we are protecting from the outside world. Put this
# here, so default policy gets set, even if interface is not up
# yet.
[ -z "$WAN_IP" ] &&\
WAN_IP=`ifconfig $WAN_IFACE |grep inet |cut -d : -f 2 |cut -d \ -f 1`
# Bail out with error message if no IP available! Default policy is
# already set, so all is not lost here.
[ -z "$WAN_IP" ] && echo "$WAN_IFACE not configured, aborting." && exit 1
WAN_MASK=`ifconfig $WAN_IFACE | grep Mask | cut -d : -f 4`
WAN_NET="$WAN_IP/$WAN_MASK"
## Reserved IPs:
#
# We should never see these private addresses coming in from outside
# to our external interface.
$IPCHAINS -A input -l -i $WAN_IFACE -s 10.0.0.0/8 -j DENY
$IPCHAINS -A input -l -i $WAN_IFACE -s 172.16.0.0/12 -j DENY
$IPCHAINS -A input -l -i $WAN_IFACE -s 192.168.0.0/16 -j DENY
$IPCHAINS -A input -l -i $WAN_IFACE -s 127.0.0.0/8 -j DENY
$IPCHAINS -A input -l -i $WAN_IFACE -s 169.254.0.0/16 -j DENY
$IPCHAINS -A input -l -i $WAN_IFACE -s 224.0.0.0/4 -j DENY
$IPCHAINS -A input -l -i $WAN_IFACE -s 240.0.0.0/5 -j DENY
# Bogus routing
$IPCHAINS -A input -l -s 255.255.255.255 -d $ANYWHERE -j DENY
## LAN access and masquerading
#
# Allow connections from our own LAN's private IP addresses via the LAN
# interface and set up forwarding for masqueraders if we have a LAN_NET
# defined above.
if [ -n "$LAN_NET" ]; then
echo 1 > /proc/sys/net/ipv4/ip_forward
$IPCHAINS -A input -i $LAN_IFACE -j ACCEPT
$IPCHAINS -A forward -s $LAN_NET -d $LAN_NET -j ACCEPT
$IPCHAINS -A forward -s $LAN_NET -d ! $LAN_NET -j MASQ
fi
## Blacklist hosts/nets
#
# Get the blacklisted hosts/nets out of the way, before we start opening
# up any services. These will have no access to us at all, and will be
# logged.
for i in $BLACKLIST; do
$IPCHAINS -A input -l -s $i -j DENY
done
## Trusted hosts/nets
#
# This is our trusted host list. These have access to everything.
for i in $TRUSTED; do
$IPCHAINS -A input -s $i -j ACCEPT
done
# Port Forwarding
#
# Which ports get forwarded to which host. This is one to one
# port mapping (ie 80 -> 80) in this case.
# NOTE: ipmasqadm is a separate package from ipchains and needs
# to be installed also. Check first!
[ -n "$FORWARD_HOST" ] && ipmasqadm portfw -f &&\
for i in $FORWARD_PORTS; do
ipmasqadm portfw -a -P tcp -L $WAN_IP $i -R $FORWARD_HOST $i
done
## Open, but Restricted Access ports/services
#
# Allow DHCP server (their port 67) to client (to our port 68) UDP traffic
# from outside source.
[ -n "$DHCP_SERVER" ] &&\
$IPCHAINS -A input -p udp -s $DHCP_SERVER 67 -d $ANYWHERE 68 -j ACCEPT
# Allow 'identd' (to our TCP port 113) from mail server only.
[ -n "$MAIL_SERVER" ] &&\
$IPCHAINS -A input -p tcp -s $MAIL_SERVER -d $WAN_IP 113 -j ACCEPT
# Open up PUBLIC server ports here (available to the world):
for i in $PUBLIC_PORTS; do
$IPCHAINS -A input -p tcp -s $ANYWHERE -d $WAN_IP $i -j ACCEPT
done
# So I can check my home POP3 mailbox from work. Also, so I can ssh
# in to home system. Only allow connections from my workplace's
# various IPs. Everything else is blocked.
$IPCHAINS -A input -p tcp -s 255.10.9.8/29 -d $WAN_IP 110 -j ACCEPT
# Uncomment to allow ftp data back (active ftp). Not required for 'passive'
# ftp connections.
#$IPCHAINS -A input -p tcp -s $ANYWHERE 20 -d $WAN_IP $LOCAL_PORTS -y -j ACCEPT
# Accept non-SYN TCP, and UDP connections to LOCAL_PORTS. These are
# the high, unprivileged ports (1024 to 4999 by default). This will
# allow return connection traffic for connections that we initiate
# to outside sources. TCP connections are opened with 'SYN' packets.
# We have already opened those services that need to accept SYNs
# for, so other SYNs are excluded here for everything else.
$IPCHAINS -A input -p tcp -s $ANYWHERE -d $WAN_IP $LOCAL_PORTS ! -y -j ACCEPT
# We can't be so selective with UDP since that protocol does not know
# about SYNs.
$IPCHAINS -A input -p udp -s $ANYWHERE -d $WAN_IP $LOCAL_PORTS -j ACCEPT
# Allow access to the masquerading ports conditionally. Masquerading
# uses it's own port range -- on 2.2 kernels ONLY! 2.4 kernels, do not
# use these ports, so comment out!
[ -n "$LAN_NET" ] &&\
$IPCHAINS -A input -p tcp -s $ANYWHERE -d $WAN_IP 61000: ! -y -j ACCEPT &&\
$IPCHAINS -A input -p udp -s $ANYWHERE -d $WAN_IP 61000: -j ACCEPT
## ICMP (ping)
#
# ICMP rules, allow the bare essential types of ICMP only. Ping
# request is blocked, ie we won't respond to someone else's pings,
# but can still ping out.
$IPCHAINS -A input -p icmp --icmp-type echo-reply \
-s $ANYWHERE -i $WAN_IFACE -j ACCEPT
$IPCHAINS -A input -p icmp --icmp-type destination-unreachable \
-s $ANYWHERE -i $WAN_IFACE -j ACCEPT
$IPCHAINS -A input -p icmp --icmp-type time-exceeded \
-s $ANYWHERE -i $WAN_IFACE -j ACCEPT
#######################################################################
# Set the catchall, default rule to DENY, and log it all. All other
# traffic not allowed by the rules above, winds up here, where it is
# blocked and logged. This is the default policy for this chain
# anyway, so we are just adding the logging ability here with '-l'.
# Outgoing traffic is allowed as the default policy for the 'output'
# chain. There are no restrictions on that.
$IPCHAINS -A input -l -j DENY
echo "Ipchains firewall is up `date`."
##-- eof ipchains.sh
</programlisting>
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3>
<title>iptables II</title>
<para>
<programlisting>
#!/bin/sh
#
# iptables.sh
#
# An example of a simple iptables configuration. This script
# can enable 'masquerading' and will open user definable ports.
#
###################################################################
# Begin variable declarations and user configuration options ######
#
# Set the location of iptables (default).
IPTABLES=/sbin/iptables
# Local Interfaces
# This is the WAN interface that is our link to the outside world.
# For pppd and pppoe users.
# WAN_IFACE="ppp0"
WAN_IFACE="eth0"
#
# Local Area Network (LAN) interface.
#LAN_IFACE="eth0"
LAN_IFACE="eth1"
# Our private LAN address(es), for masquerading.
LAN_NET="192.168.1.0/24"
# For static IP, set it here!
#WAN_IP="1.2.3.4"
# Set a list of public server port numbers here...not too many!
# These will be open to the world, so use caution. The example is
# sshd, and HTTP (www). Any services included here should be the
# latest version available from your vendor. Comment out to disable
# all Public services. Do not put any ports to be forwarded here,
# this only direct access.
#PUBLIC_PORTS="22 80 443"
PUBLIC_PORTS="22"
# If we want to do port forwarding, this is the host
# that will be forwarded to.
#FORWARD_HOST="192.168.1.3"
# A list of ports that are to be forwarded.
#FORWARD_PORTS="25 80"
# If you get your public IP address via DHCP, set this.
DHCP_SERVER=66.21.184.66
# If you need identd for a mail server, set this.
MAIL_SERVER=
# A list of unwelcome hosts or nets. These will be denied access
# to everything, even our 'Public' services. Provide your own list.
#BLACKLIST="11.22.33.44 55.66.77.88"
# A list of "trusted" hosts and/or nets. These will have access to
# ALL protocols, and ALL open ports. Be selective here.
#TRUSTED="1.2.3.4/8 5.6.7.8"
## end user configuration options #################################
###################################################################
# Any and all addresses from anywhere.
ANYWHERE="0/0"
# These modules may need to be loaded:
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
# Start building chains and rules #################################
#
# Let's start clean and flush all chains to an empty state.
$IPTABLES -F
$IPTABLES -X
# Set the default policies of the built-in chains. If no match for any
# of the rules below, these will be the defaults that IPTABLES uses.
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P INPUT DROP
# Accept localhost/loopback traffic.
$IPTABLES -A INPUT -i lo -j ACCEPT
# Get our dynamic IP now from the Inet interface. WAN_IP will be the
# address we are protecting from outside addresses.
[ -z "$WAN_IP" ] &&\
WAN_IP=`ifconfig $WAN_IFACE |grep inet |cut -d : -f 2 |cut -d \ -f 1`
# Bail out with error message if no IP available! Default policy is
# already set, so all is not lost here.
[ -z "$WAN_IP" ] && echo "$WAN_IFACE not configured, aborting." && exit 1
WAN_MASK=`ifconfig $WAN_IFACE |grep Mask |cut -d : -f 4`
WAN_NET="$WAN_IP/$WAN_MASK"
## Reserved IPs:
#
# We should never see these private addresses coming in from outside
# to our external interface.
$IPTABLES -A INPUT -i $WAN_IFACE -s 10.0.0.0/8 -j DROP
$IPTABLES -A INPUT -i $WAN_IFACE -s 172.16.0.0/12 -j DROP
$IPTABLES -A INPUT -i $WAN_IFACE -s 192.168.0.0/16 -j DROP
$IPTABLES -A INPUT -i $WAN_IFACE -s 127.0.0.0/8 -j DROP
$IPTABLES -A INPUT -i $WAN_IFACE -s 169.254.0.0/16 -j DROP
$IPTABLES -A INPUT -i $WAN_IFACE -s 224.0.0.0/4 -j DROP
$IPTABLES -A INPUT -i $WAN_IFACE -s 240.0.0.0/5 -j DROP
# Bogus routing
$IPTABLES -A INPUT -s 255.255.255.255 -d $ANYWHERE -j DROP
# Unclean
$IPTABLES -A INPUT -i $WAN_IFACE -m unclean -m limit \
--limit 15/minute -j LOG --log-prefix "Unclean: "
$IPTABLES -A INPUT -i $WAN_IFACE -m unclean -j DROP
## LAN access and masquerading
#
# Allow connections from our own LAN's private IP addresses via the LAN
# interface and set up forwarding for masqueraders if we have a LAN_NET
# defined above.
if [ -n "$LAN_NET" ]; then
echo 1 > /proc/sys/net/ipv4/ip_forward
$IPTABLES -A INPUT -i $LAN_IFACE -j ACCEPT
# $IPTABLES -A INPUT -i $LAN_IFACE -s $LAN_NET -d $LAN_NET -j ACCEPT
$IPTABLES -t nat -A POSTROUTING -s $LAN_NET -o $WAN_IFACE -j MASQUERADE
fi
## Blacklist
#
# Get the blacklisted hosts/nets out of the way, before we start opening
# up any services. These will have no access to us at all, and will
# be logged.
for i in $BLACKLIST; do
$IPTABLES -A INPUT -s $i -m limit --limit 5/minute \
-j LOG --log-prefix "Blacklisted: "
$IPTABLES -A INPUT -s $i -j DROP
done
## Trusted hosts/nets
#
# This is our trusted host list. These have access to everything.
for i in $TRUSTED; do
$IPTABLES -A INPUT -s $i -j ACCEPT
done
# Port Forwarding
#
# Which ports get forwarded to which host. This is one to one
# port mapping (ie 80 -> 80) in this case.
[ -n "$FORWARD_HOST" ] &&\
for i in $FORWARD_PORTS; do
$IPTABLES -A FORWARD -p tcp -s $ANYWHERE -d $FORWARD_HOST \
--dport $i -j ACCEPT
$IPTABLES -t nat -A PREROUTING -p tcp -d $WAN_IP --dport $i \
-j DNAT --to $FORWARD_HOST:$i
done
## Open, but Restricted Access ports
#
# Allow DHCP server (their port 67) to client (to our port 68) UDP
# traffic from outside source.
[ -n "$DHCP_SERVER" ] &&\
$IPTABLES -A INPUT -p udp -s $DHCP_SERVER --sport 67 \
-d $ANYWHERE --dport 68 -j ACCEPT
# Allow 'identd' (to our TCP port 113) from mail server only.
[ -n "$MAIL_SERVER" ] &&\
$IPTABLES -A INPUT -p tcp -s $MAIL_SERVER -d $WAN_IP --dport 113 -j ACCEPT
# Open up Public server ports here (available to the world):
for i in $PUBLIC_PORTS; do
$IPTABLES -A INPUT -p tcp -s $ANYWHERE -d $WAN_IP --dport $i -j ACCEPT
done
# So I can check my home POP3 mailbox from work. Also, so I can ssh
# in to home system. Only allow connections from my workplace's
# various IPs. Everything else is blocked.
$IPTABLES -A INPUT -p tcp -s 255.10.9.8/29 -d $WAN_IP --dport 110 -j ACCEPT
## ICMP (ping)
#
# ICMP rules, allow the bare essential types of ICMP only. Ping
# request is blocked, ie we won't respond to someone else's pings,
# but can still ping out.
$IPTABLES -A INPUT -p icmp --icmp-type echo-reply \
-s $ANYWHERE -d $WAN_IP -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type destination-unreachable \
-s $ANYWHERE -d $WAN_IP -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type time-exceeded \
-s $ANYWHERE -d $WAN_IP -j ACCEPT
# Identd Reject
#
# Special rule to reject (with rst) any identd/auth/port 113
# connections. This will speed up some services that ask for this,
# but don't require it. Be careful, some servers may require this
# one (IRC for instance).
#$IPTABLES -A INPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset
###################################################################
# Build a custom chain here, and set the default to DROP. All
# other traffic not allowed by the rules above, ultimately will
# wind up here, where it is blocked and logged, unless it passes
# our stateful rules for ESTABLISHED and RELATED connections. Let
# connection tracking do most of the worrying! We add the logging
# ability here with the '-j LOG' target. Outgoing traffic is
# allowed as that is the default policy for the 'output' chain.
# There are no restrictions placed on that in this script.
# New chain...
$IPTABLES -N DEFAULT
# Use the 'state' module to allow only certain connections based
# on their 'state'.
$IPTABLES -A DEFAULT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A DEFAULT -m state --state NEW -i ! $WAN_IFACE -j ACCEPT
# Enable logging for anything that gets this far.
$IPTABLES -A DEFAULT -j LOG -m limit --limit 30/minute --log-prefix "Dropping: "
# Now drop it, if it has gotten here.
$IPTABLES -A DEFAULT -j DROP
# This is the 'bottom line' so to speak. Everything winds up
# here, where we bounce it to our custom built 'DEFAULT' chain
# that we defined just above. This is for both the FORWARD and
# INPUT chains.
$IPTABLES -A FORWARD -j DEFAULT
$IPTABLES -A INPUT -j DEFAULT
echo "Iptables firewall is up `date`."
##-- eof iptables.sh
</programlisting>
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3>
<title>Summary</title>
<para>
A quick run down of the some highlights...
</para>
<!--
<para>
Again we started by setting some shell variables in the top section, but a
few more this time. Then we set the default rules (ipchains calls these
<quote>policies</quote>) of denying all inbound and forwarded traffic, and of
allowing all our own outbound traffic. Same as the former example.
</para>
<para>
But then we added some specific rules to block any <quote>private</quote>
IP addresses that from our external interface. We shouldn't see these on the
Internet. These are used for LANs, and private networks. We then enabled
<quote>masquerading</quote>. Then added a <quote>blacklist</quote> concept.
These would addresses that we want banned totally, no matter what. We also
added a <quote>trusted</quote> hosts rule, for our good friends who we are
allowing access to all services. Then made possible <quote>port
forwarding</quote>, if we wanted some services forwarded to an internal host,
rather than be running on our firewall itself. This is considered a safer way
in most cases. Note that <application>iptables</application> handles this
itself, but <application>ipchains</application> requires a separate helper
package, <application>ipmasqadm</application>.
</para>
<para>
We then opened a few exceptions to the inbound default policy. First by
allowing public access to our ssh server. This could have been a list of
ports, but we just used one in this example. Anybody on the Internet could
be able to access these - except the <quote>blacklisted</quote> hosts that
we have a special rule for.
</para>
-->
<para>
We added some host based access control rules: <quote>blacklisted</quote>,
and <quote>trusted</quote>. We then showed several types of service
and port based access rules. For instance, we allowed some very restrictive
access to bigcat's <application>POP3</application> server so we could connect
only from our workplace. We allowed a very narrow rule for the ISP's DHCP
server. This rule only allows one port on one outside IP address to connect
to only one of our ports and only via the UDP protocol. This is a very
specific rule! We are being specific since there is no reason to allow any
other traffic to these ports or from these addresses. Remember our goal is
the minimum amount of traffic necessary for our particular situation.
</para>
<para>
So we made those few exceptions mentioned above, and all other services
running on bigcat should be effectively blocked completely from outside
connections. These are still happily running on bigcat, but are now safe and
sound behind our packet filtering firewall. You probably have other services
that fall in this category as well.
</para>
<para>
We also have a small, home network in the above example. We did not take any
steps to block that traffic. So the LAN has access to all services running on
bigcat. And it is further <quote>masqueraded</quote>, so that it has Internet
access (different HOWTO), by manipulating the <quote>forward</quote> chain.
And the LAN is still protected by our firewall since it sits behind the
firewall. We also didn't impose any restrictive rules on the traffic leaving
bigcat. In some situations, this might be a good idea.
</para>
<para>
Of course, this is just a hypothetical example. Your individual situation is
surely different, and would require some changes and likely some additions to
the rules above. For instance, if your ISP does not use DHCP (most do not),
then that rule would make no sense. <application>PPP</application> works
differently and such rules are not needed.
</para>
<para>
Please don't interpret that running any server as we did in this example is
necessarily a <quote>safe</quote> thing to do. We shouldn't do it this way
unless a) we really need to and b) we are running the current, safe version,
and c) we are able to keep abreast of security related issues that might
effect these services. Vigilance and caution are part of our responsibilities
here too.
</para>
</sect3>
<!-- ~ End section ~ -->
<!-- ~~~~~ New section ~~~~~ -->
<sect3>
<title>iptables mini-me</title>
<para>
Just to demonstrate how succinctly <application>iptables</application> can be
configured in a minimalist situation, the below is from the Netfilter team's
<citetitle>Rusty's Really Quick Guide To Packet Filtering</citetitle>:
</para>
<blockquote>
<para>
<quote>Most people just have a single PPP connection to the Internet, and
don't want anyone coming back into their network, or the firewall:</quote>
</para>
</blockquote>
<para>
<programlisting>
## Insert connection-tracking modules (not needed if built into kernel).
insmod ip_conntrack
insmod ip_conntrack_ftp
## Create chain which blocks new connections, except if coming from inside.
iptables -N block
iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A block -m state --state NEW -i ! ppp0 -j ACCEPT
iptables -A block -j DROP
## Jump to that chain from INPUT and FORWARD chains.
iptables -A INPUT -j block
iptables -A FORWARD -j block
</programlisting>
</para>
<para>
This simple script will allow all outbound connections that we initiate, i.e.
any <application>NEW</application> connections (since the default policy of
ACCEPT is not changed). Then any connections that are
<quote>ESTABLISHED</quote> and <quote>RELATED</quote> to these are also
allowed. And, any connections that are not incoming from our WAN side
interface, <literal>ppp0</literal>, are also allowed. This would be lo or
possibly a LAN interface like eth1. So we can do whatever we want, but no
unwanted, incoming connection attempts are allowed from the Internet. None.
</para>
<para>
This script also demonstrates the creation of a custom chain, defined here
as <quote>block</quote>, which is used both for the INPUT and FORWARD
chains.
</para>
</sect3>
</sect2>
</sect1>
</article>
<!-- ~~~~~~~~~~~~~~~~~~~~ finis ~~~~~~~~~~~~~~~~~~~~~~~~~ -->