Enhance security - Sawangg/dotfiles GitHub Wiki

Secure boot

We're going to protect our machine to prevent tempering with the boot process. To do that, we're going to use the secure boot functionnality from our BIOS. We're also going to create our own keys and sign any EFI binaries so we're in complete control of our machine. This will prevent all kind of attacks such as an Evil Maid attack or prevent any third party control of your secure BIOS keys. Of course, you'll have to keep your private key secure or else an attacker could simply sign a malicious binary with your keys. We're going to install the following packages

sudo pacman -S efitools openssl sbsigntools

Create our keys

First we're going to generate our own keys using a script found in this well written article. We will create a folder called efitools in our home folder to create our keys.

mkdir ~/efitools
vim ~/efitools/keys.sh

Paste the content of this script in keys.sh

#!/bin/bash
# Copyright (c) 2015 by Roderick W. Smith
# Licensed under the terms of the GPL v3

echo -n "Enter a Common Name to embed in the keys: "
read NAME

openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME PK/" -keyout PK.key \
        -out PK.crt -days 3650 -nodes -sha256
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME KEK/" -keyout KEK.key \
        -out KEK.crt -days 3650 -nodes -sha256
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME DB/" -keyout DB.key \
        -out DB.crt -days 3650 -nodes -sha256
openssl x509 -in PK.crt -out PK.cer -outform DER
openssl x509 -in KEK.crt -out KEK.cer -outform DER
openssl x509 -in DB.crt -out DB.cer -outform DER

GUID=`python3 -c 'import uuid; print(str(uuid.uuid1()))'`
echo $GUID > myGUID.txt

cert-to-efi-sig-list -g $GUID PK.crt PK.esl
cert-to-efi-sig-list -g $GUID KEK.crt KEK.esl
cert-to-efi-sig-list -g $GUID DB.crt DB.esl
rm -f noPK.esl
touch noPK.esl

sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \
                  -k PK.key -c PK.crt PK PK.esl PK.auth
sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \
                  -k PK.key -c PK.crt PK noPK.esl noPK.auth
sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \
                  -k PK.key -c PK.crt KEK KEK.esl KEK.auth
sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \
                  -k KEK.key -c KEK.crt db DB.esl DB.auth

chmod 0600 *.key

echo ""
echo ""
echo "For use with KeyTool, copy the *.auth and *.esl files to a FAT USB"
echo "flash drive or to your EFI System Partition (ESP)."
echo "For use with most UEFIs' built-in key managers, copy the *.cer files;"
echo "but some UEFIs require the *.auth files."
echo ""

Make it a runnable script and execute it

chmod +x ~/efitools/keys.sh
./efitools/keys.sh

Follow the instructions and you should get all the necessary files created. Remember that you'll have to protect those keys from being accessed by an intruder.

Sign a binary

Now that we have our own secure boot keys, we can sign any binary (here our GRUB) we want by running the following

sudo sbsign --key ~/efitools/DB.key --cert ~/efitools/DB.crt --output /boot/efi/EFI/artix/grubx64-signed.efi /boot/efi/EFI/artix/grubx64.efi
sudo mv grubx64-signed.efi grubx64.efi

Enroll the keys

Now we're going to setup KeyTool provided by efitools to manage our keys in our BIOS. It might not be usefull for some BIOS that provide the option to manage your keys but for simplicity and ease of use, we're going to install it. The .efi is located in /usr/share/efitools/efi/KeyTool.efi.

Sign it by running

sudo mkdir /boot/efi/EFI/keytool
sudo sbsign --key ~/efitools/DB.key --cert ~/efitools/DB.crt --output /boot/efi/EFI/keytool/KeyTool.efi /usr/share/efitools/efi/KeyTool.efi

Now we're going to add it to our GRUB menu so we can access it easily.

Access your BIOS by restarting your computer and using the key (ESC, F5, ...) linked to your motherboard.

Finally, to prevent an attacker from just disabling our secure boot, we're going to add an administrator password. You can find that setting in your BIOS.

Congrats, now boot in your system and run the command

od --address-radix=n --format=u1 /sys/firmware/efi/efivars/SecureBoot-*

Your result should end with a 1 if you booted using secure boot. If so, your system is now even more secure! Remember that you'll need to either disable secure boot temporarily or sign your USB stick or whatever you want to boot to if you want to be able to use it to.

Firewall

Once you're back in your system, login as a user. I assume you know what a firewall is all about so we're going to install one called nftables. You could just configure your iptables to create the same rules.

sudo pacman -S nftables nftables-dinit

Edit and comment the tcp sshd line

sudo vim /etc/nftables.conf

And enable the service by running

dinitctl enable nftables

You can now see the rules used currently

sudo nft list ruleset

Kernel parameters

We already installed the hardened version of the Linux kernel so we just have to tweak a few network kernel parameters

sudo mkdir /etc/sysctl.d/
sudo vim /etc/sysctl.d/99-network.conf

Add this config

# Do not act as a router
net.ipv4.ip_forward = 0

# SYN flood protection
net.ipv4.tcp_syncookies = 1

# Disable ICMP redirect
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0

# Don't send ICMP redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

Finally apply your changes by running

sysctl --system

Disable ipv6

If you want to disable ipv6 you can do so by creating the file /etc/sysctl.d/40-ipv6.conf and add this config

# Disable IPv6
net.ipv6.conf.all.disable_ipv6 = 1

Don't forget to reload your config

You also need to edit your dhcpcd config located at /etc/dhcpcd.conf

noipv6rs
noipv6

You can check that you don't have any ipv6 left in your interfaces

ip -c addr

You can now test pinging something with ipv6. It should fail!

ping -6 wiki.archlinux.org

MAC address & Host randomization

The MAC address of an interface is a unique identifier that can be used to track us. We're going to randomize it when we boot our system. To achieve that, we can install a GNU package called macchager

yay -S macchanger-git

Next we're going to create a udev rule called 81-mac-spoof.rules and paste this

ACTION=="add", SUBSYSTEM=="net", ATTR{address}=="original MAC of interface", RUN+="/usr/bin/macchanger -r interfaceName"

The original MAC of interface is the orginal address of your interface and interfaceName is the name of the interface. You can find both by running

ip -c addr

You can add a new line for each interface your PC has but do not change your lo MAC adress. Now, each time you reboot you'll get a new MAC address!

TODO: wifi (https://wiki.archlinux.org/title/MAC_address_spoofing#iwd)

DNS traffic encryption

TODO DNSCrypt https://dnsleaktest.com/

Auto mount

doas mkdir /media
doas chmod 775 /media
doas chown root:wheel /media
yay -S autofs