Slackware post install

Michał ‘mina86’ Nazarewicz | 25 stycznia 2014

Same as my previous article written in Polish, this text will describe some steps I take after installing Slackware Linux. I try to strike a balance between performance, security and usability, but not everything written here may work for everyone. You have been warned.

New user

The very first step is creation of a new user account. Since I have recently discovered benefits of having a group for each user I now do it with the following commands:

sed -i 's/^ENCRYPT_METHOD.*/ENCRYPT_METHOD SHA512/' \
    /etc/login.defs
useradd -U -G users,root,wheel -m username
passwd username

root access

Having the user in root and wheel groups makes it easy to restrict access to su command:

echo 'ALL:ALL EXCEPT GROUP root:DENY' >>/etc/suauth
sed -i 's/^SU_WHEEL_ONLY.*/SU_WHEEL_ONLY yes/' /etc/login.defs
chown root:root /bin/su
chmod 4750 /bin/su
echo chown root:root /bin/su >>/etc/rc.d/rc.local
echo chmod 4750 /bin/su >>/etc/rc.d/rc.local

It prevents any users not in root and wheel groups from using su. Both on command’s configuration level and file system level. Modifying /etc/rc.d/rc.local file makes sure that file system permissions will be preserved even if shadow package is upgraded or reinstalled.

In case of sudo the file to edit is /etc/sudoers and executable to protect is /bin/sudo. Since I do not use sudo on Slackware, exactly what needs to be done is left as an exercises for the reader.

Local login restrictions

Another thing to block is letting root log in directly to the system. I recommend that change since having a single path of gaining super user privileges (namely via first logging in a user account and then switching to root via su) is more secure and easier to audit.

Login restrictions are set in a /etc/login.access file and to give only a single user access just run:

echo '-:ALL EXCEPT username:ALL' >>/etc/login.access

It denies access to all users except username when logging from any host. Changing username to users would let all users in group users to log in. For greater control, creating a new group, say ttylogin, is also an option.

Before proceeding, it is advisable to verify (on another TTY) whether logging in to the machine still works.

Remote login restrictions

With local logins taken care of, SSH is all that is left. Its configuration is stored in /etc/ssh/sshd_config file. To limit who can ssh in and increase security of SSH the following options need to be set:

Protocol 2

PermitRootLogin no
DenyUsers root
AllowUsers username

AllowTcpForwarding no
X11Forwarding no

# Allow username use X11 and port forwarding
Match User username
	X11Forwarding yes
	AllowTcpForwarding yes

Similarly to local login, one might use AllowGroups users instead of AllowUsers to let all users in, or create additional group, say sshlogin, with users who are granted the privilege of accessing the machine remotely. The Match directive can also be replaced with Match Group users.

Another thing to consider is changing listening port to a non-standard one. Changing Port option to, say, 1000, will achieve that result. It should keep log files slightly cleaner by avoiding some brute force attacks, but it is not a bullet proof solution of course.

X11 security

/tmp/.ICE-unix and /tmp/.X11-unix directories are used by X server but they do not need to be writable only by users who are supposed to have access to X window system. The directories are initialised in /etc/rc.d/rc.S file in the following way:

  mkdir -p /tmp/.ICE-unix
  chmod 1777 /tmp/.ICE-unix

with the same code for the other directory. To achieve greater security, this should be changed to:

  mkdir -p /tmp/.ICE-unix
  chgrp users /tmp/.ICE-unix
  chmod 1730 /tmp/.ICE-unix

with analogous change for .X11-unix directory.

Furthermore, to prevent X server from ever listening on network interfaces, the following changes should be applied:

  • in /usr/X11R6/bin/startx, set defaultserverargs="-nolisten tcp"
  • in /etc/X11/xdm/Xservers, add :0 local /usr/X11R6/bin/X -nolisten tcp
  • in /etc/rc.d/rc.4, add exec /usr/X11R6/bin/xdm -nodaemon -udpPort 0 and
  • in /etc/X11/fs/config, set use-syslog = yes and no-listen = tcp

NTP

I usually do not set up NTP daemon to run, but still want to have my clock synchronised, so instead I am using ntpdate to query for the time every hour. This can be set up by invoking:

cat >/etc/cron.hourly/ntpsync <<EOF
#!/bin/sh
# Change to two-letter code of the country the machine is in.
country=us
exec /usr/sbin/ntpdate -u -s 0.$$country.pool.ntp.org \
	1.$$country.pool.ntp.org 2.$$country.pool.ntp.org
EOF
chmod 755 /etc/cron.hourly/ntpsync
/etc/cron.hourly/ntpsync

Logging

In /etc/rc.d/rc.syslog modify syslogd and klogd invocations:

    /usr/sbin/syslogd -m 0
    /usr/sbin/klogd -c 3 -x -p

Adding -m 0 disables the -- MARK -- messages (which are arguably useful but I find them noisy) and -p enables klogd’s paranoia mode.

Furthermore, to be able to see log messages on TTY 12 run the following:

echo '*.* -/dev/tty12' >>/etc/syslog.conf
kill -SIGHUP $(cat /var/run/syslogd.pid)

With one more addition to /etc/rc.d/rc.local the 12th TTY can also include a convenient clock:

## Clock on TTY12
(
	renice -n 20 $$
	cd /
	while sleep 1; do
		printf %s\\r "$(LANG=C date '+%b %e %H:%M:%S')"
	done >>/dev/tty12 2>/dev/null </dev/null &
) &

Another thing to add to /etc/rc.d/rc.local is:

/usr/sbin/icmpinfo -vvv -s -l

Which will log any ICMP packets sent to the host. This may be noisy especially for hosts that are connected directly to the Internet, i.e. without a router or a firewall which blocks most traffic.

Log files are rotated with logrotate whose configuration is saved in /etc/logrotate.conf. To increase amount of logs kept without increasing disk usage much, it may be good idea to change rotate option to 12 (or so) and uncomment compress option.

Other network security

To prevent, or at least limit, sniffing on local network, it’s beneficial to set up a static hardware addresses for the default gateway and some most important hosts the machine is connecting to. For this to work those hosts need to have a static IP as well of course.

arp -n |awk 'FNR > 1 && NF == 5 {print $3, $1}' >>/etc/ethers
# Remove entries that should not have static entries
nano /etc/ethers
arp -f
# Make sure everything still works before proceeding
echo 'arf -f' >>/etc/rc.d/rc.local

Block FTP access to everyone except for a single user:

cut -d: -f1 /etc/passwd |\
    grep -v '^username$' >>/etc/ftpusers

Or just block it to everyone if FTP is not used with:

cut -d: -f1 /etc/passwd >>/etc/ftpusers

In /etc/inetd.conf comment out auth which turn all lines in that files to comments.

Finally, configure TCP Wrapper to prevent any services using them from accepting connections:

echo 'sshd: ALL: ALLOW' >>/etc/hosts.allow
echo 'ALL: ALL' >>/etc/hosts.deny

Other miscellaneous security

Regular user need no access to many of the system-wide configuration files. That access can be revoked with a few simple commands:

chmod -R go-rwx /etc/cron.*
chmod -R go-rwx /etc/rc.d
chmod -R o-rwx /var/log

Furthermore, users don’t need to be able to list contents of /tmp directory, thus it’s safe to change /etc/rc.d/rc.M file by modifying the lines setting permissions for /tmp and /var/tmp directories to:

chmod 1733 /tmp /var/tmp

Filesystems

All the file systems mounted during the boot on the system are configured in the /etc/fstab file. There are a few options that’s worth adding:

noatime
Disables access time tracking which speeds things up by reducing number of IO operations. Even if it’s desired to have accurate access time, it’s best to add relatime option.
nodev
Disables device files. Should be set up on all file systems except for / (or /dev if it’s on separate partition).
noexec
Disables executable bit. The limitation is relatively easy to work around, but I still add it to /boot and /var.
nosuid
Disables set-UID bit. Should be set on all file systems except for /, /usr and /opt (if any of those are on separate partitions).

LILO

Slackware comes with a splash screen used in LILO and a 30-second prompt timeout. For me both are just annoyances. To improve the situation, note down value of the boot option as well as root options for all the images, run chmod 600 /etc/lilo.conf, and finally edit it to have the following content:

# Enter a password only when a boot time parameter is used
restricted
# Enter a password with every boot
# mandatory
# Use "lilo -p" to set up password after modifying lilo.conf
password = ""

append = "vt.default_utf8=1"

compact
lba32

install = text
vga = normal
prompt
single-key
timeout = 5

change-rules
	reset

boot = /dev/sda  # Replace with whatever was in old lilo.conf

image = /boot/vmlinuz
	root = /dev/sda1  # Ditto
	label = l
	read-only

image = /boot/vmlinuz
	root = /dev/sda1  # Ditto
	label = s
	read-only
	append = "single"
	# Require password for single boot
	mandatory

# Possibly some “other” entries may follow.  If they do,
# labels for all of them have to be changed to one-letter long.

With those changes a single-key text prompt will be used with half a second timeout. This requires a timely pressing of a desired key in order to boot non-default system.

The other thing those changes do is require password when “single” mode is enabled. Password can be enabled for all systems by choosing mandatory as opposed to restricted.

Miscellaneous customisations

Back in /etc/login.defs file, some eye-candy can be achieved by changing the following options:

MAIL_CHECK_ENAB no
LOGIN_STRING    "%s's password:"
ISSUE_FILE      /etc/issue
MOTD_FILE       /etc/motd

and then execute as root:

>/etc/issue printf '
 _____ _____ _____                              _____ _____ _____ _____
|   | |   __|  _  | ... %shemtrails %sontrol ... |   __|     |  |  |     |
| | | |__   |     | Regional %sonitoring %system |  |  |   --|     |  |  |
|_|___|_____|__|__| ....... Node %s/%02d ....... |_____|_____|__|__|__  _|
                                                       Scarborough  |__|

' C C M S "$(tr -dc a-z </dev/urandom |head -c2)" "$((RANDOM % 100))"

Any other ASCII art will do, and with ANSI escape codes even colours can be added!

While on the topic of colours, I find blue to be too dark on my terminals (since I prefer black backgrounds), so the next thing I do is change colour of directories to white, by editing /etc/DIR_COLORS:

DIR 01;37      # directory

Since I like a fast repeat rate of my keyboard:

echo 'kbdrate -r 50 -d 250' >>/etc/rc.d/rc.local

And since I reboot and halt the machine from command line without switching to root account, I also do this:

cmds='/sbin/shutdown /sbin/halt /sbin/reboot /sbin/poweroff'
echo "chown root:root $cmds" >>/etc/rc.d/rc.local
echo "chmod 4750 $cmds" >>/etc/rc.d/rc.local

Final clean ups

Depending on the way Slackware was installed, it may contain many packages that aren’t used. Those should be removed since the fewer packages system has, the fewer bugs it contains. For instance, I haven’t used finger or talk for ages, and really don’t see a need for those as well as some other packages to be installed:

cd /var/log/packages
removepkg biff+comsat bsd-finger netkit-* netwrite pidentd
removepkg inetd ytalk uucp NetworkManager trn yptools
removepkg slrn sendmail-* procmail

Using grep all series of packages can be removed. For example, if X packages were installed by mistake (for example because full installation has been chosen), but the machine will not run X window system, this will remove all packages from x, xap, kde and kdei series:

cd /var/log/packages
removepkg $(grep -l \
    -e 'PACKAGE LOCATION:.*/slackware/xap/' \
    -e 'PACKAGE LOCATION:.*/slackware/x/' \
    -e 'PACKAGE LOCATION:.*/slackware/kde/' \
    -e 'PACKAGE LOCATION:.*/slackware/kdei/' \
    *)

Choice of which packages should be removed and which should be kept needs to be made individually. What may help is this command:

cd /var/log/packages
grep 'PACKAGE LOCATION.*/slackware/.*/' * | \
    sed 's~^\([^:]*\):.*/slackware/\([^/]*\)/.*~\2 \1~' | \
    sort

It prints all the packages that have been installed from Slackware image with series they came from. Packages in a and l series should be handled with care, but for other series my motto is “if in doubt, removepkg”. This is especially true for n series which includes many servers.

Besides packages, Slackware comes with a bunch of user accounts and groups that aren’t really used for anything. First make sure that those are really unused by invoking:

find / -user adm -o -user games -o -user gdm -o -user lp \
    -o -user news -o -user operator -o -user pop -o -user rpc \
    -o -user uucp -o -group adm -o -group lp -o -group news \
    -o -group pop -o -group uucp -ls

If that command returns no files (errors about any files in /proc can be ignored) it should then be safe to run the following commands to remove unnecessary users and groups:

for USR in adm gdm lp news operator pop rpc uucp halt \
                shutdown sync; do userdel "$USR"; done
for GRP in adm news pop; do groupdel "$GRP"; done