Update hy2 server config template generation
This commit is contained in:
191
hy2.sh
191
hy2.sh
@@ -4,6 +4,9 @@ trap 'echo "[错误] 第 $LINENO 行执行失败:$BASH_COMMAND" >&2' ERR
|
||||
|
||||
CONFIG_FILE="/etc/hysteria/config.yaml"
|
||||
SERVICE_NAME="hysteria-server.service"
|
||||
DEVICE_USERS=(macminim4 iphone12p ipadmini5 pve_debian other)
|
||||
USERPASS_ENTRIES=()
|
||||
TRAFFIC_STATS_SECRET=""
|
||||
|
||||
red() { printf '\033[31m%s\033[0m\n' "$*"; }
|
||||
green() { printf '\033[32m%s\033[0m\n' "$*"; }
|
||||
@@ -89,8 +92,16 @@ wait_for_apt_lock() {
|
||||
}
|
||||
|
||||
generate_password() {
|
||||
openssl rand -base64 24 | tr -dc 'A-Za-z0-9' | head -c 24
|
||||
echo
|
||||
local length="${1:-36}"
|
||||
local password=""
|
||||
|
||||
while ((${#password} < length)); do
|
||||
password+="$(
|
||||
openssl rand -base64 48 | tr -dc 'A-Za-z0-9'
|
||||
)"
|
||||
done
|
||||
|
||||
printf '%s\n' "${password:0:length}"
|
||||
}
|
||||
|
||||
mask_secret() {
|
||||
@@ -103,6 +114,13 @@ mask_secret() {
|
||||
fi
|
||||
}
|
||||
|
||||
yaml_quote() {
|
||||
local value="$1"
|
||||
value="${value//\\/\\\\}"
|
||||
value="${value//\"/\\\"}"
|
||||
printf '"%s"' "$value"
|
||||
}
|
||||
|
||||
validate_domain() {
|
||||
local domain="$1"
|
||||
[[ -n "$domain" ]] || return 1
|
||||
@@ -369,12 +387,75 @@ backup_existing_config() {
|
||||
fi
|
||||
}
|
||||
|
||||
write_config() {
|
||||
render_userpass_block() {
|
||||
local indent="${1:-4}"
|
||||
local prefix="" entry username password
|
||||
|
||||
prefix="$(printf '%*s' "${indent}" '')"
|
||||
for entry in "${USERPASS_ENTRIES[@]}"; do
|
||||
username="${entry%%:*}"
|
||||
password="${entry#*:}"
|
||||
printf '%s%s: %s\n' "${prefix}" "${username}" "$(yaml_quote "$password")"
|
||||
done
|
||||
}
|
||||
|
||||
render_config() {
|
||||
local domain="$1"
|
||||
local email="$2"
|
||||
local cf_token="$3"
|
||||
local password="$4"
|
||||
local proxy_url="$5"
|
||||
local proxy_url="$4"
|
||||
|
||||
cat <<EOF
|
||||
listen: :443
|
||||
|
||||
acme:
|
||||
domains:
|
||||
- $(yaml_quote "$domain")
|
||||
email: $(yaml_quote "$email")
|
||||
type: dns
|
||||
dns:
|
||||
name: cloudflare
|
||||
config:
|
||||
cloudflare_api_token: $(yaml_quote "$cf_token")
|
||||
|
||||
auth:
|
||||
type: userpass
|
||||
userpass:
|
||||
EOF
|
||||
render_userpass_block 4
|
||||
cat <<EOF
|
||||
|
||||
trafficStats:
|
||||
listen: 127.0.0.1:9999
|
||||
secret: $(yaml_quote "$TRAFFIC_STATS_SECRET")
|
||||
|
||||
disableUDP: false
|
||||
udpIdleTimeout: 90s
|
||||
|
||||
resolver:
|
||||
type: https
|
||||
https:
|
||||
addr: 1.1.1.1:443
|
||||
timeout: 10s
|
||||
sni: cloudflare-dns.com
|
||||
insecure: false
|
||||
|
||||
speedTest: true
|
||||
|
||||
masquerade:
|
||||
type: proxy
|
||||
proxy:
|
||||
url: $(yaml_quote "$proxy_url")
|
||||
rewriteHost: true
|
||||
insecure: false
|
||||
EOF
|
||||
}
|
||||
|
||||
render_preview_config() {
|
||||
local domain="$1"
|
||||
local email="$2"
|
||||
local cf_token="$3"
|
||||
local proxy_url="$4"
|
||||
local masked_token
|
||||
|
||||
if ! validate_domain "$domain"; then
|
||||
@@ -383,32 +464,23 @@ write_config() {
|
||||
fi
|
||||
|
||||
masked_token="$(mask_secret "$cf_token")"
|
||||
render_config "$domain" "$email" "$masked_token" "$proxy_url"
|
||||
}
|
||||
|
||||
write_config() {
|
||||
local domain="$1"
|
||||
local email="$2"
|
||||
local cf_token="$3"
|
||||
local proxy_url="$4"
|
||||
|
||||
if ! validate_domain "$domain"; then
|
||||
red "域名无效,拒绝写入配置:${domain@Q}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
blue "==> 即将写入如下配置到 ${CONFIG_FILE}"
|
||||
cat <<EOF
|
||||
listen: :443
|
||||
|
||||
acme:
|
||||
domains:
|
||||
- ${domain}
|
||||
email: ${email}
|
||||
type: dns
|
||||
dns:
|
||||
name: cloudflare
|
||||
config:
|
||||
cloudflare_api_token: ${masked_token}
|
||||
|
||||
auth:
|
||||
type: password
|
||||
password: ${password}
|
||||
|
||||
masquerade:
|
||||
type: proxy
|
||||
proxy:
|
||||
url: ${proxy_url}
|
||||
rewriteHost: true
|
||||
EOF
|
||||
render_preview_config "$domain" "$email" "$cf_token" "$proxy_url"
|
||||
echo
|
||||
|
||||
if ! confirm_yn "是否确认写入配置文件?"; then
|
||||
@@ -419,32 +491,10 @@ EOF
|
||||
mkdir -p /etc/hysteria
|
||||
backup_existing_config
|
||||
|
||||
cat > "${CONFIG_FILE}" <<EOF
|
||||
listen: :443
|
||||
|
||||
acme:
|
||||
domains:
|
||||
- ${domain}
|
||||
email: ${email}
|
||||
type: dns
|
||||
dns:
|
||||
name: cloudflare
|
||||
config:
|
||||
cloudflare_api_token: ${cf_token}
|
||||
|
||||
auth:
|
||||
type: password
|
||||
password: ${password}
|
||||
|
||||
masquerade:
|
||||
type: proxy
|
||||
proxy:
|
||||
url: ${proxy_url}
|
||||
rewriteHost: true
|
||||
EOF
|
||||
render_config "$domain" "$email" "$cf_token" "$proxy_url" > "${CONFIG_FILE}"
|
||||
|
||||
chown root:root "${CONFIG_FILE}"
|
||||
chmod 644 "${CONFIG_FILE}"
|
||||
chmod 600 "${CONFIG_FILE}"
|
||||
green "配置已写入 ${CONFIG_FILE}"
|
||||
}
|
||||
|
||||
@@ -463,25 +513,34 @@ start_service() {
|
||||
|
||||
show_result() {
|
||||
local domain="$1"
|
||||
local password="$2"
|
||||
local proxy_url="$3"
|
||||
local ip_info="$4"
|
||||
local proxy_url="$2"
|
||||
local ip_info="$3"
|
||||
local ipv4="${ip_info%%|*}"
|
||||
local ipv6="${ip_info##*|}"
|
||||
|
||||
local share_link="hysteria2://${password}@${domain}:443/?sni=${domain}&insecure=0"
|
||||
local entry username password
|
||||
|
||||
echo
|
||||
green "================= HY2 节点信息 ================="
|
||||
echo "域名: ${domain}"
|
||||
echo "端口: 443"
|
||||
echo "密码: ${password}"
|
||||
echo "认证方式: userpass"
|
||||
echo "伪装站点: ${proxy_url}"
|
||||
echo "流量统计监听: 127.0.0.1:9999"
|
||||
echo "流量统计密钥: ${TRAFFIC_STATS_SECRET}"
|
||||
[[ -n "${ipv4}" ]] && echo "IPv4: ${ipv4}"
|
||||
[[ -n "${ipv6}" ]] && echo "IPv6: ${ipv6}"
|
||||
echo
|
||||
echo "代理链接:"
|
||||
echo "${share_link}"
|
||||
echo "客户端连接参数:"
|
||||
echo " server: ${domain}:443"
|
||||
echo " sni: ${domain}"
|
||||
echo " auth: userpass"
|
||||
echo
|
||||
echo "设备账号:"
|
||||
for entry in "${USERPASS_ENTRIES[@]}"; do
|
||||
username="${entry%%:*}"
|
||||
password="${entry#*:}"
|
||||
echo " ${username}: ${password}"
|
||||
done
|
||||
echo
|
||||
echo "hysteria 状态:"
|
||||
systemctl --no-pager --full status "${SERVICE_NAME}" || true
|
||||
@@ -509,7 +568,7 @@ main() {
|
||||
require_cmd python3
|
||||
require_python3_json || { red "python3 缺少 json 模块,无法解析 Cloudflare API 返回值。"; exit 1; }
|
||||
|
||||
local email zone subdomain proxy_url password ip_info ipv4 ipv6 domain
|
||||
local email zone subdomain default_subdomain proxy_url ip_info ipv4 ipv6 domain username
|
||||
|
||||
email="$(prompt_nonempty '请输入 ACME 邮箱: ')"
|
||||
zone="$(prompt_nonempty '请输入 Cloudflare Zone(例如 example.com): ')"
|
||||
@@ -522,7 +581,11 @@ main() {
|
||||
CF_API_TOKEN="$(prompt_nonempty '请输入 Cloudflare API Token: ')"
|
||||
export CF_API_TOKEN
|
||||
|
||||
password="$(generate_password)"
|
||||
USERPASS_ENTRIES=()
|
||||
for username in "${DEVICE_USERS[@]}"; do
|
||||
USERPASS_ENTRIES+=("${username}:$(generate_password 36)")
|
||||
done
|
||||
TRAFFIC_STATS_SECRET="$(generate_password 36)"
|
||||
|
||||
ip_info="$(get_server_ip)"
|
||||
ipv4="${ip_info%%|*}"
|
||||
@@ -549,9 +612,9 @@ main() {
|
||||
domain="$(prompt_nonempty '请输入已存在并已解析到本机的完整域名: ')"
|
||||
fi
|
||||
|
||||
write_config "${domain}" "${email}" "${CF_API_TOKEN}" "${password}" "${proxy_url}"
|
||||
write_config "${domain}" "${email}" "${CF_API_TOKEN}" "${proxy_url}"
|
||||
start_service
|
||||
show_result "${domain}" "${password}" "${proxy_url}" "${ip_info}"
|
||||
show_result "${domain}" "${proxy_url}" "${ip_info}"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user