From 987c815d076990769780a92adcd1d71f303464a2 Mon Sep 17 00:00:00 2001 From: marauder-actual Date: Fri, 12 Jun 2026 14:55:38 +0200 Subject: [PATCH] Initial madcat-caddy: Caddy + Cloudflare DNS + caddy-security Forked from tengu-apps/tengu-caddy, adding: - caddy-security plugin (OAuth 2.0, Basic Auth, JWT) - Gitea apt registry publishing in CI - Linux-only builds (arm64 + amd64) - Replaces/conflicts with caddy and tengu-caddy packages --- .github/workflows/build.yml | 106 ++++++++++++++++++++++++++++++++++++ .gitignore | 2 + Makefile | 65 ++++++++++++++++++++++ README.md | 81 +++++++++++++++++++++++++++ debian/caddy.service | 23 ++++++++ debian/conffiles | 1 + debian/control | 12 ++++ debian/postinst | 24 ++++++++ debian/postrm | 13 +++++ debian/prerm | 7 +++ 10 files changed, 334 insertions(+) create mode 100644 .github/workflows/build.yml create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 debian/caddy.service create mode 100644 debian/conffiles create mode 100644 debian/control create mode 100644 debian/postinst create mode 100644 debian/postrm create mode 100644 debian/prerm diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..84b770d --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,106 @@ +name: Build and Release + +on: + push: + tags: + - 'v*' + workflow_dispatch: + +permissions: + contents: write + +env: + CADDY_PLUGINS: "github.com/caddy-dns/cloudflare@v0.2.4&p=github.com/greenpau/caddy-security@v1.1.62" + +jobs: + build-deb: + strategy: + matrix: + include: + - arch: amd64 + runner: ubuntu-latest + - arch: arm64 + runner: ubuntu-24.04-arm + + runs-on: ${{ matrix.runner }} + + steps: + - uses: actions/checkout@v4 + + - name: Build .deb package + run: make deb ARCH=${{ matrix.arch }} + + - name: Upload deb artifact + uses: actions/upload-artifact@v4 + with: + name: madcat-caddy-deb-${{ matrix.arch }} + path: build/*.deb + + build-binaries: + strategy: + matrix: + include: + - os: linux + arch: amd64 + asset: madcat-caddy-linux-amd64 + - os: linux + arch: arm64 + asset: madcat-caddy-linux-arm64 + + runs-on: ubuntu-latest + + steps: + - name: Download Caddy with plugins + run: | + curl -fsSL "https://caddyserver.com/api/download?os=${{ matrix.os }}&arch=${{ matrix.arch }}&p=${CADDY_PLUGINS}" \ + -o ${{ matrix.asset }} + chmod +x ${{ matrix.asset }} + file ${{ matrix.asset }} + + - name: Upload binary artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.asset }} + path: ${{ matrix.asset }} + + release: + needs: [build-deb, build-binaries] + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + merge-multiple: true + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + files: artifacts/* + generate_release_notes: true + + publish-apt: + needs: [build-deb] + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + + steps: + - name: Download deb artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + merge-multiple: true + + - name: Publish to Gitea Debian registry + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + run: | + for deb in artifacts/*.deb; do + echo "Publishing $(basename $deb)..." + curl --fail --user "madcat:${GITEA_TOKEN}" \ + --upload-file "$deb" \ + "https://repos.saiden.dev/api/packages/madcat-os/debian/pool/bookworm/main/upload" + echo " -> done" + done diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..93a22b9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +*.deb diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9f1b47e --- /dev/null +++ b/Makefile @@ -0,0 +1,65 @@ +VERSION := 2.11.2 +REVISION := 1 +CADDY_PLUGINS := github.com/caddy-dns/cloudflare@v0.2.4&p=github.com/greenpau/caddy-security@v1.1.62 + +ARCH := $(shell dpkg --print-architecture 2>/dev/null || uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/') +OS := linux +PACKAGE_NAME := madcat-caddy +DEB_NAME := $(PACKAGE_NAME)_$(VERSION)-$(REVISION)_$(ARCH).deb + +BUILD_DIR := build +STAGING_DIR := $(BUILD_DIR)/staging + +.PHONY: all clean build deb install + +all: deb + +clean: + rm -rf $(BUILD_DIR) + +# Download pre-built Caddy with plugins from official API +$(BUILD_DIR)/caddy: + @mkdir -p $(BUILD_DIR) + @echo "Downloading Caddy $(VERSION) for $(OS)/$(ARCH) with plugins..." + curl -sL "https://caddyserver.com/api/download?os=$(OS)&arch=$(ARCH)&p=$(CADDY_PLUGINS)" -o $@ + chmod +x $@ + @echo "Verifying binary..." + @file $@ + +build: $(BUILD_DIR)/caddy + +# Build .deb package +deb: $(BUILD_DIR)/caddy + @echo "Building .deb package..." + @mkdir -p $(STAGING_DIR)/DEBIAN + @mkdir -p $(STAGING_DIR)/usr/bin + @mkdir -p $(STAGING_DIR)/usr/lib/systemd/system + @mkdir -p $(STAGING_DIR)/etc/caddy + + @# Binary + cp $(BUILD_DIR)/caddy $(STAGING_DIR)/usr/bin/caddy + + @# Systemd service + cp debian/caddy.service $(STAGING_DIR)/usr/lib/systemd/system/ + + @# Default Caddyfile + cp debian/Caddyfile $(STAGING_DIR)/etc/caddy/ + + @# Control file + sed 's/{{VERSION}}/$(VERSION)-$(REVISION)/g; s/{{ARCH}}/$(ARCH)/g' debian/control > $(STAGING_DIR)/DEBIAN/control + + @# Scripts + cp debian/postinst $(STAGING_DIR)/DEBIAN/ + cp debian/prerm $(STAGING_DIR)/DEBIAN/ + cp debian/postrm $(STAGING_DIR)/DEBIAN/ + chmod 755 $(STAGING_DIR)/DEBIAN/postinst $(STAGING_DIR)/DEBIAN/prerm $(STAGING_DIR)/DEBIAN/postrm + + @# Conffiles + cp debian/conffiles $(STAGING_DIR)/DEBIAN/ + + @# Build package + dpkg-deb --build $(STAGING_DIR) $(BUILD_DIR)/$(DEB_NAME) + @echo "Built: $(BUILD_DIR)/$(DEB_NAME)" + +install: deb + sudo dpkg -i $(BUILD_DIR)/$(DEB_NAME) diff --git a/README.md b/README.md new file mode 100644 index 0000000..da2bb03 --- /dev/null +++ b/README.md @@ -0,0 +1,81 @@ +# madcat-caddy + +Caddy web server with **Cloudflare DNS** and **caddy-security** plugins built in. +Pre-built `.deb` packages for Linux servers. + +## Plugins + +| Plugin | Purpose | +|---|---| +| [caddy-dns/cloudflare](https://github.com/caddy-dns/cloudflare) | DNS-01 ACME challenge via Cloudflare API | +| [caddy-security](https://github.com/greenpau/caddy-security) | OAuth 2.0 (GitHub, Google, etc.), Basic Auth, JWT authorization | + +## Install + +### APT (Debian/Ubuntu) + +```bash +# Add signing key +sudo curl https://repos.saiden.dev/api/packages/madcat-os/debian/repository.key \ + -o /etc/apt/keyrings/madcat-os.asc + +# Add repository +echo "deb [signed-by=/etc/apt/keyrings/madcat-os.asc] https://repos.saiden.dev/api/packages/madcat-os/debian bookworm main" \ + | sudo tee /etc/apt/sources.list.d/madcat-os.list + +# Install +sudo apt update +sudo apt install madcat-caddy +``` + +### Manual .deb + +Download from [Releases](https://github.com/madcat-os/madcat-caddy/releases): + +```bash +# ARM64 +curl -fsSLO https://github.com/madcat-os/madcat-caddy/releases/latest/download/madcat-caddy_2.11.2-1_arm64.deb +sudo dpkg -i madcat-caddy_2.11.2-1_arm64.deb + +# AMD64 +curl -fsSLO https://github.com/madcat-os/madcat-caddy/releases/latest/download/madcat-caddy_2.11.2-1_amd64.deb +sudo dpkg -i madcat-caddy_2.11.2-1_amd64.deb +``` + +## Configuration + +Edit `/etc/caddy/Caddyfile`: + +``` +{ + email you@example.com + acme_dns cloudflare {env.CF_API_TOKEN} +} + +example.com { + reverse_proxy localhost:8080 +} +``` + +For Cloudflare API token: + +```bash +sudo mkdir -p /etc/systemd/system/caddy.service.d +sudo tee /etc/systemd/system/caddy.service.d/env.conf << EOF +[Service] +Environment="CF_API_TOKEN=your-cloudflare-api-token" +EOF +sudo systemctl daemon-reload +sudo systemctl restart caddy +``` + +## Building + +```bash +make deb ARCH=arm64 +make deb ARCH=amd64 +``` + +## License + +Caddy is licensed under Apache 2.0. This packaging is MIT. diff --git a/debian/caddy.service b/debian/caddy.service new file mode 100644 index 0000000..aacc0b2 --- /dev/null +++ b/debian/caddy.service @@ -0,0 +1,23 @@ +[Unit] +Description=Caddy web server (madcat-caddy) +Documentation=https://caddyserver.com/docs/ +After=network.target network-online.target +Requires=network-online.target + +[Service] +Type=notify +User=caddy +Group=caddy +ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile +ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force +TimeoutStopSec=5s +LimitNOFILE=1048576 +LimitNPROC=512 +PrivateTmp=true +ProtectSystem=full +AmbientCapabilities=CAP_NET_BIND_SERVICE +CapabilityBoundingSet=CAP_NET_BIND_SERVICE +NoNewPrivileges=true + +[Install] +WantedBy=multi-user.target diff --git a/debian/conffiles b/debian/conffiles new file mode 100644 index 0000000..f296f4e --- /dev/null +++ b/debian/conffiles @@ -0,0 +1 @@ +/etc/caddy/Caddyfile diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..3049903 --- /dev/null +++ b/debian/control @@ -0,0 +1,12 @@ +Package: madcat-caddy +Version: {{VERSION}} +Architecture: {{ARCH}} +Maintainer: madcat-os +Description: Caddy web server with Cloudflare DNS and caddy-security plugins + Custom Caddy build with Cloudflare DNS-01 ACME challenge support + and caddy-security (OAuth 2.0, Basic Auth, JWT authorization). + Provides GitHub OAuth + Basic Auth gateway capabilities. +Section: web +Priority: optional +Conflicts: caddy +Replaces: caddy, tengu-caddy diff --git a/debian/postinst b/debian/postinst new file mode 100644 index 0000000..737a12f --- /dev/null +++ b/debian/postinst @@ -0,0 +1,24 @@ +#!/bin/sh +set -e + +# Create caddy user/group if they don't exist +if ! getent group caddy >/dev/null 2>&1; then + groupadd --system caddy +fi + +if ! getent passwd caddy >/dev/null 2>&1; then + useradd --system --gid caddy --create-home --home-dir /var/lib/caddy --shell /usr/sbin/nologin caddy +fi + +# Create config and data directories +mkdir -p /etc/caddy +mkdir -p /var/lib/caddy/.config/caddy +mkdir -p /var/lib/caddy/.local/share/caddy +chown -R caddy:caddy /var/lib/caddy + +# Enable and start the service +if [ -d /run/systemd/system ]; then + systemctl daemon-reload + systemctl enable caddy.service + systemctl start caddy.service || true +fi diff --git a/debian/postrm b/debian/postrm new file mode 100644 index 0000000..517c32e --- /dev/null +++ b/debian/postrm @@ -0,0 +1,13 @@ +#!/bin/sh +set -e + +if [ "$1" = "purge" ]; then + rm -rf /etc/caddy + rm -rf /var/lib/caddy + userdel caddy 2>/dev/null || true + groupdel caddy 2>/dev/null || true +fi + +if [ -d /run/systemd/system ]; then + systemctl daemon-reload +fi diff --git a/debian/prerm b/debian/prerm new file mode 100644 index 0000000..15a5ca1 --- /dev/null +++ b/debian/prerm @@ -0,0 +1,7 @@ +#!/bin/sh +set -e + +if [ -d /run/systemd/system ]; then + systemctl stop caddy.service || true + systemctl disable caddy.service || true +fi