title:Setting up a Firewall
date: 2023-01-23 13:00
tags: nftables firewall
summary: Firewalls are hard at first.
---

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&rsquo;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&rsquo;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&rsquo;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&rsquo;s try that.

Well that caused a kernel panic. That didn&rsquo;t work. Probably because I told
linode to set the root password, and linode doesn&rsquo;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&rsquo;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&rsquo;s
`etc/ssh/ssh_host_ed25519_key.pub` file.

Now nginx serves my websites via http.  Let&rsquo;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!

