File size: 3,286 Bytes
d9ee7c4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-or-later
# Copyright (C) 2026 SnapKitty Collective
#
# Provision cloudflared on the server that runs Ollama:
#   1. installs cloudflared
#   2. creates a tunnel and routes DNS for the API + SSH hostnames
#   3. renders /etc/cloudflared/config.yml from config.yml
#   4. installs + starts a systemd unit (outbound-only: no inbound firewall ports)
#
# Usage:
#   sudo DOMAIN=yourdomain.com TUNNEL_NAME=command-center ./setup.sh
#
# DOMAIN is required and must be YOUR domain. Nothing here phones home;
# cloudflared only ever opens outbound connections to Cloudflare's edge.
set -euo pipefail

DOMAIN="${DOMAIN:-}"
TUNNEL_NAME="${TUNNEL_NAME:-command-center}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

if [[ -z "$DOMAIN" ]]; then
  echo "error: set DOMAIN to your real domain, e.g. DOMAIN=example.com $0" >&2
  exit 1
fi
if [[ "$EUID" -ne 0 ]]; then
  echo "error: run as root (needs apt + /etc/cloudflared)" >&2
  exit 1
fi

echo "==> Installing cloudflared"
if ! command -v cloudflared >/dev/null 2>&1; then
  mkdir -p /usr/share/keyrings
  curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg \
    | tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
  echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main' \
    | tee /etc/apt/sources.list.d/cloudflared.list >/dev/null
  apt-get update -qq && apt-get install -y -qq cloudflared
fi
cloudflared --version

echo "==> Authenticating (opens a browser URL; on a headless box copy ~/.cloudflared/cert.pem from a machine where you ran 'cloudflared tunnel login')"
cloudflared tunnel login

echo "==> Creating tunnel '$TUNNEL_NAME'"
if cloudflared tunnel list 2>/dev/null | grep -q "$TUNNEL_NAME"; then
  echo "    tunnel already exists, reusing"
else
  cloudflared tunnel create "$TUNNEL_NAME"
fi
TUNNEL_ID="$(cloudflared tunnel list --output json 2>/dev/null \
  | python3 -c "import json,sys; print([t['id'] for t in json.load(sys.stdin) if t['name']=='$TUNNEL_NAME'][0])")"
echo "    tunnel id: $TUNNEL_ID"

echo "==> Routing DNS"
cloudflared tunnel route dns "$TUNNEL_ID" "ollama-internal.$DOMAIN" || true
cloudflared tunnel route dns "$TUNNEL_ID" "ssh.$DOMAIN" || true

echo "==> Rendering /etc/cloudflared/config.yml"
mkdir -p /etc/cloudflared
sed -e "s/TUNNEL_UUID/$TUNNEL_ID/g" \
    -e "s/yourdomain\.com/$DOMAIN/g" \
    "$SCRIPT_DIR/config.yml" > /etc/cloudflared/config.yml
chmod 600 /etc/cloudflared/config.yml
echo "    wrote /etc/cloudflared/config.yml"

echo "==> Installing systemd unit"
cat > /etc/systemd/system/cloudflared.service <<'UNIT'
[Unit]
Description=cloudflared tunnel for Kotlin Command Center
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/cloudflared tunnel --config /etc/cloudflared/config.yml run
Restart=on-failure
RestartSec=5s
# Harden: no new privileges, private /tmp
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
UNIT
systemctl daemon-reload
systemctl enable --now cloudflared
systemctl --no-pager status cloudflared | head -8

echo
echo "==> Done. Next: follow ACCESS_SETUP.md to lock both hostnames behind"
echo "    Cloudflare Access with a service token, then deploy worker/."