From cb51761427cb46b5f13a113ef8f607b706363e14 Mon Sep 17 00:00:00 2001 From: svefnz Date: Sat, 28 Mar 2026 17:36:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20Alpine=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hy2.sh | 272 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 253 insertions(+), 19 deletions(-) diff --git a/hy2.sh b/hy2.sh index 7352b96..1895350 100644 --- a/hy2.sh +++ b/hy2.sh @@ -3,10 +3,20 @@ set -Eeuo pipefail trap 'echo "[错误] 第 $LINENO 行执行失败:$BASH_COMMAND" >&2' ERR CONFIG_FILE="/etc/hysteria/config.yaml" -SERVICE_NAME="hysteria-server.service" +HYSTERIA_BIN="/usr/local/bin/hysteria" +HYSTERIA_WORK_DIR="/var/lib/hysteria" +SYSTEMD_SERVICE_NAME="hysteria-server.service" +OPENRC_SERVICE_NAME="hysteria-server" +OPENRC_SERVICE_FILE="/etc/init.d/${OPENRC_SERVICE_NAME}" +OPENRC_LOG_FILE="/var/log/${OPENRC_SERVICE_NAME}.log" +SERVICE_NAME="${SYSTEMD_SERVICE_NAME}" DEVICE_USERS=(macminim4 iphone12p ipadmini5 pve_debian other) USERPASS_ENTRIES=() TRAFFIC_STATS_SECRET="" +PACKAGE_MANAGER="" +INIT_SYSTEM="" +OS_ID="" +OS_ID_LIKE="" red() { printf '\033[31m%s\033[0m\n' "$*"; } green() { printf '\033[32m%s\033[0m\n' "$*"; } @@ -33,6 +43,70 @@ import json PY } +is_systemd() { + [[ "${INIT_SYSTEM}" == "systemd" ]] +} + +is_openrc() { + [[ "${INIT_SYSTEM}" == "openrc" ]] +} + +load_os_release() { + if [[ -r /etc/os-release ]]; then + OS_ID="$(awk -F= '/^ID=/{gsub(/"/, "", $2); print $2; exit}' /etc/os-release)" + OS_ID_LIKE="$(awk -F= '/^ID_LIKE=/{gsub(/"/, "", $2); print $2; exit}' /etc/os-release)" + fi +} + +platform_label() { + printf '%s/%s/%s' "${OS_ID:-unknown}" "${PACKAGE_MANAGER:-unknown}" "${INIT_SYSTEM:-unknown}" +} + +detect_platform() { + load_os_release + + if command -v apk >/dev/null 2>&1 || [[ "${OS_ID}" == "alpine" ]] || [[ " ${OS_ID_LIKE} " == *" alpine "* ]]; then + PACKAGE_MANAGER="apk" + INIT_SYSTEM="openrc" + SERVICE_NAME="${OPENRC_SERVICE_NAME}" + if ! command -v rc-service >/dev/null 2>&1 || ! command -v rc-update >/dev/null 2>&1; then + red "检测到 Alpine/apk,但未发现 OpenRC(rc-service/rc-update),无法继续。" + exit 1 + fi + return 0 + fi + + if command -v apt >/dev/null 2>&1; then + PACKAGE_MANAGER="apt" + INIT_SYSTEM="systemd" + SERVICE_NAME="${SYSTEMD_SERVICE_NAME}" + if ! command -v systemctl >/dev/null 2>&1; then + red "检测到 APT 环境,但未发现 systemctl,当前脚本暂不支持该初始化系统。" + exit 1 + fi + return 0 + fi + + red "当前仅支持 Debian/Ubuntu(apt + systemd)和 Alpine(apk + OpenRC)。" + exit 1 +} + +detect_hysteria_arch() { + case "$(uname -m)" in + x86_64|amd64) echo "amd64" ;; + i386|i686) echo "386" ;; + armv5*|arm5*) echo "armv5" ;; + armv6*|armv7*|arm) echo "arm" ;; + aarch64|arm64) echo "arm64" ;; + s390x) echo "s390x" ;; + mips64le|mipsle|mips) echo "mipsle" ;; + riscv64) echo "riscv64" ;; + *) + return 1 + ;; + esac +} + random_subdomain_prefix() { openssl rand -hex 8 | cut -c1-8 } @@ -137,7 +211,7 @@ get_server_ip() { } apt_update_and_install_base() { - if ! confirm_yn "即将执行 apt update 并安装基础依赖 curl sed ufw openssl python3,是否继续?"; then + if ! confirm_yn "即将执行 apt update 并安装基础依赖 curl sed ufw openssl python3 ca-certificates,是否继续?"; then red "已取消。" exit 1 fi @@ -150,7 +224,65 @@ apt_update_and_install_base() { blue "==> 安装基础依赖" wait_for_apt_lock 300 || { red "APT 被占用,无法继续。"; exit 1; } - apt install -y curl sed ufw openssl python3 + apt install -y curl sed ufw openssl python3 ca-certificates +} + +apk_update_and_install_base() { + if ! confirm_yn "即将执行 apk update 并安装基础依赖 bash curl sed ufw ufw-openrc openssl python3 iptables ca-certificates,是否继续?"; then + red "已取消。" + exit 1 + fi + + blue "==> 更新 APK 软件索引" + apk update + + blue "==> 安装基础依赖" + apk add --no-cache bash curl sed ufw ufw-openrc openssl python3 iptables ca-certificates +} + +install_base_dependencies() { + case "${PACKAGE_MANAGER}" in + apt) apt_update_and_install_base ;; + apk) apk_update_and_install_base ;; + *) + red "未知包管理器:${PACKAGE_MANAGER}" + exit 1 + ;; + esac +} + +service_exists() { + local service="$1" + + if is_systemd; then + systemctl list-unit-files 2>/dev/null | grep -Eq "^${service}(\\.service)?" + return $? + fi + + if is_openrc; then + [[ -x "/etc/init.d/${service}" ]] + return $? + fi + + return 1 +} + +stop_and_disable_service() { + local service="$1" + + if is_systemd; then + systemctl stop "${service}" || true + systemctl disable "${service}" || true + return 0 + fi + + if is_openrc; then + rc-service "${service}" stop || true + rc-update del "${service}" default || true + return 0 + fi + + return 1 } disable_existing_firewalls() { @@ -165,19 +297,22 @@ disable_existing_firewalls() { yellow "检测到 UFW,正在关闭并重置" ufw disable || true yes | ufw reset || true + if is_openrc && service_exists ufw; then + rc-service ufw stop || true + fi fi - if systemctl list-unit-files 2>/dev/null | grep -q '^firewalld\.service'; then + if service_exists firewalld; then yellow "检测到 firewalld,正在停止并禁用" - systemctl stop firewalld || true - systemctl disable firewalld || true - systemctl mask firewalld || true + stop_and_disable_service firewalld || true + if is_systemd; then + systemctl mask firewalld || true + fi fi - if systemctl list-unit-files 2>/dev/null | grep -q '^nftables\.service'; then + if service_exists nftables; then yellow "检测到 nftables,正在停止并禁用" - systemctl stop nftables || true - systemctl disable nftables || true + stop_and_disable_service nftables || true fi if command -v nft >/dev/null 2>&1; then @@ -234,9 +369,62 @@ configure_ufw() { ufw allow 443/udp || true yes | ufw enable || true + if is_openrc && service_exists ufw; then + rc-update add ufw default || true + rc-service ufw restart || rc-service ufw start || true + fi + green "UFW 配置完成。" } +write_openrc_service_file() { + mkdir -p "${HYSTERIA_WORK_DIR}" + + cat > "${OPENRC_SERVICE_FILE}" < 下载 Hysteria 2 二进制 (${arch})" + curl -fsSL "${download_url}" -o "${tmp_bin}" + + blue "==> 安装 Hysteria 2 二进制" + install -m 755 "${tmp_bin}" "${HYSTERIA_BIN}" + rm -f "${tmp_bin}" + + write_openrc_service_file +} + install_hysteria2() { if ! confirm_yn "即将安装 Hysteria 2,是否继续?"; then red "已取消 Hysteria 2 安装。" @@ -244,7 +432,13 @@ install_hysteria2() { fi blue "==> 安装 Hysteria 2" - bash <(curl -fsSL https://get.hy2.sh/) + + if is_openrc; then + install_hysteria2_alpine + else + bash <(curl -fsSL https://get.hy2.sh/) + fi + green "Hysteria 2 安装完成。" } @@ -390,6 +584,13 @@ backup_existing_config() { set_config_permissions() { local service_user service_group + if is_openrc; then + chown root:root "${CONFIG_FILE}" + chmod 600 "${CONFIG_FILE}" + green "已按 OpenRC 服务配置将配置文件权限设置为 root:root 600" + return 0 + fi + service_user="$(systemctl show -p User --value "${SERVICE_NAME}" 2>/dev/null || true)" service_user="${service_user//$'\n'/}" @@ -525,12 +726,38 @@ start_service() { fi blue "==> 启动并设置开机自启" - systemctl daemon-reload || true - systemctl enable --now "${SERVICE_NAME}" - systemctl restart "${SERVICE_NAME}" + if is_systemd; then + systemctl daemon-reload || true + systemctl enable --now "${SERVICE_NAME}" + systemctl restart "${SERVICE_NAME}" + else + rc-update add "${SERVICE_NAME}" default || true + rc-service "${SERVICE_NAME}" restart || rc-service "${SERVICE_NAME}" start + fi green "服务已启动。" } +show_service_status() { + if is_systemd; then + systemctl --no-pager --full status "${SERVICE_NAME}" || true + else + rc-service "${SERVICE_NAME}" status || true + pgrep -af "${HYSTERIA_BIN##*/}" || true + fi +} + +show_recent_logs() { + if is_systemd; then + journalctl --no-pager -n 30 -u "${SERVICE_NAME}" || true + else + if [[ -f "${OPENRC_LOG_FILE}" ]]; then + tail -n 30 "${OPENRC_LOG_FILE}" || true + else + yellow "暂未找到 OpenRC 日志文件:${OPENRC_LOG_FILE}" + fi + fi +} + show_result() { local domain="$1" local proxy_url="$2" @@ -544,6 +771,7 @@ show_result() { echo "域名: ${domain}" echo "端口: 443" echo "认证方式: userpass" + echo "服务管理器: ${INIT_SYSTEM}" echo "伪装站点: ${proxy_url}" echo "流量统计监听: 127.0.0.1:9999" echo "流量统计密钥: ${TRAFFIC_STATS_SECRET}" @@ -563,29 +791,35 @@ show_result() { done echo echo "hysteria 状态:" - systemctl --no-pager --full status "${SERVICE_NAME}" || true + show_service_status echo echo "最近日志:" - journalctl --no-pager -n 30 -u "${SERVICE_NAME}" || true + show_recent_logs echo "================================================" } main() { require_root + detect_platform - if ! confirm_yn "本脚本将更新软件源、关闭现有防火墙、配置 UFW、安装并配置 Hysteria 2,是否继续?"; then + if ! confirm_yn "本脚本将更新软件源、关闭现有防火墙、配置 UFW、安装并配置 Hysteria 2(检测到: $(platform_label)),是否继续?"; then red "用户取消执行。" exit 1 fi - apt_update_and_install_base + install_base_dependencies require_cmd curl require_cmd sed - require_cmd systemctl require_cmd ufw require_cmd openssl require_cmd python3 + if is_systemd; then + require_cmd systemctl + else + require_cmd rc-service + require_cmd rc-update + fi require_python3_json || { red "python3 缺少 json 模块,无法解析 Cloudflare API 返回值。"; exit 1; } local email zone subdomain default_subdomain proxy_url ip_info ipv4 ipv6 domain username