Geomys Tuscolo CT Log Server Public Configuration

This is the live public configuration for the Geomys Tuscolo CT Log Server, a Sunlight instance.

See also the public playbooks.

/etc/sunlight/sunlight.yaml

listen:
  - "185.230.223.193:443"
  - "[2a0c:2f07:c1::c1]:443"
acme:
  hosts:
    - tuscolo.sunlight.geomys.org
  cache: /var/db/sunlight/autocert/
checkpoints: /tank/shared/checkpoints.db
logs:
  - shortname: tuscolo2025h2
    inception: 2025-04-25
    period: 200
    submissionprefix: https://tuscolo2025h2.sunlight.geomys.org
    monitoringprefix: https://tuscolo2025h2.skylight.geomys.org
    secret: /tank/enc/tuscolo2025h2.seed.bin
    cache: /tank/logs/tuscolo2025h2/cache.db
    poolsize: 750
    localdirectory: /tank/logs/tuscolo2025h2/data
    notafterstart: 2025-07-01T00:00:00Z
    notafterlimit: 2026-01-01T00:00:00Z
  - shortname: tuscolo2026h1
    inception: 2025-04-27
    period: 200
    submissionprefix: https://tuscolo2026h1.sunlight.geomys.org
    monitoringprefix: https://tuscolo2026h1.skylight.geomys.org
    secret: /tank/enc/tuscolo2026h1.seed.bin
    cache: /tank/logs/tuscolo2026h1/cache.db
    poolsize: 750
    localdirectory: /tank/logs/tuscolo2026h1/data
    notafterstart: 2026-01-01T00:00:00Z
    notafterlimit: 2026-07-01T00:00:00Z
  - shortname: tuscolo2026h2
    inception: 2025-04-27
    period: 200
    submissionprefix: https://tuscolo2026h2.sunlight.geomys.org
    monitoringprefix: https://tuscolo2026h2.skylight.geomys.org
    secret: /tank/enc/tuscolo2026h2.seed.bin
    cache: /tank/logs/tuscolo2026h2/cache.db
    poolsize: 750
    localdirectory: /tank/logs/tuscolo2026h2/data
    notafterstart: 2026-07-01T00:00:00Z
    notafterlimit: 2027-01-01T00:00:00Z
  - shortname: tuscolo2027h1
    inception: 2025-06-02
    period: 200
    submissionprefix: https://tuscolo2027h1.sunlight.geomys.org
    monitoringprefix: https://tuscolo2027h1.skylight.geomys.org
    secret: /tank/enc/tuscolo2027h1.seed.bin
    cache: /tank/logs/tuscolo2027h1/cache.db
    poolsize: 750
    localdirectory: /tank/logs/tuscolo2027h1/data
    notafterstart: 2027-01-01T00:00:00Z
    notafterlimit: 2027-07-01T00:00:00Z
  - shortname: tuscolo2027h2
    inception: 2025-06-02
    period: 200
    submissionprefix: https://tuscolo2027h2.sunlight.geomys.org
    monitoringprefix: https://tuscolo2027h2.skylight.geomys.org
    secret: /tank/enc/tuscolo2027h2.seed.bin
    cache: /tank/logs/tuscolo2027h2/cache.db
    poolsize: 750
    localdirectory: /tank/logs/tuscolo2027h2/data
    notafterstart: 2027-07-01T00:00:00Z
    notafterlimit: 2028-01-01T00:00:00Z

/etc/sunlight/sunlight-staging.yaml

listen:
  - "185.230.223.195:443"
  - "[2a0c:2f07:c1::c3]:443"
acme:
  hosts:
    - navigli.sunlight.geomys.org
  cache: /var/db/sunlight/autocert-staging/
checkpoints: /tank/shared/checkpoints.db
witness:
  name: navigli.sunlight.geomys.org/dev
  submissionprefix: https://navigli.sunlight.geomys.org/dev
  secret: /tank/enc/navigli-witness-dev.seed.bin
  knownlogs:
    - origin: go.sum database tree
      verifierkeys:
        - sum.golang.org+033de0ae+Ac4zctda0e5eza+HJyk9SxEdh+s3Ux18htTTAD8OuAn8
    - origin: sigsum.org/v1/tree/44ad38f8226ff9bd27629a41e55df727308d0a1cd8a2c31d3170048ac1dd22a1
      verifierkeys:
        - sigsum.org/v1/tree/44ad38f8226ff9bd27629a41e55df727308d0a1cd8a2c31d3170048ac1dd22a1+682b49db+AQ7H4WhDEZsSA3enOROsasvC0D2CQy4sNrhBsJqVhB8l
    - origin: sigsum.org/v1/tree/4e89cc51651f0d95f3c6127c15e1a42e3ddf7046c5b17b752689c402e773bb4d
      verifierkeys:
        - sigsum.org/v1/tree/4e89cc51651f0d95f3c6127c15e1a42e3ddf7046c5b17b752689c402e773bb4d+778629b1+AUZEryq9QPSJWgA7yjUPnVkSqzAaScd/E+W22QXCCl/m
    - origin: sigsum.org/v1/tree/c9e525b98f412ede185ff2ac5abf70920a2e63a6ae31c88b1138b85de328706b
      verifierkeys:
        - sigsum.org/v1/tree/c9e525b98f412ede185ff2ac5abf70920a2e63a6ae31c88b1138b85de328706b+d6c89be8+ARVPSZdrWf8JoSNnX1jLPjRuBFV1PDw7FdRl3LT2USsL
logs:
  - shortname: navigli2025h2
    inception: 2025-05-03
    period: 200
    submissionprefix: https://navigli2025h2.sunlight.geomys.org
    monitoringprefix: https://navigli2025h2.skylight.geomys.org
    ccadbroots: testing
    extraroots: /etc/sunlight/extra-roots-staging.pem
    secret: /tank/enc/navigli2025h2.seed.bin
    cache: /tank/logs/navigli2025h2/cache.db
    poolsize: 750
    localdirectory: /tank/logs/navigli2025h2/data
    notafterstart: 2025-07-01T00:00:00Z
    notafterlimit: 2026-01-01T00:00:00Z
  - shortname: navigli2026h1
    inception: 2025-05-03
    period: 200
    submissionprefix: https://navigli2026h1.sunlight.geomys.org
    monitoringprefix: https://navigli2026h1.skylight.geomys.org
    ccadbroots: testing
    extraroots: /etc/sunlight/extra-roots-staging.pem
    secret: /tank/enc/navigli2026h1.seed.bin
    cache: /tank/logs/navigli2026h1/cache.db
    poolsize: 750
    localdirectory: /tank/logs/navigli2026h1/data
    notafterstart: 2026-01-01T00:00:00Z
    notafterlimit: 2026-07-01T00:00:00Z
  - shortname: navigli2026h2
    inception: 2025-05-03
    period: 200
    submissionprefix: https://navigli2026h2.sunlight.geomys.org
    monitoringprefix: https://navigli2026h2.skylight.geomys.org
    ccadbroots: testing
    extraroots: /etc/sunlight/extra-roots-staging.pem
    secret: /tank/enc/navigli2026h2.seed.bin
    cache: /tank/logs/navigli2026h2/cache.db
    poolsize: 750
    localdirectory: /tank/logs/navigli2026h2/data
    notafterstart: 2026-07-01T00:00:00Z
    notafterlimit: 2027-01-01T00:00:00Z
  - shortname: navigli2027h1
    inception: 2025-06-02
    period: 200
    submissionprefix: https://navigli2027h1.sunlight.geomys.org
    monitoringprefix: https://navigli2027h1.skylight.geomys.org
    ccadbroots: testing
    extraroots: /etc/sunlight/extra-roots-staging.pem
    secret: /tank/enc/navigli2027h1.seed.bin
    cache: /tank/logs/navigli2027h1/cache.db
    poolsize: 750
    localdirectory: /tank/logs/navigli2027h1/data
    notafterstart: 2027-01-01T00:00:00Z
    notafterlimit: 2027-07-01T00:00:00Z
  - shortname: navigli2027h2
    inception: 2025-06-02
    period: 200
    submissionprefix: https://navigli2027h2.sunlight.geomys.org
    monitoringprefix: https://navigli2027h2.skylight.geomys.org
    ccadbroots: testing
    extraroots: /etc/sunlight/extra-roots-staging.pem
    secret: /tank/enc/navigli2027h2.seed.bin
    cache: /tank/logs/navigli2027h2/cache.db
    poolsize: 750
    localdirectory: /tank/logs/navigli2027h2/data
    notafterstart: 2027-07-01T00:00:00Z
    notafterlimit: 2028-01-01T00:00:00Z

/etc/sunlight/skylight.yaml

listen:
  - "185.230.223.194:443"
  - "[2a0c:2f07:c1::c2]:443"
acme:
  hosts:
    - skylight.geomys.org
  cache: /var/db/sunlight/skylight/
homeredirect: https://tuscolo.sunlight.geomys.org
logs:
  - shortname: tuscolo2025h2
    monitoringprefix: https://tuscolo2025h2.skylight.geomys.org
    localdirectory: /tank/logs/tuscolo2025h2/data
  - shortname: tuscolo2026h1
    monitoringprefix: https://tuscolo2026h1.skylight.geomys.org
    localdirectory: /tank/logs/tuscolo2026h1/data
  - shortname: tuscolo2026h2
    monitoringprefix: https://tuscolo2026h2.skylight.geomys.org
    localdirectory: /tank/logs/tuscolo2026h2/data
  - shortname: tuscolo2027h1
    monitoringprefix: https://tuscolo2027h1.skylight.geomys.org
    localdirectory: /tank/logs/tuscolo2027h1/data
  - shortname: tuscolo2027h2
    monitoringprefix: https://tuscolo2027h2.skylight.geomys.org
    localdirectory: /tank/logs/tuscolo2027h2/data

  - shortname: navigli2025h2
    monitoringprefix: https://navigli2025h2.skylight.geomys.org
    localdirectory: /tank/logs/navigli2025h2/data
    staging: true
  - shortname: navigli2026h1
    monitoringprefix: https://navigli2026h1.skylight.geomys.org
    localdirectory: /tank/logs/navigli2026h1/data
    staging: true
  - shortname: navigli2026h2
    monitoringprefix: https://navigli2026h2.skylight.geomys.org
    localdirectory: /tank/logs/navigli2026h2/data
    staging: true
  - shortname: navigli2027h1
    monitoringprefix: https://navigli2027h1.skylight.geomys.org
    localdirectory: /tank/logs/navigli2027h1/data
    staging: true
  - shortname: navigli2027h2
    monitoringprefix: https://navigli2027h2.skylight.geomys.org
    localdirectory: /tank/logs/navigli2027h2/data
    staging: true

/usr/local/bin/debug

#!/bin/bash
set -euo pipefail

unit_flag="skylight"

display_help() {
    echo "Usage: debug [-u unit] {useragents|ips|keylog={on|off}|logs={on|off}|port}"
}

while getopts "u:h" opt; do
    case ${opt} in
        u )
            unit_flag=$OPTARG
            ;;
        h )
            display_help >&2
            exit 0
            ;;
        \? )
            echo "Invalid option: -$OPTARG" >&2
            display_help >&2
            exit 1
            ;;
        : )
            echo "Option -$OPTARG requires an argument" >&2
            display_help >&2
            exit 1
            ;;
    esac
done

shift $((OPTIND - 1))

if [ "$#" -ne 1 ]; then
    echo "Exactly one positional argument is required" >&2
    display_help >&2
    exit 1
fi

PID=$(systemctl show "$unit_flag" --property MainPID | cut -d'=' -f2)
if [ -z "$PID" ]; then
    echo "Unit $unit_flag is not running" >&2
    exit 1
fi
PORT=$(ss -tulnp | grep "pid=$PID," | awk '{print $5}' | grep 127.0.0.1)
if [ -z "$PORT" ]; then
    echo "No port found for unit $unit_flag" >&2
    exit 1
fi

case $1 in
    useragents )
        curl -s "$PORT/debug/heavyhitter/useragents"
        ;;
    ips )
        curl -s "$PORT/debug/heavyhitter/ips"
        ;;
    keylog=on )
        curl -s -x POST "$PORT/debug/keylog/on"
        ;;
    keylog=off )
        curl -s -x POST "$PORT/debug/keylog/off"
        ;;
    logs=on )
        curl -s -x POST "$PORT/debug/logs/on"
        ;;
    logs=off )
        curl -s -x POST "$PORT/debug/logs/off"
        ;;
    port )
    	echo "$PORT"
    	;;
    * )
        echo "Invalid argument: $1" >&2
        display_help >&2
        exit 1
        ;;
esac

/etc/systemd/system/sunlight.service

[Unit]
Description=Sunlight Certificate Transparency Log
After=network-online.target tank-enc.mount
Wants=network-online.target
StartLimitIntervalSec=0

[Service]
ExecStart=/usr/local/bin/sunlight -c /etc/sunlight/sunlight.yaml
ExecReload=kill -HUP $MAINPID
StandardOutput=append:/var/log/sunlight.jsonl
StandardError=journal
Restart=always
# RestartSteps=10
# RestartMaxDelaySec=60s
RestartSec=60s

[Install]
WantedBy=tank-enc.mount

/etc/systemd/system/sunlight-staging.service

[Unit]
Description=Sunlight Certificate Transparency Log (staging)
After=network-online.target tank-enc.mount
Wants=network-online.target
StartLimitIntervalSec=0

[Service]
ExecStart=/usr/local/bin/sunlight-staging -c /etc/sunlight/sunlight-staging.yaml
ExecReload=kill -HUP $MAINPID
StandardOutput=append:/var/log/sunlight-staging.jsonl
StandardError=journal
Restart=always
# RestartSteps=10
# RestartMaxDelaySec=60s
RestartSec=60s

[Install]
WantedBy=tank-enc.mount

/etc/systemd/system/skylight.service

[Unit]
Description=Sunlight Certificate Transparency Log (read path)
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=0

[Service]
ExecStart=/usr/local/bin/skylight -c /etc/sunlight/skylight.yaml
StandardOutput=append:/var/log/skylight.jsonl
StandardError=journal
Restart=always
# RestartSteps=10
# RestartMaxDelaySec=60s
RestartSec=60s

[Install]
WantedBy=multi-user.target

/etc/systemd/system/partial-aftersun.service

[Unit]
Description=Clean up partial tiles

[Service]
Type=oneshot
ExecStart=/usr/local/bin/partial-aftersun -c /etc/sunlight/sunlight.yaml
ExecStartPost=/usr/bin/curl --retry 3 --retry-delay 1 -m 15 https://sm.hetrixtools.net/hb/?s=a4f010ea1bd8d93598fc96f94000190f
StandardOutput=append:/var/log/partial-aftersun.jsonl
StandardError=journal

/etc/systemd/system/partial-aftersun.timer

[Unit]
Description=Periodically run partial tiles cleanup while Sunlight is running
RefuseManualStart=yes
PartOf=sunlight.service

[Timer]
OnActiveSec=5s
OnUnitActiveSec=5m

[Install]
WantedBy=sunlight.service

/etc/systemd/system/partial-aftersun-staging.service

[Unit]
Description=Clean up partial tiles (staging)

[Service]
Type=oneshot
ExecStart=/usr/local/bin/partial-aftersun -c /etc/sunlight/sunlight-staging.yaml
ExecStartPost=/usr/bin/curl --retry 3 --retry-delay 1 -m 15 https://sm.hetrixtools.net/hb/?s=590ce0eb9954e649e6f2be05a4c651bd
StandardOutput=append:/var/log/partial-aftersun.jsonl
StandardError=journal

/etc/systemd/system/partial-aftersun-staging.timer

[Unit]
Description=Periodically run partial tiles cleanup while Sunlight is running (staging)
RefuseManualStart=yes
PartOf=sunlight-staging.service

[Timer]
OnActiveSec=5s
OnUnitActiveSec=5m

[Install]
WantedBy=sunlight-staging.service

/etc/systemd/system/public-config.service

[Unit]
Description=https://github.com/FiloSottile/mostly-harmless/tree/main/public-config
After=network-online.target
Wants=network-online.target
Before=caddy.service
StartLimitIntervalSec=0

[Service]
ExecStart=/usr/local/bin/public-config
DynamicUser=true
Restart=always
# RestartSteps=10
# RestartMaxDelaySec=60s
RestartSec=60s

[Install]
WantedBy=multi-user.target

/etc/caddy/Caddyfile

config.sunlight.geomys.org:443 {
	bind 185.230.223.196 [2a0c:2f07:c1::c4]
	reverse_proxy localhost:8080
}

/etc/prometheus/prometheus.yml

global:
  scrape_interval: 15s
scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets:
        - localhost:9090
  - job_name: node
    static_configs:
      - targets:
        - localhost:9100
  - job_name: tuscolo
    scheme: https
    static_configs:
      - targets:
        - tuscolo.sunlight.geomys.org
  - job_name: navigli
    scheme: https
    static_configs:
      - targets:
        - navigli.sunlight.geomys.org
  - job_name: skylight
    scheme: https
    static_configs:
      - targets:
        - skylight.geomys.org
  - job_name: twig
    scheme: https
    static_configs:
      - targets:
        - twig.ct.letsencrypt.org
  - job_name: sycamore
    scheme: https
    static_configs:
      - targets:
        - sycamore.ct.letsencrypt.org
  - job_name: willow
    scheme: https
    static_configs:
      - targets:
        - willow.ct.letsencrypt.org