4.1 Subscribe to the Debian Security Announce mailing list

In order to receive information on available security updates you should
subscribe yourself to the debian-security-announce mailing list in order to
receive the Debian Security Advisories (DSAs). See The Debian Security Team, Section 7.1
for more information on how the Debian security team works. For information on
how to subscribe to the Debian mailing lists read http://lists.debian.org.

You should consider, also, subscribing to the debian-security mailing
list for general discussion on security issues in the Debian
operating system. You will be able to contact other fellow system
administrators in the list as well as Debian developers and upstream developers
of security tools who can answer your questions and offer advice.

FIXME: Add the key here too?

4.2 Execute a security update

As soon as new security bugs are detected in packages, Debian maintainers and
upstream authors generally patch them within days or even hours. After the bug
is fixed, a new package is provided on http://security.debian.org.

If you are installing a Debian release you must take into account that since
the release was made there might have been security updates after it has been
determined that a given package is vulnerable. Also, there might have been
minor releases (there have been four for the Debian 3.0 sarge release)
which include these package updates.

During installation security updates are configured for your system and pending
updates downloaded and applied, unless you specifically opt out of this or the
system was not connected to the Internet. The updates are applied even before
the first boot, so the new system starts its life as up to date as possible.

To manually update the system, put the following line in your
sources.list and you will get security updates automatically,
whenever you update your system. Replace [CODENAME] with the release
codename, e.g. squeeze.

Once you've done this you can use multiple tools to upgrade your system. If
you are running a desktop system you will have[9] an application called update-notifier that will
make it easy to check if new updates are available, by selecting it you can
make a system upgrade from the desktop (using update-manager).
For more information see Checking for
updates at the Desktop, Section 10.1.2.2. In desktop environments you can
also use synaptic (GNOME), kpackage or
adept (KDE) for more advanced interfaces. If you are running a
text-only terminal you can use aptitude, apt or
dselect (deprecated) to upgrade:

If you want to use aptitude's text interface you just have to
press u (update) followed by g (to upgrade). Or just do the
following from the command line (as root):

# aptitude update
# aptitude upgrade

If you want to use apt do just like with aptitude but substitute
the aptitude lines above with apt-get.

If you want to use dselect then first [U]pdate, then [I]nstall and
finally, [C]onfigure the installed/upgraded packages.

If you like, you can add the deb-src lines to
/etc/apt/sources.list as well. See apt(8) for
further details.

4.2.1 Security update of libraries

Once you have executed a security update you might need to restart some of the
system services. If you do not do this, some services might still be
vulnerable after a security upgrade. The reason for this is that daemons that
are running before an upgrade might still be using the old libraries before the
upgrade [10].

From Debian Jessie and up, you can install the
needrestart package, which will run automatically after each APT
upgrade and prompt you to restart services that are affected by the
just-installed updates. In earlier releases, you can run the
checkrestart program (available in the debian-goodies
package) manually after your APT upgrade.

Some packages (like libc6) will do this check in the postinst
phase for a limited set of services specially since an upgrade of essential
libraries might break some applications (until restarted)[11].

Bringing the system to run level 1 (single user) and then back to run level 3
(multi user) should take care of the restart of most (if not all) system
services. But this is not an option if you are executing the security upgrade
from a remote connection (like ssh) since it will be severed.

Excercise caution when dealing with security upgrades if you are doing them
over a remote connection like ssh. A suggested procedure for a security
upgrade that involves a service restart is to restart the SSH daemon and then,
immediately, attempt a new ssh connection without breaking the previous one.
If the connection fails, revert the upgrade and investigate the issue.

4.2.2 Security update of the kernel

First, make sure your kernel is being managed through the packaging system. If
you have installed using the installation system from Debian 3.0 or previous
releases, your kernel is not integrated into the packaging system and
might be out of date. You can easily confirm this by running:

If your kernel is not being managed you will see a message saying that the
package manager did not find the file associated to any package instead of the
message above, which says that the file associated to the current running
kernel is being provided by the linux-image-2.6.18-4-686. So
first, you will need to manually install a kernel image package. The exact
kernel image you need to install depends on your architecture and your prefered
kernel version. Once this is done, you will be able to manage the security
updates of the kernel just like those of any other package. In any case,
notice that the kernel updates will only be done for kernel updates of
the same kernel version you are using, that is, apt will not
automatically upgrade your kernel from the 2.4 release to the 2.6 release (or
from the 2.4.26 release to the 2.4.27 release[12]).

The installation system of recent Debian releases will handle the selected
kernel as part of the package system. You can review which kernels you have
installed by running:

If you are doing a security update which includes the kernel image you
need to reboot the system in order for the security update to be
useful. Otherwise, you will still be running the old (and vulnerable) kernel
image.

If you need to do a system reboot (because of a kernel upgrade) you should make
sure that the kernel will boot up correctly and network connectivity will be
restored, specially if the security upgrade is done over a remote connection
like ssh. For the former you can configure your boot loader to reboot to the
original kernel in the event of a failure (for more detailed information read
Remotely
rebooting Debian GNU/Linux machines). For the latter you have to
introduce a network connectivity test script that will check if the kernel has
started up the network subsystem properly and reboot the system if it did
not[13]. This should prevent
nasty surprises like updating the kernel and then realizing, after a reboot,
that it did not detect or configure the network hardware properly and you need
to travel a long distance to bring the system up again. Of course, having the
system serial console [14] in
the system connected to a console or terminal server should also help debug
reboot issues remotely.

4.3 Change the BIOS (again)

Remember Choose a BIOS password, Section
3.1? Well, then you should now, once you do not need to boot from
removable media, to change the default BIOS setup so that it only
boots from the hard drive. Make sure you will not lose the BIOS password,
otherwise, in the event of a hard disk failure you will not be able to return
to the BIOS and change the setup so you can recover it using, for example, a
CD-ROM.

Another less secure but more convenient way is to change the setup to have the
system boot up from the hard disk and, if it fails, try removable media. By
the way, this is often done because most people don't use the BIOS password
that often; it's easily forgotten.

4.4 Set a LILO or GRUB password

Anybody can easily get a root-shell and change your passwords by entering
<name-of-your-bootimage> init=/bin/sh at the boot prompt.
After changing the passwords and rebooting the system, the person has unlimited
root-access and can do anything he/she wants to the system. After this
procedure you will not have root access to your system, as you do not know the
root password.

To make sure that this cannot happen, you should set a password for the boot
loader. You can choose between a global password or a password for a certain
image.

For LILO you need to edit the config file /etc/lilo.conf and add a
password and restricted line as in the example below.

Then, make sure that the configuration file is not world readable to prevent
local users from reading the password. When done, rerun lilo. Omitting the
restricted line causes lilo to always prompt for a password,
regardless of whether LILO was passed parameters. The default permissions for
/etc/lilo.conf grant read and write permissions to root, and
enable read-only access for lilo.conf's group, root.

If you use GRUB instead of LILO, edit /boot/grub/menu.lst and add
the following two lines at the top (substituting, of course hackme
with the desired password). This prevents users from editing the boot items.
timeout 3 specifies a 3 second delay before grub
boots the default item.

timeout 3
password hackme

To further harden the integrity of the password, you may store the password in
an encrypted form. The utility grub-md5-crypt generates a hashed
password which is compatible with GRUB's encrypted password algorithm (MD5).
To specify in grub that an MD5 format password will be used, use
the following directive:

timeout 3
password --md5 $1$bw0ez$tljnxxKLfMzmnDVaQWgjP0

The --md5 parameter was added to instruct grub to perform the MD5
authentication process. The provided password is the MD5 encrypted version of
hackme. Using the MD5 password method is preferable to choosing its clear-text
counterpart. More information about grub passwords may be found
in the grub-doc package.

4.5 Disable root prompt on the initramfs

Note: This applies to the default kernels provided for releases after Debian
3.1

Linux 2.6 kernels provide a way to access a root shell while booting which will
be presented during loading the initramfs on error. This is helpful to permit
the administrator to enter a rescue shell with root permissions. This shell
can be used to manually load modules when autodetection fails. This behavior
is the default for initramfs-tools generated initramfs. The
following message will appear:

"ALERT! /dev/sda1 does not exist. Dropping to a shell!

In order to remove this behavior you need to set the following boot
argument:panic=0. Add this to the variable
GRUB_CMDLINE_LINUX in /etc/default/grub and issue
update-grub or to the append section of
/etc/lilo.conf.

4.6 Remove root prompt on the kernel

Note: This does not apply to the kernels provided for Debian 3.1 as the timeout
for the kernel delay has been changed to 0.

Linux 2.4 kernels provide a way to access a root shell while booting which will
be presented just after loading the cramfs file system. A message will appear
to permit the administrator to enter an executable shell with root permissions,
this shell can be used to manually load modules when autodetection fails. This
behavior is the default for initrd's linuxrc. The
following message will appear:

Press ENTER to obtain a shell (waits 5 seconds)

In order to remove this behavior you need to change
/etc/mkinitrd/mkinitrd.conf and set:

# DELAY The number of seconds the linuxrc script should wait to
# allow the user to interrupt it before the system is brought up
DELAY=0

Then regenerate your ramdisk image. You can do this for example with:

# cd /boot
# mkinitrd -o initrd.img-2.4.18-k7 /lib/modules/2.4.18-k7

or (preferred):

# dpkg-reconfigure -plow kernel-image-2.4.x-yz

4.7 Restricting console login access

Some security policies might force administrators to log in to the system
through the console with their user/password and then become superuser (with
su or sudo). This policy is implemented in Debian by
editing the /etc/pam.d/login and the /etc/securetty
when using PAM:

/etc/pam.d/login [15] enables the pam_securetty.so module. This module, when
properly configured will not ask for a password when the root user tries to
login on an insecure console, rejecting access as this user.

securetty [16] by
adding/removing the terminals to which root access will be allowed. If you
wish to allow only local console access then you need console,
ttyX[17] and
vc/X (if using devfs devices), you might want to add also
ttySX[18] if you are
using a serial console for local access (where X is an integer, you might want
to have multiple instances. The default configuration for Wheezy [19] includes many tty devices,
serial ports, vc consoles as well as the X server and the console
device. You can safely adjust this if you are not using that many consoles.
You can confirm the virtual consoles and the tty devices you have by reviewing
/etc/inittab [20]
. For more information on terminal devices read the Text-Terminal-HOWTO.

When using PAM, other changes to the login process, which might include
restrictions to users and groups at given times, can be configured in
/etc/pam.d/login. An interesting feature that can be disabled is
the possibility to login with null (blank) passwords. This feature can be
limited by removing nullok from the line:

auth required pam_unix.so nullok

4.8 Restricting system reboots through the console

If your system has a keyboard attached to it anyone (yes anyone) with
physical access to the system can reboot the system through it without login in
just pressing the Ctrl+Alt+Delete keyboard combination, also known as
the three finger salute. This might, or might not, adhere to your
security policy.

This is aggravated in environments in which the operating system is running
virtualised. In these environments, the possibility extends to users that have
access to the virtual console (which might be accessed over the network). Also
note that, in these environments, this keyboard combination is used constantly
(to open a login shell in some GUI operating systems) and an administrator
might virtually send it and force a system reboot.

There are two ways to restrict this:

configure it so that only allowed users can reboot the system,

disable this feature completely.

If you want to restrict this, you must check the /etc/inittab so
that the line that includes ctrlaltdel calls shutdown
with the -a switch.

The default in Debian includes this switch:

ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now

The -a switch, as the shutdown(8) manpage
describes,makes it possible to allow some users to shutdown the
system. For this the file /etc/shutdown.allow must be created and
the administrator has to include there the name of users which can boot the
system. When the three finger salute combination is pressed in a
console the program will check if any of the users listed in the file are
logged in. If none of them is, shutdown will not reboot
the system.

If you want to disable the Ctrl+Alt+Del combination you just need to comment
the line with the ctrlaltdel definition in the
/etc/inittab.

Remember to run init q after making any changes to the
/etc/inittab file for the changes to take effect.

4.9 Restricting the use of the Magic SysRq key

The Magic SysRq key is a key combination that allows users connected
to the system console of a Linux kernel to perform some low-level commands.
These low-level commands are sent by pressing simultaneously Alt+SysRq
and a command key. The SysRq key in many keyboards is labeled as the Print
Screen key.

Since the Etch release, the Magic SysRq key feature is enabled in the Linux
kernel to allow console users certain privileges. You can confirm this by
checking if the /proc/sys/kernel/sysrq exists and reviewing its
value:

$ cat /proc/sys/kernel/sysrq
438

The default value shown above allows all of the SysRq functions except for the
possibility of sending signals to processes. For example, it allow users
connected to the console to remount all systems read-only, reboot the system or
cause a kernel panic. In all the features are enabled, or in older kernels
(earlier than 2.6.12) the value will be just 1.

You should disable this functionality ifaccess to the console is not restricted
to authorised users: the console is connected to a modem line, there is easy
physical access to the system or it is running in a virtualised environment and
other users access the console. To do this edit the
/etc/sysctl.conf and add the following lines:

4.10 Mounting partitions the right way

When mounting an Ext file system (ext2,
ext3 or ext4), there are several additional options
you can apply to the mount call or to /etc/fstab. For instance,
this is my fstab entry for the /tmp partition:

/dev/hda7 /tmp ext2 defaults,nosuid,noexec,nodev 0 2

You see the difference in the options sections. The option nosuid
ignores the setuid and setgid bits completely, while noexec
forbids execution of any program on that mount point, and nodev
ignores device files. This sounds great, but it:

only applies to ext2 or ext3 file systems

can be circumvented easily

The noexec option prevents binaries from being executed directly,
but was easily circumvented in earlier versions of the kernel:

However, many script kiddies have exploits which try to create and execute
files in /tmp. If they do not have a clue, they will fall into
this pit. In other words, a user cannot be tricked into executing a trojanized
binary in /tmp e.g. when /tmp is accidentally added
into the local PATH.

Also be forewarned, some script might depend on /tmp being
executable. Most notably, Debconf has (had?) some issues regarding this, for
more information see Bug 116448.

The following is a more thorough example. A note, though: /var
could be set noexec, but some software [21] keeps its programs under in /var. The same
applies to the nosuid option.

4.10.1 Setting /tmp noexec

Be careful if setting /tmp noexec when you want to install new
software, since some programs might use it for installation. apt
is one such program (see http://bugs.debian.org/116448)
if not configured properly APT::ExtractTemplates::TempDir (see
apt-extracttemplates(1)). You can set this variable in
/etc/apt/apt.conf to another directory with exec privileges other
than /tmp.

4.10.2 Setting /usr read-only

If you set /usr read-only you will not be able to install new
packages on your Debian GNU/Linux system. You will have to first remount it
read-write, install the packages and then remount it read-only.
apt can be configured to run commands before and after installing
packages, so you might want to configure it properly.

Note that the Post-Invoke may fail with a "/usr busy" error message.
This happens mainly when you are using files during the update that got
updated. You can find these programs by running

# lsof +L1

Stop or restart these programs and run the Post-Invoke manually.
Beware! This means you'll likely need to restart your X session (if
you're running one) every time you do a major upgrade of your system. You
might want to reconsider whether a read-only /usr is suitable for
your system. See also this discussion
on debian-devel about read-only /usr.

4.11 Providing secure user access

4.11.1 User authentication: PAM

PAM (Pluggable Authentication Modules) allows system administrators to choose
how applications authenticate users. Note that PAM can do nothing unless an
application is compiled with support for PAM. Most of the applications that
are shipped with Debian have this support built in (Debian did not have PAM
support before 2.2). The current default configuration for any PAM-enabled
service is to emulate UNIX authentication (read
/usr/share/doc/libpam0g/Debian-PAM-MiniPolicy.gz for more
information on how PAM services should work in Debian).

Each application with PAM support provides a configuration file in
/etc/pam.d/ which can be used to modify its behavior:

what backend is used for authentication.

what backend is used for sessions.

how do password checks behave.

The following description is far from complete, for more information you might
want to read the Linux-PAM Guides as
a reference. This documentation is available in the system if you install the
libpam-doc at /usr/share/doc/libpam-doc/html/.

PAM offers you the possibility to go through several authentication steps at
once, without the user's knowledge. You could authenticate against a Berkeley
database and against the normal passwd file, and the user only
logs in if the authentication succeeds in both. You can restrict a lot with
PAM, just as you can open your system doors very wide. So be careful. A
typical configuration line has a control field as its second element.
Generally it should be set to requisite, which returns a login
failure if one module fails.

4.11.1.1 Password security in PAM

Review the /etc/pam.d/common-password, included by
/etc/pam.d/passwd [22] . This file is included by other files in
/etc/pam.d/ to define the behaviour of password use in subsystems
that grant access to services in the machine, like the console login
(login), graphical login managers (such as gdm or
lightdm), and remote login (such as sshd). This
definition is

You have to make sure that the pam_unix.so module uses the "sha512"
option to use encrypted passwords. This is the default in Debian Squeeze.

The line with the definition of the pam_unix module will look something like:

You have to ensure that encrypted passwords are used in PAM applications, since
this helps protect against dictionary cracks. Using encryption also makes it
possible to use passwords longer than 8 characters.

Since this module is also used to define how passwords are changed (it is
included by chpasswd) you can strengthen the password security in
the system by installing libpam-cracklib and introducing this
definition in the /etc/pam.d/common-password configuration file:

# Be sure to install libpam-cracklib first or you will not be able to log in
password required pam_cracklib.so retry=3 minlen=12 difok=3
password [success=1 default=ignore] pam_unix.so obscure minlen=8 sha512 use_authok

So, what does this incantation do? The first line loads the cracklib PAM
module, which provides password strength-checking, prompts for a new password
with a minimum size [23] of 12
characters, and difference of at least 3 characters from the old password, and
allows 3 retries. Cracklib depends on a wordlist package (such as
wenglish, wspanish, wbritish, ...), so
make sure you install one that is appropriate for your language or cracklib
might not be useful to you at all.

The second line (using the pam_unix.so module) is the default configuration in
Debian, as described above, save for the use_authok option. The
use_authok option is required if pam_unix.so is stacked after
pam_cracklib.so, and is used to hand over the password from the previous
module. Otherwise, the user would be prompted for the password twice.

By enabling the cracklib PAM module you setup a policy that forces uses to use
strong passwords.

Alternatively, you can setup and configure PAM modules to use double factor
authentication such as: libpam-barada,
libpam-google-authenticator, libpam-oath,
libpam-otpw, libpam-poldi, libpam-usb or
libpam-yubico. The configuration of these modules would make it
possible to access the system using external authentication mechanisms such as
smartcards, external USB keys, or One-Time-Passwords generated by external
applications running, for example, in the user's mobile phone.

Please note that these restrictions apply to all users but not to the
password changes done by the root user. The root user will be able to set up
any password (any length or complexity) for personal use or others regardless
of the restrictions defined here.

4.11.1.2 User access control in PAM

To make sure that the user root can only log into the system from local
terminals, the following line should be enabled in
/etc/pam.d/login:

auth requisite pam_securetty.so

Then you should modify the list of terminals on which direct root login is
allowed in /etc/securetty (as described in Restricting console login access, Section
4.7). Alternatively, you could enable the pam_access module
and modify /etc/security/access.conf which allows for a more
general and fine-tuned access control, but (unfortunately) lacks decent log
messages (logging within PAM is not standardized and is particularly
unrewarding problem to deal with). We'll return to access.conf a
little later.

4.11.1.3 User limits in PAM

The following line should be enabled in /etc/pam.d/login to set up
user resource limits.

4.11.1.4 Control of su in PAM

If you want to protect su, so that only some people can use it to
become root on your system, you need to add a new group "wheel" to
your system (that is the cleanest way, since no file has such a group
permission yet). Add root and the other users that should be able to
su to the root user to this group. Then add the following line to
/etc/pam.d/su:

auth requisite pam_wheel.so group=wheel debug

This makes sure that only people from the group "wheel" can use
su to become root. Other users will not be able to become root.
In fact they will get a denied message if they try to become root.

If you want only certain users to authenticate at a PAM service, this is quite
easy to achieve by using files where the users who are allowed to login (or
not) are stored. Imagine you only want to allow users 'ref' to log in via
ssh. So you put them into /etc/sshusers-allowed and
write the following into /etc/pam.d/ssh:

4.11.1.5 Temporary directories in PAM

Since there have been a number of so called insecure tempfile vulnerabilities,
thttpd is one example (see DSA-883-1), the
libpam-tmpdir is a good package to install. All you have to do is
add the following to /etc/pam.d/common-session:

These lines will provide a good default configuration for all applications that
support PAM (access is denied by default).

4.11.2 Limiting resource usage: the limits.conf file

You should really take a serious look into this file. Here you can define user
resource limits. In old releases this configuration file was
/etc/limits.conf, but in newer releases (with PAM) the
/etc/security/limits.conf configuration file should be used
instead.

If you do not restrict resource usage, any user with a valid shell in
your system (or even an intruder who compromised the system through a service
or a daemon going awry) can use up as much CPU, memory, stack, etc. as the
system can provide. This resource exhaustion problem can be fixed by
the use of PAM.

There is a way to add resource limits to some shells (for example,
bash has ulimit, see bash(1)), but since
not all of them provide the same limits and since the user can change shells
(see chsh(1)) it is better to place the limits on the PAM modules
as they will apply regardless of the shell used and will also apply to PAM
modules that are not shell-oriented.

Resource limits are imposed by the kernel, but they need to be configured
through the limits.conf and the PAM configuration of the different
services need to load the appropriate PAM. You can check which services are
enforcing limits by running:

Commonly, login, ssh and the graphic session managers
(gdm, kdm or xdm) should enforce user
limits but you might want to do this in other PAM configuration files, such as
cron, to prevent system daemons from taking over all system
resources.

The specific limits settings you might want to enforce depend on your system's
resources, that's one of the main reasons why no limits are enforced in the
default installation.

For example, the configuration example below enforces a 100 process limit for
all users (to prevent fork bombs) as well as a limit of 10MB of memory
per process and a limit of 10 simultaneous logins. Users in the
adm group have higher limits and can produce core files if they
want to (there is only a soft limit).

4.11.3 User login actions: edit /etc/login.defs

The next step is to edit the basic configuration and action upon user login.
Note that this file is not part of the PAM configuration, it's a configuration
file honored by login and su programs, so it doesn't
make sense tuning it for cases where neither of the two programs are at least
indirectly called (the getty program which sits on the consoles
and offers the initial login prompt does invoke login).

FAILLOG_ENAB yes

If you enable this variable, failed logins will be logged. It is important to
keep track of them to catch someone who tries a brute force attack.

LOG_UNKFAIL_ENAB no

If you set this variable to 'yes' it will record unknown usernames if the login
failed. It is best if you use 'no' (the default) since, otherwise, user
passwords might be inadvertenly logged here (if a user mistypes and they enter
their password as the username). If you set it to 'yes', make sure the logs
have the proper permissions (640 for example, with an appropriate group setting
such as adm).

SYSLOG_SU_ENAB yes

This one enables logging of su attempts to syslog.
Quite important on serious machines but note that this can create privacy
issues as well.

SYSLOG_SG_ENAB yes

The same as SYSLOG_SU_ENAB but applies to the sg
program.

ENCRYPT_METHOD SHA512

As stated above, encrypted passwords greatly reduce the problem of dictionary
attacks, since you can use longer passwords. This definition has to be
consistent with the value defined in /etc/pam.d/common-password.

4.11.4 User login actions: edit /etc/pam.d/login

You can adjust the login configuration file to implement an stricter policy.
For example, you can change the default configuration and increase the delay
time between login prompts. The default configuration sets a 3 seconds delay:

auth optional pam_faildelay.so delay=3000000

Increasing the delay value to a higher value to make it harder to use
the terminal to log in using brute force. If a wrong password is typed in, the
possible attacker (or normal user!) has to wait longer seconds to get a new
login prompt, which is quite time consuming when you test passwords. For
example, if you set delay=10000000, users will have to wait 10 seconds
if they type a wrong password.

In this file you can also set the system to present a message to users before a
user logs in. The default is disabled, as shown below:

# auth required pam_issue.so issue=/etc/issue

If required by your security policy, this file can be used to show a standard
message indicating that access to the system is restricted and user acess is
logged. This kind of disclaimer might be required in some environments and
jurisdictions. To enable it, just include the relevant information in the
/etc/issue [24]
file and uncomment the line enabling the pam_issue.so module in
/etc/pam.d/login. In this file you can also enable additional
features which might be relevant to apply local security policies such as:

setting rules for which users can access at which times, by enabling the
pam_time.so module and configuring
/etc/security/time.conf accordingly (disabled by default),

setup login sessions to use user limits as defined in
/etc/security/limits.conf (enabled by default),

present the user with the information of previous login information (enabled by
default),

print a message (/etc/motd and /run/motd.dynamic) to
users after login in (enabled by default),

4.11.5 Restricting ftp: editing /etc/ftpusers

The /etc/ftpusers file contains a list of users who are not
allowed to log into the host using ftp. Only use this file if you really want
to allow ftp (which is not recommended in general, because it uses clear-text
passwords). If your daemon supports PAM, you can also use that to allow and
deny users for certain services.

FIXME (BUG): Is it a bug that the default ftpusers in Debian does
not include all the administrative users (in
base-passwd).

A convenient way to add all system accounts to the /etc/ftpusers
is to run

$ awk -F : '{if ($3<1000) print $1}' /etc/passwd > /etc/ftpusers

4.11.6 Using su

If you really need users to become the super user on your system, e.g. for
installing packages or adding users, you can use the command su to
change your identity. You should try to avoid any login as user root and
instead use su. Actually, the best solution is to remove
su and switch to the sudo mechanism which has a
broader logic and more features than su. However, su
is more common as it is used on many other Unices.

4.11.7 Using sudo

sudo allows the user to execute defined commands under another
user's identity, even as root. If the user is added to
/etc/sudoers and authenticates correctly, the commands defined in
/etc/sudoers get enabled. Violations, such as incorrect passwords
or trying to run a program you don't have permission for, are logged and mailed
to root.

4.11.8 Disallow remote administrative access

You should also modify /etc/security/access.conf to disallow
remote logins to administrative accounts. This way users need to invoke
su (or sudo) to use any administrative powers and the
appropriate audit trace will always be generated.

You need to add the following line to /etc/security/access.conf,
the default Debian configuration file has a sample line commented out:

-:wheel:ALL EXCEPT LOCAL

Remember to enable the pam_access module for every service (or
default configuration) in /etc/pam.d/ if you want your changes to
/etc/security/access.conf honored.

4.11.9 Restricting users's access

Sometimes you might think you need to have users created in your local system
in order to provide a given service (pop3 mail service or ftp). Before doing
so, first remember that the PAM implementation in Debian GNU/Linux allows you
to validate users with a wide variety of external directory services (radius,
ldap, etc.) provided by the libpam packages.

If users need to be created and the system can be accessed remotely take into
account that users will be able to log in to the system. You can fix this by
giving users a null (/dev/null) shell (it would need to be listed
in /etc/shells). If you want to allow users to access the system
but limit their movements, you can use the /bin/rbash, equivalent
to adding the -r option in bash (RESTRICTED
SHELL see bash(1)). Please note that even with restricted
shell, a user that access an interactive program (that might allow execution of
a subshell) could be able to bypass the limits of the shell.

Debian currently provides in the unstable release (and might be included in the
next stable releases) the pam_chroot module (in the
libpam-chroot). An alternative to it is to chroot
the service that provides remote logging (ssh,
telnet). [25]

If you wish to restrict when users can access the system you will have
to customize /etc/security/access.conf for your needs.

4.11.10 User auditing

If you are really paranoid you might want to add a system-wide configuration to
audit what the users are doing in your system. This sections presents some
tips using diverse utilities you can use.

4.11.10.1 Input and output audit with script

You can use the script command to audit both what the users run
and what are the results of those commands. You cannot setup
script as a shell (even if you add it to
/etc/shells). But you can have the shell initialization file run
the following:

umask 077
exec script -q -a "/var/log/sessions/$USER"

Of course, if you do this system wide it means that the shell would not
continue reading personal initialization files (since the shell gets
overwritten by script). An alternative is to do this in the
user's initialization files (but then the user could remove this, see the
comments about this below)

You also need to setup the files in the audit directory (in the example
/var/log/sessions/) so that users can write to it but cannot
remove the file. This could be done, for example, by creating the user session
files in advance and setting them with the append-only flag using
chattr.

A useful alternative for sysadmins, which includes date information would be:

umask 077
exec script -q -a "/var/log/sessions/$USER-`date +%Y%m%d`"

4.11.10.2 Using the shell history file

If you want to review what does the user type in the shell (but not what the
result of that is) you can setup a system-wide /etc/profile that
configures the environment so that all commands are saved into a history file.
The system-wide configuration needs to be setup in such a way that users cannot
remove audit capabilities from their shell. This is somewhat shell specific so
make sure that all users are using a shell that supports this.

For example, for bash, the /etc/profile could be set as follows
[26] :

For this to work, the user can only append information to
.bash_history file. You need also to set the
append-only option using chattr program for
.bash_history for all users. [27].

Note that you could introduce the configuration above in the user's
.profile. But then you would need to setup permissions properly
in such a way that prevents the user from modifying this file. This includes:
having the user's home directories not belong to the user (since the
user would be able to remove the file otherwise) but at the same time allow the
user to read the .profile configuration file and write on the
.bash_history. It would be good to set the immutable
flag (also using chattr) for .profile too if you do
it this way.

4.11.10.3 Complete user audit with accounting utilities

The previous example is a simple way to configure user auditing but might be
not useful for complex systems or for those in which users do not run shells at
all (or exclusively). If this is your case, you need to look at
acct, the accounting utilities. These utilities will log all the
commands run by users or processes in the system, at the expense of disk space.

When activating accounting, all the information on processes and users is kept
under /var/account/, more specifically in the pacct.
The accounting package includes some tools (sa, ac
and lastcomm) to analyse this data.

4.11.10.4 Other user auditing methods

If you are completely paranoid and want to audit every user's command, you
could take bash source code, edit it and have it send all that the
user typed into another file. Or have ttysnoop constantly monitor
any new ttys [28] and dump the
output into a file. Other useful program is snoopy (see also
the project
page) which is a user-transparent program that hooks in as a library
providing a wrapper around execve() calls, any command executed is
logged to syslogd using the authpriv facility
(usually stored at /var/log/auth.log).

4.11.11 Reviewing user profiles

If you want to see what users are actually doing when they logon to
the system you can use the wtmp database that includes all login
information. This file can be processed with several utilities, amongst them
sac which can output a profile on each user showing in which
timeframe they usually log on to the system.

In case you have accounting activated, you can also use the tools provided by
it in order to determine when the users access the system and what do they
execute.

4.11.12 Setting users umasks

Depending on your user policy you might want to change how information is
shared between users, that is, what the default permissions of new files
created by users are.

Debian's default umask setting is 022 this means that
files (and directories) can be read and accessed by the user's group and by any
other users in the system. This definition is set in the standard
configuration file /etc/profile which is used by all shells.

If Debian's default value is too permissive for your system you will have to
change the umask setting for all the shells. More restrictive umask settings
include 027 (no access is allowed to new files for the other group,
i.e. to other users in the system) or 077 (no access is allowed to new files
to the members the user's group). Debian (by default[29]) creates one group per user so
that only the user is included in its group. Consequently 027 and 077 are
equivalent as the user's group contains only the user.

This change is set by defining a proper umask setting for all
users. You can change this by introducing an umask call in the
shell configuration files: /etc/profile (source by all
Bourne-compatible shells), /etc/csh.cshrc,
/etc/csh.login, /etc/zshrc and probably some others
(depending on the shells you have installed on your system). You can also
change the UMASK setting in /etc/login.defs, Of all of
these the last one that gets loaded by the shell takes precedence. The order
is: the default system configuration for the user's shell (i.e.
/etc/profile and other system-wide configuration files) and then
the user's shell (his ~/.profile, ~/.bash_profile,
etc...). Some shells, however, can be executed with a nologin value
which might skip sourcing some of those files. See your shell's manpage for
additional information.

For connections that make use of login the UMASK definition in
/etc/login.defs is used before any of the others. However, that
value does not apply to user executed programs that do not use
login such as those run through su, cron
or ssh.

Don't forget to review and maybe modify the dotfiles under
/etc/skel/ since these will be new user's defaults when created
with the adduser command. Debian default dotfiles do not include
any umask call but if there is any in the dotfiles newly created
users might a different value.

Note, however that users can modify their own umask setting if
they want to, making it more permissive or more restricted, by changing their
own dotfiles.

The libpam-umask package adjusts the users' default
umask using PAM. Add the following, after installing the package,
to /etc/pam.d/common-session:

session optional pam_umask.so umask=077

Finally, you should consider changing root's default 022 umask (as defined in
/root/.bashrc) to a more strict umask. That will prevent the
system administrator from inadvertenly dropping sensitive files when working as
root to world-readable directories (such as /tmp) and having them
available for your average user.

4.11.13 Limiting what users can see/access

FIXME: Content needed. Describe the consequences of changing packages
permissions when upgrading (an admin this paranoid should chroot
his users BTW) if not using dpkg-statoverride.

If you need to grant users access to the system with a shell think about it
very carefully. A user can, by default unless in a severely restricted
environment (like a chroot jail), retrieve quite a lot of
information from your system including:

some configuration files in /etc. However, Debian's default
permissions for some sensitive files (which might, for example, contain
passwords), will prevent access to critical information. To see which files
are only accessible by the root user for example find /etc -type f -a
-perm 600 -a -uid 0 as superuser.

your installed packages, either by looking at the package database, at the
/usr/share/doc directory or by guessing by looking at the binaries
and libraries installed in your system.

some log files at /var/log. Note also that some log files are
only accessible to root and the adm group (try find /var/log
-type f -a -perm 640) and some are even only available to the root user
(try find /var/log -type f -a -perm 600 -a -uid 0).

What can a user see in your system? Probably quite a lot of things, try this
(take a deep breath):

The output is the list of files that a user can see and the accessable
directories.

4.11.13.1 Limiting access to other user's information

If you still grant shell access to users you might want to limit what
information they can view from other users. Users with shell access have a
tendency to create quite a number of files under their $HOMEs: mailboxes,
personal documents, configuration of X/GNOME/KDE applications...

In Debian each user is created with one associated group, and no two users
belong to the same group. This is the default behavior: when an user account
is created, a group of the same name is created too, and the user is assigned
to it. This avoids the concept of a common users group which might
make it more difficult for users to hide information from other users.

However, users' $HOME directories are created with 0755 permissions
(group-readable and world-readable). The group permissions is not an issue
since only the user belongs to the group, however the world permissions might
(or might not) be an issue depending on your local policy.

You can change this behavior so that user creation provides different
$HOME permissions. To change the behavior for new users
when they get created, change DIR_MODE in the configuration file
/etc/adduser.conf to 0750 (no world-readable access).

Users can still share information, but not directly in their $HOME
directories unless they change its permissions.

Note that disabling world-readable home directories will prevent users from
creating their personal web pages in the ~/public_html directory,
since the web server will not be able to read one component in the path -
namely their $HOME directory. If you want to permit users to
publish HTML pages in their ~/public_html, then change
DIR_MODE to 0751. This will allow the web server to access the final
public_html directory (which itself should have a mode of 0755)
and provide the content published by users. Of course, we are only talking
about a default configuration here; users can generally tune modes of their own
files completely to their liking, or you could keep content intended for the
web in a separate location which is not a subdirectory of user's
$HOME directory.

4.11.14 Generating user passwords

There are many cases when an administrator needs to create many user accounts
and provide passwords for all of them. Of course, the administrator could
easily just set the password to be the same as the user's account name, but
that would not be very sensitive security-wise. A better approach is to use a
password generating program. Debian provides makepasswd,
apg and pwgen packages which provide programs (the
name is the same as the package) that can be used for this purpose.
Makepasswd will generate true random passwords with an emphasis on
security over pronounceability while pwgen will try to make
meaningless but pronounceable passwords (of course this might depend on your
mother language). Apg has algorithms to provide for both (there
is a client/server version for this program but it is not included in the
Debian package).

Passwd does not allow non-interactive assignation of passwords
(since it uses direct tty access). If you want to change passwords when
creating a large number of users you can create them using adduser
with the --disabled-login option and then use usermod
or chpasswd [30]
(both from the passwd package so you already have them installed).
If you want to use a file with all the information to make users as a batch
process you might be better off using newusers.

4.11.15 Checking user passwords

User passwords can sometimes become the weakest link in the security
of a given system. This is due to some users choosing weak passwords for their
accounts (and the more of them that have access to it the greater the chances
of this happening). Even if you established checks with the cracklib PAM
module and password limits as described in User
authentication: PAM, Section 4.11.1 users will still be able to use weak
passwords. Since user access might include remote shell access (over
ssh, hopefully) it's important to make password guessing as hard
as possible for the remote attackers, especially if they were somehow able to
collect important information such as usernames or even the passwd
and shadow files themselves.

A system administrator must, given a big number of users, check if the
passwords they have are consistent with the local security policy. How to
check? Try to crack them as an attacker would if having access to the hashed
passwords (the /etc/shadow file).

An administrator can use john or crack (both are
brute force password crackers) together with an appropriate wordlist to check
users' passwords and take appropriate action when a weak password is detected.
You can search for Debian GNU packages that contain word lists using
apt-cache search wordlist, or visit the classic Internet wordlist
sites such as ftp://ftp.ox.ac.uk/pub/wordlists
or ftp://ftp.cerias.purdue.edu/pub/dict.

4.11.16 Logging off idle users

Idle users are usually a security problem, a user might be idle maybe because
he's out to lunch or because a remote connection hung and was not
re-established. For whatever the reason, idle users might lead to a
compromise:

because the user's console might be unlocked and can be accessed by an
intruder.

because an attacker might be able to re-attach to a closed network connection
and send commands to the remote shell (this is fairly easy if the remote shell
is not encrypted as in the case of telnet).

Some remote systems have even been compromised through an idle (and detached)
screen.

Automatic disconnection of idle users is usually a part of the local security
policy that must be enforced. There are several ways to do this:

If bash is the user shell, a system administrator can set a
default TMOUT value (see bash(1)) which will make the
shell automatically log off remote idle users. Note that it must be set with
the -o option or users will be able to change (or unset) it.

Install timeoutd and configure /etc/timeouts
according to your local security policy. The daemon will watch for idle users
and time out their shells accordingly.

Install autolog and configure it to remove idle users.

The timeoutd or autolog daemons are the preferred
method since, after all, users can change their default shell or can, after
running their default shell, switch to another (uncontrolled) shell.

4.12 Using tcpwrappers

TCP wrappers were developed when there were no real packet filters available
and access control was needed. Nevertheless, they're still very interesting
and useful. The TCP wrappers allow you to allow or deny a service for a host
or a domain and define a default allow or deny rule (all performed on the
application level). If you want more information take a look at
hosts_access(5).

Many services installed in Debian are either:

launched through the tcpwrapper service (tcpd)

compiled with libwrapper support built-in.

On the one hand, for services configured in /etc/inetd.conf (this
includes telnet, ftp, netbios,
swat and finger) you will see that the configuration
file executes /usr/sbin/tcpd first. On the other hand, even if a
service is not launched by the inetd superdaemon, support for the
tcp wrappers rules can be compiled into it. Services compiled with tcp
wrappers in Debian include ssh, portmap,
in.talk, rpc.statd, rpc.mountd,
gdm, oaf (the GNOME activator daemon),
nessus and many others.

Take this into account when running tcpdchk (a very useful TCP
wrappers config file rule and syntax checker). When you add stand-alone
services (that are directly linked with the wrapper library) into the
hosts.deny and hosts.allow files,
tcpdchk will warn you that it is not able to find the mentioned
services since it only looks for them in /etc/inetd.conf (the
manpage is not totally accurate here).

Now, here comes a small trick, and probably the smallest intrusion detection
system available. In general, you should have a decent firewall policy as a
first line, and tcp wrappers as the second line of defense. One little trick
is to set up a SPAWN [32] command in /etc/hosts.deny that sends mail to
root whenever a denied service triggers wrappers:

Beware: The above printed example is open to a DoS attack by making
many connections in a short period of time. Many emails mean a lot of file I/O
by sending only a few packets.

4.13 The importance of logs and alerts

It is easy to see that the treatment of logs and alerts is an important issue
in a secure system. Suppose a system is perfectly configured and 99% secure.
If the 1% attack occurs, and there are no security measures in place to, first,
detect this and, second, raise alarms, the system is not secure at all.

Debian GNU/Linux provides some tools to perform log analysis, most notably
swatch, [33]
logcheck or log-analysis (all will need some
customisation to remove unnecessary things from the report). It might also be
useful, if the system is nearby, to have the system logs printed on a virtual
console. This is useful since you can (from a distance) see if the system is
behaving properly. Debian's /etc/syslog.conf comes with a
commented default configuration; to enable it uncomment the lines and restart
syslogd (/etc/init.d/syslogd restart):

To colorize the logs, you could take a look at colorize,
ccze or glark. There is a lot to log analysis that
cannot be fully covered here, so a good information resource would be books
should as Security log management:
identifying patterns in the chaos. In any case, even automated
tools are no match for the best analysis tool: your brain.

4.13.1 Using and customizing logcheck

The logcheck package in Debian is divided into the three packages
logcheck (the main program), logcheck-database (a
database of regular expressions for the program) and logtail
(prints loglines that have not yet been read). The Debian default (in
/etc/cron.d/logcheck) is that logcheck is run every
hour and after reboots.

This tool can be quite useful if properly customized to alert the administrator
of unusual system events. Logcheck can be fully customized so
that it sends mails based on events found in the logs and worthy of attention.
The default installation includes profiles for ignored events and policy
violations for three different setups (workstation, server and paranoid). The
Debian package includes a configuration file
/etc/logcheck/logcheck.conf, sourced by the program, that defines
which user the checks are sent to. It also provides a way for packages that
provide services to implement new policies in the directories:
/etc/logcheck/cracking.d/_packagename_,
/etc/logcheck/violations.d/_packagename_,
/etc/logcheck/violations.ignore.d/_packagename_,
/etc/logcheck/ignore.d.paranoid/_packagename_,
/etc/logcheck/ignore.d.server/_packagename_, and
/etc/logcheck/ignore.d.workstation/_packagename_. However, not
many packages currently do so. If you have a policy that can be useful for
other users, please send it as a bug report for the appropriate package (as a
wishlist bug). For more information read
/usr/share/doc/logcheck/README.Debian.

The best way to configure logcheck is to edit its main
configuration file /etc/logcheck/logcheck.conf after installation.
Change the default user (root) to whom reports should be mailed. You should
set the reportlevel in there, too. logcheck-database has three
report levels of increasing verbosity: workstation, server, paranoid.
"server" being the default level, paranoid is only recommended for
high-security machines running as few services as possible and workstation for
relatively sheltered, non-critical machines. If you wish to add new log files
just add them to /etc/logcheck/logcheck.logfiles. It is tuned for
default syslog install.

Once this is done you might want to check the mails that are sent, for the
first few days/weeks/months. If you find you are sent messages you do not wish
to receive, just add the regular expressions (see regex(7) and
egrep(1)) that correspond to these messages to the
/etc/logcheck/ignore.d.reportlevel/local. Try to match
the whole logline. Details on howto write rules are explained in
/usr/share/doc/logcheck-database/README.logcheck-database.gz.
It's an ongoing tuning process; once the messages that are sent are always
relevant you can consider the tuning finished. Note that if
logcheck does not find anything relevant in your system it will
not mail you even if it does run (so you might get a mail only once a week, if
you are lucky).

4.13.2 Configuring where alerts are sent

Debian comes with a standard syslog configuration (in
/etc/syslog.conf) that logs messages to the appropriate files
depending on the system facility. You should be familiar with this; have a
look at the syslog.conf file and the documentation if not. If you
intend to maintain a secure system you should be aware of where log messages
are sent so they do not go unnoticed.

For example, sending messages to the console also is an interesting setup
useful for many production-level systems. But for many such systems it is also
important to add a new machine that will serve as loghost (i.e. it receives
logs from all other systems).

Root's mail should be considered also, many security controls (like
snort) send alerts to root's mailbox. This mailbox usually points
to the first user created in the system (check /etc/aliases).
Take care to send root's mail to some place where it will be read (either
locally or remotely).

There are other role accounts and aliases on your system. On a small system,
it's probably simplest to make sure that all such aliases point to the root
account, and that mail to root is forwarded to the system administrator's
personal mailbox.

FIXME: It would be interesting to tell how a Debian system can send/receive
SNMP traps related to security problems (jfs). Check:
snmptrapfmt, snmp and snmpd.

4.13.3 Using a loghost

A loghost is a host which collects syslog data remotely over the network. If
one of your machines is cracked, the intruder is not able to cover the tracks,
unless hacking the loghost as well. So, the loghost should be especially
secure. Making a machine a loghost is simple. Just start the
syslogd with syslogd -r and a new loghost is born.
In order to do this permanently in Debian, edit
/etc/default/syslogd and change the line

SYSLOGD=""

to

SYSLOGD="-r"

Next, configure the other machines to send data to the loghost. Add an entry
like the following to /etc/syslog.conf:

facility.level @your_loghost

See the documentation for what to use in place of facility and
level (they should not be entered verbatim like this). If you want to
log everything remotely, just write:

*.* @your_loghost

into your syslog.conf. Logging remotely as well as locally is the
best solution (the attacker might presume to have covered his tracks after
deleting the local log files). See the syslog(3),
syslogd(8) and syslog.conf(5) manpages for additional
information.

4.13.4 Log file permissions

It is not only important to decide how alerts are used, but also who has
read/modify access to the log files (if not using a remote loghost). Security
alerts which the attacker can change or disable are not worth much in the event
of an intrusion. Also, you have to take into account that log files might
reveal quite a lot of information about your system to an intruder who has
access to them.

Some log file permissions are not perfect after the installation (but of course
this really depends on your local security policy). First
/var/log/lastlog and /var/log/faillog do not need to
be readable by normal users. In the lastlog file you can see who
logged in recently, and in the faillog you see a summary of failed
logins. The author recommends chmod 660 for both. Take a brief
look at your log files and decide very carefully which log files to make
readable/writable for a user with a UID other than 0 and a group other than
'adm' or 'root'. You can easily check this in your system with:

To customize how log files are created you will probably have to customize the
program that generates them. If the log file gets rotated, however, you can
customize the behavior of creation and rotation.

4.14 Adding kernel patches

Debian GNU/Linux provides some of the patches for the Linux kernel that enhance
its security. These include:

Linux Intrusion Detection
provided in the kernel-patch-2.4-lids package. This kernel patch
makes the process of hardening your Linux system easier by allowing you to
restrict, hide and protect processes, even from root. It implements mandatory
access control capabilities.

Linux Trustees,
provided in package trustees. This patch adds a decent advanced
permissions management system to your Linux kernel. Special objects (called
trustees) are bound to every file or directory, and are stored in kernel
memory, which allows fast lookup of all permissions.

The exec-shield
patch provided in the kernel-patch-exec-shield package.
This patch provides protection against some buffer overflows (stack smashing
attacks).

The Grsecurity patch,
provided by the kernel-patch-2.4-grsecurity and
kernel-patch-grsecurity2 packages [34] implements Mandatory Access Control through RBAC, provides
buffer overflow protection through PaX, ACLs, network randomness (to make OS
fingerprinting more difficult) and many more features.

The kernel-patch-adamantix provides the patches developed for
Adamantix, a Debian-based
distribution. This kernel patch for the 2.4.x kernel releases introduces some
security features such as a non-executable stack through the use of PaX and mandatory access
control based on RSBAC. Other
features include: the
Random PID patch, AES encrypted loop device, MPPE support and an
IPSEC v2.6 backport.

cryptoloop-source. This patches allows you to use the functions
of the kernel crypto API to create encrypted filesystems using the loopback
device.

IPSEC kernel support (in package linux-patch-openswan). If you
want to use the IPsec protocol with Linux, you need this patch. You can create
VPNs with this quite easily, even to Windows machines, as IPsec is a common
standard. IPsec capabilities have been added to the 2.5 development kernel, so
this feature will be present by default in the future Linux Kernel 2.6.
Homepage: http://www.openswan.org.
FIXME: The latest 2.4 kernels provided in Debian include a backport of
the IPSEC code from 2.5. Comment on this.

The following security kernel patches are only available for old kernel
versions in woody and are deprecated:

POSIX Access Control Lists
(ACLs) for Linux provided in the package kernel-patch-acl. This
kernel patch adds access control lists, an advanced method for restricting
access to files. It allows you to control fine-grain access to files and
directory.

The Openwall linux
kernel patch by Solar Designer, provided in the
kernel-patch-2.2.18-openwall package. This is a useful set of
kernel restrictions, like restricted links, FIFOs in /tmp, a
restricted /proc file system, special file descriptor handling,
non-executable user stack area and other features. Note: This package applies
to the 2.2 release, no packages are available for the 2.4 release patches
provided by Solar.

kernel-patch-int. This patch also adds cryptographic capabilities
to the Linux kernel, and was useful with Debian releases up to Potato. It
doesn't work with Woody, and if you are using Sarge or a newer version, you
should use a more recent kernel which includes these features already.

4.15 Protecting against buffer overflows

Buffer overflow is the name of a common attack to software [35] which makes use of
insufficient boundary checking (a programming error, most commonly in the C
language) in order to execute machine code through program inputs. These
attacks, against server software which listen to connections remotely and
against local software which grant higher privileges to users
(setuid or setgid) can result in the compromise of
any given system.

There are mainly four methods to protect against buffer overflows:

patch the kernel to prevent stack execution. You can use either: Exec-shield,
OpenWall or PaX (included in the Grsecurity and Adamantix patches).

fix the source code by using tools to find fragments of it that might introduce
this vulnerability.

Debian GNU/Linux, as of the 3.0 release, provides software to introduce all of
these methods except for the protection on source code compilation (but this
has been requested in Bug
#213994).

Notice that even if Debian provided a compiler which featured stack/buffer
overflow protection all packages would need to be recompiled in order to
introduce this feature. This is, in fact, what the Adamantix distribution does
(among other features). The effect of this new feature on the stability of
software is yet to be determined (some programs or some processor architectures
might break due to it).

If you want to test out your buffer overflow protection once you have
implemented it (regardless of the method) you might want to install the
paxtest and run the tests it provides.

4.15.1 Kernel patch protection for buffer overflows

Kernel patches related to buffer overflows include the Openwall patch provides
protection against buffer overflows in 2.2 linux kernels. For 2.4 or newer
kernels, you need to use the Exec-shield implementation, or the PaX
implementation (provided in the grsecurity patch,
kernel-patch-2.4-grsecurity, and in the Adamantix patch,
kernel-patch-adamantix). For more information on using these
patches read the the section Adding kernel patches,
Section 4.14.

4.15.2 Testing programs for overflows

The use of tools to detect buffer overflows requires, in any case, of
programming experience in order to fix (and recompile) the code. Debian
provides, for example: bfbtester (a buffer overflow tester that
brute-forces binaries through command line and environment overflows). Other
packages of interest would also be rats, pscan,
flawfinder and splint.

4.16 Secure file transfers

During normal system administration one usually needs to transfer files in and
out from the installed system. Copying files in a secure manner from a host to
another can be achieved by using the ssh server package. Another
possibility is the use of ftpd-ssl, a ftp server which uses the
Secure Socket Layer to encrypt the transmissions.

Any of these methods need special clients. Debian does provide client
software, such as scp from the ssh package, which
works like rcp but is encrypted completely, so the bad
guys cannot even find out WHAT you copy. There is also a
ftp-ssl package for the equivalent server. You can find clients
for these software even for other operating systems (non-UNIX),
putty and winscp provide secure copy implementations
for any version of Microsoft's operating system.

Note that using scp provides access to the users to all the file
system unless chroot'ed as described in Chrooting ssh, Section 5.1.1.
FTP access can be chroot'ed, probably easier depending on you
chosen daemon, as described in Securing FTP, Section 5.3. If
you are worried about users browsing your local files and want to have
encrypted communication you can either use an ftp daemon with SSL support or
combine clear-text ftp and a VPN setup (see Virtual Private Networks, Section 8.5).

4.17 File system limits and control

4.17.1 Using quotas

Having a good quota policy is important, as it keeps users from filling up the
hard disk(s).

You can use two different quota systems: user quota and group quota. As you
probably figured out, user quota limits the amount of space a user can take up,
group quota does the equivalent for groups. Keep this in mind when you're
working out quota sizes.

There are a few important points to think about in setting up a quota system:

Keep the quotas small enough, so users do not eat up your disk space.

Keep the quotas big enough, so users do not complain or their mail quota keeps
them from accepting mail over a longer period.

Use quotas on all user-writable areas, on /home as well as on
/tmp.

Every partition or directory to which users have full write access should be
quota enabled. Calculate and assign a workable quota size for those partitions
and directories which combines usability and security.

So, now you want to use quotas. First of all you need to check whether you
enabled quota support in your kernel. If not, you will need to recompile it.
After this, control whether the package quota is installed. If
not you will need this one as well.

Enabling quota for the respective file systems is as easy as modifying the
defaults setting to defaults,usrquota in your
/etc/fstab file. If you need group quota, substitute
usrquota to grpquota. You can also use them both.
Then create empty quota.user and quota.group files in the roots of the file
systems you want to use quotas on (e.g. touch /home/quota.user
/home/quota.group for a /home file system).

Restart quota by doing /etc/init.d/quota
stop;/etc/init.d/quota start. Now quota should be running, and quota
sizes can be set.

Editing quotas for a specific user can be done by edquota -u
<user>. Group quotas can be modified with edquota -g
<group>. Then set the soft and hard quota and/or inode quotas as
needed.

For more information about quotas, read the quota man page, and the quota
mini-howto (/usr/share/doc/HOWTO/en-html/mini/Quota.html). You
may also want to look at pam_limits.so.

4.17.2 The ext2 filesystem specific attributes (chattr/lsattr)

In addition to the usual Unix permissions, the ext2 and ext3 filesystems offer
a set of specific attributes that give you more control over the files on your
system. Unlike the basic permissions, these attributes are not displayed by
the usual ls -l command or changed using chmod, and
you need two other utilities, lsattr and chattr (in
package e2fsprogs) to manage them. Note that this means that
these attributes will usually not be saved when you backup your system, so if
you change any of them, it may be worth saving the successive
chattr commands in a script so that you can set them again later
if you have to restore a backup.

Among all available attributes, the two that are most important for increasing
security are referenced by the letters 'i' and 'a', and they can only be set
(or removed) by the superuser:

The 'i' attribute ('immutable'): a file with this attribute can neither be
modified nor deleted or renamed and no link can be created to it, even by the
superuser.

The 'a' attribute ('append'): this attribute has the same effect that the
immutable attribute, except that you can still open the file in append mode.
This means that you can still add more content to it but it is impossible to
modify previous content. This attribute is especially useful for the log files
stored in /var/log/, though you should consider that they get
moved sometimes due to the log rotation scripts.

These attributes can also be set for directories, in which case everyone is
denied the right to modify the contents of a directory list (e.g. rename or
remove a file, ...). When applied to a directory, the append attribute only
allows file creation.

It is easy to see how the 'a' attribute improves security, by giving to
programs that are not running as the superuser the ability to add data to a
file without modifying its previous content. On the other hand, the 'i'
attribute seems less interesting: after all, the superuser can already use the
basic Unix permissions to restrict access to a file, and an intruder that would
get access to the superuser account could always use the chattr
program to remove the attribute. Such an intruder may first be confused when
noticing not being able to remove a file, but you should not assume blindness -
after all, the intruder got into your system! Some manuals (including a
previous version of this document) suggest to simply remove the
chattr and lsattr programs from the system to
increase security, but this kind of strategy, also known as "security by
obscurity", is to be absolutely avoided, since it provides a false sense
of security.

A secure way to solve this problem is to use the capabilities of the Linux
kernel, as described in Proactive defense,
Section 10.4.2.1. The capability of interest here is called
CAP_LINUX_IMMUTABLE: if you remove it from the capabilities
bounding set (using for example the command lcap
CAP_LINUX_IMMUTABLE) it won't be possible to change any 'a' or 'i'
attribute on your system anymore, even by the superuser ! A complete strategy
could be as follows:

Set the 'i' attribute on this script and other startup files, as well as on the
lcap binary itself;

Execute the above command manually (or reboot your system to make sure
everything works as planned).

Now that the capability has been removed from the system, an intruder cannot
change any attribute on the protected files, and thus cannot change or remove
the files. If the machine is forced to reboot (which is the only way to
restore the capabilities bounding set), it will easily be detected, and the
capability will be removed again as soon as the system restarts anyway. The
only way to change a protected file would be to boot the system in single-user
mode or using another bootdisk, two operations that require physical access to
the machine !

4.17.3 Checking file system integrity

Are you sure /bin/login on your hard drive is still the binary you
installed there some months ago? What if it is a hacked version, which stores
the entered password in a hidden file or mails it in clear-text version all
over the Internet?

The only method to have some kind of protection is to check your files every
hour/day/month (I prefer daily) by comparing the actual and the old md5sum of
this file. Two files cannot have the same md5sum (the MD5 digest is 128 bits,
so the chance that two different files will have the same md5sum is roughly one
in 3.4e3803), so you're on the safe site here, unless someone has also hacked
the algorithm that creates md5sums on that machine. This is, well, extremely
difficult and very unlikely. You really should consider this auditing of your
binaries as very important, since it is an easy way to recognize changes at
your binaries.

Common tools used for this are sxid, aide (Advanced
Intrusion Detection Environment), tripwire, integrit
and samhain. Installing debsums will also help you
to check the file system integrity, by comparing the md5sums of every file
against the md5sums used in the Debian package archive. But beware: those
files can easily be changed by an attacker and not all packages provide md5sums
listings for the binaries they provided. For more information please read Do periodic integrity checks, Section
10.2 and Taking a snapshot of the system, Section
4.19.

You might want to use locate to index the whole filesystem, if so,
consider the implications of that. The Debian findutils package
contains locate which runs as user nobody, and so it only indexes
files which are visible to everybody. However, if you change it's behaviour
you will make all file locations visible to all users. If you want to index
all the filesystem (not the bits that the user nobody can see) you can replace
locate with the package slocate. slocate is labeled
as a security enhanced version of GNU locate, but it actually provides
additional file-locating functionality. When using slocate, the
user only sees the actually accessible files and you can exclude any files or
directories on the system. The slocate package runs its update
process with higher privledges than locate, and indexes every file. Users are
then able to quickly search for every file which they are able to see.
slocate doesn't let them see new files; it filters the output
based on your UID.

You might want to use bsign or elfsign.
elfsign provides an utility to add a digital signature to an ELF
binary and a second utility to verify that signature. The current
implementation uses PKI to sign the checksum of the binary. The benefits of
doing this are that it enables one to determine if a binary has been modified
and who created it. bsign uses GPG, elfsign uses PKI
(X.509) certificates (OpenSSL).

4.17.4 Setting up setuid check

The Debian checksecurity package provides a cron job
that runs daily in /etc/cron.daily/checksecurity [36]. This cron job
will run the /usr/sbin/checksecurity script that will store
information of this changes.

The default behavior does not send this information to the superuser but,
instead keeps daily copies of the changes in
/var/log/setuid.changes. You should set the MAILTO variable (in
/etc/checksecurity.conf) to 'root' to have this information mailed
to the superuser. See checksecurity(8) for more configuration
info.

4.18 Securing network access

FIXME: More (Debian-specific) content needed.

4.18.1 Configuring kernel network features

Many features of the kernel can be modified while running by echoing something
into the /proc file system or by using sysctl. By
entering /sbin/sysctl -A you can see what you can configure and
what the options are, and it can be modified running /sbin/sysctl -w
variable=value (see sysctl(8)). Only in rare cases do you
need to edit something here, but you can increase security that way as well.
For example:

net/ipv4/icmp_echo_ignore_broadcasts = 1

This is a Windows emulator because it acts like Windows on broadcast
ping if this option is set to 1. That is, ICMP echo requests sent to the
broadcast address will be ignored. Otherwise, it does nothing.

If you want to prevent you system from answering ICMP echo requests, just
enable this configuration option:

For more information on what things can be done with
/proc/sys/net/ipv4/* read
/usr/src/linux/Documentation/filesystems/proc.txt. All the
options are described thoroughly under
/usr/src/linux/Documentation/networking/ip-sysctl.txt [37].

4.18.2 Configuring syncookies

This option is a double-edged sword. On the one hand it protects your system
against syn packet flooding; on the other hand it violates defined standards
(RFCs).

net/ipv4/tcp_syncookies = 1

If you want to change this option each time the kernel is working you need to
change it in /etc/network/options by setting
syncookies=yes. This will take effect when ever
/etc/init.d/networking is run (which is typically done at boot
time) while the following will have a one-time effect until the reboot:

echo 1 > /proc/sys/net/ipv4/tcp_syncookies

This option will only be available if the kernel is compiled with the
CONFIG_SYNCOOKIES. All Debian kernels are compiled with this
option builtin but you can verify it running:

4.18.3 Securing the network on boot-time

When setting configuration options for the kernel networking you need configure
it so that it's loaded every time the system is restarted. The following
example enables many of the previous options as well as other useful options.

There are actually two ways to configure your network at boot time. You can
configure /etc/sysctl.conf (see: sysctl.conf(5)) or
introduce a script that is called when the interface is enabled. The first
option will be applied to all interfaces, whileas the second option allows you
to configure this on a per-interface basis.

An example of a /etc/sysctl.conf configuration that will secure
some network options at the kernel level is shown below. Notice the comment in
it, /etc/network/options might override some values if they
contradict those in this file when the /etc/init.d/networking is
run (which is later than procps on the startup sequence).

Notice that you can actually have per-interface scripts that will enable
different network options for different interfaces (if you have more than one),
just change the pre-up line to:

pre-up /etc/network/interface-secure $IFACE

And use a script which will only apply changes to a specific interface, not to
all of the interfaces available. Notice that some networking options can only
be enabled globally, however. A sample script is this one:

An alternative solution is to create an init.d script and have it
run on bootup (using update-rc.d to create the appropriate
rc.d links).

4.18.4 Configuring firewall features

In order to have firewall capabilities, either to protect the local system or
others behind it, the kernel needs to be compiled with firewall
capabilities. The standard Debian 2.2 kernel (Linux 2.2) provides the packet
filter ipchains firewall, Debian 3.0 standard kernel (Linux 2.4)
provides the stateful packet filter iptables (netfilter)
firewall.

In any case, it is pretty easy to use a kernel different from the one provided
by Debian. You can find pre-compiled kernels as packages you can easily
install in the Debian system. You can also download the kernel sources using
the kernel-source-X and build custom kernel packages
using make-kpkg from the kernel-package package.

4.18.5 Disabling weak-end hosts issues

Systems with more than one interface on different networks can have services
configured so that they will bind only to a given IP address. This usually
prevents access to services when requested through any other address. However,
this does not mean (although it is a common misconception) that the service is
bound to a given hardware address (interface card). [38]

This is not an ARP issue and it's not an RFC violation (it's called weak
end host in RFC1122, section
3.3.4.2). Remember, IP addresses have nothing to do with physical interfaces.

Along this text there will be many occasions in which it is shown how to
configure some services (sshd server, apache, printer service...) in order to
have them listening on any given address, the reader should take into account
that, without the fixes given here, the fix would not prevent accesses from
within the same (local) network. [41]

FIXME: Comments on Bugtraq indicate there is a Linux specific method to bind to
a given interface.

FIXME: Submit a bug against netbase so that the routing fix is standard
behavior in Debian?

4.18.6 Protecting against ARP attacks

When you don't trust the other boxes on your LAN (which should always be the
case, because it's the safest attitude) you should protect yourself from the
various existing ARP attacks.

As you know the ARP protocol is used to link IP addresses to MAC addresses (see
RFC826 for all
the details). Every time you send a packet to an IP address an ARP resolution
is done (first by looking into the local ARP cache then if the IP isn't present
in the cache by broadcasting an ARP query) to find the target's hardware
address. All the ARP attacks aim to fool your box into thinking that box B's
IP address is associated to the intruder's box's MAC address; Then every packet
that you want to send to the IP associated to box B will be send to the
intruder's box...

Those attacks (ARP cache poisoning, ARP spoofing...) allow the attacker to
sniff the traffic even on switched networks, to easily hijack connections, to
disconnect any host from the network... ARP attacks are powerful and simple to
implement, and several tools exists, such as arpspoof from the
dsniff package or arpoison.

However, there is always a solution:

Use a static ARP cache. You can set up "static" entries in your ARP
cache with:

arp -s host_name hdwr_addr

By setting static entries for each important host in your network you ensure
that nobody will create/modify a (fake) entry for these hosts (static entries
don't expire and can't be modified) and spoofed ARP replies will be ignored.

Detect suspicious ARP traffic. You can use arpwatch,
karpski or more general IDS that can also detect suspicious ARP
traffic (snort, prelude...).

Implement IP traffic filtering validating the MAC address.

4.19 Taking a snapshot of the system

Before putting the system into production system you could take a snapshot of
the whole system. This snapshot could be used in the event of a compromise
(see After the compromise (incident
response), Chapter 11). You should remake this upgrade whenever the system
is upgraded, especially if you upgrade to a new Debian release.

For this you can use a writable removable-media that can be set up read-only,
this could be a floppy disk (read protected after use), a CD on a CD-ROM unit
(you could use a rewritable CD-ROM so you could even keep backups of md5sums in
different dates), or a USB disk or MMC card (if your system can access those
and they can be write protected).

Note that the md5sum binary (and sha1sum, if available) is placed on the floppy
drive so it can be used later on to check the binaries of the system (just in
case it gets trojaned). However, if you want to make sure that you are running
a legitimate binary, you might want to either compile a static copy of the
md5sum binary and use that one (to prevent a trojaned libc library from
interfering with the binary) or to use the snapshot of md5sums only from a
clean environment such as a rescue CD-ROM or a Live-CD (to prevent a trojaned
kernel from interfering). I cannot stress this enough: if you are on a
compromised system you cannot trust its output, see After the compromise (incident response),
Chapter 11.

The snapshot does not include the files under /var/lib/dpkg/info
which includes the MD5 hashes of installed packages (in files ending with
.md5sums). You could copy this information along too, however you
should notice:

the md5sums files include the md5sum of all files provided by the Debian
packages, not just system binaries. As a consequence, that database is bigger
(5 Mb versus 600 Kb in a Debian GNU/Linux system with a graphical system and
around 2.5 Gb of software installed) and will not fit in small removable media
(like a single floppy disk, but would probably fit in a removable USB memory).

not all Debian packages provide md5sums for the files installed since it is not
(currently) mandated policy. Notice, however, that you can generate the
md5sums for all packages using debsums after you've finished the
system installation:

# debsums --generate=missing,keep

Once the snapshot is done you should make sure to set the medium read-only.
You can then store it for backup or place it in the drive and use it to drive a
cron check nightly comparing the original md5sums against those on
the snapshot.

4.20 Other recommendations

4.20.1 Do not use software depending on svgalib

SVGAlib is very nice for console lovers like me, but in the past it has been
proven several times that it is very insecure. Exploits against
zgv were released, and it was simple to become root. Try to
prevent using SVGAlib programs wherever possible.