This commit is contained in:
sindricn
2025-09-25 22:17:54 +08:00
parent 11fd94aaf1
commit ce3cfce19d
2 changed files with 121 additions and 273 deletions
-242
View File
@@ -1,242 +0,0 @@
#!/bin/bash
# Hysteria2出站规则配置修复脚本
# 解决配置不完整和语法验证失败问题
# 配置文件路径
HYSTERIA_CONFIG="/etc/hysteria/config.yaml"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 完整稳定的配置应用函数
apply_outbound_complete() {
local name="$1" type="$2"
echo -e "${BLUE}[INFO]${NC} 🔧 开始添加完整的出站规则配置"
echo -e "${BLUE}[INFO]${NC} 规则名称: $name"
echo -e "${BLUE}[INFO]${NC} 规则类型: $type"
# 检查配置文件
if [[ ! -f "$HYSTERIA_CONFIG" ]]; then
echo -e "${RED}[ERROR]${NC} ❌ 配置文件不存在: $HYSTERIA_CONFIG"
return 1
fi
# 创建备份
local backup_file="/tmp/hysteria_backup_$(date +%s).yaml"
echo -e "${BLUE}[INFO]${NC} 📦 创建配置备份: $backup_file"
if ! cp "$HYSTERIA_CONFIG" "$backup_file" 2>/dev/null; then
echo -e "${RED}[ERROR]${NC} ❌ 无法创建备份文件"
return 1
fi
# 创建临时文件
local temp_file="/tmp/hysteria_temp_$(date +%s).yaml"
echo -e "${BLUE}[INFO]${NC} 📝 创建临时配置文件: $temp_file"
if ! cp "$HYSTERIA_CONFIG" "$temp_file" 2>/dev/null; then
echo -e "${RED}[ERROR]${NC} ❌ 无法创建临时文件"
rm -f "$backup_file" 2>/dev/null
return 1
fi
# 添加完整的出站配置(包含ACL规则)
echo -e "${BLUE}[INFO]${NC} ⚙️ 添加完整的出站配置"
if grep -q "^[[:space:]]*outbounds:" "$temp_file" 2>/dev/null; then
echo -e "${BLUE}[INFO]${NC} 🔍 检测到现有outbounds配置,追加新规则"
case $type in
"direct")
cat >> "$temp_file" << EOF
# 新增出站规则 - $name (Direct)
- name: $name
type: direct
direct:
mode: auto
# bindDevice: "eth0" # 可选:绑定网络接口
# bindIPv4: "0.0.0.0" # 可选:绑定IPv4地址
# bindIPv6: "::" # 可选:绑定IPv6地址
EOF
;;
"socks5")
cat >> "$temp_file" << EOF
# 新增出站规则 - $name (SOCKS5)
- name: $name
type: socks5
socks5:
addr: "${SOCKS5_ADDR:-127.0.0.1:1080}"
EOF
if [[ -n "${SOCKS5_USERNAME:-}" ]]; then
echo " username: \"$SOCKS5_USERNAME\"" >> "$temp_file"
echo " password: \"$SOCKS5_PASSWORD\"" >> "$temp_file"
fi
;;
esac
# 检查并添加ACL规则
echo -e "${BLUE}[INFO]${NC} 🛠️ 处理ACL路由规则"
if ! grep -q "^[[:space:]]*acl:" "$temp_file" 2>/dev/null; then
echo -e "${BLUE}[INFO]${NC} 📋 创建ACL规则以使用新的出站规则"
cat >> "$temp_file" << EOF
# ACL规则 - 路由配置
acl: |
# 使用新增的出站规则 $name 处理中国网站
$name(geosite:cn)
# 其他流量使用直连
direct(all)
EOF
else
echo -e "${YELLOW}[WARN]${NC} ⚠️ 已存在ACL规则,请手动配置以使用新的出站规则 '$name'"
fi
else
echo -e "${BLUE}[INFO]${NC} 🆕 未检测到outbounds配置,创建完整的配置节点"
case $type in
"direct")
cat >> "$temp_file" << EOF
# 出站规则配置
outbounds:
- name: $name
type: direct
direct:
mode: auto
# bindDevice: "eth0" # 可选:绑定网络接口
# bindIPv4: "0.0.0.0" # 可选:绑定IPv4地址
# bindIPv6: "::" # 可选:绑定IPv6地址
# ACL规则 - 路由配置
acl: |
# 使用 $name 进行直连
$name(all)
EOF
;;
"socks5")
cat >> "$temp_file" << EOF
# 出站规则配置
outbounds:
- name: $name
type: socks5
socks5:
addr: "${SOCKS5_ADDR:-127.0.0.1:1080}"
EOF
if [[ -n "${SOCKS5_USERNAME:-}" ]]; then
echo " username: \"$SOCKS5_USERNAME\"" >> "$temp_file"
echo " password: \"$SOCKS5_PASSWORD\"" >> "$temp_file"
fi
cat >> "$temp_file" << EOF
# ACL规则 - 路由配置
acl: |
# 使用 $name 代理所有流量
$name(all)
EOF
;;
esac
fi
# 验证配置语法(严格验证)
echo -e "${BLUE}[INFO]${NC} 🔍 验证配置语法"
if command -v hysteria >/dev/null 2>&1; then
local validation_output
validation_output=$(hysteria check-config -c "$temp_file" 2>&1)
local validation_result=$?
if [[ $validation_result -eq 0 ]]; then
echo -e "${GREEN}[SUCCESS]${NC} ✅ 配置语法验证通过"
else
echo -e "${RED}[ERROR]${NC} ❌ 配置语法验证失败"
echo -e "${RED}错误详情:${NC}"
echo "----------------------------------------"
echo "$validation_output"
echo "----------------------------------------"
echo -e "${YELLOW}[WARN]${NC} ⚠️ 应用此配置可能导致Hysteria2无法启动"
echo -e "${YELLOW}是否仍要继续应用配置? [y/N]${NC}"
read -r force_apply
if [[ ! $force_apply =~ ^[Yy]$ ]]; then
echo -e "${BLUE}[INFO]${NC} 🚫 操作已取消,配置未应用"
rm -f "$temp_file" "$backup_file" 2>/dev/null
return 1
fi
echo -e "${YELLOW}[WARN]${NC} ⚠️ 用户选择强制应用配置"
fi
else
echo -e "${YELLOW}[WARN]${NC} ⚠️ 未找到hysteria命令,跳过语法验证"
echo -e "${YELLOW}[WARN]${NC} 强烈建议在生产环境中安装hysteria进行配置验证"
fi
# 显示配置预览
echo -e "${BLUE}[INFO]${NC} 📋 配置预览(新增部分):"
echo -e "${GREEN}===================${NC}"
tail -25 "$temp_file" 2>/dev/null | head -20
echo -e "${GREEN}===================${NC}"
# 应用配置
echo -e "${BLUE}[INFO]${NC} 🚀 应用新配置"
if mv "$temp_file" "$HYSTERIA_CONFIG" 2>/dev/null; then
echo -e "${GREEN}[SUCCESS]${NC} ✅ 配置已成功应用到: $HYSTERIA_CONFIG"
echo -e "${GREEN}[SUCCESS]${NC} 🎉 出站规则 '$name' ($type) 添加完成"
# 提示用户重启服务
echo -e "${BLUE}[INFO]${NC} 💡 建议重启Hysteria2服务以应用新配置:"
echo -e "${BLUE} sudo systemctl restart hysteria-server${NC}"
rm -f "$backup_file" 2>/dev/null
return 0
else
echo -e "${RED}[ERROR]${NC} ❌ 配置应用失败,恢复备份"
mv "$backup_file" "$HYSTERIA_CONFIG" 2>/dev/null || echo -e "${RED}[ERROR]${NC} 备份恢复也失败了"
rm -f "$temp_file" 2>/dev/null
return 1
fi
}
# 主函数
main() {
echo -e "${GREEN}🔧 Hysteria2出站规则配置修复工具${NC}"
echo -e "${GREEN}版本: 2.0 (完整配置版本)${NC}"
echo -e "${GREEN}时间: $(date)${NC}"
echo ""
if [[ $# -lt 2 ]]; then
echo "用法: $0 <规则名称> <规则类型>"
echo "示例: $0 my_direct direct"
echo "示例: $0 my_proxy socks5"
exit 1
fi
local rule_name="$1"
local rule_type="$2"
echo -e "${BLUE}[INFO]${NC} 准备添加出站规则:"
echo -e "${BLUE}[INFO]${NC} 名称: $rule_name"
echo -e "${BLUE}[INFO]${NC} 类型: $rule_type"
echo ""
if apply_outbound_complete "$rule_name" "$rule_type"; then
echo ""
echo -e "${GREEN}[SUCCESS]${NC} 🎉 出站规则配置完成!"
echo -e "${GREEN}[SUCCESS]${NC} ✅ 现在可以查看配置并重启服务了"
else
echo ""
echo -e "${RED}[ERROR]${NC} ❌ 出站规则配置失败!"
echo -e "${RED}[ERROR]${NC} 请检查错误信息并重试"
exit 1
fi
}
# 如果脚本被直接执行
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi
+121 -31
View File
@@ -403,8 +403,7 @@ apply_outbound_config() {
echo -e "${BLUE}[INFO]${NC} 开始应用出站配置: $name ($type)"
# 使用极简稳定的方法
# 使用修复脚本进行完整配置
if bash "$(dirname "${BASH_SOURCE[0]}")/outbound-fix.sh" "$name" "$type"; then
if apply_outbound_simple "$name" "$type"; then
echo -e "${GREEN}[SUCCESS]${NC} 出站配置已添加:$name ($type)"
# 询问是否重启服务
@@ -495,23 +494,57 @@ EOF
fi
;;
esac
# 检查并添加ACL规则以使用新的出站规则
echo -e "${BLUE}[INFO]${NC} 检查ACL路由规则"
if ! grep -q "^[[:space:]]*acl:" "$temp_file" 2>/dev/null; then
echo -e "${BLUE}[INFO]${NC} 添加ACL规则以使用新的出站规则"
cat >> "$temp_file" << EOF
# ACL规则 - 路由配置
acl: |
# 使用新增的出站规则 $name
$name(geosite:cn)
# 其他流量直连
direct(all)
EOF
fi
else
echo -e "${BLUE}[INFO]${NC} 未检测到outbounds配置,创建新节点"
cat >> "$temp_file" << EOF
case $type in
"direct")
cat >> "$temp_file" << EOF
# 出站规则配置
outbounds:
- name: $name
type: $type
EOF
case $type in
"direct")
cat >> "$temp_file" << EOF
type: direct
direct:
mode: auto
# ACL规则 - 路由配置
acl: |
# 使用 $name 进行直连
$name(all)
EOF
;;
"socks5")
cat >> "$temp_file" << EOF
# 出站规则配置
outbounds:
- name: $name
type: socks5
socks5:
addr: "${SOCKS5_ADDR:-127.0.0.1:1080}"
# ACL规则 - 路由配置
acl: |
# 使用 $name 代理流量
$name(all)
EOF
;;
# 其他类型省略,需要时可以添加
esac
fi
@@ -803,9 +836,21 @@ generate_http_yaml_config() {
# 备份当前配置
backup_current_config() {
if [[ -f "$HYSTERIA_CONFIG" ]]; then
# 确保备份目录存在并且可写
if ! mkdir -p "$BACKUP_DIR" 2>/dev/null; then
# 如果无法创建备份目录,使用临时目录
BACKUP_DIR="/tmp/s-hy2-backup"
mkdir -p "$BACKUP_DIR" 2>/dev/null
fi
local backup_file="$BACKUP_DIR/config-$(date +%Y%m%d_%H%M%S).yaml"
cp "$HYSTERIA_CONFIG" "$backup_file"
log_info "配置已备份到: $backup_file"
if cp "$HYSTERIA_CONFIG" "$backup_file" 2>/dev/null; then
log_info "配置已备份到: $backup_file"
else
log_warn "备份失败,将使用简单备份方式"
backup_file="/tmp/hysteria_backup_$(date +%s).yaml"
cp "$HYSTERIA_CONFIG" "$backup_file" 2>/dev/null || log_error "备份失败"
fi
fi
}
@@ -1048,41 +1093,86 @@ modify_outbound_config() {
delete_outbound_rule() {
local rule_name="$1"
echo -e "${RED}警告: 即将删除出站规则 '$rule_name'${NC}"
echo -e "${RED}[WARNING]${NC} 即将删除出站规则: $rule_name"
echo -e "${YELLOW}此操作不可逆,请确认操作${NC}"
echo -n "确认删除? [y/N]: "
read -r confirm
if [[ ! $confirm =~ ^[Yy]$ ]]; then
log_info "取消删除"
echo -e "${BLUE}[INFO]${NC} 取消删除操作"
return
fi
backup_current_config
echo -e "${BLUE}[INFO]${NC} 开始删除出站规则: $rule_name"
# 创建临时文件,移除指定的出站规则
local temp_config="/tmp/hysteria_temp_modify.yaml"
# 创建简单备份
local backup_file="/tmp/hysteria_delete_backup_$(date +%s).yaml"
if ! cp "$HYSTERIA_CONFIG" "$backup_file" 2>/dev/null; then
echo -e "${RED}[ERROR]${NC} 无法创建备份,删除操作取消"
return 1
fi
echo -e "${BLUE}[INFO]${NC} 配置已备份到: $backup_file"
# 使用sed删除指定的出站规则块
sed "/- name: $rule_name/,/^ - name:/{ /^ - name:/!d; }" "$HYSTERIA_CONFIG" > "$temp_config"
# 创建临时文件
local temp_config="/tmp/hysteria_delete_temp_$(date +%s).yaml"
# 检查删除结果
if ! grep -q "name: $rule_name" "$temp_config"; then
mv "$temp_config" "$HYSTERIA_CONFIG"
log_success "出站规则 '$rule_name' 已删除"
# 使用更简单的方法:逐行处理,跳过要删除的规则块
local in_target_rule=false
local line_num=0
# 询问是否重启服务
echo "是否重启 Hysteria2 服务? [y/N]"
read -r restart_service
if [[ $restart_service =~ ^[Yy]$ ]]; then
systemctl restart hysteria-server
log_success "服务已重启"
while IFS= read -r line || [[ -n "$line" ]]; do
((line_num++))
# 检查是否是要删除的规则的开始
if [[ "$line" =~ ^[[:space:]]*-[[:space:]]*name:[[:space:]]*${rule_name}[[:space:]]*$ ]]; then
in_target_rule=true
echo -e "${BLUE}[INFO]${NC} 找到要删除的规则在第 $line_num"
continue
fi
else
# 检查是否是下一个规则的开始(结束当前删除块)
if [[ "$in_target_rule" == true ]] && [[ "$line" =~ ^[[:space:]]*-[[:space:]]*name: ]]; then
in_target_rule=false
fi
# 如果不在要删除的规则块中,则写入行
if [[ "$in_target_rule" == false ]]; then
echo "$line" >> "$temp_config"
fi
done < "$HYSTERIA_CONFIG"
# 检查删除是否成功
if grep -q "name: *$rule_name" "$temp_config" 2>/dev/null; then
echo -e "${RED}[ERROR]${NC} 删除失败,规则仍存在"
rm -f "$temp_config"
log_error "删除出站规则失败"
return 1
fi
wait_for_user
# 应用修改
if mv "$temp_config" "$HYSTERIA_CONFIG" 2>/dev/null; then
echo -e "${GREEN}[SUCCESS]${NC} 出站规则 '$rule_name' 已删除"
# 询问是否重启服务
echo ""
echo "是否重启 Hysteria2 服务以应用配置? [y/N]"
read -r restart_service
if [[ $restart_service =~ ^[Yy]$ ]]; then
if systemctl restart hysteria-server 2>/dev/null; then
echo -e "${GREEN}[SUCCESS]${NC} 服务已重启"
else
echo -e "${YELLOW}[WARN]${NC} 服务重启失败,请手动重启"
fi
fi
else
echo -e "${RED}[ERROR]${NC} 配置应用失败,恢复备份"
mv "$backup_file" "$HYSTERIA_CONFIG" 2>/dev/null
return 1
fi
echo ""
echo "按回车键继续..."
read -r
}
# 替换出站规则