title:Setting up a Firewall date: 2023-01-23 13:00 tags: nftables firewall
Edit: Feb 12: The below firewall does NOT work. I currently do NOT use a firewall on my servers.
So my guix system servers have been running without a firewall. I have decided to actually fix that. Unfortunately, OpenBSD’s pf does not work on linux. It seems like the best packaged firewall for GNU Guix System is currently provided by the netfilter service. Luckily Guix’s default server provides a good basic configuration for enabling ssh access to the machine. That configuration looks like this:
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# early drop of invalid connections
ct state invalid drop
# allow established/related connections
ct state { established, related } accept
# allow from loopback
iifname lo accept
# allow icmp
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# allow ssh
tcp dport ssh accept
# reject everything else
reject with icmpx type port-unreachable
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
So it looks like I just need to add in policies just after the #allow ssh
line.
It seems like the easiest way to test this service out, is to first, guix
install nft
, then put your configuration into a file. Then load in those
firewall rules via sudo nft -f nftables.conf
. If those rules end up breaking
things, you can revert the firewall to allow everything via sudo nft flush
ruleset
. You can also list the current ruleset via sudo nft list ruleset
.
You can also check the syntax in nftables.conf
via sudo nft -cf nftable.conf
.
Well I had a firewall working fairly well. I tested the firewall rules via
sudo nft -f nftables-lamora.conf
, and it worked really well. But this scheme
code seemed to break everything on the server. Now, I can’t login to lamora and
the websites it hosts are not working.
(service nftables-service-type
(nftables-configuration
(ruleset
(mixed-text-file "nftables.conf"
"./nftables-lamora.conf"))))
I reached out to linode support, and I am able to boot the machine in a rescue
image, which is pretty awesome. From there I might be able to mount the
/dev/sda
drive such that /gnu/store
is set up properly. But I think that is
pretty much beyond me. Too much work to get correct. So instead, I shall start
from scratch I suppose. :(
What if I had just run,
mount /dev/sda /mnt
chroot /mnt
sudo guix system roll-back
That might have worked. But it also might not have and it might have just taken me longer too.
Looks like I have a small basic guix image lying around that I can tell linode to use. Let’s try that.
Well that caused a kernel panic. That didn’t work. Probably because I told linode to set the root password, and linode doesn’t know how to mess with guix system?
So I whiped my linode server, and started over. And it looks like I need to modify the current cookbook entry about running guix system on linode via adding in
sudo apt-get update
, then sudo apt-get install gpg
.
Here are some of the commands that I used to set up my new linode server. It's on the same IP address. It's currently hosting gnucode.me.
wget https://notabug.org/jbranso/linode-guix-system-configuration/raw/master/gnucode.me-initial-config.scm
mount /dev/sdc /mnt
sudo guix system reconfigure locke-lamora-initial-config.scm
guix install git
mkdir -p ~/prog/gnu/guix/guix-config/
cd ~/prog/gnu/guix/guix-config/
git clone https://notabug.org/jbranso/linode-guix-system-configuration
cd ../
git clone https://git.sr.ht/~whereiseveryone/guixrus
sudo mkdir -p /srv/www/html
Now I need to git clone my various static websites on the server.
cd /srv/www/html
sudo git clone https://notabug.org/jbranso/gnucode.me.git
sudo git clone https://notabug.org/jbranso/propernaming.git
sudo git clone https://notabug.org/jbranso/gnu-hurd.com.git
sudo mv propernaming propernaming.org
So I believe that I need to chmod the files in /srv/www/html, so that nginx can
actually serve them. Unfortunately, I cannot do a sudo chown -R nginx /srv
,
because my current guix system does not have an nginx user yet. But I believe
that I can still reconfigure the system, even if nginx will not be able to serve
the html files. After I have reconfigured, then I should be able chown the owner
of /srv to nginx. In the end I actually just did a cd /srv; sudo chmod -R o+r
*
and just made every file readable by everyone. That sort of violates the
principle of least privledge, oh well.
Now that I have made some modifications to my gnucode.me-current-config.scm that comments out various certificate files that are not there yet, I can attempt to reconfigure on the server:
cd prog/gnu/guix/guix-config/linode-guix-system-configuration/
sudo guix system reconfigure gnucode.me-current-config.scm
guix system: error: aborting reconfiguration because commit
9fe5b490df83ff32e2e0a604bf636eca48b9e240 of channel 'guix' is not a descendant
of 900d33527c9286a811f064d4bb8f4a9b18d1db0b
Well let’s try this updating everything. And I believe that you need to do a guix pull as root at least once.
su
guix pull;
exit;
guix pull;
Oh yeah, I also need to power down my linode, delete the debian partition, and resize the guix partition to full size.
Now I believe that I cannot reconfigure my server with the current
gnucode.me-current-config.scm
, because nginx will fail to start because the
letsencrypt scripts are not there yet. So I need to modify the nginx bits before
I can start the service. I also decided to set up guix deploy
on my gnucode.me
machine, so that reconfiguring the remote server is faster.
Ok, so I have my current-config for gnucode.me deployed. Geez, guix deploy is
sooo super fast! And all you need to do is to set up ssh-agent and customize a
deployment list. I set up ssh-agent via my .bash_profile
cat .bash_profile | grep eval -A 1
if [[ -z $DISPLAY ]] && [[ $(tty) = /dev/tty6 ]]; then
eval `ssh-agent -s`
ssh-add
exec dbus-run-session sway
fi
Now all you need to do is customize this:
(list (machine
(operating-system %system)
(environment managed-host-environment-type)
(configuration (machine-ssh-configuration
(host-name "45.56.66.20")
(system "x86_64-linux")
(user "joshua")
(identity "~/.ssh/id_rsa")
(host-key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJgL0hBTWmCVGGvNJYa+YS+fEXs89v0GbdkQ+M+LdZlf root@(none)")
(port 63355)))))
The port is the ssh port. And the ssh-ed25519 is found on your remote server’s
etc/ssh/ssh_host_ed25519_key.pub
file.
Now nginx serves my websites via http. Let’s get https working.
sudo /var/lib/certbot/renew-certificates
Alright, now I can set up my config.scm to allow nginx to serve web traffic via https.
Well, can I get a nftables service running now?
At first it seemed that (service nftables-service-type)
is apparently good
enough to be a decent firewall for my server. Then very quickly I realized that
it was a terrible firewall for a server, because it blocked all http and https
traffic.
It looks like the arch linux wiki has a decent configuration example for a server:
https://wiki.archlinux.org/title/Nftables#Examples
So I just took the example nftables configuration for a server and used that. The configuration file is here:
https://notabug.org/jbranso/linode-guix-system-configuration/src/master/nftables.scm
Let me know if you see that I did something silly in it, because I probably did.
Bonus paragraph! It took me about 2-4 hours to re-set up my server just the way it was before, except I haven't set up email yet. If you crashed your server lost your backups, how long would it take you to set up you server, just as it was? 2-4 hours is longer than I expected, but I think guix's declarative approach certainly is pretty awesome!