#!/bin/bash
# Installs the Battleship relay as a systemd service. Run once, as root:
#     sudo bash install-relay.sh                # plain, on port 8642
#     sudo bash install-relay.sh djvlk.de       # encrypted, using that certbot
#                                                      # certificate and keeping it renewed
set -euo pipefail

SRC="$(cd "$(dirname "$0")" && pwd)"
DOMAIN="${1:-}"
[ "$(id -u)" -eq 0 ] || { echo "Run this with sudo." >&2; exit 1; }

# A system account with no home and no shell: the relay needs neither.
id -u battleship >/dev/null 2>&1 \
    || useradd --system --no-create-home --shell /usr/sbin/nologin battleship

install -d -m 755 /opt/battleship-relay
install -m 644 "$SRC/relay.py" /opt/battleship-relay/relay.py
install -m 644 "$SRC/battleship-relay.service" /etc/systemd/system/battleship-relay.service

# The access key. Generated once and kept, so reinstalling does not lock the players out;
# readable by the service account and nobody else.
install -d -o root -g battleship -m 750 /etc/battleship-relay
if [ ! -s /etc/battleship-relay/key ]; then
    python3 -c "import secrets; print(secrets.token_urlsafe(18))" > /etc/battleship-relay/key
    echo "Generated a new access key."
fi
chown root:battleship /etc/battleship-relay/key
chmod 640 /etc/battleship-relay/key

# TLS, if a certbot certificate was named. Its live directory is root's alone, so the
# certificate is copied where the service account can read it - by a renewal hook, since a
# copy made once would go stale the first time certbot renews.
if [ -n "$DOMAIN" ]; then
    LINEAGE="/etc/letsencrypt/live/$DOMAIN"
    [ -r "$LINEAGE/fullchain.pem" ] || { echo "No certificate at $LINEAGE" >&2; exit 1; }

    HOOK=/etc/letsencrypt/renewal-hooks/deploy/battleship-relay.sh
    install -d -m 755 /etc/letsencrypt/renewal-hooks/deploy
    cat > "$HOOK" <<HOOKEOF
#!/bin/bash
# Puts the certificate where the relay's account can read it, then restarts it. certbot
# sets RENEWED_LINEAGE when it calls this; run by hand, it does the same work.
set -eu
LINEAGE="$LINEAGE"
[ "\${RENEWED_LINEAGE:-\$LINEAGE}" = "\$LINEAGE" ] || exit 0
install -o root -g battleship -m 640 "\$LINEAGE/fullchain.pem" /etc/battleship-relay/tls-cert.pem
install -o root -g battleship -m 640 "\$LINEAGE/privkey.pem" /etc/battleship-relay/tls-key.pem
systemctl restart battleship-relay
HOOKEOF
    chmod 755 "$HOOK"

    install -o root -g battleship -m 640 "$LINEAGE/fullchain.pem" /etc/battleship-relay/tls-cert.pem
    install -o root -g battleship -m 640 "$LINEAGE/privkey.pem" /etc/battleship-relay/tls-key.pem

    cat > /etc/battleship-relay/options <<'OPTEOF'
RELAY_EXTRA=--tls-cert /etc/battleship-relay/tls-cert.pem --tls-key /etc/battleship-relay/tls-key.pem
OPTEOF
else
    echo 'RELAY_EXTRA=' > /etc/battleship-relay/options
fi
chmod 644 /etc/battleship-relay/options

systemctl daemon-reload
systemctl enable battleship-relay
# restart rather than start: run again after a change, the service must pick the new unit up.
systemctl restart battleship-relay
sleep 2

echo "=== Service ==="
systemctl is-enabled battleship-relay
systemctl is-active battleship-relay

echo "=== Port ==="
ss -ltnp | grep 8642 || echo "nothing is listening on 8642 - see the journal below"

echo "=== Firewall ==="
if command -v ufw >/dev/null 2>&1 && ufw status | grep -q "Status: active"; then
    ufw allow 8642/tcp
    ufw status | grep 8642
else
    echo "ufw is not active - no rule added"
fi

echo "=== Journal ==="
journalctl -u battleship-relay -n 5 --no-pager

echo
echo "=== Access key - type this into both apps ==="
cat /etc/battleship-relay/key
