Services can be secured in a running system in two ways:
Restricting services so that they can only be accessed from a given place can be done by restricting access to them at the kernel (i.e. firewall) level, configure them to listen only on a given interface (some services might not provide this feature) or using some other methods, for example the linux vserver patch (for 2.4.16) can be used to force processes to use only one interface.
Regarding the services running from inetd
(telnet
,
ftp
, finger
, pop3
...) it is worth noting
that inetd
cannot be configured so that services only listen on a
given interface. However, its substitute, the xinetd
meta-daemon
includes a bind just for this matter. See
xinetd.conf(5)
.
service nntp { socket_type = stream protocol = tcp wait = no user = news group = news server = /usr/bin/env server_args = POSTING_OK=1 PATH=/usr/sbin/:/usr/bin:/sbin/:/bin +/usr/sbin/snntpd logger -p news.info bind = 127.0.0.1 }
The following sections detail how determined services can be configured properly depending on their intented use.
If you are still running telnet instead of ssh, you should take a break from this manual and change this. Ssh should be used for all remote logins instead of telnet. In an age where it is easy to sniff internet traffic and get cleartext passwords, you should use only protocols which use cryptography. So, perform an apt-get install ssh on your system now.
Encourage all the users on your system to use ssh instead of telnet, or even
better, uninstall telnet/telnetd. In addition you should avoid logging into
the system using ssh as root and use alternative methods to become root
instead, like su
or sudo
. Finally, the
sshd_config
file, in /etc/ssh
, should be modified to
increase security as well:
Have ssh listen only on a given interface, just in case you have more than one (and do not want ssh available on it) or in the future add a new network card (and don't want ssh connections from it).
Try not to permit Root Login wherever possible. If anyone wants to become root via ssh, now two logins are needed and the root password cannot be brute forced via SSH.
Change the listen port, so the intruder cannot be completely sure whether a sshd daemon runs (be forewarned, this is security by obscurity).
Empty passwords make a mockery of system security.
Allow only certain users to have access via ssh to this machine. user@host can also be used to restrict a given user from accessing only at a given host.
Allow only certain group members to have access via ssh to this machine. AllowGroups and AllowUsers have equivalent directives for denying access to a machine. Not surprisingly they are called "DenyUsers" and "DenyGroups".
It is completely your choice what you want to do. It is more secure only to allow access to machine from users with ssh-keys placed in the ~/.ssh/authorized_keys file. If you want so, set this one to "no".
sshd_config(5)
).
Disable the protocol version 1, since it has some design flaws that make it
easier to crack passwords. For more information read a paper
regarding ssh protocol problems
or the Xforce advisory
.
Add a banner (it will retrieved from the file) to users connecting to the ssh server, in some countries sending a warning before access to a given system warning about unauthorised access or user monitoring should be added to have legal protection.
You can also restrict access to the ssh server using pam_listfile
or pam_wheel in the PAM control file for ssh to restrict ssh
logins. For example, you could keep anyone not listed in
/etc/loginusers
by adding this line to
/etc/pam.d/ssh
:
auth required pam_listfile.so sense=allow onerr=fail item=user file=/etc/loginusers
As a final note, be aware that these directives are from a OpenSSH
configuration file. Right now, there are three commonly used SSH daemons,
ssh1, ssh2, and OpenSSH by the OpenBSD people. Ssh1 was the first ssh daemon
available and it is still the most commonly used (there are rumors that there
is even a Windows port). Ssh2 has many advantages over ssh1 except it is
released under an closed-source license. OpenSSH is completely free ssh
daemon, which supports both ssh1 and ssh2. OpenSSH is the version installed on
Debian when the package ssh
is chosen.
You can read more information on how to set up SSH with PAM support in the
security
mailing list archives
.
Currently OpenSSH does not provide a way to chroot automatically users upon
connection (the commercial version does provide this functionality). However
there is a project to provide this functionality for OpenSSH too, see http://chrootssh.sourceforge.net
,
it is not currently packaged for Debian, though. You could use, however, the
pam_chroot
module as described in Restricting users's access, Section
4.10.8.
In Chroot
environment for
SSH
, Appendix G you can several options to make chroot
environment for SSH.
If you are using an SSH client against the SSH server you must make sure that
it supports the same protocols that are enforced on the server. For example,
if you use the mindterm
package, it only supports protocol version
1. However, the sshd server is, by default, configured to only accept version
2 (for security reasons).
If you do not want users to transfer files to and from the ssh server
you need to restrict access to the sftp-server
and the
scp
access. You can restrict sftp-server
by
configuring the proper Subsystem in the
/etc/ssh/sshd_config
. However, to restrict scp
access, however, you must either:
Squid is one of the most popular proxy/cache server, and there are some
security issues that should be taken into account. Squid's default
configuration file denies all users requests. However the Debian package
allows access from 'localhost', you just need to configure your browser
properly. You should configure Squid to allow access to trusted users, hosts
or networks defining an Access Control List on /etc/squid.conf
,
see the Squid User's
Guide
for more information about defining ACLs rules.
Also, if not properly configured, someone may relay a mail message through Squid, since the HTTP and SMTP protocols are designed similarly. Squid's default configuration file denies access to port 25. If you wish to allow connections to port 25 just add it to Safe_ports lists. However, this is NOT recommended.
Setting and configuring the proxy/cache server properly is only part of keeping your site secure. Another necessary task is to analyse Squid's logs to assure that all things are working as they should be working. There are some packages in Debian GNU/Linux that can help an administrator to do this. The following packages are available in woody (Debian 3.0):
calamaris
- Log analyzer for Squid or Oops proxy log files.
modlogan
- A modular logfile analyzer.
squidtaild
- Squid log monitoring program.
When using Squid in Accelerator Mode it acts as a web server too. Turning on
this option code complexity increases, making it less reliable. By default
Squid is not configured to act as a web server, so you don't need to worry
about this. Note that if you want to use this feature be sure that it is
really necessary. Too find more information about Accelerator Mode on Squid
see the Squid User's
Guide #Chapter9
.
If you really have to use FTP (without wrapping it with sslwrap or inside a SSL
or SSH tunnel), you should chroot ftp into the ftp users' home directory, so
that the user is unable to see anything else than their own directory.
Otherwise they could traverse your root file system just like if they had a
shell in it. You can add the following line in your proftpd.conf
in your global section to enable this chroot feature:
DefaultRoot ~
Restart proftpd by /etc/init.d/proftpd restart and check whether you can escape from your homedir now.
To prevent Proftp DoS attacks using ../../.., add the following line in
/etc/proftpd.conf
: DenyFilter \*.*/
Always remember that FTP sends login and authentication passwords in clear text
(this is not an issue if you are providing an anonymous public service) and
there are better alternatives in Debian for this. For example,
sftp
(provided by ssh
). There are also free
implementations of SSH for other operating systems: putty
and
cygwin
for example.
However, if you still maintain the FTP server while making users access through
SSH you migh encounter a typical problem. Users accessing Anonymous FTP
servers inside SSH-secured systems might try to log in the FTP server.
While the access will be refused, the password will nevertheless be sent
through the net in clear form. To avoid that, ProFTPd developer TJ Saunders
has created a patch that prevents users feeding the anonymous FTP server with
valid SSH acounts. More information and patch available at: ProFTPD Patches
.
Today, X terminals are used by more and more companies where one server is needed for a lot of workstations. This can be dangerous, because you need to allow the file server to connect to the the clients (X server from the X point of view. X switches the definition of client and server). If you follow the (very bad) suggestion of many docs, you type xhost + on your machine. This allows any X client to connect to your system. For slightly better security, you can use the command xhost +hostname instead to only allow access from specific hosts.
A much more secure solution, though, is to use ssh to tunnel X and encrypt the
whole session. This is done automatically when you ssh to another machine.
This has to be enabled in /etc/ssh/ssh_config
by setting
X11Forwarding to yes. In times of SSH, you should
drop the xhost based access control completely.
For best security, if you do not need X access from other machines, is to switch off the binding on tcp port 6000 simply by typing:
$ startx -- -nolisten tcp
This is the default behavior in Xfree 4.1.0 (the Xserver provided in Debian
3.0). If you are running Xfree 3.3.6 (i.e. you have Debian 2.2 installed) you
can edit /etc/X11/xinit/xserverrcc
to have it something along the
lines of:
#!/bin/sh exec /usr/bin/X11/X -dpi 100 -nolisten tcp
If you are using XDM set /etc/X11/xdm/Xservers
to: :0 local
/usr/bin/X11/X vt7 -dpi 100 -nolisten tcp. If you are using Gdm make
sure that the -nolisten tcp option is set in the
/etc/gdm/gdm.conf
(which is the default in Debian) such as this:
[server-Standard] name=Standard Server command=/usr/bin/X11/X -nolisten tcp
You can also set the default's system timeout for xscreensaver
locks. Even if the user can override it, you should edit the
/etc/X11/app-defaults/XScreenSaver
configuration file and change
the lock line:
*lock: False
(which is the default in Debian) to:
*lock: True
FIXME: add information on how to disable the screensavers which show the user desktop (which might have sensitive information).
Read more on X Window security in XWindow-User-HOWTO
(/usr/share/doc/HOWTO/en-txt/XWindow-User-HOWTO.txt.gz
).
FIXME: Add info on thread of debian-security on how to change config files of XFree 3.3.6 to do this.
If you only want to have a display manager installed for local usage (having a nice graphical login, that is), make sure the XDMCP (X Display Manager Control Protocol) stuff is disabled. In XDM you can do this with this line in /etc/X11/xdm/xdm-config:
DisplayManager.requestPort: 0
Normally, all display managers are configured not to start XDMCP services per default in Debian.
Imagine, you arrive at work, and the printer is spitting out endless amounts of paper because someone is DoSing your line printer daemon. Nasty, isn't it?
In any unix printing architecture, there has to be a way to get the client's
data to the host's print server. In traditional lpr
and
lp
, the client command copies or symlinks the data into the spool
directory (which is why these programs is usually SUID or SGID).
In order to avoid any issues you should keep your printer servers specially
secure. This means you need to configure your printer service so it will only
allow connections from a set of trusted servers. In order to do this, add the
servers you want to allow printing to your /etc/hosts.lpd
.
However, even if you do this, the lpr
daemon accepts incoming
connections on port 515 of any interface. You should consider firewalling
connections from networks/hosts which are not allowed printing (the
lpr
daemon cannot be limited to listen only on a given IP
address).
Lprng
should be preferred over lpr
since it can be
configured to do IP access control. And you can specify which interface to
bind to (although somewhat weirdly).
If you are using a printer in your system, but only locally, you will not want
to share this service over a network. You can consider using other printing
systems, like the one provided by cups
or PDQ
which is based on user
permissions of the /dev/lp0
device.
In cups
, the print data is transferred to the server via the http
protocol. This means the client program doesn't need any special privileges,
but does require that the server be listening on a port somewhere.
However, if you want to use cups
, but only locally, you can
configure it to bind to the loopback interface by changing
/etc/cups/cupsd.conf
:
Listen 127.0.0.1:631
There are many other security options like allowing or denying networks and
hosts in this config file. However, if you do not need them you might be
better off just limiting the listening port. Cups
also serves
documentation through the HTTP port, if you do not want to disclose potential
useful information to outside attackers (and the port is open) add also:
<Location /> Order Deny,Allow Deny From All Allow From 127.0.0.1 </Locationi>
This configuration file can be modified to add some more features including
SSL/TLS certificates and crypto. The manuals are available at
http://localhost:631/ or at cups.org
.
FIXME: Add more content (the article on Amateur Fortress Building
provides
some very interesting views).
FIXME: Check if PDG is available in Debian, and if so, suggest this as the preferred printing system.
FIXME: Check if Farmer/Wietse has a replacement for printer daemon and if it's available in Debian.
If your server is not a mailing system, you do not really need to have a mail daemon listening for incoming connections, but you might want local mail delivered in order, for example, to receive mail for the root user from any alert systems you have in place.
If you have exim
you do not need the daemon to be working in order
to do this since the standard cron
job flushes the mail queue.
See Disabling daemon services, Section
3.6.1 on how to do this.
However you might want to have a local mailer daemon so that it can relay the mails sent locally to a realy system. This is common when you have to administer a number of systems and do not want to connect to each of them to read the local mail sent, it is usual to relay the local mail to a remote system that consolidates all of it (similarly to what should be done to logging for those systems).
Such a relay-only system should be configured properly for this. The daemon could, as well, be configured to only listen on the loopback address.
To do this in a Debian system, you will have to remove the smtp daemon from
inetd
:
$ update-inetd --disable smtp
and configure the mailer daemon to only listen on the loopback interface. In
exim
(the default MTA) you can do this by editing the file
/etc/exim.conf
and adding the following line:
local_interfaces = "127.0.0.1"
Restart both daemons (inetd and exim) and you will have exim listening on the 127.0.0.1:25 socket only. Be careful, and first disable inetd, otherwise, exim will not start since the inetd daemon is already handling incoming connections.
For postfix
edit /etc/postfix/main.conf
:
inet_interfaces = localhost
If you only want local mail, this approach is better than tcp-wrapping the
mailer daemon or adding firewalling rules to limit anybody accessing it.
However, if you do need it to listen on other interfaces, you might consider
launching it from inetd and adding a tcp wrapper so incoming connections are
checked against /etc/hosts.allow
and /etc/hosts.deny
.
Also, you will be aware of when an unauthorized access is attempted against
your mailer daemon, if you set up proper logging for any of the methods above.
In any case, to reject mail relay attempts at the SMTP level, you can change
/etc/exim/exim.conf
to include:
receiver_verify = true
Even if you mail server will not relay the message, this kind of configuration
is needed for the relay tester at http://www.abuse.net/relay.html
to determine that your server is not relay capable.
If you want a relay-only setup, however, you can consider changing the mailer
daemon to programs that can only be configured to forward the mail to
a remote mail server. Debian provides currently both ssmtp
and
nullmailer
for this purpose. In any case, you can evaluate for
yourself any of the mail transport agents [13] provided by Debian and see which one suits best to the
system's purposes.
If you want to give remote access to mailboxes there are a number of POP3 and IMAP daemons available [14] . However, if you provide IMAP access note that it is a general file access protocol, it can become the equivalent of a shell access because users might be able to retrieve any file that they can through it.
Try, for example, to configure as your inbox path {server.com}/etc/passwd if it succeeds your IMAP daemon is not properly configured to prevent this kind of access.
Of the IMAP servers in Debian the cyrus
server (in the
cyrus-imapd
package) gets around this by having all access be to a
database in a restricted part of the file system. Also, uw-imapd
(either installing the uw-imapd
or, better if your IMAP clients
support it, uw-imapd-ssl
) can be configured to chroot the users
mail directory but this is not enabled by default. The documentation provided
gives more information on how to configure it.
Also, you might want to run an IMAP server that does not need valid users to be
created on the local system (which would might grant shell access too), both
courier-imap
(for IMAP) and courier-pop
teapop
(for POP3) and cyrus-imapd
(for both POP3 and
IMAP) provide servers with authentication methods beside the local user
accounts. cyrus
can use any authentication method that can be
configured through PAM whileas teapop
might use databases (such as
postgresql
and mysql
) for user authentication.
FIXME: Check: uw-imapd
might be configured with user
authentication through PAM too..
Reading/receiving mail is the most common cleartext protocol. If you use
either POP3 or IMAP to get your mail, you send your cleartext password across
the net, so almost anyone can read your mail from now on. Instead, use SSL
(Secure Sockets Layer) to receive your mail. The other alternative is ssh, if
you have a shell account on the box which acts as your POP or IMAP server.
Here is a basic fetchmailrc
to demonstrate this:
poll my-imap-mailserver.org via "localhost" with proto IMAP port 1236 user "ref" there with password "hackme" is alex here warnings 3600 folders .Mail/debian preconnect 'ssh -f -P -C -L 1236:my-imap-mailserver.org:143 -l ref my-imap-mailserver.org sleep 15 </dev/null > /dev/null'
The preconnect is the important line. It fires up a ssh session and creates the necessary tunnel, which automatically forwards connections to localhost port 1236 to the IMAP mail server, but encrypted. Another possibility would be to use fetchmail with the ssl feature.
If you want to provide encrypted mail services like POP and IMAP, apt-get install stunnel and start your daemons this way:
stunnel -p /etc/ssl/certs/stunnel.pem -d pop3s -l /usr/sbin/popd
This command wraps the provided daemon (-l) to the port (-d) and uses the specified ssl cert (-p).
There are different issues that can be tackled in order to secure the Domain server daemon, which are similar to the ones considered when securing any given service:
You should restrict some of the information that is served from the DNS server
to outside clients so that it cannot be used to retrieve valuable information
from your organization that you do not want to give away. This includes adding
the following options: allow-transfer, allow-query,
allow-recursive and version. You can either limit this on
the global section (so it applies to all the zones served) or on a per-zone
basis. This information is documented on the bind-doc
package,
read more on this on /usr/share/doc/bind/html/index.html
once the
package is installed.
Imagine that your server is connected to the Internet and to your internal
(your internal IP is 192.168.1.2) network (a basic multi-homed server), you do
not want to give any service to the Internet and you just want to enable DNS
lookups from your internal hosts. You could restrict it by including in
/etc/bind/named.conf
:
options { allow-query { 192.168.1/24; } ; allow-transfer { none; } ; allow-recursive { 192.168.1/24; } ; listen-on { 192.168.1.2; } ; forward { only; } ; forwarders { A.B.C.D; } ; };
The listen-on option makes the DNS bind to only the interface that has the internal address, but, even if this interface is the same as the interface that connects to the Internet (if you are using NAT, for example), queries will only be accepted if coming from your internal hosts. If the system has multiple interfaces and the listen-on is not present, only internal users could query, but, since the port would be accessible to outside attackers, they could try to crash (or exploit buffer overflow attacks) on the DNS server. You could even make it listen only on 127.0.0.1 if you are not giving DNS service for any other systems than yourself.
The version.bind record in the chaos class contains the version of the of the currently running bind process. This information is often used by automated scanners and malicious individuals who wish to determine if one's bind is vulnerable to a specific attack. By providing false or no information in the version.bind record, one limits the probability that one's server will be attacked based on its publicized version. To provide your own version, use the version directive in the following manner:
options { ... various options here ... version "Not available."; };
Changing the version.bind record does not provide actual protection against attacks, but it might be considered a useful safeguard.
A sample named.conf
configuration file might be the following:
acl internal { 127.0.0.1/32; // localhost 10.0.0.0/8; // internal aa.bb.cc.dd; // eth0 IP }; acl friendly { ee.ff.gg.hh; // slave DNS aa.bb.cc.dd; // eth0 IP 127.0.0.1/32; // localhost 10.0.0.0/8; // internal }; options { directory "/var/cache/bind"; allow-query { internal; }; allow-recursive { internal; }; allow-transfer { none; }; }; // From here to the mysite.bogus zone // is basically unmodified from the debian default logging { category lame-servers { null; }; category cname { null; }; }; zone "." { type hint; file "/etc/bind/db.root"; }; zone "localhost" { type master; file "/etc/bind/db.local"; }; zone "127.in-addr.arpa" { type master; file "/etc/bind/db.127"; }; zone "0.in-addr.arpa" { type master; file "/etc/bind/db.0"; }; zone "255.in-addr.arpa" { type master; file "/etc/bind/db.255"; }; // zones I added myself zone "mysite.bogus" { type master; file "/etc/bind/named.mysite"; allow-query { any; }; allow-transfer { friendly; }; };
Please (again) check the Bug Tracking System regarding Bind, specifically
Bug #94760 (regarding ACLs on zone
transfers)
. Feel free to contribute to the bug report if you think
you can add useful information.
Regarding limiting BIND's privileges you must be aware that if a non-root user
runs BIND, then BIND cannot detect new interfaces automatically. For example,
if you stick a PCMCIA card into your laptop. Check the README.Debian file in
your named documentation (/usr/share/doc/bind/README.Debian
)
directory for more information about this issue. There have been many recent
security problems concerning BIND, so switching the user is useful when
possible. We will detail here the steps needed in order to do this, however,
if you want to do this in an automatic way you might try the script provided in
Sample script to change the default Bind
installation., Appendix E.
To run BIND under a different user, first create a separate user and group for it (it is not a good idea to use nobody or nogroup for every service not running as root). In this example, the user and group named will be used. You can do this by entering:
addgroup named adduser --system --home /home/named --no-create-home --ingroup named \ --disabled-password --disabled-login named
Notice that the user named will be quite restricted. If you want, for whatever reason, to have a less restrictive setup use:
adduser --system --ingroup named named
Now edit /etc/init.d/bind with your favorite editor and change the line beginning with
start-stop-daemon --start
to
start-stop-daemon --start --quiet --exec /usr/sbin/named -- -g named -u named
Also, in order to avoid running anything as root, change the reload line commenting out:
reload) /usr/sbin/ndc reload
And change it to:
reload) $0 stop sleep 1 $0 start
Note: Depending on your Debian version you might have to change the restart line too. This was fixed in Debian's bind version 1:8.3.1-2.
All you need to do now is to restart bind via '/etc/init.d/bind restart', and then check your syslog for two entries like this:
Sep 4 15:11:08 nexus named[13439]: group = named Sep 4 15:11:08 nexus named[13439]: user = named
Voilá! Your named now does not run as root. If you want to read more
information on why BIND does not run as non-root user on Debian systems, please
check the Bug Tracking System regarding Bind, specifically Bug #50013: bind should not run as
root
and Bug #132582:
Default install is potentially insecure
, Bug #53550
, Bug #128120
, and Bug #128120
. Feel free to
contribute to the bug reports if you think you can add useful information.
To achieve maximum BIND security, now build a chroot jail (see Using chroot
, Section 4.13) around
your daemon. There is an easy way to do this: the -t option (see
the named(8)
manpage). This will make Bind chroot itself into the
given directory without you needing to set up a chroot jail and worry about
dynamic libraries. The only files there needs to be in these chroot jail:
dev/null etc/bind/ - should hold named.conf and all the server zones sbin/named-xfer - if you do name transfers var/run/named/ - should hold the pid and the name server cache (if any) this directory needs to be writable by named user var/log/named - if you set up logging to a file, needs to be writable for the named user dev/log - syslogd should be listening here if named is configure to log through it
In order for your Bind daemon to work properly it needs permission in the named files. This is an easy task since the configuration files are always at /etc/named/. Take in account that it only needs read-only access to the zone files, unless it is a secondary or cache name server. If this is your case you will have to give read-write permissions to the necessary zones (so that zone transfers from the primary server work).
Also, you can find more information regarding Bind chrooting in the Chroot-BIND-HOWTO
(regarding Bind 9) and Chroot-BIND8-HOWTO
(regarding Bind 8). This same documents should be available through the
installation of the doc-linux-text
(text version) or
doc-linux-html
(html version). Another useful document is
http://www.psionic.com/papers/dns/dns-linux
.
If you are setting up a full chroot jail (i.e. not just -t) for Bind 8.2.3 in Debian (potato), make sure you have the following files in it:
dev/log - syslogd should be listening here dev/null etc/bind/named.conf etc/localtime etc/group - with only a single line: "named:x:GID:" etc/ld.so.cache - generated with ldconfig lib/ld-2.1.3.so lib/libc-2.1.3.so lib/ld-linux.so.2 - symlinked to ld-2.1.3.so lib/libc.so.6 - symlinked to libc-2.1.3.so sbin/ldconfig - may be deleted after setting up the chroot sbin/named-xfer - if you do name transfers var/run/
And modify also syslogd
listen on $CHROOT/dev/log so the named
server can write syslog entries into the local system log.
If you want to avoid problems with dynamic libraries, you can compile bind
statically. You can use apt-get
for this, with the
source option. It can even download the packages you need to
properly compile it. You would need to do someting similar to:
$ apt-get --download-only source bind build-dep bind $ cd bind-8.2.5-2 (edit the Makefile.in so CFLAGS includes the '-static' option before the @CFLAGS@ definition substituted by autoconf) $ dpkg-buildpackage -rfakeroot $ cd .. $ dpkg -i bind-8.2.5-2*deb
After installation, you will need to move around the files to the chroot jail
[15] you can keep the
init.d scripts in /etc/init.d
so that the system will
automatically start the name server, but edit them to add --chroot
/location_of_chroot in the calls to start-stop-daemon
in
those scripts.
For more information on how to set up chroots seee General chroot and suid paranoia, Section 5.10.
FIXME, merge info from http://people.debian.org/~pzn/howto/chroot-bind.sh.txt
,
http://people.pdxlinux.org/~karlheg/
(Bind9 on Debian), http://www.cryptio.net/~ferlatte/config/
(Debian-specific), http://www.psionic.com/papers/whitep01.html
,
http://csrc.nist.gov/fasp/FASPDocs/NISTSecuringDNS.htm
and http://www.acmebw.com/papers/securing.pdf
.
FIXME: Add content: modules provided with the normal Apache installation (under /usr/lib/apache/X.X/mod_*) and modules that can be installed separately in libapache-mod-XXX packages.
You can limit access to the Apache server if you only want to use it internally
(for testing purposes, to access the doc-central
archive, etc..)
and do not want outsiders to access it. To do this use the Listen
or BindAddress directives in /etc/apache/http.conf
.
Using Listen:
Listen 127.0.0.1:80
Using BindAddress:
BindAddress 127.0.0.1
Then restart apache with /etc/init.d/apache restart and you will see that it is only listening on the loopback interface.
In any case, if you are not using all the functionality provided by Apache, you
might want to take a look at other web servers provided in Debian like
dhttpd
.
The Apache
Documentation
provides information regarding security measures to be
taken on Apache webserver (this same information is provided in Debian by the
apache-doc
package).
FIXME: Add pointer to Intersect's Alliance.
The default Apache installation in Debian permits users to publish contents
under the $HOME/publish_html
. These contents can be retrieved
remotely using an URL such as: http://your_apache_server/~user.
If you do not want to permit this you must change the
/etc/apache/http.conf
configuration file which includes:
<Directory /home/*/public_html> AllowOverride FileInfo AuthConfig Limit Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec <Limit GET POST OPTIONS PROPFIND> Order allow,deny Allow from all </Limit> <Limit PUT DELETE PATCH PROPPATCH MKCOL COPY MOVE LOCK UNLOCK> Order deny,allow Deny from all </Limit> </Directory>
Change it to:
<Directory /home/*/public_html> AllowOverride None Order deny,allow Deny from all </Directory>
Note: An attacker might still do user enumeration, since the answer of the web server will be a 403 Permission Denied and not a 404 Not available.
Apache logfiles, since 1.3.22-1, are owned by user 'root' and group 'adm' with permissions 640 this permissions are changed after rotation. An intruder that accesed the system through the web server would not be able (without priviledge escalation) to remove old log file entries.
Apache files are located under /var/www
. Just after installation
the default file provides some information on the system (mainly that it's a
Debian system running Apache). The default webpages are owned by user root and
group root by default, whileas the Apache process runs as user www-data and
group www-data. This should make attackers that compromise the system through
the web server harder to deface the site. You should, of course, substitute
the default web pages (which might provide information you do not want to show
to outsiders) with your own.
If you want to run the finger service first ask yourself if you need to do so.
If you do, you will find out that Debian provides many finger daemons (output
from apt-cache search fingerd
):
ffingerd
is the recommended finger daemon if you are going to use
it for a public service. In any case, you are encouraged to, when setting it
up through inetd, xinetd or tcpserver to: limit the number of processes that
will be running at the same time, limit access to the finger daemon from a
given number of hosts (using tcp wrappers) and having it only listening to the
interface you need it to be in.
It is probably fair to say that the complexity of BIND is the reason why it has been exposed to a lot of attacks in recent years. (see Securing BIND, Section 5.7)
Other programs with complex features and a large installed user base include Sendmail and some ftp daemons (e.g. WUftpd). (Of course, a program with no features and no satisfied users can be just as insecure, besides being useless.)
Anyway, if you run any of these, consider similar arrangements for them — revoking root privileges, running in a chroot jail — or replacing them with a more secure equivalent.
There are several programs to chroot automatically servers and services.
Debian currently (accepted in may 2002) provides Wietse Venema's
chrootuid
in the chrootuid
package. This program can
be used to set up a restricted environment for executing a command (including
running it as a restricted user). However, you must set up the chroot
environment yourself.
In the near future Debian will provide tools to set up the chroot environment
easily. The makejail
program for example, can create and update a
chroot jail with short configuration files (it provides sample configuration
files for bind
, apache
, postgresql
and
mysql
). It attempts to guess and install into the jail all files
required by the daemon using strace
, stat
and
Debian's package dependancies. More information at http://www.floc.net/makejail/
.
Jailer
is a similar tool which can be retrieved from http://www.balabit.hu/downloads/jailer/
.
FIXME: I have packages ready for makejail and jailer, update this when they get accepted.
Also useful to create chroots (or jails) is deb.pl
, a script that
analyses dependencies of a set of files.
You should try to avoid any network service which sends and receives passwords in cleartext over a net like FTP/Telnet/NIS/RPC. The author recommends the use of ssh instead of telnet and ftp to everybody.
Keep in mind that migrating from telnet to ssh, but using other cleartext protocols does not increase your security in ANY way! Best would be to remove ftp, telnet, pop, imap, http and to supersede them with their respective encrypted services. You should consider moving from these services to their SSL versions, ftp-ssl, telnet-ssl, pop-ssl, https ...
Most of these above listed hints apply to every Unix system (you will find them if reading any other hardening-related document related to Linux and other Unices).
You should not use NIS, the Network Information Service, if it is possible, because it allows password sharing. This can be highly insecure if your setup is broken.
If you need password sharing between machines, you might want to consider using
other alternatives. For example, you can set a LDAP server and configure PAM
on your system in order to contact the LDAP server for user authentication.
You can find a detailed setup in the LDAP-HOWTO
(/usr/share/doc/HOWTO/en-txt/LDAP-HOWTO.txt.gz
).
Read more on NIS security in NIS-HOWTO
(/usr/share/doc/HOWTO/en-txt/NIS-HOWTO.txt.gz
).
FIXME (jfs): Add info on how to set up this in Debian
You should disable RPC wherever possible, that is, when you do not need it.
[16] Many security holes for
both the portmapper service and RPC-based services are known and could be
easily exploited. On the other hand NFS services are quite important in some
networks, so find a balance of security and usability in your network. Some of
the DDoS (distributed denial of service) attacks use rpc exploits to get into
the system and act as a so called agent/handler. Read more on NFS security in
NFS-HOWTO
(/usr/share/doc/HOWTO/en-txt/NFS-HOWTO.txt.gz
).
Disabling portmap is quite simple. There are different methods. The simplest
one in a Debian 3.0 system is to do uninstall the portmap
package.
If you are running another version you will have to disable the service as seen
in Disabling daemon services, Section
3.6.1, this is due to the program being a part of the net-base
package (which cannot be de-installed without breaking the system).
This in fact removes every symlink relating to portmap in
/etc/rc${runlevel}.d/, which is something you could also do
manually. Another possibility is to chmod 644
/etc/init.d/portmap, but that gives an error message when booting. You
can also strip off the start-stop-daemon part in
/etc/init.d/portmap
shell script.
The Debian GNU/Linux operating system has the built-in capabilities provided by
the Linux kernel. This means that if you install a potato (Debian 2.2 release)
system (default kernel is 2.2) you will have ipchains
firewalling
available in the kernel, you need to install the ipchains
which
will be surely (due to its priority) be already installed. If you install a
woody (Debian 3.0 release) system (default kernel is 2.4) you will have
iptables
(neftfilter) firewalling available. The main different
between ipchains
and iptables
is that the later is
based on stateful packet inspection which provides for more secure
(and easier to build) filtering configurations.
You can use firewall rules as a way to secure the access to your local system and, even, to limit the outbound communications made by it. Firewall rules can be used also to protect processes that cannot be properly configured not to provide services to some networks, IP addresses, etc..
However, this step is presented last in this manual basically because it is much better to not depend solely on firewalling capabilities in order to protect a given system. Security in a system is made up of layers, firewalling should be the last to include, once all services have been hardened. You can easily imagine a setup in which the system is solely protected by a built-in firewall and an administrator blissfully removes the firewall rules for whatever reason (problems with the setup, annoyance, human error...), this system would be wide open to an attack if there were no other hardening in the system to protect from it.
On the other hand, having firewall rules on the local system also prevents some bad things from happening. Even if the services provided are configured securely, a firewall can protect from misconfigurations or from fresh installed services that have not yet been properly configured. Also, a tight configuration will prevent trojans calling home from working unless the firewalling code is removed. Note that an intruder does not need superuser access to install a trojan locally that could be remotely controlled (since binding on ports is allowed if they are not priviledge ports and capabilities have not been removed).
Thus, a proper firewall setup would be one with a default deny policy, that is:
A Debian firewall can also be installed in order to protect, with filtering rules, access to systems behind it, limiting their exposure to the Internet. The firewall can be configured to prevent systems outside the local network to access services (ports) that are not public. For example, on a mail server, only port 25 (where the mail service is being given) needs to be accesible from the outside. A firewall can be configured to, even if there are other services besides the public ones, throw away packets (this is known as filtering) directed towards them.
You can even set up a Debian GNU/Linux box as a bridge firewall, i.e. a filtering firewall completely transparent to the network that lacks an IP address and thus cannot be attacked directly. Depending on the kernel you have installed, you might need to might to install the bridge firewall patch and then go to 802.1d Ethernet Bridging when configuring the kernel and a new option netfilter ( firewalling ) suport. See the Setting up a bridge firewall, Appendix D for more information on how to set this up in a Debian GNU/Linux system).
Of course, the configuration of the firewall is always system and network
dependant. An administrator must know beforehand what is the network layout
and the systems he wants to protect, the services that need to be accessed, and
wether or not other network considerations (like NAT or routing) need to be
taken into account. Be careful when configuring your firewall, as Laurence J.
Lane says in the iptables
package:
The tools can easily be misused, causing enormous amounts of grief by completely cripple network access to a computer system. It is not terribly uncommon for a remote system administrator to accidentally lock himself out of a system hundreds or thousands of miles away. One can even manage to lock himself out of a computer who's keyboard is under his fingers. Please, use due caution.
Remember this: just installing the iptables
(or the older
firewalling code) does not give you any protection, just provides the software.
In order to have a firewall you need to configure it!
If you do not know much about firewalling, read the Firewalling-HOWTO that can
be found in doc-linux-text
package (other document formats also
available). See Be aware of general
security problems, Section 2.2 for more (general) pointers.
If you are using Debian 3.0, you will notice that you have the
iptables
package installed. This is the support for the 2.4.4+
kernels netfilter implementation. Since just after installation the system
cannot know any firewall rules (firewall rules are too
system-specific) you have to enable iptables. However, the scripts have been
configured so that the administrator can set up firewall rules and then have
the init scripts learn them and use them always as the setup for the
firewall.
In order to do so you must:
/etc/default/iptables
so that the variable
enable_iptables_initd was set to true.
iptables(8)
) or some of the tools provided by the Debian firewall
packages (see Using Firewall
packages, Section 5.14.3.2). You need to create one set of firewall rules
to be used when the firewall is in active state and another to be used
when the firewall is in inactive state (these can be just empty
rules).
Once this is done your firewall setup is saved in the
/var/lib/iptables/
directory and will be executed when the system
boots (or when running the initd script with start and stop
arguments). Please notice that the default Debian setups starts the
firewalling code in the multiuser runlevels (2 to 5) pretty soon (10). Also,
it is stopped in singleuser runlevel (1), change this if it does not mach your
local policy.
If you do not have a clue on how to set up your firewall rules manually consult
the Packet Filtering HOWTO and NAT HOWTO provided by
iptables
for offline reading at
/usr/share/doc/iptables/html/
. Also, the configuration file
/etc/default/iptables
provides some more information about the
issues regarding this package.
Setting up manually a firewall can be complicated for novice (and sometimes even expert) administrators. However, the free software community has created a number of tools that can be used to easily configure a local firewall. Be forewarned that some of this tools are oriented more towards local-only protection (also known as personal firewall) and some are more versatile and can be used to configure complex rules to protect whole networks.
Some software that can be used to set up firewall rules in a Debian system is:
firestarter
, oriented towards end-users including a wizard to
quickly defined the firewall rules.
knetfilter
fwbuilder
, an object oriented GUI which includes policy compilers
for various firewall platforms including iptables as well as router's
access-lists.
shorewall
which provides support for IPsec as well as limited
support for traffic shaping as well as the definition of the firewall rules.
mason
, which can propose firewall rules based on the network
traffic your system "sees".
bastille
(among the hardening steps that can make new versions of
bastille is the possibility of adding firewall rules to the system to be
executed on startup)
ferm
fwctl
easyfw
firewall-easy
ipac-ng
gfcc
lokkit
or gnome-lokkit
The last packages: gfcc,firestarter and knetfilter are administration GUIs using either GNOME (first two) or KDE (last one) which are much more user-oriented (i.e. for home users) than the other packages in the list which might be more administrator-oriented.
Be forewarned that some of the packages outlined previousline will probably introduce firewalling scripts to be run when the system boots, this will undoubtedly conflict with the common setup (if configured) and you might undesireds effects. Usually, the firewalling script that runs last will be the one that configures the system (which might not be what you pretend). Consult the package documentation and use either one of these setups. Generally, other programs that help you set up the firewalling rules can tweak othe conriguration files.
FIXME: Add more info regarding this packages
FIXME: Check Information on Debian firewalling and what/how does it change from other distributions.
FIXME: Where should the custom firewalling code be enabled (common FAQ in debian-firewall?)
FIXME: Add information on Zorp
in Debian
(see Bug #88347
.
Debian packages are provided but they depend on libglib1.3 which is not yet
available in Debian distribution.
Securing Debian Manual
2.6 10 October 2002Wed, 18 Sep 2002 14:09:35 +0200jfs@computer.org