From 929c527ad0746cf2acc208c3aee7e7c729945870 Mon Sep 17 00:00:00 2001 From: m1ngsama Date: Sat, 28 Feb 2026 02:00:52 +0800 Subject: [PATCH] fix: bundle config templates, add find_template fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deploy scripts now look for templates in INFRA_DIR first, then fall back to the bundled copies in automa. This makes automa fully self-contained: a .env with filled values is all that is needed — no infra checkout required. Bundle: config.json.example, privoxy.conf.example, shadowsocks-client.service, shadowsocks-rust.service, frps.toml.example, frps.service, frpc.toml.example, frpc.service --- services/frp/client/deploy.sh | 42 +++++++++++++------ services/frp/client/frpc.service | 15 +++++++ services/frp/client/frpc.toml.example | 21 ++++++++++ services/frp/server/deploy.sh | 42 +++++++++++++------ services/frp/server/frps.service | 15 +++++++ services/frp/server/frps.toml.example | 17 ++++++++ .../shadowsocks/client/config.json.example | 11 +++++ services/shadowsocks/client/deploy.sh | 21 ++++++++-- .../shadowsocks/client/privoxy.conf.example | 5 +++ .../client/shadowsocks-client.service | 14 +++++++ .../shadowsocks/server/config.json.example | 10 +++++ services/shadowsocks/server/deploy.sh | 16 ++++++- .../server/shadowsocks-rust.service | 14 +++++++ 13 files changed, 213 insertions(+), 30 deletions(-) create mode 100644 services/frp/client/frpc.service create mode 100644 services/frp/client/frpc.toml.example create mode 100644 services/frp/server/frps.service create mode 100644 services/frp/server/frps.toml.example create mode 100644 services/shadowsocks/client/config.json.example create mode 100644 services/shadowsocks/client/privoxy.conf.example create mode 100644 services/shadowsocks/client/shadowsocks-client.service create mode 100644 services/shadowsocks/server/config.json.example create mode 100644 services/shadowsocks/server/shadowsocks-rust.service diff --git a/services/frp/client/deploy.sh b/services/frp/client/deploy.sh index 4dd9f4b..8f6668c 100755 --- a/services/frp/client/deploy.sh +++ b/services/frp/client/deploy.sh @@ -12,22 +12,40 @@ source "$ENV_FILE" require_env FRP_SERVER_ADDR FRP_SERVER_PORT FRP_TOKEN -log_info "Downloading FRP..." -VERSION=$(curl -s https://api.github.com/repos/fatedier/frp/releases/latest \ - | python3 -c "import sys,json; print(json.load(sys.stdin)['tag_name'][1:])") -ARCHIVE="frp_${VERSION}_linux_amd64.tar.gz" -wget -q "https://github.com/fatedier/frp/releases/download/v${VERSION}/${ARCHIVE}" -tar -xf "$ARCHIVE" -mkdir -p /opt/frp -cp "frp_${VERSION}_linux_amd64/frpc" /opt/frp/ -chmod +x /opt/frp/frpc -rm -rf "$ARCHIVE" "frp_${VERSION}_linux_amd64" +find_template() { + local f="$1" + if [[ -n "${INFRA_DIR:-}" && -f "${INFRA_DIR}/$f" ]]; then + echo "${INFRA_DIR}/$f" + elif [[ -f "$SCRIPT_DIR/$f" ]]; then + echo "$SCRIPT_DIR/$f" + else + log_error "Template not found: $f" + return 1 + fi +} + +FRPC_BIN="/opt/frp/frpc" + +if [[ -x "$FRPC_BIN" ]]; then + log_info "frpc already at $FRPC_BIN, skipping download" +else + log_info "Downloading FRP..." + VERSION=$(curl -s https://api.github.com/repos/fatedier/frp/releases/latest \ + | python3 -c "import sys,json; print(json.load(sys.stdin)['tag_name'][1:])") + ARCHIVE="frp_${VERSION}_linux_amd64.tar.gz" + wget -q "https://github.com/fatedier/frp/releases/download/v${VERSION}/${ARCHIVE}" + tar -xf "$ARCHIVE" + mkdir -p /opt/frp + cp "frp_${VERSION}_linux_amd64/frpc" /opt/frp/ + chmod +x /opt/frp/frpc + rm -rf "$ARCHIVE" "frp_${VERSION}_linux_amd64" +fi log_info "Deploying config..." -envsubst < "${INFRA_DIR}/frpc.toml.example" > /opt/frp/frpc.toml +envsubst < "$(find_template frpc.toml.example)" > /opt/frp/frpc.toml log_info "Installing service..." -cp "${INFRA_DIR}/frpc.service" /etc/systemd/system/ +cp "$(find_template frpc.service)" /etc/systemd/system/ systemctl daemon-reload systemctl enable --now frpc diff --git a/services/frp/client/frpc.service b/services/frp/client/frpc.service new file mode 100644 index 0000000..5154d26 --- /dev/null +++ b/services/frp/client/frpc.service @@ -0,0 +1,15 @@ +[Unit] +Description=FRP Client +After=network.target + +[Service] +Type=simple +ExecStart=/opt/frp/frpc -c /opt/frp/frpc.toml +WorkingDirectory=/opt/frp +Restart=on-failure +RestartSec=5 +User=root +Group=root + +[Install] +WantedBy=multi-user.target diff --git a/services/frp/client/frpc.toml.example b/services/frp/client/frpc.toml.example new file mode 100644 index 0000000..1344512 --- /dev/null +++ b/services/frp/client/frpc.toml.example @@ -0,0 +1,21 @@ +serverAddr = "${FRP_SERVER_ADDR}" +serverPort = ${FRP_SERVER_PORT} + +auth.method = "token" +auth.token = "${FRP_TOKEN}" + +# Example: expose home SSH +[[proxies]] +name = "home-ssh" +type = "tcp" +localIP = "127.0.0.1" +localPort = 22 +remotePort = 1234 + +# Example: expose Minecraft +[[proxies]] +name = "minecraft" +type = "tcp" +localIP = "127.0.0.1" +localPort = 25565 +remotePort = 25565 diff --git a/services/frp/server/deploy.sh b/services/frp/server/deploy.sh index 377b9a9..db57fff 100755 --- a/services/frp/server/deploy.sh +++ b/services/frp/server/deploy.sh @@ -12,22 +12,40 @@ source "$ENV_FILE" require_env FRP_TOKEN FRP_WEB_PASSWORD FRP_BIND_PORT -log_info "Downloading FRP..." -VERSION=$(curl -s https://api.github.com/repos/fatedier/frp/releases/latest \ - | python3 -c "import sys,json; print(json.load(sys.stdin)['tag_name'][1:])") -ARCHIVE="frp_${VERSION}_linux_amd64.tar.gz" -wget -q "https://github.com/fatedier/frp/releases/download/v${VERSION}/${ARCHIVE}" -tar -xf "$ARCHIVE" -mkdir -p /opt/frp -cp "frp_${VERSION}_linux_amd64/frps" /opt/frp/ -chmod +x /opt/frp/frps -rm -rf "$ARCHIVE" "frp_${VERSION}_linux_amd64" +find_template() { + local f="$1" + if [[ -n "${INFRA_DIR:-}" && -f "${INFRA_DIR}/$f" ]]; then + echo "${INFRA_DIR}/$f" + elif [[ -f "$SCRIPT_DIR/$f" ]]; then + echo "$SCRIPT_DIR/$f" + else + log_error "Template not found: $f" + return 1 + fi +} + +FRPS_BIN="/opt/frp/frps" + +if [[ -x "$FRPS_BIN" ]]; then + log_info "frps already at $FRPS_BIN, skipping download" +else + log_info "Downloading FRP..." + VERSION=$(curl -s https://api.github.com/repos/fatedier/frp/releases/latest \ + | python3 -c "import sys,json; print(json.load(sys.stdin)['tag_name'][1:])") + ARCHIVE="frp_${VERSION}_linux_amd64.tar.gz" + wget -q "https://github.com/fatedier/frp/releases/download/v${VERSION}/${ARCHIVE}" + tar -xf "$ARCHIVE" + mkdir -p /opt/frp + cp "frp_${VERSION}_linux_amd64/frps" /opt/frp/ + chmod +x /opt/frp/frps + rm -rf "$ARCHIVE" "frp_${VERSION}_linux_amd64" +fi log_info "Deploying config..." -envsubst < "${INFRA_DIR}/frps.toml.example" > /opt/frp/frps.toml +envsubst < "$(find_template frps.toml.example)" > /opt/frp/frps.toml log_info "Installing service..." -cp "${INFRA_DIR}/frps.service" /etc/systemd/system/ +cp "$(find_template frps.service)" /etc/systemd/system/ systemctl daemon-reload systemctl enable --now frps diff --git a/services/frp/server/frps.service b/services/frp/server/frps.service new file mode 100644 index 0000000..64a921d --- /dev/null +++ b/services/frp/server/frps.service @@ -0,0 +1,15 @@ +[Unit] +Description=FRP Server +After=network.target + +[Service] +Type=simple +ExecStart=/opt/frp/frps -c /opt/frp/frps.toml +WorkingDirectory=/opt/frp +Restart=on-failure +RestartSec=5 +User=root +Group=root + +[Install] +WantedBy=multi-user.target diff --git a/services/frp/server/frps.toml.example b/services/frp/server/frps.toml.example new file mode 100644 index 0000000..c9e9834 --- /dev/null +++ b/services/frp/server/frps.toml.example @@ -0,0 +1,17 @@ +bindAddr = "0.0.0.0" +bindPort = ${FRP_BIND_PORT} + +vhostHTTPPort = 8080 +vhostHTTPSPort = 8443 + +webServer.addr = "127.0.0.1" +webServer.port = 7500 +webServer.user = "root" +webServer.password = "${FRP_WEB_PASSWORD}" + +log.to = "./frps.log" +log.level = "info" +log.maxDays = 3 + +auth.method = "token" +auth.token = "${FRP_TOKEN}" diff --git a/services/shadowsocks/client/config.json.example b/services/shadowsocks/client/config.json.example new file mode 100644 index 0000000..7d6b57b --- /dev/null +++ b/services/shadowsocks/client/config.json.example @@ -0,0 +1,11 @@ +{ + "server": "${SS_SERVER}", + "server_port": ${SS_PORT}, + "password": "${SS_PASSWORD}", + "method": "${SS_METHOD}", + "local_address": "127.0.0.1", + "local_port": 1080, + "timeout": 300, + "fast_open": true, + "mode": "tcp_and_udp" +} diff --git a/services/shadowsocks/client/deploy.sh b/services/shadowsocks/client/deploy.sh index 002ec83..f2aeca0 100755 --- a/services/shadowsocks/client/deploy.sh +++ b/services/shadowsocks/client/deploy.sh @@ -12,9 +12,22 @@ source "$ENV_FILE" require_env SS_SERVER SS_PORT SS_PASSWORD SS_METHOD +# Find a template file: prefer INFRA_DIR override, fall back to bundled default. +find_template() { + local f="$1" + if [[ -n "${INFRA_DIR:-}" && -f "${INFRA_DIR}/$f" ]]; then + echo "${INFRA_DIR}/$f" + elif [[ -f "$SCRIPT_DIR/$f" ]]; then + echo "$SCRIPT_DIR/$f" + else + log_error "Template not found: $f" + return 1 + fi +} + SSLOCAL_BIN="/usr/local/bin/sslocal" -# Install sslocal — skip download if already present, symlink if installed elsewhere +# Install sslocal — skip if already present, symlink if installed elsewhere. if [[ -x "$SSLOCAL_BIN" ]]; then log_info "sslocal already at $SSLOCAL_BIN ($($SSLOCAL_BIN --version 2>&1 | head -1)), skipping download" elif command -v sslocal &>/dev/null; then @@ -42,14 +55,14 @@ fi log_info "Deploying configs..." mkdir -p /etc/shadowsocks-rust -envsubst < "${INFRA_DIR}/config.json.example" > /etc/shadowsocks-rust/client.json -cp "${INFRA_DIR}/privoxy.conf.example" /etc/privoxy/config +envsubst < "$(find_template config.json.example)" > /etc/shadowsocks-rust/client.json +cp "$(find_template privoxy.conf.example)" /etc/privoxy/config log_info "Stopping any existing shadowsocks service on port 1080..." systemctl stop shadowsocks 2>/dev/null || true log_info "Installing service..." -cp "${INFRA_DIR}/shadowsocks-client.service" /etc/systemd/system/ +cp "$(find_template shadowsocks-client.service)" /etc/systemd/system/ systemctl daemon-reload systemctl enable --now shadowsocks-client systemctl enable --now privoxy diff --git a/services/shadowsocks/client/privoxy.conf.example b/services/shadowsocks/client/privoxy.conf.example new file mode 100644 index 0000000..271210c --- /dev/null +++ b/services/shadowsocks/client/privoxy.conf.example @@ -0,0 +1,5 @@ +# Privoxy config — bridges SOCKS5 (sslocal) to HTTP proxy +# Listens on :8118, forwards to sslocal SOCKS5 on :1080 + +listen-address 127.0.0.1:8118 +forward-socks5t / 127.0.0.1:1080 . diff --git a/services/shadowsocks/client/shadowsocks-client.service b/services/shadowsocks/client/shadowsocks-client.service new file mode 100644 index 0000000..4977c01 --- /dev/null +++ b/services/shadowsocks/client/shadowsocks-client.service @@ -0,0 +1,14 @@ +[Unit] +Description=Shadowsocks-Rust Client +Documentation=https://github.com/shadowsocks/shadowsocks-rust +After=network.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/sslocal -c /etc/shadowsocks-rust/client.json +Restart=on-failure +RestartSec=5 +LimitNOFILE=51200 + +[Install] +WantedBy=multi-user.target diff --git a/services/shadowsocks/server/config.json.example b/services/shadowsocks/server/config.json.example new file mode 100644 index 0000000..e1c9468 --- /dev/null +++ b/services/shadowsocks/server/config.json.example @@ -0,0 +1,10 @@ +{ + "server": "0.0.0.0", + "server_port": ${SS_PORT}, + "password": "${SS_PASSWORD}", + "method": "${SS_METHOD}", + "timeout": 300, + "fast_open": true, + "no_delay": true, + "mode": "tcp_and_udp" +} diff --git a/services/shadowsocks/server/deploy.sh b/services/shadowsocks/server/deploy.sh index 455a25b..dda0cf0 100755 --- a/services/shadowsocks/server/deploy.sh +++ b/services/shadowsocks/server/deploy.sh @@ -12,6 +12,18 @@ source "$ENV_FILE" require_env SS_PORT SS_PASSWORD SS_METHOD +find_template() { + local f="$1" + if [[ -n "${INFRA_DIR:-}" && -f "${INFRA_DIR}/$f" ]]; then + echo "${INFRA_DIR}/$f" + elif [[ -f "$SCRIPT_DIR/$f" ]]; then + echo "$SCRIPT_DIR/$f" + else + log_error "Template not found: $f" + return 1 + fi +} + SSSERVER_BIN="/usr/local/bin/ssserver-rust" if [[ -x "$SSSERVER_BIN" ]]; then @@ -34,10 +46,10 @@ fi log_info "Deploying config..." mkdir -p /etc/shadowsocks-rust -envsubst < "${INFRA_DIR}/config.json.example" > /etc/shadowsocks-rust/config.json +envsubst < "$(find_template config.json.example)" > /etc/shadowsocks-rust/config.json log_info "Installing service..." -cp "${INFRA_DIR}/shadowsocks-rust.service" /etc/systemd/system/ +cp "$(find_template shadowsocks-rust.service)" /etc/systemd/system/ systemctl daemon-reload systemctl enable --now shadowsocks-rust diff --git a/services/shadowsocks/server/shadowsocks-rust.service b/services/shadowsocks/server/shadowsocks-rust.service new file mode 100644 index 0000000..c1dec81 --- /dev/null +++ b/services/shadowsocks/server/shadowsocks-rust.service @@ -0,0 +1,14 @@ +[Unit] +Description=Shadowsocks-Rust Server +Documentation=https://github.com/shadowsocks/shadowsocks-rust +After=network.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/ssserver-rust -c /etc/shadowsocks-rust/config.json +Restart=on-failure +RestartSec=5 +LimitNOFILE=51200 + +[Install] +WantedBy=multi-user.target