This guide was originally written for the Cybercenturion X competition in which my team came 3rd. Since that competition has now ended this now serves as a guide for some basic hardening of Linux systems, especially debian based ones.
Below steps are in rough order, see below sections for explanation on how to perform each step
IMPORTANT NOTE: All commands should be run as the root user, that means either putting sudo
in front of every command or by logging in as root using sudo -i
(preferred option)
Update the sources
apt update
Install wget and nano
apt install wget nano
Add the webmin key
wget -q -O- http://www.webmin.com/jcameron-key.asc | sudo apt-key add
Edit the sources file with the following command
sudo nano /etc/apt/sources.list
Now using the arrow keys to scroll to the end of the file, add the following line
deb http://download.webmin.com/download/repository sarge contrib
Press Ctrl-X
followed by pressing y
then enter
to save and exit the file
Now update the sources again and install webmin
apt update
apt install webmin
Now navigate to http://localhost:10000 in firefox. Click advanced on the window that appears and click accept the risk and continue. Log in with the admin user and password. You are now in webmin!
apt install git net-tools
Clone the script repository
git clone https://github.com/kenneth-karlsson/Cisecurity
Change directory to the script directory
cd Cisecurity
Allow the script to be executed
chmod +x *
Run the script once to generate the config file, run the script most relevant to your distribution (EG: Ivan run cisdebian.sh, dylan run cis2004.sh)
./cisdebian.sh
Now edit the config file using nano
nano .cisrc
Set the following parameters to yes, you may need to set more depending on the Cybercenturion readme file
SX11="Y"
SSSHD="Y"
Maybe also change the sugroup
to something else
Now press Ctrl-X
followed by pressing y
then enter
to save and exit the file. Make sure you have at least one other root shell open before running the script below
./cisdebian.sh -u
Update and upgrade everything
apt update
apt upgrade
Install various other useful software
apt install ufw gufw lynis auditd libpam-pwquality unhide fail2ban clamav software-properties-common apt-transport-https wget git chkrootkit rkhunter apparmor apparmor-profiles unattended-upgrades software-properties-gtk
Try enabling automatic updates from the GUI
software-properties-gtk
Enable automatic updates service
sudo systemctl enable unattended-upgrades
sudo systemctl start unattended-upgrades
Edit file to setup unattended updates, then uncomment Debian security etc
nano /etc/apt/apt.conf.d/50unattended-upgrades
Now edit the apt file to enable the updates
nano /etc/apt/apt.conf.d/20auto-upgrades
Add the following to this file
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "7";
Install the firewall
apt install ufw
Setup the firewall with reasonable requirements like this, you may need to allow additional stuff if it says so in the readme file
ufw default deny incoming
ufw allow ssh
ufw allow 10000
ufw enable
ufw status
Common Password
nano /etc/pam.d/common-password
After pam_unix.so
sha512 obscure use_authtok try_first_pass minlen=10 remeber=5 obscure rounds=5
After pam_pwquailty.so
retry=3 minlen=10 lcredit=-1 ucredit=-1 ocredit=-1 dcredit=-1 reject_username difok=3 enforce_for_root
Common Auth
nano /etc/pam.d/common-auth
Add this to bottom of ifile
auth required pam_faillock.so preauth deny=3 onerr=fail unlock_time=1800
auth required pam_faillock.so authfail deny=3 onerr=fail unlock_time=1800
Login.defs
PASS_MAX_DAYS 30
PASS_MIN_DAYS 2
PASS_MIN_LEN 10
PASS_WARN_AGE 7
ENCRYPT_METHOD SHA512
LOGIN_RETRIES 3
LOGIN_TIMEOUT 60
SYS_UID_MIN 100
SYS_UID_MAX 499
SYS_GID_MIN 100
SYS_GID_MAX 499
UID_MIN 1000
UID_MAX 60000
GID_MIN 1000
GID_MAX 60000
USERGROUPS_ENAB yes
UMASK 077
Find audio/video files. You may need to replace /
with /home
or /usr/share
if there is lots of output
find /home -type f \( -name "*.mp3" -o -name "*.wav" -o -name "*.flac" -o -name "*.aac" -o -name "*.ogg" -o -name "*.wma" -o -name "*.m4a" -o -name "*.mp4" -o -name "*.avi" -o -name "*.mkv" -o -name "*.mov" -o -name "*.wmv" -o -name "*.webm" -o -name "*.3gp" -o -name "*.flv" -o -name "*.m4v" -o -name "*.asf" -o -name "*.ts" -o -name "*.ogg" \)
Find image files
find /home -type f \( -name "*.jpg" -o -name "*.jpeg" -o -name "*.png" -o -name "*.gif" -o -name "*.bmp" -o -name "*.tiff" -o -name "*.tif" -o -name "*.webp" -o -name "*.raw" -o -name "*.svg" \)
Look in Webmin for cron jobs. Once that's done check who is allowed and not allowed to make cron jobs
cat /etc/cron.d/cron.deny
nano /etc/cron.d/cron.allow
Make sure the correct people own the file
#add root to this file
chown root:root cron.allow
chmod 644 cron.allow
Check the output of the command below:
ls -la /etc/init/
ls -la /etc/init.d/
ls -la /etc/rc*.d
Disable popup/ enable security features in Firefox
Run the below and check nothing blows up
#!/bin/bash
sysctl -w net.ipv4.conf.default.secure_redirects=0
sysctl -w net.ipv4.conf.all.secure_redirects=0
sysctl -w net.ipv4.conf.default.accept_redirects=0
sysctl -w net.ipv4.conf.all.accept_redirects=0
sysctl -w net.ipv4.conf.default.send_redirects=0
sysctl -w net.ipv4.conf.all.send_redirects=0
sysctl -w net.ipv4.ip_forward=0
sysctl -w net.ipv4.tcp_syncookies=1
sysctl -w kernel.randomize_va_space=2
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1
sysctl -w net.ipv4.icmp_ignore_bogus_error_responses=1
sysctl -w net.ipv4.icmp_ratelimit=100
sysctl -w kernel.kptr_restrict=1
sysctl -w kernel.dmesg_restrict=1
sysctl -w fs.protected_hardlinks=1
sysctl -w fs.protected_symlinks=1
sysctl -w net.ipv4.icmp_echo_ignore_all=1
sysctl -w net.ipv4.tcp_max_syn_backlog=1280
sysctl -w net.ipv6.conf.all.disable_ipv6=1
sysctl -w net.ipv6.conf.default.disable_ipv6=1
sysctl -w net.ipv6.conf.all.accept_ra=0
sysctl -w net.ipv6.conf.default.accept_ra=0
sysctl -w net.ipv6.conf.all.disable_ipv6 = 1
sysctl -w net.ipv6.conf.default.disable_ipv6 = 1
sysctl -w net.ipv6.conf.lo.disable_ipv6 = 1
sysctl -w net.ipv4.conf.all.rp_filter=1
sysctl -w net.ipv4.conf.default.rp_filter=1
sysctl -w net.ipv4.conf.all.accept_source_route=0
sysctl -w net.ipv4.conf.default.accept_source_route=0
sysctl -w net.ipv4.tcp_synack_retries=2
sysctl -w net.ipv4.tcp_syn_retries=5
sysctl -w net.ipv4.conf.all.log_martians=1
sysctl -w vm.panic_on_oom=1
sysctl -w kernel.panic=10
sysctl -p
If that is all fine, then open this file
nano /etc/sysctl.conf
Add this to the file
net.ipv4.conf.default.secure_redirects=0
net.ipv4.conf.all.secure_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.send_redirects=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.ip_forward=0
net.ipv4.tcp_syncookies=1
kernel.randomize_va_space=2
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.icmp_ignore_bogus_error_responses=1
net.ipv4.icmp_ratelimit=100
kernel.kptr_restrict=1
kernel.dmesg_restrict=1
fs.protected_hardlinks=1
fs.protected_symlinks=1
net.ipv4.icmp_echo_ignore_all=1
net.ipv4.tcp_max_syn_backlog=1280
net.ipv6.conf.all.disable_ipv6=1
net.ipv6.conf.default.disable_ipv6=1
net.ipv6.conf.all.accept_ra=0
net.ipv6.conf.default.accept_ra=0
net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.default.rp_filter=1
net.ipv4.conf.all.accept_source_route=0
net.ipv4.conf.default.accept_source_route=0
net.ipv4.tcp_synack_retries=2
net.ipv4.tcp_syn_retries=5
net.ipv4.conf.all.log_martians=1
vm.panic_on_oom=1
kernel.panic=10
Lock root user
passwd -l root
Check this directory for things
ls /etc/sudoers.d
Check for users with UID 0, should be only one user shown
awk -F: '$3 == 0 { print "Username: " $1, "UID: " $3 }' /etc/passwd
Check for users with empty password (copy and paste this all in one go)
#!/bin/bash
empty_password_users=()
# Read the /etc/shadow file and check for empty passwords
while IFS=: read -r username password; do
if [ -z "$password" ] || [ "$password" = "!" ] || [ "$password" = "*" ]; then
empty_password_users+=("$username")
fi
done < /etc/shadow
# Check if there are any users with empty passwords
if [ ${#empty_password_users[@]} -eq 0 ]; then
echo "No users have empty passwords."
else
echo "Users with empty passwords:"
for user in "${empty_password_users[@]}"; do
echo "- $user"
done
fi
Look for hidden users, most of these will be system users who are fine
#!/bin/bash
# Define the minimum UID to consider as hidden (e.g., 1000)
MIN_UID=1000
# Iterate through /etc/passwd to find hidden users
while IFS=: read -r username password uid rest; do
if [ "$uid" -lt "$MIN_UID" ]; then
echo "Hidden User: $username (UID: $uid)"
fi
done < /etc/passwd
NOTE: You will need to run the long install command in the section Clamav Will take a long time
freshclam
clamscan -r /
Chkrootkit
chkrootkit -q
Rkhunter First modify the config file
gedit /etc/rkhunter.conf
Add the following to the bottom
MIRRORS_MODE=0
UPDATE_MIRRORS=1
WEB_CMD=""
Now run the check
rkhunter --update
rkhunter --propupd
rkhunter -c --enable all --disable none
Open the config file
nano /etc/ssh/sshd_config
Add/change this stuff
PermitEmptyPasswords no
LoginGraceTime 20
AllowTcpForwarding no
AllowAgentForwarding no
X11Forwarding no
UsePAM yes
MACs hmac-sha2-256,hmac-sha2-512
Ciphers aes256-ctr,aes192-ctr,aes128-ctr
Protocol 2
ClientAliveInterval 300
ClientAliveCountMax 0
MaxAuthTries 3
IgnoreRhosts yes
StrictModes yes
PermitEmptyPasswords no
MaxStartups 2
PubkeyAuthentication yes
PermitRootLogin no
Port 2222
PasswordAuthentication no
HostBasedAuthentication no
PubkeyAuthentication yes
LogLevel VERBOSE
Disable systemd logging
systemctl stop systemd-journald.service
systemctl disable systemd-journald.service
systemctl mask systemd-journald.service
systemctl stop rsyslog.service
systemctl disable rsyslog.service
systemctl mask rsyslog.service
Check for running processes
ps axk start_time -o start_time,pid,user,cmd
Check sudoers file for NOPASSWD etc
visudo
Check all users have /bin/bash as login shell
gedit /etc/passwd
Check for backdoors
ss -an4
netstat -plunet
netstat -nwput
pgrep -a nc
Check PATH variable and environment stuff
echo $PATH
cat /etc/profile
cat /etc/environment
Check root directory for anything suspicious
ls /root/
Miscellaneous file inspection
nano /etc/resolv.conf
nano /etc/hosts
nano /etc/hosts.allow
nano /etc/hosts.deny
nano /etc/apt/sources.list
Check for world readable files
find / -type f -perm 777 2>/dev/null
Check for anything in home directories
ls /home/*/.bashrc
ls /home/*/.*
Check the skeleton directory
ls /etc/skel