██████ ███ ███ █████ ██████ ██████ ██ ██ ██ ██
██ ██ ████ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ████ ██ ███████ ██████ ██ ███████ ████
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██████ ██ ██ ██ ██ ██ ██ ██████ ██ ██ ██
█ █ ▄▀█ █▀█ █▀▄ █▀▀ █▄ █ █ █▄ █ █▀▀
█▀█ █▀█ █▀▄ █▄▀ ██▄ █ ▀█ █ █ ▀█ █▄█
Interactive security hardening for Omarchy and Arch Linux installations.
You should not rely on automation to secure your system.
This tool exists to demonstrate security improvements, but the best approach is to understand your distribution and make these changes yourself. Read the source code, understand each command, and run them manually. This builds knowledge you'll need when things go wrong.
See A Word on Omarchy for the context behind these recommendations.
- Create a snapshot:
omarchy-snapshot create - Read the source code: Understand what each option does before enabling it
git clone https://github.com/dannymcc/omarchy-hardening.git
cd omarchy-hardening
./omarchy-hardening.shThe script provides an interactive menu with five hardening options. None are selected by default - you must explicitly choose what to apply.
What it is: LLMNR (Link-Local Multicast Name Resolution) is a protocol that resolves hostnames on local networks when DNS fails.
Why disable it: LLMNR is a well-known attack vector. Attackers on your local network can respond to LLMNR queries before legitimate hosts, redirecting your traffic to malicious destinations. Tools like Responder exploit this for credential theft.
What the script does:
- Creates
/etc/systemd/resolved.conf.d/disable-llmnr.confwithLLMNR=no - Restarts systemd-resolved
Manual equivalent:
sudo mkdir -p /etc/systemd/resolved.conf.d
echo -e "[Resolve]\nLLMNR=no" | sudo tee /etc/systemd/resolved.conf.d/disable-llmnr.conf
sudo systemctl restart systemd-resolvedWhat it is: UFW (Uncomplicated Firewall) is a frontend for iptables that simplifies firewall management.
Why enable it: Earlier versions of Omarchy shipped with UFW rules pre-configured but the service was not enabled, leaving systems exposed. This has since been fixed in newer releases.
What the script does:
- Resets all existing UFW rules (
ufw --force reset) - Sets default policy: deny incoming, allow outgoing
- Allows SSH connections (port 22)
- Enables the UFW service
Manual equivalent:
sudo ufw --force reset
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw --force enableNote: The reset step removes any existing rules. If you have custom firewall rules, apply this option carefully or configure UFW manually.
What it is: Restricts SSH to only accept connections from your Tailscale network.
Why use it: SSH exposed to the public internet is constantly targeted by brute-force attacks. By binding SSH only to your Tailscale IP, the service becomes invisible to the public internet. Attackers cannot connect to a service they cannot reach.
What the script does:
- Creates
/etc/ssh/sshd_config.d/tailscale-only.conf - Sets
ListenAddressto your Tailscale IPv4 address - Disables password authentication (keys only)
- Restarts sshd
Manual equivalent:
TAILSCALE_IP=$(tailscale ip -4)
sudo mkdir -p /etc/ssh/sshd_config.d
cat << EOF | sudo tee /etc/ssh/sshd_config.d/tailscale-only.conf
ListenAddress $TAILSCALE_IP
PasswordAuthentication no
EOF
sudo systemctl restart sshdPrerequisites: Tailscale must be installed and connected. Ensure you can SSH via Tailscale before enabling this option, or you may lock yourself out.
What it is: Configures PAM faillock to lock accounts after repeated failed login attempts.
Why reduce it: Omarchy increases the default faillock attempts from 3 to 10, making brute-force attacks against local accounts easier. If someone gains physical access or a shell, they have more attempts to guess passwords.
What the script does:
- Edits
/etc/security/faillock.conf - Sets
deny=3(or your configured value)
Manual equivalent:
sudo sed -i 's/^deny = .*/deny = 3/' /etc/security/faillock.confWhat it is: Enables SSH-based commit signing for Git.
Why use it: Git commits are trivially forgeable - anyone can set any name and email in their git config. SSH signing cryptographically proves that commits came from someone with access to your private key. GitHub displays a "Verified" badge on signed commits.
What the script does:
- Sets
user.signingkeyto your SSH public key - Enables commit and tag signing (
gpg.format=ssh,commit.gpgsign=true,tag.gpgsign=true) - Applies workflow optimizations (pull.rebase, rerere, etc.)
- Optionally configures GitHub credential helper
Manual equivalent:
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global gpg.format ssh
git config --global commit.gpgsign true
git config --global tag.gpgsign trueNext step: Add your SSH key to GitHub as a signing key (Settings > SSH and GPG keys > New SSH key > Key type: Signing Key).
Press c in the menu to configure:
- SSH Key Path: Location of your SSH public key for Git signing (default:
~/.ssh/id_ed25519.pub) - Max Login Attempts: Failed attempts before lockout (default: 3)
- Git Name/Email: Your identity for commits
- GitHub Username: For credential helper configuration
This script covers the basics. For users who want to go deeper, here are recommended next steps:
OpenSnitch is an application-level firewall that prompts you whenever a program tries to make a network connection. It's an excellent way to understand what your system is actually doing and catch unexpected outbound connections.
yay -S opensnitch
sudo systemctl enable --now opensnitchdOnce installed, you'll see prompts for each new connection - allow or deny, once or forever. It's educational and practical.
-
ArchWiki Security Guide - Comprehensive security recommendations for Arch Linux
-
linux-hardened kernel - Arch provides a hardened kernel with security patches:
sudo pacman -S linux-hardened linux-hardened-headers
Remember to update your bootloader configuration after installing.
-
arch-audit - Check your system for known vulnerabilities:
sudo pacman -S arch-audit arch-audit
-
AppArmor - Mandatory access control to restrict what applications can do. See the ArchWiki AppArmor page.
-
Kernel sysctl hardening - Tune kernel parameters for security. Create
/etc/sysctl.d/99-security.conf:# Hide kernel pointers kernel.kptr_restrict = 2 # Restrict dmesg access kernel.dmesg_restrict = 1 # Disable kexec kernel.kexec_load_disabled = 1
-
DNS encryption - Configure DNS-over-TLS in systemd-resolved. See the ArchWiki systemd-resolved page.
-
Filesystem hardening - Add
noexecto tmpfs mounts, hide other users' processes withhidepid=2on /proc.
MIT