Icon Hardening Arch Linux (HAL)

From Wiki³

Icon Introduction

This is geared at providing a checklists one can walk through after setting up a new Arch Linux installation that has an open connection to the internet. Whether it is a server or just a machine at home that you have ports open on; some if not all of this information might be useful to you.

IconWARNING: While I have administered BSD and Linux machines for many years now, I am not a security expert!

Icon Legacy Services

If at all possible disable all legacy services, there are just too many vulnerabilities in these services. They include but are not limited to: NIS, RSH client/server, talk client/server, telnet, TFTP, XINETD, CHARGEN, Daytime, echo, discard and time.

There are also a few non-legacy services it is recommended to stay away from: X Window system, Avahi Print Server, DHCP server, LDAP, NFS/RPC, DNS server, FTP server, Samba and SNMP.

While some of these services might be required such as DNS, it is highly recommended if at all possible to run these on a private secluded machine all by itself or inside some sort of container. This way if that host were to get compromised there would not be any sensitive data aside from the DNS records which are already publicly accessible. Realistically one should containerize all daemons that are publicly accessible.

Icon Service Containerization

If you would like to isolate services (DNS, WWW, SQL, etc.) by installing them inside of separate virtual machines, see the article on KVM.

Icon See also: KVM on Arch Linux 

Icon Root Restrictions

The root user, or super-user account, is the command-line God. It is all powerful and has no allegiances but has the one downfall of doing whatever it is told. To this end it does precisely what it is told, even if that might spell it's own doom and destruction.

IconNot actually meant in a religious way, more as a scare tactic in to taking it seriously.

Before continuing verify that your user account, not root, has proper access to sudo (non-restricted with password prompt).

If not, one can simple install sudo. First su to root or login as root via KVM.

# pikaur -S sudo

And then set the privileges correctly.

# visudo

%wheel ALL=(ALL) ALL

For the final house-keeping, add a group for shm and make sure the user is apart of the wheel and shm groups.

# groupadd shm
# gpasswd -a username wheel
# gpasswd -a username wheel

Provided everything works, log back into the regular user account to begin restricting the root account.

Icon Editor

Hard-code the EDITOR shell variable for the root account.
Putting this in bashrc versus bash_profile makes sure it is used with non-interactive shells in addition to login shells. In addition add a default editor for sudo.

# echo -e "EDITOR=/usr/bin/rvim\nSUDO_EDITOR=/usr/bin/rvim" | sudo tee --append /root/.bashrc
IconIf the root account already has a bashrc file setup, make sure it does not already include an EDITOR setting.

Then hard-code the editor used for visudo to prevent users from launching it with a prefix EDITOR=editor visudo.

# sudo visudo

Add the following line near the top.

Defaults editor=/usr/bin/rvim

ArchWiki: "Running a text editor as root can be a security vulnerability as many editors can run arbitrary shell commands or affect files other than the one you intend to edit."
From now on since it is now setup, use sudoedit in order to edit files as the root account instead of using sudo vim file.

This actually has a two-fold response. First it is added security as the file is edited as a copy in user-space and then copied back over the original with sudo once the editor is closed. Second, because the editor then runs in user-space it will use all of the current logged in users settings and themes for said editor along with using their specified editor of choice.

Icon Wheel only Superuser

In order to restrict access to the su command to only the wheel group, edit both /etc/pam.d/su and /etc/pam.d/su-l and uncomment the following.

# Uncomment the following line to require a user to be in the "wheel" group.
auth required pam_wheel.so use_uid

Icon Cron

If cron is going to be used, it is a good idea to set it up properly.

First install cron.

# pikaur -S cronie

Restricting access to cron is as simple as creating a /etc/cron.allow and inserting only the names of users you want to allow access to cron. Every other user on the system will be denied cron access.

# sudoedit /etc/cron.allow


Enable and start the cronie service.

# sudo systemctl enable cronie
# sudo systemctl start cronie

Finally set proper permissions to all cron files.

# sudo chmod -R go-rwx /etc/cron* /etc/anacrontab

Icon File Permissions

The default file permissions, umask 0022, are not setup for security. The NSA themselves recommend a umask of 0077 for maximum security, which makes new files not readable by users other than the owner.

# sudoedit /etc/profile

Find the line that marks umask 022 and change it to:

umask 077

Then make sure the user directory is already setup with the proper permissions, we can also add the boot directory and the firewall configs if present.

# sudo chmod -R go-rwx /root /home/kyau /boot

Icon Mount Points

Icon tmpfs

Despite the very secure defaults that Arch uses there is still one more thing we can do to tmpfs. Arch already sets nodev to block the creation of special devices that could potential have direct world-writable access to hardware and nosuid to prevent setuid binaries and root escalation issues. However, adding noexec to prevent all execution will help prevent basic script attacks as well. Finally adding a binding mount for /var/tmp simplifies the security.
Add the following lines into the fstab for the /tmp, /var/tmp, /dev/shm mount points.

filename: /etc/fstab
tmpfs /tmp tmpfs rw,noatime,nodev,nosuid,mode=1777 0 0
tmpfs /dev/shm tmpfs rw,nodev,nosuid,noexec,size=1024M,mode=1770,uid=root,gid=shm 0 0
/tmp /var/tmp none rw,noatime,nodev,noexec,nosuid,bind 0 0

Icon Hide Processes

Hiding all other users' processes can make it very difficult for an attacker to assess a system. Adding a line for proc in the fstab file with the right options can limit all users' ability to view processes aside from their own. An exception can also be made for users belonging to the wheel group.

filename: /etc/fstab
proc /proc proc nosuid,nodev,noexec,hidepid=2,gid=wheel 0 0

Icon Sysctl

Being honest, Arch Linux comes fairly secure out of the box. Things like source routed packets, packet forwarding, multicast packet forwarding and ICMP redirection all default to disabled. Alas, improvements can still be made.

Sysctl can be used to change kernel parameters at runtime by adding to the file /etc/sysctl.d/50-security.conf. There are several improvements that can be made here security wise. Not all of these will be optimal in every use case scenario, but none of them will have harmful effects on your system unless you are running it as a router.

Icon Secure ICMP Routing Redirects

If the source gateway is compromised then an user can update the routing table using Secure ICMP redirects. This can potentially lead to remote packet capture.
This can be disabled.


Icon Send Redirects

An unauthorized user can use a compromised host to send ICMP redirects packets to another routing device to corrupt its routing. This functionality can be disabled.



An attacker can start a DDoS attack at the server by flooding it with SYN packets without initializing three way handshake. Setting this will helps protect against SYN flood attacks, however it only kicks in when net.ipv4.tcp_max_syn_backlog is reached.


Icon TCP Time-wait

To protect against TCP time-wait assassination hazards drop all RST packets for sockets in the time-wait state (not widely supported outside of Linux, but conforms to RFC).


Icon Restrict Kernel Log Access

Kernel logs can contain sensitive system information that you might not want everyone on your system to have access to. This will restrict access to only the root account.


Icon Restrict Kernel Pointers Access

Allowing all users to view kernel pointer addresses can make it easier for kernel exploits to occur. Again restrict this to only the root account.


Icon OpenSSH

Hardening SSH is a requirement on any machine connected to the internet with SSH running. It is one of the most common services on the internet and also one of the most common ports attackers go for. The default openssh config is subpar at best, a lot can be done to fix it up. All of the following changes are done in the /etc/ssh/sshd_config file.

Icon Listening Port

One of the easiest ways to improve security with SSH is to change the port it listens on. Sometimes this is not an option (if a large number of individuals require access to the server for example), but if you can this option is highly recommended. If possible, choose a port greater than 1024.

filename: /usr/ssh/sshd_config
Port 2222

Icon Key Exchange

The key exchange ensures that the server and the client shares a secret no one else knows. OpenSSH supports 8 key exchange protocols, the two chosen here are the only ones left given current security risks.[4]

KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256

Regenerate the prime numbers used for SSH.

filename: /etc/ssh/sshd_config
# sudo ssh-keygen -G /etc/ssh/moduli.all -b 4096
# sudo ssh-keygen -T /etc/ssh/moduli.safe -f /etc/ssh/moduli.all
# sudo mv /etc/ssh/moduli.safe /etc/ssh/moduli
# sudo rm /etc/ssh/moduli.all
IconThis is going to take a while, feel free to continue while it is running

Icon Authentication

Authentication makes sure that the secret that the server and the client shared during key exchange is only shared with each other and no one else. For authentication, only protocol 2 should be used, as protocol 1 presents security risks. A large RSA key and an Ed25519 key are recommended for authentication.

filename: /etc/ssh/sshd_config
Protocol 2
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key

This also requires the host keys to be regenerated.

# cd /etc/ssh
# sudo rm ssh_host_*key*
# sudo ssh-keygen -t ed25519 -f ssh_host_ed25519_key -N "" < /dev/null
# sudo ssh-keygen -t rsa -b 4096 -f ssh_host_rsa_key -N "" < /dev/null
IconWARNING: After doing this, upon connecting to SSH it will prompt you to accept a new fingerprint.
If access is denied due to this, then delete the fingerprint manually from ~/.ssh/known_hosts

Client authentication via password is susceptible to brute force attacks and should be disabled the moment you have public keys applied and activated in the config. Using public keys instead of password auth means the login grace time can also be effectively disabled.

filename: /etc/ssh/sshd_config
PasswordAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
LoginGraceTime 20
IconSetting LoginGraceTime to a lower value such as 1 is recommended if you are using an ssh key agent.

Public keys can be generated with the following commands.

# ssh-keygen -t ed25519 -o -a 100
# ssh-keygen -t rsa -b 4096 -o -a 100

These keys can be deployed to remote machines with ssh-copy-id.

Despite public keys being very secure, SSH access should also be limited. For this we can create a group specific to allow users SSH access.

filename: /etc/ssh/sshd_config
AllowGroups ssh

Don't forget to create the group and add your user.

# sudo groupadd ssh
# sudo gpasswd -a kyau ssh

Icon Symmetric Ciphers

The symmetric ciphers are used to encrypt data that goes across the connection after key exchange and authentication have taken place. Taking into account security of the cipher algorithm, key size, block size and cipher mode the following ciphers are recommended.

filename: /etc/ssh/sshd_config
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr

Icon Message Authentication Codes

"Encryption provides confidentiality, message authentication code provides integrity. We need both."[4] Taking into account security of the hash algorithm, encrypt-then-mac, tag size and key size the following MACs are recommended.

filename: /etc/ssh/sshd_config
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com

Icon OpenSSH Client Config

Replicating these changes in the global user config is also a good idea, that way your connections are the same on all your machines and you will not be locked out due to conflicting algorithms.

filename: /etc/ssh/ssh_config
# OpenSSH Client Config

Host *
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
# comment this if you need password authentication
PasswordAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
UseRoaming no
HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,ssh-rsa
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com

Copy over your newly created SSH keys.

# ssh-copy-id -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no -i id_ed25519 kyau@neutron.kyau.net

Keep an active connection to SSH, in-case something goes wrong, and restart the daemon.

# sudo systemctl restart sshd

SSH should now be setup properly with it prompting for the SSH key password on login with 20 seconds to enter the password or login fails.

IconIf issues arise, stop the service and run the daemon manually with debugging enabled sudo /usr/sbin/sshd -ddd

Icon CPU

Typically for servers the CPU should function in performance mode with a low perf bias. This will allow the CPU to respond as fast as possible and give full power when necessary.
Install cpupower to manage this.

# pikaur -S cpupower

Edit the default configuration.

filename: /etc/default/cpupower

Then enable and start the service.

# sudo systemctl enable cpupower
# sudo systemctl start cpupower

Changes should then be verified.

# sudo cpupower frequency-info
# sudo cpupower info

Icon Firewall

Some believe nftables will eventually replace iptables as the defacto standard, while this is unclear at this time it is not a bad alternative.[1]

# pikaur -S nftables

Then create a basic firewall allowing only SSH and Web traffic, limiting SSH and echo requests to protect against flooding.

filename: /etc/nftables.conf
#!/usr/bin/nft -f
# ipv4/ipv6 Simple & Safe Firewall
# you can find examples in /usr/share/nftables/

table inet filter {

chain input {
type filter hook input priority 0;

# allow established/related connections
ct state {established, related} accept

# early drop of invalid connections
ct state invalid drop

# allow from loopback
iifname lo accept

# no ping floods
ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate 10/second accept
ip protocol icmp icmp type echo-request limit rate 10/second accept

# allow ssh, but with brute force protection
tcp dport ssh limit rate 15/minute accept

# allow http and https traffic
tcp dport {http,https} accept

# everything else (blackhole)
reject with icmp type port-unreachable

# all forwarding traffic gets dropped (we are not a router)
chain forward {
type filter hook forward priority 0;

# let all traffic outbound through the firewall
chain output {
type filter hook output priority 0;


Then enable and start the service.

# sudo systemctl enable nftables
# sudo systemctl start nftables

To verify all the rules were applied pull up a list of the current ruleset.

# sudo nft list ruleset

Icon References

  1. "ArchWiki". Cron. https://wiki.archlinux.org/index.php/cron
  2. "ArchWiki". Security. https://wiki.archlinux.org/index.php/Security
  3. "LinOxide". An Ultimate Guide to Secure Ubuntu Host. https://linoxide.com/ubuntu-how-to/ultimate-guide-secure-ubuntu/
  4. "stribika". Secure Secure Shell. https://stribika.github.io/2015/01/04/secure-secure-shell.html
  1. ^ RHD Blog. Benchmarking nftables