mirror of
https://github.com/Dichgrem/singbox-example.git
synced 2026-02-04 23:41:56 -05:00
Compare commits
3 Commits
05c03a4030
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
edb8d0ff85 | ||
|
|
657103e957 | ||
|
|
e043bb0159 |
@@ -17,6 +17,7 @@ DEFAULT_PORT=443
|
|||||||
DEFAULT_MASQUERADE_URL="https://cn.bing.com/"
|
DEFAULT_MASQUERADE_URL="https://cn.bing.com/"
|
||||||
CONFIG_FILE="/etc/hysteria/config.yaml"
|
CONFIG_FILE="/etc/hysteria/config.yaml"
|
||||||
SERVICE_NAME="hysteria-server"
|
SERVICE_NAME="hysteria-server"
|
||||||
|
NEED_ROOT_MODE=false
|
||||||
|
|
||||||
# 打印彩色消息
|
# 打印彩色消息
|
||||||
print_message() {
|
print_message() {
|
||||||
@@ -39,11 +40,19 @@ check_system() {
|
|||||||
if ! command -v curl &>/dev/null; then
|
if ! command -v curl &>/dev/null; then
|
||||||
print_message $YELLOW "正在安装 curl..."
|
print_message $YELLOW "正在安装 curl..."
|
||||||
apt update && apt install -y curl
|
apt update && apt install -y curl
|
||||||
|
if ! command -v curl &>/dev/null; then
|
||||||
|
print_message $RED "curl 安装失败"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v openssl &>/dev/null; then
|
if ! command -v openssl &>/dev/null; then
|
||||||
print_message $YELLOW "正在安装 openssl..."
|
print_message $YELLOW "正在安装 openssl..."
|
||||||
apt update && apt install -y openssl
|
apt update && apt install -y openssl
|
||||||
|
if ! command -v openssl &>/dev/null; then
|
||||||
|
print_message $RED "openssl 安装失败"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,18 +64,19 @@ generate_password() {
|
|||||||
# 安装 Hysteria 2
|
# 安装 Hysteria 2
|
||||||
install_hysteria() {
|
install_hysteria() {
|
||||||
print_message $BLUE "开始安装 Hysteria 2..."
|
print_message $BLUE "开始安装 Hysteria 2..."
|
||||||
|
print_message $YELLOW "警告: 即将下载并执行 Hysteria 2 官方安装脚本"
|
||||||
|
print_message $YELLOW "来源: https://get.hy2.sh/"
|
||||||
|
|
||||||
# 下载并执行官方安装脚本
|
# 下载并执行官方安装脚本
|
||||||
if bash <(curl -fsSL https://get.hy2.sh/); then
|
if bash <(curl -fsSL https://get.hy2.sh/); then
|
||||||
print_message $GREEN "Hysteria 2 安装成功"
|
print_message $GREEN "Hysteria 2 安装成功"
|
||||||
|
# 设置开机自启(仅在安装成功后执行)
|
||||||
|
systemctl enable hysteria-server.service
|
||||||
|
print_message $GREEN "已设置 Hysteria 2 开机自启"
|
||||||
else
|
else
|
||||||
print_message $RED "Hysteria 2 安装失败"
|
print_message $RED "Hysteria 2 安装失败"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 设置开机自启
|
|
||||||
systemctl enable hysteria-server.service
|
|
||||||
print_message $GREEN "已设置 Hysteria 2 开机自启"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# 生成自签名证书
|
# 生成自签名证书
|
||||||
@@ -77,11 +87,14 @@ generate_self_signed_cert() {
|
|||||||
mkdir -p /etc/hysteria
|
mkdir -p /etc/hysteria
|
||||||
|
|
||||||
# 生成自签名证书
|
# 生成自签名证书
|
||||||
openssl req -x509 -nodes -newkey ec:<(openssl ecparam -name prime256v1) \
|
if ! openssl req -x509 -nodes -newkey ec:<(openssl ecparam -name prime256v1) \
|
||||||
-keyout /etc/hysteria/server.key \
|
-keyout /etc/hysteria/server.key \
|
||||||
-out /etc/hysteria/server.crt \
|
-out /etc/hysteria/server.crt \
|
||||||
-subj "/CN=bing.com" \
|
-subj "/CN=bing.com" \
|
||||||
-days 3650
|
-days 3650; then
|
||||||
|
print_message $RED "证书生成失败"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# 设置文件权限
|
# 设置文件权限
|
||||||
chown hysteria:hysteria /etc/hysteria/server.key /etc/hysteria/server.crt 2>/dev/null || {
|
chown hysteria:hysteria /etc/hysteria/server.key /etc/hysteria/server.crt 2>/dev/null || {
|
||||||
@@ -156,6 +169,8 @@ fix_permissions() {
|
|||||||
|
|
||||||
# 配置防火墙
|
# 配置防火墙
|
||||||
configure_firewall() {
|
configure_firewall() {
|
||||||
|
local port=$1
|
||||||
|
|
||||||
if command -v ufw &>/dev/null; then
|
if command -v ufw &>/dev/null; then
|
||||||
print_message $BLUE "正在配置UFW防火墙..."
|
print_message $BLUE "正在配置UFW防火墙..."
|
||||||
|
|
||||||
@@ -169,11 +184,24 @@ configure_firewall() {
|
|||||||
# 开放端口
|
# 开放端口
|
||||||
ufw allow http >/dev/null 2>&1
|
ufw allow http >/dev/null 2>&1
|
||||||
ufw allow https >/dev/null 2>&1
|
ufw allow https >/dev/null 2>&1
|
||||||
ufw allow $1 >/dev/null 2>&1
|
ufw allow $port >/dev/null 2>&1
|
||||||
|
|
||||||
|
print_message $GREEN "防火墙配置完成"
|
||||||
|
elif command -v iptables &>/dev/null; then
|
||||||
|
print_message $BLUE "正在配置iptables防火墙..."
|
||||||
|
|
||||||
|
# 检查规则是否已存在,避免重复添加
|
||||||
|
if ! iptables -L INPUT -n | grep -q "dpt:$port"; then
|
||||||
|
iptables -I INPUT -p tcp --dport $port -j ACCEPT
|
||||||
|
iptables -I INPUT -p udp --dport $port -j ACCEPT
|
||||||
|
print_message $YELLOW "请运行以下命令保存iptables规则:"
|
||||||
|
print_message $YELLOW " iptables-save > /etc/iptables/rules.v4 (Debian/Ubuntu)"
|
||||||
|
print_message $YELLOW " service iptables save (CentOS/RHEL)"
|
||||||
|
fi
|
||||||
|
|
||||||
print_message $GREEN "防火墙配置完成"
|
print_message $GREEN "防火墙配置完成"
|
||||||
else
|
else
|
||||||
print_message $YELLOW "未检测到UFW防火墙,跳过防火墙配置"
|
print_message $YELLOW "未检测到UFW或iptables防火墙,跳过防火墙配置"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,13 +213,15 @@ optimize_performance() {
|
|||||||
sysctl -w net.core.rmem_max=16777216 >/dev/null
|
sysctl -w net.core.rmem_max=16777216 >/dev/null
|
||||||
sysctl -w net.core.wmem_max=16777216 >/dev/null
|
sysctl -w net.core.wmem_max=16777216 >/dev/null
|
||||||
|
|
||||||
# 写入系统配置文件持久化
|
# 写入系统配置文件持久化(避免重复添加)
|
||||||
|
if ! grep -q "net.core.rmem_max=16777216" /etc/sysctl.conf 2>/dev/null; then
|
||||||
cat >>/etc/sysctl.conf <<EOF
|
cat >>/etc/sysctl.conf <<EOF
|
||||||
|
|
||||||
# Hysteria 2 性能优化
|
# Hysteria 2 性能优化
|
||||||
net.core.rmem_max=16777216
|
net.core.rmem_max=16777216
|
||||||
net.core.wmem_max=16777216
|
net.core.wmem_max=16777216
|
||||||
EOF
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
print_message $GREEN "性能优化完成"
|
print_message $GREEN "性能优化完成"
|
||||||
}
|
}
|
||||||
@@ -232,7 +262,20 @@ url_encode() {
|
|||||||
show_connection_info() {
|
show_connection_info() {
|
||||||
local password=$1
|
local password=$1
|
||||||
local port=$2
|
local port=$2
|
||||||
local server_ip=$(curl -s ifconfig.me 2>/dev/null || curl -s ipinfo.io/ip 2>/dev/null || echo "YOUR_SERVER_IP")
|
|
||||||
|
# 获取服务器IP(提供多个备选方案)
|
||||||
|
local server_ip=""
|
||||||
|
for url in "ifconfig.me" "ipinfo.io/ip" "icanhazip.com" "api.ipify.org"; do
|
||||||
|
server_ip=$(curl -s --connect-timeout 5 $url 2>/dev/null)
|
||||||
|
if [[ -n "$server_ip" ]] && [[ "$server_ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z "$server_ip" ]] || [[ ! "$server_ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
|
print_message $YELLOW "警告: 无法自动获取服务器公网IP"
|
||||||
|
server_ip="YOUR_SERVER_IP"
|
||||||
|
fi
|
||||||
|
|
||||||
# 生成节点名称(URL编码)
|
# 生成节点名称(URL编码)
|
||||||
local node_name="Hysteria2-${server_ip}"
|
local node_name="Hysteria2-${server_ip}"
|
||||||
@@ -265,6 +308,9 @@ show_connection_info() {
|
|||||||
echo " - 请妥善保存上述连接信息"
|
echo " - 请妥善保存上述连接信息"
|
||||||
echo " - 客户端需要设置 insecure: true(因为使用自签名证书)"
|
echo " - 客户端需要设置 insecure: true(因为使用自签名证书)"
|
||||||
echo " - 配置文件位置: $CONFIG_FILE"
|
echo " - 配置文件位置: $CONFIG_FILE"
|
||||||
|
if [[ "$server_ip" == "YOUR_SERVER_IP" ]]; then
|
||||||
|
echo " - 请将 YOUR_SERVER_IP 替换为实际的服务器IP地址"
|
||||||
|
fi
|
||||||
echo " - 复制标准连接链接可直接导入支持的客户端"
|
echo " - 复制标准连接链接可直接导入支持的客户端"
|
||||||
print_message $GREEN "=============================================="
|
print_message $GREEN "=============================================="
|
||||||
}
|
}
|
||||||
@@ -296,41 +342,19 @@ uninstall_hysteria() {
|
|||||||
|
|
||||||
# 检查安装状态
|
# 检查安装状态
|
||||||
check_installation() {
|
check_installation() {
|
||||||
if command -v hysteria &>/dev/null && systemctl list-unit-files | grep -q hysteria-server; then
|
if command -v hysteria &>/dev/null && systemctl list-unit-files | grep -q "hysteria-server.service"; then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# 主菜单
|
|
||||||
show_menu() {
|
|
||||||
clear
|
|
||||||
print_message $BLUE "=============================================="
|
|
||||||
print_message $BLUE " Dich's Hysteria 2 管理脚本"
|
|
||||||
print_message $BLUE "=============================================="
|
|
||||||
echo
|
|
||||||
|
|
||||||
if check_installation; then
|
|
||||||
echo "1. 重新配置 Hysteria 2"
|
|
||||||
echo "2. 重启 Hysteria 2 服务"
|
|
||||||
echo "3. 查看服务状态"
|
|
||||||
echo "4. 查看配置信息"
|
|
||||||
echo "5. 卸载 Hysteria 2"
|
|
||||||
echo "0. 退出"
|
|
||||||
else
|
|
||||||
echo "1. 安装 Hysteria 2"
|
|
||||||
echo "0. 退出"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
}
|
|
||||||
|
|
||||||
# 获取用户输入
|
# 获取用户输入
|
||||||
get_user_input() {
|
get_user_input() {
|
||||||
# 获取密码
|
# 获取密码
|
||||||
while true; do
|
while true; do
|
||||||
read -p "请输入认证密码 (留空使用随机密码): " user_password
|
read -sp "请输入认证密码 (留空使用随机密码): " user_password
|
||||||
|
echo
|
||||||
if [[ -z "$user_password" ]]; then
|
if [[ -z "$user_password" ]]; then
|
||||||
PASSWORD=$(generate_password)
|
PASSWORD=$(generate_password)
|
||||||
print_message $GREEN "已生成随机密码: $PASSWORD"
|
print_message $GREEN "已生成随机密码: $PASSWORD"
|
||||||
@@ -358,12 +382,18 @@ get_user_input() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
# 获取伪装网址
|
# 获取伪装网址
|
||||||
|
while true; do
|
||||||
read -p "请输入伪装网址 (默认: $DEFAULT_MASQUERADE_URL): " user_masquerade
|
read -p "请输入伪装网址 (默认: $DEFAULT_MASQUERADE_URL): " user_masquerade
|
||||||
if [[ -z "$user_masquerade" ]]; then
|
if [[ -z "$user_masquerade" ]]; then
|
||||||
MASQUERADE_URL="$DEFAULT_MASQUERADE_URL"
|
MASQUERADE_URL="$DEFAULT_MASQUERADE_URL"
|
||||||
else
|
break
|
||||||
|
elif [[ "$user_masquerade" =~ ^https?:// ]]; then
|
||||||
MASQUERADE_URL="$user_masquerade"
|
MASQUERADE_URL="$user_masquerade"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
print_message $RED "请输入有效的URL格式 (如: https://example.com)"
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# 完整安装流程
|
# 完整安装流程
|
||||||
@@ -372,6 +402,10 @@ install_process() {
|
|||||||
|
|
||||||
get_user_input
|
get_user_input
|
||||||
|
|
||||||
|
# 清除密码历史记录
|
||||||
|
history -c 2>/dev/null || true
|
||||||
|
export HISTFILE="/dev/null"
|
||||||
|
|
||||||
check_system
|
check_system
|
||||||
install_hysteria
|
install_hysteria
|
||||||
generate_self_signed_cert
|
generate_self_signed_cert
|
||||||
@@ -392,8 +426,19 @@ install_process() {
|
|||||||
reconfigure_process() {
|
reconfigure_process() {
|
||||||
print_message $BLUE "开始重新配置 Hysteria 2..."
|
print_message $BLUE "开始重新配置 Hysteria 2..."
|
||||||
|
|
||||||
|
# 询问是否重新生成证书
|
||||||
|
read -p "是否重新生成自签名证书?[y/N]: " renew_cert
|
||||||
|
if [[ "$renew_cert" == "y" || "$renew_cert" == "Y" ]]; then
|
||||||
|
generate_self_signed_cert
|
||||||
|
fix_permissions
|
||||||
|
fi
|
||||||
|
|
||||||
get_user_input
|
get_user_input
|
||||||
|
|
||||||
|
# 清除密码历史记录
|
||||||
|
history -c 2>/dev/null || true
|
||||||
|
export HISTFILE="/dev/null"
|
||||||
|
|
||||||
systemctl stop hysteria-server.service
|
systemctl stop hysteria-server.service
|
||||||
create_config "$PASSWORD" "$PORT" "$MASQUERADE_URL"
|
create_config "$PASSWORD" "$PORT" "$MASQUERADE_URL"
|
||||||
configure_firewall "$PORT"
|
configure_firewall "$PORT"
|
||||||
@@ -423,7 +468,28 @@ main() {
|
|||||||
check_root
|
check_root
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
show_menu
|
# 显示菜单
|
||||||
|
clear
|
||||||
|
print_message $BLUE "=============================================="
|
||||||
|
print_message $BLUE " Dich's Hysteria 2 管理脚本"
|
||||||
|
print_message $BLUE "=============================================="
|
||||||
|
echo
|
||||||
|
|
||||||
|
if check_installation; then
|
||||||
|
echo "1. 重新配置 Hysteria 2"
|
||||||
|
echo "2. 重启 Hysteria 2 服务"
|
||||||
|
echo "3. 查看服务状态"
|
||||||
|
echo "4. 查看配置信息"
|
||||||
|
echo "5. 卸载 Hysteria 2"
|
||||||
|
echo "0. 退出"
|
||||||
|
else
|
||||||
|
echo "1. 安装 Hysteria 2"
|
||||||
|
echo "0. 退出"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
# 获取用户选择
|
||||||
read -p "请选择操作 [0-5]: " choice
|
read -p "请选择操作 [0-5]: " choice
|
||||||
|
|
||||||
case $choice in
|
case $choice in
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# install_singbox.sh
|
# install_singbox.sh
|
||||||
# 版本号
|
# 版本号
|
||||||
SCRIPT_VERSION="1.12.15"
|
SCRIPT_VERSION="1.12.17"
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# 颜色定义
|
# 颜色定义
|
||||||
@@ -104,8 +104,16 @@ install_singbox() {
|
|||||||
printf "${YELLOW}请输入 SNI 域名 (默认: s0.awsstatic.com):${NC}"
|
printf "${YELLOW}请输入 SNI 域名 (默认: s0.awsstatic.com):${NC}"
|
||||||
read -r SNI
|
read -r SNI
|
||||||
SNI=${SNI:-s0.awsstatic.com}
|
SNI=${SNI:-s0.awsstatic.com}
|
||||||
read -rp "请输入监听端口 (默认: 443): " PORT
|
|
||||||
|
while true; do
|
||||||
|
read -rp "请输入监听端口 (默认: 443,范围 1-65535): " PORT
|
||||||
PORT=${PORT:-443}
|
PORT=${PORT:-443}
|
||||||
|
if [[ "$PORT" =~ ^[0-9]+$ ]] && [ "$PORT" -ge 1 ] && [ "$PORT" -le 65535 ]; then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
printf "${RED}端口无效,请输入 1-65535 之间的数字${NC}\n"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
update_singbox
|
update_singbox
|
||||||
hash -r
|
hash -r
|
||||||
@@ -117,8 +125,17 @@ install_singbox() {
|
|||||||
VERSION=$($BIN_PATH version | head -n1 | awk '{print $NF}')
|
VERSION=$($BIN_PATH version | head -n1 | awk '{print $NF}')
|
||||||
printf "${GREEN}已安装/更新 sing-box 版本:%s${NC}\n" "$VERSION"
|
printf "${GREEN}已安装/更新 sing-box 版本:%s${NC}\n" "$VERSION"
|
||||||
|
|
||||||
UUID=$($BIN_PATH generate uuid)
|
# 检查openssl是否安装
|
||||||
KEY_OUTPUT=$($BIN_PATH generate reality-keypair)
|
if ! command -v openssl &>/dev/null; then
|
||||||
|
printf "${RED}未安装 openssl,正在安装...${NC}\n"
|
||||||
|
apt update && apt install -y openssl || {
|
||||||
|
printf "${RED}openssl 安装失败${NC}\n" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
UUID=$($BIN_NAME generate uuid)
|
||||||
|
KEY_OUTPUT=$($BIN_NAME generate reality-keypair)
|
||||||
PRIVATE_KEY=$(echo "$KEY_OUTPUT" | awk -F': ' '/PrivateKey/ {print $2}')
|
PRIVATE_KEY=$(echo "$KEY_OUTPUT" | awk -F': ' '/PrivateKey/ {print $2}')
|
||||||
PUB_KEY=$(echo "$KEY_OUTPUT" | awk -F': ' '/PublicKey/ {print $2}')
|
PUB_KEY=$(echo "$KEY_OUTPUT" | awk -F': ' '/PublicKey/ {print $2}')
|
||||||
SHORT_ID=$(openssl rand -hex 8)
|
SHORT_ID=$(openssl rand -hex 8)
|
||||||
@@ -254,16 +271,39 @@ show_link() {
|
|||||||
# 如果状态文件不存在,尝试从 config.json 读取并生成
|
# 如果状态文件不存在,尝试从 config.json 读取并生成
|
||||||
if [[ ! -f "$STATE_FILE" ]]; then
|
if [[ ! -f "$STATE_FILE" ]]; then
|
||||||
if [[ -f "$CONFIG_DIR/config.json" ]]; then
|
if [[ -f "$CONFIG_DIR/config.json" ]]; then
|
||||||
NAME=$(grep -oP '"name"\s*:\s*"\K[^"]+' "$CONFIG_DIR/config.json")
|
# 使用Python解析JSON更可靠,避免grep -P兼容性问题
|
||||||
UUID=$(grep -oP '"uuid"\s*:\s*"\K[^"]+' "$CONFIG_DIR/config.json")
|
if command -v python3 &>/dev/null; then
|
||||||
SNI=$(grep -oP '"server_name"\s*:\s*"\K[^"]+' "$CONFIG_DIR/config.json")
|
NAME=$(python3 -c "import json; print(json.load(open('$CONFIG_DIR/config.json'))['inbounds'][0]['users'][0]['name'])" 2>/dev/null)
|
||||||
PUB_KEY=$(grep -oP '"public_key"\s*:\s*"\K[^"]+' "$CONFIG_DIR/config.json")
|
UUID=$(python3 -c "import json; print(json.load(open('$CONFIG_DIR/config.json'))['inbounds'][0]['users'][0]['uuid'])" 2>/dev/null)
|
||||||
SHORT_ID=$(grep -oP '"short_id"\s*:\s*"\K[^"]+' "$CONFIG_DIR/config.json")
|
SNI=$(python3 -c "import json; print(json.load(open('$CONFIG_DIR/config.json'))['inbounds'][0]['tls']['server_name'])" 2>/dev/null)
|
||||||
|
SHORT_ID=$(python3 -c "import json; print(json.load(open('$CONFIG_DIR/config.json'))['inbounds'][0]['tls']['reality']['short_id'])" 2>/dev/null)
|
||||||
|
PORT=$(python3 -c "import json; print(json.load(open('$CONFIG_DIR/config.json'))['inbounds'][0]['listen_port'])" 2>/dev/null)
|
||||||
|
else
|
||||||
|
# 回退到grep方案(使用基本正则表达式)
|
||||||
|
NAME=$(grep -o '"name"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG_DIR/config.json" | head -1 | cut -d'"' -f4)
|
||||||
|
UUID=$(grep -o '"uuid"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG_DIR/config.json" | head -1 | cut -d'"' -f4)
|
||||||
|
SNI=$(grep -o '"server_name"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG_DIR/config.json" | head -1 | cut -d'"' -f4)
|
||||||
|
SHORT_ID=$(grep -o '"short_id"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG_DIR/config.json" | head -1 | cut -d'"' -f4)
|
||||||
|
PORT=$(grep -o '"listen_port"[[:space:]]*:[[:space:]]*[0-9]*' "$CONFIG_DIR/config.json" | head -1 | grep -o '[0-9]*$')
|
||||||
|
fi
|
||||||
|
|
||||||
|
# reality的public_key在服务端配置中不存在,需要从private_key生成或重新获取
|
||||||
|
# 这里尝试重新生成
|
||||||
|
if command -v sing-box &>/dev/null; then
|
||||||
|
PUB_KEY=$(sing-box generate reality-keypair | awk -F': ' '/PublicKey/ {print $2}' 2>/dev/null)
|
||||||
|
fi
|
||||||
|
[[ -z "$PUB_KEY" ]] && { printf "${RED}无法获取 public_key${NC}\n"; return 1; }
|
||||||
|
|
||||||
FP="firefox"
|
FP="firefox"
|
||||||
SERVER_IP=$(get_server_ip)
|
SERVER_IP=$(get_server_ip)
|
||||||
PORT=$(grep -oP '"listen_port"\s*:\s*\K[^,}]+' "$CONFIG_DIR/config.json")
|
|
||||||
SPX="/"
|
SPX="/"
|
||||||
|
|
||||||
|
# 检查必要字段
|
||||||
|
[[ -z "$NAME" || -z "$UUID" || -z "$SNI" || -z "$SHORT_ID" || -z "$PORT" ]] && {
|
||||||
|
printf "${RED}无法从配置文件读取完整信息${NC}\n"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
# 保存新的 state.env
|
# 保存新的 state.env
|
||||||
mkdir -p "$CONFIG_DIR"
|
mkdir -p "$CONFIG_DIR"
|
||||||
cat >"$STATE_FILE" <<EOF
|
cat >"$STATE_FILE" <<EOF
|
||||||
@@ -326,10 +366,6 @@ uninstall_singbox() {
|
|||||||
|
|
||||||
# 删除 Sing-box 可执行文件
|
# 删除 Sing-box 可执行文件
|
||||||
rm -f /usr/bin/sing-box
|
rm -f /usr/bin/sing-box
|
||||||
|
|
||||||
# 删除 env 文件
|
|
||||||
rm -f /etc/sing-box/state.env
|
|
||||||
|
|
||||||
printf "${GREEN}卸载完成。${NC}\n"
|
printf "${GREEN}卸载完成。${NC}\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,20 +434,20 @@ update_singbox() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
sudo dpkg -i /tmp/sing-box.deb || {
|
dpkg -i /tmp/sing-box.deb || {
|
||||||
echo "⚠️ dpkg 安装失败,尝试修复依赖..."
|
echo "⚠️ dpkg 安装失败,尝试修复依赖..."
|
||||||
sudo apt-get install -f -y
|
apt-get install -f -y
|
||||||
sudo dpkg -i /tmp/sing-box.deb
|
dpkg -i /tmp/sing-box.deb
|
||||||
}
|
}
|
||||||
|
|
||||||
rm -f /tmp/sing-box.deb
|
rm -f /tmp/sing-box.deb
|
||||||
|
|
||||||
NEW_VER=$($BIN_NAME version 2>/dev/null | head -n1 | awk '{print $NF}')
|
NEW_VER=$($BIN_NAME version 2>/dev/null | head -n1 | awk '{print $NF}')
|
||||||
echo "✅ Sing-box 已升级到版本:$NEW_VER"
|
echo "✅ Sing-box 已升级到版本:$NEW_VER"
|
||||||
echo "🔁 正在重启服务..."
|
echo "🔁 正在重载 systemd 并重启服务..."
|
||||||
|
|
||||||
if systemctl restart sing-box.service; then
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
|
if systemctl restart sing-box.service; then
|
||||||
echo "✅ 服务已重启。"
|
echo "✅ 服务已重启。"
|
||||||
else
|
else
|
||||||
echo "⚠️ 服务重启失败,请手动检查。"
|
echo "⚠️ 服务重启失败,请手动检查。"
|
||||||
@@ -436,8 +472,16 @@ change_sni() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sed -i -E '/"reality": *\{/,/}/ s/"server_name": *"[^"]*"/"server_name": "'"$NEW_SNI"'"/' "$CONFIG_DIR/config.json"
|
# 使用更精确的sed替换,避免匹配到错误的字段
|
||||||
sed -i -E '/"handshake": *\{/,/}/ s/"server": *"[^"]*"/"server": "'"$NEW_SNI"'"/' "$CONFIG_DIR/config.json"
|
if ! sed -i -E '/"tag": *"VLESSReality"/,/\}/ s/"server_name": *"[^"]*"/"server_name": "'"$NEW_SNI"'"/' "$CONFIG_DIR/config.json"; then
|
||||||
|
printf "${RED}修改 server_name 失败${NC}\n"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! sed -i -E '/"tag": *"VLESSReality"/,/\}/ s/"server": *"[^"]*"/"server": "'"$NEW_SNI"'"/' "$CONFIG_DIR/config.json"; then
|
||||||
|
printf "${RED}修改 server 失败${NC}\n"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
sed -i "s/^SNI=.*/SNI=\"$NEW_SNI\"/" "$STATE_FILE"
|
sed -i "s/^SNI=.*/SNI=\"$NEW_SNI\"/" "$STATE_FILE"
|
||||||
|
|
||||||
@@ -467,14 +511,14 @@ set_bbr() {
|
|||||||
read -p "⚠️ 当前使用的不是 BBR,是否切换为 BBR?(y/n): " confirm
|
read -p "⚠️ 当前使用的不是 BBR,是否切换为 BBR?(y/n): " confirm
|
||||||
if [[ "$confirm" =~ ^[Yy]$ ]]; then
|
if [[ "$confirm" =~ ^[Yy]$ ]]; then
|
||||||
# 临时生效
|
# 临时生效
|
||||||
sudo sysctl -w net.ipv4.tcp_congestion_control=bbr
|
sysctl -w net.ipv4.tcp_congestion_control=bbr
|
||||||
echo "✅ 已切换为 BBR(临时)"
|
echo "✅ 已切换为 BBR(临时)"
|
||||||
|
|
||||||
# 永久生效
|
# 永久生效
|
||||||
if ! grep -q "^net.ipv4.tcp_congestion_control" /etc/sysctl.conf; then
|
if ! grep -q "^net.ipv4.tcp_congestion_control" /etc/sysctl.conf; then
|
||||||
echo "net.ipv4.tcp_congestion_control = bbr" | sudo tee -a /etc/sysctl.conf
|
echo "net.ipv4.tcp_congestion_control = bbr" | tee -a /etc/sysctl.conf
|
||||||
else
|
else
|
||||||
sudo sed -i "s/^net.ipv4.tcp_congestion_control.*/net.ipv4.tcp_congestion_control = bbr/" /etc/sysctl.conf
|
sed -i "s/^net.ipv4.tcp_congestion_control.*/net.ipv4.tcp_congestion_control = bbr/" /etc/sysctl.conf
|
||||||
fi
|
fi
|
||||||
echo "✅ 已写入 /etc/sysctl.conf,重启后永久生效"
|
echo "✅ 已写入 /etc/sysctl.conf,重启后永久生效"
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ chmod 700 /root/.ssh
|
|||||||
# 生成SSH密钥对
|
# 生成SSH密钥对
|
||||||
echo -e "${YELLOW}生成SSH密钥对...${NC}"
|
echo -e "${YELLOW}生成SSH密钥对...${NC}"
|
||||||
KEY_FILE="/root/.ssh/id_rsa"
|
KEY_FILE="/root/.ssh/id_rsa"
|
||||||
|
GENERATE_KEY=true
|
||||||
|
|
||||||
if [ -f "$KEY_FILE" ]; then
|
if [ -f "$KEY_FILE" ]; then
|
||||||
echo -e "${YELLOW}密钥文件 $KEY_FILE 已存在${NC}"
|
echo -e "${YELLOW}密钥文件 $KEY_FILE 已存在${NC}"
|
||||||
read -p "是否要重新生成密钥对? (y/n): " REGENERATE
|
read -p "是否要重新生成密钥对? (y/n): " REGENERATE
|
||||||
@@ -31,15 +33,24 @@ if [ -f "$KEY_FILE" ]; then
|
|||||||
KEY_FILE="/root/.ssh/id_rsa_new"
|
KEY_FILE="/root/.ssh/id_rsa_new"
|
||||||
else
|
else
|
||||||
echo -e "${YELLOW}使用现有的密钥文件${NC}"
|
echo -e "${YELLOW}使用现有的密钥文件${NC}"
|
||||||
|
GENERATE_KEY=false
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 生成密钥对
|
# 生成密钥对
|
||||||
ssh-keygen -t rsa -b 4096 -f "$KEY_FILE" -N "" -q
|
if [ "$GENERATE_KEY" == true ]; then
|
||||||
|
ssh-keygen -t rsa -b 4096 -f "$KEY_FILE" -N "" -q
|
||||||
|
chmod 600 "$KEY_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
# 将公钥添加到授权文件
|
# 将公钥添加到授权文件
|
||||||
echo -e "${YELLOW}将公钥添加到授权文件...${NC}"
|
echo -e "${YELLOW}将公钥添加到授权文件...${NC}"
|
||||||
cat "${KEY_FILE}.pub" >> /root/.ssh/authorized_keys
|
if ! grep -q -f "${KEY_FILE}.pub" /root/.ssh/authorized_keys 2>/dev/null; then
|
||||||
|
cat "${KEY_FILE}.pub" >> /root/.ssh/authorized_keys
|
||||||
|
echo -e "${GREEN}公钥已添加到授权文件${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}公钥已存在于授权文件中,跳过添加${NC}"
|
||||||
|
fi
|
||||||
chmod 600 /root/.ssh/authorized_keys
|
chmod 600 /root/.ssh/authorized_keys
|
||||||
|
|
||||||
# 配置SSH服务器
|
# 配置SSH服务器
|
||||||
@@ -52,9 +63,9 @@ cp "$CONFIG_FILE" "$CONFIG_BACKUP"
|
|||||||
echo -e "${GREEN}SSH配置已备份到 $CONFIG_BACKUP${NC}"
|
echo -e "${GREEN}SSH配置已备份到 $CONFIG_BACKUP${NC}"
|
||||||
|
|
||||||
# 修改SSH配置
|
# 修改SSH配置
|
||||||
sed -i 's/#\?PasswordAuthentication yes/PasswordAuthentication no/g' "$CONFIG_FILE"
|
sed -i 's/^\s*#\?\s*PasswordAuthentication.*/PasswordAuthentication no/g' "$CONFIG_FILE"
|
||||||
sed -i 's/#\?PubkeyAuthentication no/PubkeyAuthentication yes/g' "$CONFIG_FILE"
|
sed -i 's/^\s*#\?\s*PubkeyAuthentication.*/PubkeyAuthentication yes/g' "$CONFIG_FILE"
|
||||||
sed -i 's/#\?PermitRootLogin.*/PermitRootLogin prohibit-password/g' "$CONFIG_FILE"
|
sed -i 's/^\s*#\?\s*PermitRootLogin.*/PermitRootLogin prohibit-password/g' "$CONFIG_FILE"
|
||||||
|
|
||||||
# 确保PubkeyAuthentication设置为yes
|
# 确保PubkeyAuthentication设置为yes
|
||||||
if ! grep -q "PubkeyAuthentication yes" "$CONFIG_FILE"; then
|
if ! grep -q "PubkeyAuthentication yes" "$CONFIG_FILE"; then
|
||||||
|
|||||||
Reference in New Issue
Block a user