Explorar o código

Release 1.2.2: complete AMD64 and ARM64 installation dependencies

Proxmox Router hai 4 días
pai
achega
1646732ad9
Modificáronse 5 ficheiros con 248 adicións e 31 borrados
  1. 12 3
      README.md
  2. 1 1
      VERSION
  3. 66 0
      docs/dependencies.md
  4. 13 27
      install.sh
  5. 156 0
      scripts/install-dependencies.sh

+ 12 - 3
README.md

@@ -2,11 +2,11 @@
 
 DebTik is a Debian/Proxmox router appliance with an embedded web interface, REST API and RouterOS-style CLI. It manages network interfaces, routing, firewall/NAT, DHCP/DNS, WireGuard, IPsec, PPP, VRRP and AeroTUN. AeroTUN v3 uses pinned peer identities and encrypted tunnels; it works with native TUN or a veth fallback when `/dev/net/tun` is unavailable.
 
-Current release: **1.2.1**. See [functionality corrections and verification](docs/functionality-fixes.md) for network persistence, firewall isolation/IPv6, service error handling and certificate renewal changes.
+Current release: **1.2.2**. See [functionality corrections and verification](docs/functionality-fixes.md) for network persistence, firewall isolation/IPv6, service error handling and certificate renewal changes.
 
 ## Install
 
-On a Debian 13 host or container with systemd and root access:
+On a Debian 13 AMD64 or ARM64 host/container with systemd and root access:
 
 ```sh
 git clone http://gogs.eparmak.local/eparmak/DebTik.git
@@ -14,7 +14,16 @@ cd DebTik
 sudo ./install.sh
 ```
 
-`install.sh` installs the Debian packages used by the application, including BIRD, WireGuard, firewall, DHCP/DNS, PPP, keepalived, pptp-linux, charon-systemd and diagnostic tools. It obtains the Go toolchain specified by `go.mod` when the installed Go is older, builds `proxmox-router` and `debtik-cli`, installs the updater helper, and starts `proxmox-router.service`. It can be run again; existing `/etc/proxmox-router` files and tunnel keys are preserved. Previous binaries are saved as `/usr/local/bin/*.previous`. For native TUN in an LXC container, enable `/dev/net/tun` on the Proxmox host; otherwise AeroTUN uses veth.
+`install.sh` installs and verifies the dependencies listed in [Dependencies](docs/dependencies.md), including Go, WireGuard, firewall, BIRD, DHCP/DNS, PPP clients and servers, strongSwan plugins, diagnostics and the RSTP daemon. It builds `proxmox-router` and `debtik-cli`, installs the updater helpers, and starts `proxmox-router.service`. It can be run again; existing `/etc/proxmox-router` files and tunnel keys are preserved. Previous binaries are saved as `/usr/local/bin/*.previous`. For native TUN in an LXC container, enable `/dev/net/tun` on the Proxmox host; otherwise AeroTUN uses veth.
+
+To install or repair dependencies on an existing appliance without replacing the application binaries or restarting DebTik:
+
+```sh
+sudo ./install.sh --dependencies-only
+sudo ./install.sh --check-dependencies
+```
+
+The dependency check exits nonzero and names missing packages, commands or an outdated Go toolchain. Existing Proxmox `ifupdown2` installations are retained. On Debian 13, where `mstpd` is not packaged, the installer builds a pinned upstream release with archive checksum verification; its daemon is enabled before DebTik starts. Go archives are checksum verified as well.
 
 The web UI and authenticated REST API use HTTP port **80** by default. HTTPS is an optional separate `www-ssl` management service, normally port **443**, configured in **Certificates** and **Management Services**. The application SSH CLI normally listens on **2222**, and Telnet/`debtik-cli` on **8282**. The built-in bandwidth test server uses **2000**. Ports can be changed in the management services UI where available. The main service command is `/usr/local/bin/proxmox-router -addr :80`; `systemd/proxmox-router.service` defines the installed unit.
 

+ 1 - 1
VERSION

@@ -1 +1 @@
-1.2.1
+1.2.2

+ 66 - 0
docs/dependencies.md

@@ -0,0 +1,66 @@
+# Installation dependencies (1.2.2)
+
+`install.sh` invokes `scripts/install-dependencies.sh` as the single dependency
+manifest. Both the full installation and `--dependencies-only` use it;
+`--check-dependencies` verifies package status, executable availability and Go
+version without installing anything. Debian 13, systemd and root are required.
+
+| Feature | Debian packages |
+| --- | --- |
+| Shell and system management | bash, coreutils, grep, gawk, sed, findutils, util-linux, systemd, procps, tzdata |
+| Downloads, Git, SSH repositories and helpers | ca-certificates, curl, git, openssh-client, tar, python3, openssl |
+| Interfaces, bridges and firewall | iproute2, bridge-utils, iptables, ipset, conntrack |
+| WireGuard | wireguard-tools |
+| VRRP and dynamic routing | keepalived, bird2 |
+| DHCP/DNS | dnsmasq, isc-dhcp-client |
+| PPPoE, PPTP, L2TP clients and servers | ppp, pppoe, pptp-linux, pptpd, xl2tpd |
+| IPsec | charon-systemd, strongswan-swanctl, libstrongswan-standard-plugins, libcharon-extra-plugins, libcharon-extauth-plugins |
+| Diagnostics | iputils-ping, iputils-tracepath, traceroute, bind9-dnsutils, mtr-tiny |
+| Debian network persistence | existing ifupdown2 or ifupdown; install ifupdown only when neither is installed |
+
+Go modules are resolved from `go.mod`/`go.sum` during the build. The installer
+checks the native toolchain version with `GOTOOLCHAIN=local`, prefers
+`/opt/debtik/go/bin/go`, and installs the version requested by `go.mod` there
+when needed. AMD64 and ARM64 are supported for downloaded Go toolchains.
+Downloads use official HTTPS endpoints and the matching SHA-256 checksum.
+Explicit HOME and Go cache locations support execution from systemd.
+
+## RSTP
+
+Use the distribution's `mstpd` package when available. Otherwise build upstream
+[release 0.2.0](https://github.com/mstpd/mstpd/tree/8995e5d11ee89f2251734e34cea711bb5a5bb911),
+pinned to commit `8995e5d11ee89f2251734e34cea711bb5a5bb911`. The archive SHA-256 is
+`f965e715c82640484f89fcf11cd85dbd86c325dcf42ef85bd15173d9a9aa45b3`.
+The source build needs gcc, make, libc6-dev, autoconf, automake, libtool and pkg-config;
+these are installed only when compilation is needed. It installs `mstpd` and
+`mstpctl` under `/usr/local/sbin`, plus the upstream license and revision record
+under `/usr/local/share/doc/debtik-mstpd`.
+
+The daemon runs through `mstpd.service`. A DebTik service drop-in orders it before
+the application. DebTik explicitly adds its configured RSTP bridges to the daemon;
+the source installation does not install global bridge-stp or ifupdown hooks.
+See the [upstream control manual](https://github.com/mstpd/mstpd/blob/8995e5d11ee89f2251734e34cea711bb5a5bb911/utils/mstpctl.8).
+
+Package-triggered daemon starts/restarts are suppressed while dependencies are
+installed, using a temporary policy-rc.d only if no existing policy is present.
+The existing policy is preserved, and an installer-created policy is removed on
+success or failure. Dependency repair does not restart DebTik. Newly installed
+runtime daemons are started by their corresponding application features;
+`mstpd` is explicitly started and enabled for RSTP readiness.
+
+ACME issuance and renewal are implemented in Go; external certbot is not a
+runtime dependency. Kernel capabilities such as WireGuard, bridge networking and
+network administration permissions must be provided by the host/container.
+
+Git application updates currently replace binaries and updater helpers. Use the
+latest checkout's `./install.sh --dependencies-only` to synchronize dependencies
+on an existing installation; the updater does not run apt automatically.
+
+## Verification
+
+The dependency installation and command check were exercised on the existing
+AMD64 appliance. RSTP daemon/control integration was verified using a real bridge
+in an isolated network namespace. All 42 runtime packages and the source-build
+tools were checked against Debian 13 ARM64 package metadata. The server and CLI
+are cross-built for ARM64; a complete fresh ARM64 installation remains a separate
+end-to-end deployment check.

+ 13 - 27
install.sh

@@ -3,40 +3,26 @@ set -euo pipefail
 if [[ $EUID -ne 0 ]]; then echo 'Run as root' >&2; exit 1; fi
 src=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
 command -v apt-get >/dev/null || { echo 'Debian apt-get required' >&2; exit 1; }
-archive="";build="";policy_created=false
-cleanup(){
- if [[ -n $archive ]];then rm -f "$archive";fi
- if [[ -n $build ]];then rm -rf "$build";fi
- if [[ $policy_created == true ]];then rm -f /usr/sbin/policy-rc.d;fi
-}
-trap cleanup EXIT
+mode=${1:-install}
+[[ $# -le 1 && ( $mode == install || $mode == --dependencies-only || $mode == --check-dependencies ) ]] || { echo 'Usage: install.sh [--dependencies-only|--check-dependencies]' >&2; exit 2; }
+if [[ $mode == --check-dependencies ]]; then exec bash "$src/scripts/install-dependencies.sh" --check; fi
+build=""
+trap 'if [[ -n $build ]]; then rm -rf "$build"; fi' EXIT
 install -d -m 0700 /var/lib/debtik/update
 exec 9>/var/lib/debtik/update/lock
 flock -n 9 || { echo 'An update or installation is already running' >&2;exit 1; }
-if [[ ! -e /usr/sbin/policy-rc.d && ! -L /usr/sbin/policy-rc.d ]];then
- printf '#!/bin/sh\nexit 101\n' > /usr/sbin/policy-rc.d
- chmod 0755 /usr/sbin/policy-rc.d
- policy_created=true
-fi
-export DEBIAN_FRONTEND=noninteractive
-apt-get update
-apt-get install -y --no-install-recommends ca-certificates curl git tar iproute2 bridge-utils iptables ipset conntrack wireguard-tools keepalived pptp-linux bird2 dnsmasq isc-dhcp-client ppp pppoe charon-systemd strongswan-swanctl libcharon-extra-plugins xl2tpd iputils-ping iputils-tracepath traceroute procps openssl certbot python3 util-linux
-required=$(awk '$1=="toolchain" {sub(/^go/,"",$2);print $2}' "$src/go.mod")
-if [[ -z $required ]]; then required=$(awk '$1=="go" {print $2}' "$src/go.mod"); fi
-if ! command -v go >/dev/null || [[ $(printf '%s\n%s\n' "$required" "$(go version | awk '{sub(/^go/,"",$3);print $3}')" | sort -V | head -n1) != "$required" ]]; then
-  case $(uname -m) in x86_64) arch=amd64;; aarch64) arch=arm64;; *) echo 'Unsupported CPU' >&2; exit 1;; esac
-  archive=$(mktemp)
-  curl --fail --location --retry 3 "https://go.dev/dl/go${required}.linux-${arch}.tar.gz" -o "$archive"
-  install -d /opt/debtik
-  rm -rf /opt/debtik/go
-  tar -C /opt/debtik -xzf "$archive"
-  rm -f "$archive"
-  export PATH=/opt/debtik/go/bin:$PATH
-fi
+bash "$src/scripts/install-dependencies.sh"
+if [[ $mode == --dependencies-only ]]; then exit; fi
+export HOME=${HOME:-/root}
+export GOPATH=${GOPATH:-/var/cache/debtik/go}
+export GOCACHE=${GOCACHE:-/var/cache/debtik/go-build}
+if [[ -x /opt/debtik/go/bin/go ]]; then export PATH=/opt/debtik/go/bin:$PATH; fi
 cd "$src"
 build=$(mktemp -d)
 commit=$(git rev-parse HEAD 2>/dev/null || printf unknown)
+echo "Building DebTik server for $(uname -m); the first build may take several minutes..."
 CGO_ENABLED=0 go build -trimpath -ldflags "-X proxmox-router/internal/api.BuildCommit=$commit" -o "$build/proxmox-router" ./cmd/server
+echo "Building DebTik CLI..."
 CGO_ENABLED=0 go build -trimpath -o "$build/debtik-cli" ./cmd/debtik-cli
 install -d -m 0700 /etc/proxmox-router
 install -d -m 0700 /var/lib/debtik/update

+ 156 - 0
scripts/install-dependencies.sh

@@ -0,0 +1,156 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+export HOME=${HOME:-/root}
+export GOPATH=${GOPATH:-/var/cache/debtik/go}
+export GOCACHE=${GOCACHE:-/var/cache/debtik/go-build}
+src=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
+mode=${1:-install}
+[[ $# -le 1 && ( $mode == install || $mode == --check ) ]] || { echo 'Usage: install-dependencies.sh [--check]' >&2; exit 2; }
+packages=(
+  bash coreutils grep gawk sed findutils util-linux systemd procps
+  ca-certificates curl git openssh-client tar python3 openssl tzdata
+  iproute2 bridge-utils iptables ipset conntrack wireguard-tools
+  keepalived bird2 dnsmasq isc-dhcp-client
+  ppp pppoe pptp-linux pptpd xl2tpd
+  charon-systemd strongswan-swanctl libstrongswan-standard-plugins
+  libcharon-extra-plugins libcharon-extauth-plugins
+  iputils-ping iputils-tracepath traceroute bind9-dnsutils mtr-tiny
+)
+installed() { [[ $(dpkg-query -W -f='${db:Status-Status}' "$1" 2>/dev/null || :) == installed ]]; }
+required=$(awk '$1=="toolchain" {sub(/^go/,"",$2); print $2}' "$src/go.mod")
+if [[ -z $required ]]; then required=$(awk '$1=="go" {print $2}' "$src/go.mod"); fi
+[[ $required =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]] || { echo 'Invalid Go version in go.mod' >&2; exit 1; }
+go_version_ok() {
+  local actual
+  actual=$(GOTOOLCHAIN=local "$1" version 2>/dev/null | awk '{sub(/^go/,"",$3);print $3}') || return 1
+  [[ -n $actual && $(printf '%s\n%s\n' "$required" "$actual" | sort -V | head -n1) == "$required" ]]
+}
+check_dependencies() {
+  local missing=0 package binary go_cmd
+  for package in "${packages[@]}"; do
+    if ! installed "$package"; then echo "Missing package: $package" >&2; missing=1; fi
+  done
+  if ! installed ifupdown && ! installed ifupdown2; then echo 'Missing ifupdown or ifupdown2' >&2; missing=1; fi
+  for binary in ssh ip bridge brctl iptables ip6tables iptables-save ip6tables-save iptables-restore ip6tables-restore ipset conntrack wg wg-quick keepalived bird birdc dnsmasq dhclient pppd pon poff pppoe-server pptp pptpd xl2tpd swanctl ping tracepath traceroute dig mtr mstpd mstpctl systemctl systemd-run hostnamectl timedatectl pkill flock python3; do
+    if ! command -v "$binary" >/dev/null; then echo "Missing command: $binary" >&2; missing=1; fi
+  done
+  go_cmd=$(command -v go || :)
+  if [[ -x /opt/debtik/go/bin/go ]]; then go_cmd=/opt/debtik/go/bin/go; fi
+  if [[ -z $go_cmd ]] || ! go_version_ok "$go_cmd"; then echo "Missing Go >= $required" >&2; missing=1; fi
+  if (( missing )); then return 1; fi
+  echo "All DebTik dependencies available (Go >= $required, including RSTP)."
+}
+if [[ $mode == --check ]]; then check_dependencies; exit; fi
+[[ $EUID -eq 0 ]] || { echo 'Run as root' >&2; exit 1; }
+command -v apt-get >/dev/null || { echo 'Debian apt-get required' >&2; exit 1; }
+install -d -m 0700 /var/lib/debtik/update
+# Reuse the installer's inherited lock, or acquire it for a standalone repair.
+if [[ $(readlink /proc/self/fd/9 2>/dev/null || :) != /var/lib/debtik/update/lock ]]; then exec 9>/var/lib/debtik/update/lock; fi
+flock -n 9 || { echo 'An update or installation is already running' >&2; exit 1; }
+policy_created=false
+work=''
+cleanup() {
+  if [[ -n $work ]]; then rm -rf "$work"; fi
+  if [[ $policy_created == true ]]; then rm -f /usr/sbin/policy-rc.d; fi
+}
+trap cleanup EXIT
+if [[ ! -e /usr/sbin/policy-rc.d && ! -L /usr/sbin/policy-rc.d ]]; then
+  printf '#!/bin/sh\nexit 101\n' > /usr/sbin/policy-rc.d
+  chmod 0755 /usr/sbin/policy-rc.d
+  policy_created=true
+fi
+export DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=l
+apt-get update
+# Proxmox normally uses ifupdown2; retain that implementation.
+if ! installed ifupdown && ! installed ifupdown2; then packages+=(ifupdown); fi
+apt-get install -y --no-install-recommends "${packages[@]}"
+work=$(mktemp -d)
+if ! command -v mstpd >/dev/null || ! command -v mstpctl >/dev/null; then
+  candidate=$(apt-cache policy mstpd | awk '/Candidate:/ {print $2}')
+  if [[ -n $candidate && $candidate != '(none)' ]]; then
+    apt-get install -y --no-install-recommends mstpd
+  else
+    apt-get install -y --no-install-recommends gcc make libc6-dev autoconf automake libtool pkg-config
+    # Upstream release 0.2.0, pinned to a commit and verified archive digest.
+    mstpd_commit=8995e5d11ee89f2251734e34cea711bb5a5bb911
+    curl --fail --location --retry 3 "https://codeload.github.com/mstpd/mstpd/tar.gz/$mstpd_commit" -o "$work/mstpd.tar.gz"
+    printf '%s  %s\n' f965e715c82640484f89fcf11cd85dbd86c325dcf42ef85bd15173d9a9aa45b3 "$work/mstpd.tar.gz" | sha256sum -c -
+    mkdir "$work/mstpd"
+    tar --strip-components=1 -C "$work/mstpd" -xzf "$work/mstpd.tar.gz"
+    (
+      cd "$work/mstpd"
+      # The archive has no .git metadata; supply its verified revision label.
+      sed -i 's/^PACKAGE_BUILD=.*/PACKAGE_BUILD=8995e5d/' configure.ac
+      ./autogen.sh
+      ./configure --prefix=/usr/local --exec-prefix=/usr/local --sysconfdir=/etc --localstatedir=/var
+      make -j2 mstpd mstpctl
+    )
+    install -m 0755 "$work/mstpd/mstpd" /usr/local/sbin/mstpd.next
+    install -m 0755 "$work/mstpd/mstpctl" /usr/local/sbin/mstpctl.next
+    mv -f /usr/local/sbin/mstpd.next /usr/local/sbin/mstpd
+    mv -f /usr/local/sbin/mstpctl.next /usr/local/sbin/mstpctl
+    install -d -m 0755 /usr/local/share/doc/debtik-mstpd
+    install -m 0644 "$work/mstpd/LICENSE" /usr/local/share/doc/debtik-mstpd/LICENSE
+    printf '%s\n' "$mstpd_commit" > /usr/local/share/doc/debtik-mstpd/commit
+  fi
+fi
+# Start only the daemon. DebTik explicitly attaches its configured RSTP bridges;
+# upstream global bridge-stp/ifupdown hooks are not installed by the source build.
+if ! systemctl cat mstpd.service >/dev/null 2>&1; then
+  mstpd_binary=$(command -v mstpd)
+  cat > /etc/systemd/system/mstpd.service <<UNIT
+[Unit]
+Description=Spanning Tree Protocol daemon for DebTik
+Before=proxmox-router.service
+[Service]
+Type=simple
+ExecStart=$mstpd_binary -d
+Restart=on-failure
+RestartSec=2
+[Install]
+WantedBy=multi-user.target
+UNIT
+fi
+install -d -m 0755 /etc/systemd/system/proxmox-router.service.d
+cat > /etc/systemd/system/proxmox-router.service.d/mstpd.conf <<'UNIT'
+[Unit]
+Wants=mstpd.service
+After=mstpd.service
+UNIT
+systemctl daemon-reload
+systemctl enable --now mstpd.service
+systemctl is-active --quiet mstpd.service
+
+go_cmd=$(command -v go || :)
+if [[ -x /opt/debtik/go/bin/go ]]; then go_cmd=/opt/debtik/go/bin/go; fi
+if [[ -z $go_cmd ]] || ! go_version_ok "$go_cmd"; then
+  case $(uname -m) in x86_64) arch=amd64;; aarch64) arch=arm64;; *) echo 'Unsupported CPU' >&2; exit 1;; esac
+  archive="go${required}.linux-${arch}.tar.gz"
+  curl --fail --location --retry 3 "https://go.dev/dl/$archive" -o "$work/$archive"
+  curl --fail --location --retry 3 'https://go.dev/dl/?mode=json&include=all' -o "$work/go-releases.json"
+  digest=$(python3 - "$work/go-releases.json" "$archive" <<'PYTHON'
+import json, sys
+with open(sys.argv[1]) as f:
+    releases = json.load(f)
+for release in releases:
+    for item in release['files']:
+        if item['filename'] == sys.argv[2]:
+            print(item['sha256'])
+            raise SystemExit(0)
+raise SystemExit('Go archive is absent from the official release manifest')
+PYTHON
+  )
+  [[ $digest =~ ^[a-f0-9]{64}$ ]] || { echo 'Invalid Go archive checksum' >&2; exit 1; }
+  printf '%s  %s\n' "$digest" "$work/$archive" | sha256sum -c -
+  mkdir "$work/go-stage"
+  tar -C "$work/go-stage" -xzf "$work/$archive"
+  install -d -m 0755 /opt/debtik
+  rm -rf /opt/debtik/go.previous
+  if [[ -d /opt/debtik/go ]]; then mv /opt/debtik/go /opt/debtik/go.previous; fi
+  if ! mv "$work/go-stage/go" /opt/debtik/go; then
+    if [[ -d /opt/debtik/go.previous ]]; then mv /opt/debtik/go.previous /opt/debtik/go; fi
+    exit 1
+  fi
+fi
+check_dependencies