Slackware post install
Posted by Michał ‘mina86’ Nazarewicz on 25th of January 2014 | (cite)
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 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 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
, setdefaultserverargs="-nolisten tcp"
- in
/etc/X11/xdm/Xservers
, add:0 local /usr/X11R6/bin/X -nolisten tcp
- in
/etc/rc.d/rc.4
, addexec /usr/X11R6/bin/xdm -nodaemon -udpPort 0
and - in
/etc/X11/fs/config
, setuse-syslog = yes
andno-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 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
File systems
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 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 don’t see a need for those nor various other programs:
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 used for anything. First make sure that those are actually 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