Move TLS certicates to a new host

    Use ssh to tar a file on the remote host and pipe it to tar on the new host. This avoids the risk of leaving a file around with this sensitive data.

    On the new host,

    ssh user@other.host sudo -S tar -C /etc/letsencrypt -zvc live archive | sudo tar -C /etc/letsencrypt -zvx
    

    Note that this runs sudo on the remote host; the -S argument uses stdin to read the remote user’s password. This means that the password is displayed on the terminal, but at least it is not in the command history. After running the command, consider clearing the terminal buffer using reset or similar.

    Access home router web UI from a remote location

    The home-router web UI is only accessible from the internal network, not from the outside world. This is to prevent the evil outsiders from try to break it, or break into it.

    But sometimes I need to access it remotely. This is a multi-stage process involving multiple ssh port forwards, and some DNS and HTTP-client trickery.

    Port forwarding

    This needs a PC on the remote network (local to the router) and a server that is world-visible.

    • ssh into a PC on the remote network, then set up a local port-forward from a local port to the router

        remote-pc:~$ ssh -N -L 8123:192.168.1.1:80 stephen@localhost
      
    • ssh into the same remote PC, then set up a remote port-forward from the world-visible server to the

        remote-pc:~$ ssh -N -R 8124:localhost:8123 stephen@world.visible.server
      
    • from the local workstation, set up a local port-forward to the world-visible server

        local-pc:~$ ssh -N -L 8125:localhost:8124 stephen@world.visible.server
      

    You can now use an HTTP client to connect to the local port (localhost:8125) and this is forwarded to the very remote router (192.168.1.1:80 on the remote network).

    However, there is still a bit of HTTP trickery to do. The HTTP request include a header ‘Host:’. If the remote host (the router) is doing its job, it will verify that this hostname is correct. Normally, the HTTP client uses the hostname from the URL (localhost) as the ‘Host’ header.

    In this case, the remote router accepts either the name configured in one of its settings, or one of its own IP address. In either case, either of those name does not resolve to the correct location.

    If using curl, you can use the ‘-H’ option to set the hostname

    curl -H 'Host: 192.168.1.1' http://localhost:8125
    

    Using firefox, however, this is more tricky. You need an extension such as ‘Modify Header Value’ to change the header on a per-URL basis. I found it best to do the following:

    • add a new host-name to IP mapping to /etc/hosts, something like

        127.0.0.1    remote-router
      
    • add a new header modification to the firefox extension, something like

        remote-router  modify    'Host'   192.168.1.1
      

    Self-hosted server: router/firewall configuration

    The internet router is a residential model from Vodafone. It seems to do the following

    • Supports IPv6, including

      • full support for outgoing IPv6 connections
      • stateless address autoconfiguration (SLAAC)
    • Allows IPv4 incoming connections only.

      • By default, blocks all incoming connections (IPv4 only).
      • Opens individual ports forwarded to specified host:port (standard NAT stuff, IPv4 only).
      • Can set up a DMZ server, where all other incoming connections are routed to a single host (IPv4 only).
      • No way to configure IPv6 incoming connections.
    • It seems fairly reliable, but something drops out periodically.

      • The router itself
      • The far-end of the fibre connection
      • The local Wi-Fi extender (TP Link Deco system)

    Setup

    • Ensure that IPv4 address remains fixed: requested from Vodafone, $5 per month

    • Ensure that IPv6 address remains fixed; might happen at the same time

    • Port configuration details

      • Leave the standard port-forwards as they are
      • Set up DMZ pointing to new server
      • Ensure that new server has firewall (ufw) enabled and stopping as much as possible

    Install Let's Encrypt -- for nginx, using pip

    Edit: this turned out to be too complicated. As much as I prefer to avoid a Snap package, I decided to go with it rather than jump through these hoops. When I have the system up and running, I might re-evaluation this decision.

    • Install dependencies

        sudo apt install python3 python3-pip libaugeas0
      
    • Remove any OS-installed version

        sudo apt remove cerbot
      
    • Set up a Python virtual environment with certbot

        sudo python3 -m venv /opt/certbot/
        sudo /opt/certbot/bin/pip install --upgrade pip
        sudo /opt/certbot/bin/pip install certbot certbot-nginx
      
    • Optionally, set up a symlink in the path

        sudo ln -s /opt/certbot/bin/certbot /usr/local/bin/certbot
      
    • Enable auto-renewal

        echo "0 0,12 * * * root /opt/certbot/bin/python -c 'import random; import time; time.sleep(random.random() * 3600)' && sudo certbot renew -q" | sudo tee -a /etc/crontab > /dev/null
      

    Derived from Let’s Encrypt - pip