├── README.md ├── hy2install.sh └── alpinehy2install.sh /README.md: -------------------------------------------------------------------------------- 1 | # Hysteria 2 一键安装管理脚本 2 | 3 | 这是一个用于 Linux 系统的 Hysteria 2 一键安装管理脚本。 4 | 5 | ## 支持的系统 6 | - Debian/Ubuntu 7 | - CentOS/RHEL 8 | - Alpine Linux (使用 [alpinehy2install.sh](https://raw.githubusercontent.com/zsancc/hy2install/main/alpinehy2install.sh)) 9 | 10 | ## 快速安装 11 | 12 | ```bash 13 | # Debian/Ubuntu/CentOS 等系统 14 | bash <(curl -fsSL https://raw.githubusercontent.com/zsancc/hy2install/main/hy2install.sh) 15 | 16 | # Alpine Linux 17 | bash <(curl -fsSL https://raw.githubusercontent.com/zsancc/hy2install/main/alpinehy2install.sh) 18 | ``` 19 | 20 | ## 功能特点 21 | 22 | - 支持多种 Linux 发行版 23 | - 支持多种 TLS 验证方式: 24 | 1. 自定义证书(适用于 NAT VPS) 25 | 2. ACME HTTP 验证(需要 80 端口) 26 | 3. Cloudflare DNS 验证 27 | - 自动生成分享链接和二维码 28 | - 注册系统命令 `hy2` 便于管理 29 | - 支持开机自启动 30 | - 自动适配 systemd/sysvinit 服务管理 31 | 32 | ## 管理命令 33 | 34 | 安装完成后,运行 `hy2` 命令进入管理菜单: 35 | 36 | 1. 更新 Hysteria 2 37 | 2. 卸载 Hysteria 2 38 | 3. 启动服务 39 | 4. 停止服务 40 | 5. 重启服务 41 | 6. 查看状态 42 | 7. 查看配置 43 | 8. 修改配置 44 | 9. 查看日志 45 | 10. 查看分享链接 46 | 11. 显示分享二维码 47 | 48 | ## 配置说明 49 | 50 | ### 基础配置 51 | - 端口:默认 5525 52 | - 密码:默认随机生成 53 | - 伪装站点:默认 https://news.ycombinator.com/ 54 | 55 | ### TLS 配置选项 56 | 1. 自定义证书: 57 | - 适用于 NAT VPS 或已有证书 58 | - 需要提供证书和私钥路径 59 | 60 | 2. ACME HTTP 验证: 61 | - 需要域名已解析到服务器 62 | - 需要 80 端口可用 63 | - 自动申请和续期证书 64 | 65 | 3. Cloudflare DNS 验证: 66 | - 需要域名使用 Cloudflare 解析 67 | - 需要 Cloudflare API Token 68 | - 支持泛域名证书 69 | 70 | ## 系统要求 71 | 72 | - 支持的 Linux 发行版 73 | - Root 权限 74 | - 基本网络连接 75 | 76 | ## 注意事项 77 | 78 | 1. 使用域名功能前请确保: 79 | - 域名已正确解析 80 | - 相应端口已开放 81 | 82 | 2. 使用 Cloudflare DNS 验证时: 83 | - 需要在 Cloudflare 面板中创建 API Token 84 | - Token 位置:我的个人资料->API令牌->创建Token->使用 Edit zone DNS 模板->权限类型:Zone / DNS / Edit,资源:Include / Specific zone / 选择你的域名(如 baidu.com) 85 | 86 | ## 问题反馈 87 | 88 | 如遇问题,请提供: 89 | 1. Linux 发行版和版本 90 | 2. 错误信息 91 | 3. 相关日志(`hy2` 命令中的查看日志功能) 92 | 93 | ## 许可证 94 | 95 | MIT License 96 | 97 | ## 鸣谢 98 | 99 | - [Hysteria 2](https://github.com/apernet/hysteria) 100 | - 所有贡献者和用户 101 | -------------------------------------------------------------------------------- /hy2install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Colors 4 | RED='\033[0;31m' 5 | GREEN='\033[0;32m' 6 | YELLOW='\033[0;33m' 7 | NC='\033[0m' 8 | 9 | # Default values 10 | DEFAULT_PORT=5525 11 | DEFAULT_PASSWORD=$(openssl rand -base64 16) 12 | DEFAULT_DOMAIN="" 13 | DEFAULT_MASQ_SITE="https://news.ycombinator.com/" 14 | 15 | # Detect package manager and service manager 16 | detect_system() { 17 | if [ -f /etc/debian_version ]; then 18 | PKG_MANAGER="apt" 19 | PKG_UPDATE="apt update" 20 | PKG_INSTALL="apt install -y" 21 | if systemctl --version >/dev/null 2>&1; then 22 | SERVICE_MANAGER="systemd" 23 | else 24 | SERVICE_MANAGER="sysvinit" 25 | fi 26 | elif [ -f /etc/redhat-release ]; then 27 | if command -v dnf >/dev/null 2>&1; then 28 | PKG_MANAGER="dnf" 29 | PKG_UPDATE="dnf update -y" 30 | PKG_INSTALL="dnf install -y" 31 | else 32 | PKG_MANAGER="yum" 33 | PKG_UPDATE="yum update -y" 34 | PKG_INSTALL="yum install -y" 35 | fi 36 | if systemctl --version >/dev/null 2>&1; then 37 | SERVICE_MANAGER="systemd" 38 | else 39 | SERVICE_MANAGER="sysvinit" 40 | fi 41 | else 42 | echo "不支持的系统" 43 | exit 1 44 | fi 45 | } 46 | 47 | # Install dependencies 48 | install_dependencies() { 49 | echo -e "${YELLOW}安装依赖...${NC}" 50 | $PKG_UPDATE 51 | $PKG_INSTALL wget curl openssl 52 | 53 | # Install qrencode 54 | if ! $PKG_INSTALL qrencode; then 55 | if [ "$PKG_MANAGER" = "yum" ] || [ "$PKG_MANAGER" = "dnf" ]; then 56 | yum install -y epel-release 57 | $PKG_INSTALL qrencode 58 | fi 59 | fi 60 | 61 | if ! command -v qrencode >/dev/null 2>&1; then 62 | echo -e "${YELLOW}警告: qrencode 安装失败,二维码功能将不可用${NC}" 63 | fi 64 | } 65 | 66 | # Generate service file 67 | generate_service() { 68 | if [ "$SERVICE_MANAGER" = "systemd" ]; then 69 | cat > /etc/systemd/system/hysteria.service << EOF 70 | [Unit] 71 | Description=Hysteria 2 Server 72 | After=network.target 73 | 74 | [Service] 75 | Type=simple 76 | ExecStart=/usr/local/bin/hysteria server --config /etc/hysteria/config.yaml 77 | Restart=on-failure 78 | StandardOutput=append:/var/log/hysteria.log 79 | StandardError=append:/var/log/hysteria.error.log 80 | 81 | [Install] 82 | WantedBy=multi-user.target 83 | EOF 84 | systemctl daemon-reload 85 | else 86 | cat > /etc/init.d/hysteria << EOF 87 | #!/bin/sh 88 | ### BEGIN INIT INFO 89 | # Provides: hysteria 90 | # Required-Start: \$network \$remote_fs \$syslog 91 | # Required-Stop: \$network \$remote_fs \$syslog 92 | # Default-Start: 2 3 4 5 93 | # Default-Stop: 0 1 6 94 | # Short-Description: Hysteria 2 Server 95 | ### END INIT INFO 96 | 97 | DAEMON=/usr/local/bin/hysteria 98 | DAEMON_ARGS="server --config /etc/hysteria/config.yaml" 99 | NAME=hysteria 100 | DESC="Hysteria 2 Server" 101 | PIDFILE=/var/run/\$NAME.pid 102 | LOGFILE=/var/log/hysteria.log 103 | ERRFILE=/var/log/hysteria.error.log 104 | 105 | test -x \$DAEMON || exit 0 106 | 107 | do_start() { 108 | start-stop-daemon --start --background --make-pidfile --pidfile \$PIDFILE \\ 109 | --exec \$DAEMON -- \$DAEMON_ARGS >> \$LOGFILE 2>> \$ERRFILE 110 | } 111 | 112 | do_stop() { 113 | start-stop-daemon --stop --quiet --pidfile \$PIDFILE 114 | rm -f \$PIDFILE 115 | } 116 | 117 | case "\$1" in 118 | start) 119 | echo "Starting \$DESC" 120 | do_start 121 | ;; 122 | stop) 123 | echo "Stopping \$DESC" 124 | do_stop 125 | ;; 126 | restart) 127 | echo "Restarting \$DESC" 128 | do_stop 129 | sleep 1 130 | do_start 131 | ;; 132 | status) 133 | if [ -f \$PIDFILE ]; then 134 | echo "\$DESC is running" 135 | else 136 | echo "\$DESC is not running" 137 | fi 138 | ;; 139 | *) 140 | echo "Usage: \$0 {start|stop|restart|status}" 141 | exit 1 142 | ;; 143 | esac 144 | 145 | exit 0 146 | EOF 147 | chmod +x /etc/init.d/hysteria 148 | if [ -x /sbin/chkconfig ]; then 149 | chkconfig --add hysteria 150 | chkconfig hysteria on 151 | elif [ -x /usr/sbin/update-rc.d ]; then 152 | update-rc.d hysteria defaults 153 | fi 154 | fi 155 | } 156 | 157 | # Service control functions 158 | service_start() { 159 | if [ "$SERVICE_MANAGER" = "systemd" ]; then 160 | systemctl start hysteria 161 | else 162 | service hysteria start 163 | fi 164 | } 165 | 166 | service_stop() { 167 | if [ "$SERVICE_MANAGER" = "systemd" ]; then 168 | systemctl stop hysteria 169 | else 170 | service hysteria stop 171 | fi 172 | } 173 | 174 | service_restart() { 175 | if [ "$SERVICE_MANAGER" = "systemd" ]; then 176 | systemctl restart hysteria 177 | else 178 | service hysteria restart 179 | fi 180 | } 181 | 182 | service_status() { 183 | if [ "$SERVICE_MANAGER" = "systemd" ]; then 184 | systemctl status hysteria 185 | else 186 | service hysteria status 187 | fi 188 | } 189 | 190 | # Generate hy2 command 191 | generate_hy2_command() { 192 | cat > /usr/local/bin/hy2 << 'EOF' 193 | #!/bin/bash 194 | 195 | PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 196 | 197 | # Colors 198 | RED='\033[0;31m' 199 | GREEN='\033[0;32m' 200 | YELLOW='\033[0;33m' 201 | NC='\033[0m' 202 | 203 | show_menu() { 204 | clear 205 | echo -e "${YELLOW}Hysteria 2 管理脚本${NC}" 206 | echo "------------------------" 207 | echo -e "${GREEN}1. 更新 Hysteria 2${NC}" 208 | echo -e "${GREEN}2. 卸载 Hysteria 2${NC}" 209 | echo -e "${GREEN}3. 启动服务${NC}" 210 | echo -e "${GREEN}4. 停止服务${NC}" 211 | echo -e "${GREEN}5. 重启服务${NC}" 212 | echo -e "${GREEN}6. 查看状态${NC}" 213 | echo -e "${GREEN}7. 查看配置${NC}" 214 | echo -e "${GREEN}8. 修改配置${NC}" 215 | echo -e "${GREEN}9. 查看日志${NC}" 216 | echo -e "${GREEN}10. 查看分享链接${NC}" 217 | echo -e "${GREEN}11. 显示分享二维码${NC}" 218 | echo -e "${GREEN}0. 退出${NC}" 219 | echo "------------------------" 220 | read -p "请选择操作 [0-11]: " choice 221 | 222 | case "$choice" in 223 | 1) 224 | echo -e "${YELLOW}更新 Hysteria 2...${NC}" 225 | wget -O /usr/local/bin/hysteria https://download.hysteria.network/app/latest/hysteria-linux-amd64 226 | chmod +x /usr/local/bin/hysteria 227 | if [ "$SERVICE_MANAGER" = "systemd" ]; then 228 | systemctl restart hysteria 229 | else 230 | service hysteria restart 231 | fi 232 | echo -e "${GREEN}更新完成${NC}" 233 | ;; 234 | 2) 235 | echo -e "${YELLOW}卸载 Hysteria 2...${NC}" 236 | if [ "$SERVICE_MANAGER" = "systemd" ]; then 237 | systemctl stop hysteria 238 | systemctl disable hysteria 239 | rm -f /etc/systemd/system/hysteria.service 240 | systemctl daemon-reload 241 | else 242 | service hysteria stop 243 | if [ -x /sbin/chkconfig ]; then 244 | chkconfig --del hysteria 245 | elif [ -x /usr/sbin/update-rc.d ]; then 246 | update-rc.d -f hysteria remove 247 | fi 248 | rm -f /etc/init.d/hysteria 249 | fi 250 | rm -f /usr/local/bin/hysteria 251 | rm -f /usr/local/bin/hy2 252 | rm -rf /etc/hysteria 253 | echo -e "${GREEN}卸载完成${NC}" 254 | exit 0 255 | ;; 256 | 3) 257 | echo -e "${YELLOW}启动服务...${NC}" 258 | /usr/local/bin/hysteria server --config /etc/hysteria/config.yaml --disable-update-check 259 | if [ $? -eq 0 ]; then 260 | if [ "$SERVICE_MANAGER" = "systemd" ]; then 261 | systemctl start hysteria 262 | else 263 | service hysteria start 264 | fi 265 | else 266 | echo -e "${RED}启动失败${NC}" 267 | fi 268 | ;; 269 | 4) 270 | echo -e "${YELLOW}停止服务...${NC}" 271 | if [ "$SERVICE_MANAGER" = "systemd" ]; then 272 | systemctl stop hysteria 273 | else 274 | service hysteria stop 275 | fi 276 | ;; 277 | 5) 278 | echo -e "${YELLOW}重启服务...${NC}" 279 | /usr/local/bin/hysteria server --config /etc/hysteria/config.yaml --disable-update-check 280 | if [ $? -eq 0 ]; then 281 | if [ "$SERVICE_MANAGER" = "systemd" ]; then 282 | systemctl restart hysteria 283 | else 284 | service hysteria restart 285 | fi 286 | else 287 | echo -e "${RED}重启失败${NC}" 288 | fi 289 | ;; 290 | 6) 291 | echo -e "${YELLOW}服务状态:${NC}" 292 | if [ "$SERVICE_MANAGER" = "systemd" ]; then 293 | systemctl status hysteria 294 | else 295 | service hysteria status 296 | fi 297 | ;; 298 | 7) cat /etc/hysteria/config.yaml ;; 299 | 8) 300 | echo -e "${YELLOW}修改配置...${NC}" 301 | configure_hysteria 302 | ;; 303 | 9) 304 | if [ -f "/var/log/hysteria.log" ]; then 305 | tail -f /var/log/hysteria.log 306 | else 307 | echo "日志文件不存在" 308 | fi 309 | ;; 310 | 10|11) 311 | PASSWORD=$(grep "password:" /etc/hysteria/config.yaml | awk '{print $NF}') 312 | PORT=$(grep listen /etc/hysteria/config.yaml | awk -F: '{print $3}') 313 | DOMAIN=$(grep domains -A 1 /etc/hysteria/config.yaml | grep - | awk '{print $2}') 314 | [ -z "$DOMAIN" ] && DOMAIN="bing.com" 315 | SHARE_LINK="hysteria2://${PASSWORD}@${DOMAIN}:${PORT}/?sni=${DOMAIN}&insecure=0#${DOMAIN}" 316 | echo 317 | echo "分享链接:" 318 | echo "$SHARE_LINK" 319 | if [ "$choice" = "11" ]; then 320 | echo 321 | echo "QR Code:" 322 | command -v qrencode >/dev/null 2>&1 && { 323 | qrencode -t ANSIUTF8 "$SHARE_LINK" 324 | } || echo "qrencode not found" 325 | fi 326 | ;; 327 | 0) exit 0 ;; 328 | *) 329 | echo "无效选项" 330 | sleep 2 331 | show_menu 332 | ;; 333 | esac 334 | 335 | if [ "$choice" != "0" ] && [ "$choice" != "2" ]; then 336 | echo 337 | read -p "按回车键返回主菜单" 338 | show_menu 339 | fi 340 | } 341 | 342 | show_menu 343 | EOF 344 | chmod +x /usr/local/bin/hy2 345 | } 346 | 347 | # Get user input with default values 348 | get_user_input() { 349 | echo -e "${YELLOW}请输入端口 [默认: $DEFAULT_PORT]:${NC}" 350 | read PORT 351 | PORT=${PORT:-$DEFAULT_PORT} 352 | 353 | echo -e "${YELLOW}请输入密码 [默认: $DEFAULT_PASSWORD]:${NC}" 354 | read PASSWORD 355 | PASSWORD=${PASSWORD:-$DEFAULT_PASSWORD} 356 | 357 | echo -e "${YELLOW}请选择 TLS 验证方式:${NC}" 358 | echo "1. 自定义证书 (适用于 NAT VPS 或自定义证书)" 359 | echo "2. ACME HTTP 验证 (需要 80 端口)" 360 | echo "3. Cloudflare DNS 验证" 361 | read -p "请选择 [1-3]: " TLS_TYPE 362 | 363 | case "$TLS_TYPE" in 364 | 1) 365 | echo -e "${YELLOW}请输入证书路径:${NC}" 366 | read CERT_PATH 367 | echo -e "${YELLOW}请输入私钥路径:${NC}" 368 | read KEY_PATH 369 | ;; 370 | 2) 371 | echo -e "${YELLOW}请输入域名:${NC}" 372 | read DOMAIN 373 | if [ -z "$DOMAIN" ]; then 374 | echo "域名不能为空" 375 | exit 1 376 | fi 377 | ;; 378 | 3) 379 | echo -e "${YELLOW}请输入域名:${NC}" 380 | read DOMAIN 381 | echo -e "${YELLOW}请输入邮箱:${NC}" 382 | read EMAIL 383 | echo -e "${YELLOW}请输入 Cloudflare API Token (在 Cloudflare 面板中: 我的个人资料->API令牌->Origin CA Key):${NC}" 384 | echo -e "${YELLOW}如果没有令牌,请先在 Cloudflare 面板中创建${NC}" 385 | read CF_TOKEN 386 | if [ -z "$DOMAIN" ] || [ -z "$EMAIL" ] || [ -z "$CF_TOKEN" ]; then 387 | echo "所有字段都不能为空" 388 | exit 1 389 | fi 390 | ;; 391 | *) 392 | echo "无效选项" 393 | exit 1 394 | ;; 395 | esac 396 | 397 | echo -e "${YELLOW}请输入伪装站点 [默认: $DEFAULT_MASQ_SITE]:${NC}" 398 | read MASQ_SITE 399 | MASQ_SITE=${MASQ_SITE:-$DEFAULT_MASQ_SITE} 400 | } 401 | 402 | # Generate config based on TLS type 403 | generate_config() { 404 | case "$TLS_TYPE" in 405 | 1) 406 | cat > /etc/hysteria/config.yaml << EOF 407 | listen: :$PORT 408 | 409 | tls: 410 | cert: $CERT_PATH 411 | key: $KEY_PATH 412 | sni_guard: dns-san 413 | 414 | auth: 415 | type: password 416 | password: $PASSWORD 417 | 418 | masquerade: 419 | type: proxy 420 | proxy: 421 | url: $MASQ_SITE 422 | rewriteHost: true 423 | EOF 424 | ;; 425 | 2) 426 | cat > /etc/hysteria/config.yaml << EOF 427 | listen: :$PORT 428 | 429 | acme: 430 | domains: 431 | - $DOMAIN 432 | email: admin@$DOMAIN 433 | 434 | auth: 435 | type: password 436 | password: $PASSWORD 437 | 438 | masquerade: 439 | type: proxy 440 | proxy: 441 | url: $MASQ_SITE 442 | rewriteHost: true 443 | EOF 444 | ;; 445 | 3) 446 | cat > /etc/hysteria/config.yaml << EOF 447 | listen: :$PORT 448 | 449 | acme: 450 | domains: 451 | - $DOMAIN 452 | email: $EMAIL 453 | type: dns 454 | dns: 455 | name: cloudflare 456 | config: 457 | cloudflare_api_token: $CF_TOKEN 458 | 459 | auth: 460 | type: password 461 | password: $PASSWORD 462 | 463 | masquerade: 464 | type: proxy 465 | proxy: 466 | url: $MASQ_SITE 467 | rewriteHost: true 468 | EOF 469 | ;; 470 | esac 471 | } 472 | 473 | # Configure function for both install and modify 474 | configure_hysteria() { 475 | get_user_input 476 | generate_config 477 | 478 | echo -e "${YELLOW}重启服务以应用新配置...${NC}" 479 | service_stop 480 | /usr/local/bin/hysteria server --config /etc/hysteria/config.yaml --disable-update-check 481 | if [ $? -eq 0 ]; then 482 | service_start 483 | echo -e "${GREEN}配置修改成功${NC}" 484 | else 485 | echo -e "${RED}配置有误,启动失败${NC}" 486 | fi 487 | } 488 | 489 | # Check if Hysteria 2 is already installed 490 | check_installed() { 491 | if [ -f "/usr/local/bin/hysteria" ] || [ -f "/etc/init.d/hysteria" ] || [ -f "/etc/systemd/system/hysteria.service" ]; then 492 | echo -e "${YELLOW}检测到已安装 Hysteria 2${NC}" 493 | echo -e "请选择操作:" 494 | echo "1. 卸载重装" 495 | echo "2. 返回主菜单" 496 | read -p "请输入选项 [1-2]: " choice 497 | case "$choice" in 498 | 1) uninstall_hysteria && return 0 ;; 499 | 2) return 1 ;; 500 | *) echo "无效选项" && return 1 ;; 501 | esac 502 | fi 503 | return 0 504 | } 505 | 506 | # Main installation process 507 | main() { 508 | # 检查 root 权限 509 | if [ "$(id -u)" != "0" ]; then 510 | echo -e "${RED}请使用 root 权限运行此脚本${NC}" 511 | exit 1 512 | fi 513 | 514 | # 检测系统 515 | detect_system 516 | 517 | # 检查是否已安装 518 | check_installed 519 | 520 | echo -e "${GREEN}开始安装 Hysteria 2...${NC}" 521 | 522 | install_dependencies 523 | 524 | # Download Hysteria 2 525 | echo -e "${YELLOW}下载 Hysteria 2...${NC}" 526 | wget -O /usr/local/bin/hysteria https://download.hysteria.network/app/latest/hysteria-linux-amd64 527 | chmod +x /usr/local/bin/hysteria 528 | 529 | # Create config directory 530 | mkdir -p /etc/hysteria/ 531 | 532 | echo -e "${YELLOW}配置 Hysteria 2...${NC}" 533 | configure_hysteria 534 | 535 | echo -e "${YELLOW}生成服务文件...${NC}" 536 | generate_service 537 | generate_hy2_command 538 | 539 | # Enable and start service 540 | echo -e "${YELLOW}启动服务...${NC}" 541 | if [ "$SERVICE_MANAGER" = "systemd" ]; then 542 | systemctl enable hysteria 543 | systemctl start hysteria 544 | else 545 | service hysteria start 546 | fi 547 | 548 | # 验证安装 549 | if [ -f "/usr/local/bin/hy2" ] && [ -x "/usr/local/bin/hy2" ]; then 550 | echo -e "${GREEN}Hysteria 2 安装完成!${NC}" 551 | echo -e "${YELLOW}配置信息:${NC}" 552 | echo "端口: $PORT" 553 | echo "密码: $PASSWORD" 554 | echo "域名: ${DOMAIN:-bing.com}" 555 | echo -e "\n使用 'hy2' 命令管理 Hysteria 2" 556 | echo -e "运行 'hy2' 显示管理菜单\n" 557 | else 558 | echo -e "${RED}安装失败,请检查错误信息${NC}" 559 | exit 1 560 | fi 561 | } 562 | 563 | # 直接运行主函数 564 | main 565 | -------------------------------------------------------------------------------- /alpinehy2install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Colors for output 4 | RED='\033[0;31m' 5 | GREEN='\033[0;32m' 6 | YELLOW='\033[0;33m' 7 | NC='\033[0m' 8 | 9 | # Default values 10 | DEFAULT_PORT=5525 11 | DEFAULT_PASSWORD=$(dd if=/dev/random bs=18 count=1 status=none | base64) 12 | DEFAULT_DOMAIN="" 13 | DEFAULT_MASQ_SITE="https://news.ycombinator.com/" 14 | 15 | # Show menu 16 | show_menu() { 17 | clear 18 | echo -e "${YELLOW}Hysteria 2 管理脚本${NC}" 19 | echo "------------------------" 20 | echo -e "${GREEN}1. 安装 Hysteria 2${NC}" 21 | echo -e "${GREEN}2. 更新 Hysteria 2${NC}" 22 | echo -e "${GREEN}3. 卸载 Hysteria 2${NC}" 23 | echo -e "${GREEN}4. 启动 Hysteria 2${NC}" 24 | echo -e "${GREEN}5. 停止 Hysteria 2${NC}" 25 | echo -e "${GREEN}6. 重启 Hysteria 2${NC}" 26 | echo -e "${GREEN}7. 查看运行状态${NC}" 27 | echo -e "${GREEN}8. 查看配置${NC}" 28 | echo -e "${GREEN}9. 修改配置${NC}" 29 | echo -e "${GREEN}10. 查看日志${NC}" 30 | echo -e "${GREEN}11. 查看分享链接${NC}" 31 | echo -e "${GREEN}12. 显示分享二维码${NC}" 32 | echo -e "${GREEN}0. 退出${NC}" 33 | echo "------------------------" 34 | read -p "请选择操作 [0-12]: " choice 35 | 36 | case "$choice" in 37 | 1) check_installed && install_hysteria ;; 38 | 2) 39 | echo -e "${YELLOW}更新 Hysteria 2...${NC}" 40 | wget -O /usr/local/bin/hysteria https://download.hysteria.network/app/latest/hysteria-linux-amd64 41 | chmod +x /usr/local/bin/hysteria 42 | service hysteria restart 43 | echo -e "${GREEN}更新完成${NC}" 44 | ;; 45 | 3) uninstall_hysteria ;; 46 | 4) 47 | echo -e "${YELLOW}启动服务...${NC}" 48 | service hysteria stop >/dev/null 2>&1 49 | /usr/local/bin/hysteria server --config /etc/hysteria/config.yaml --disable-update-check 50 | if [ $? -eq 0 ]; then 51 | service hysteria start 52 | else 53 | echo -e "${RED}启动失败${NC}" 54 | fi 55 | ;; 56 | 5) service hysteria stop ;; 57 | 6) service hysteria restart ;; 58 | 7) service hysteria status ;; 59 | 8) [ -f "/etc/hysteria/config.yaml" ] && cat /etc/hysteria/config.yaml || echo "配置文件不存在" ;; 60 | 9) modify_config ;; 61 | 10) view_logs ;; 62 | 11) [ -f "/usr/local/bin/hy2" ] && /usr/local/bin/hy2 share || echo "Hysteria 2 未安装" ;; 63 | 12) [ -f "/usr/local/bin/hy2" ] && /usr/local/bin/hy2 share || echo "Hysteria 2 未安装" ;; 64 | 0) exit 0 ;; 65 | *) echo "无效选项" && sleep 2 && show_menu ;; 66 | esac 67 | } 68 | 69 | # View logs function 70 | view_logs() { 71 | if [ -f "/var/log/hysteria.log" ]; then 72 | tail -f /var/log/hysteria.log 73 | else 74 | echo "日志文件不存在" 75 | fi 76 | } 77 | 78 | # Modify config function 79 | modify_config() { 80 | if [ ! -f "/etc/hysteria/config.yaml" ]; then 81 | echo "配置文件不存在" 82 | return 83 | fi 84 | get_user_input 85 | generate_config 86 | service hysteria restart 87 | echo "配置已更新" 88 | } 89 | 90 | # Update function 91 | update_hysteria() { 92 | wget -O /usr/local/bin/hysteria https://download.hysteria.network/app/latest/hysteria-linux-amd64 93 | chmod +x /usr/local/bin/hysteria 94 | service hysteria restart 95 | echo "更新完成" 96 | } 97 | 98 | # 配置函数,用于安装和修改配置 99 | configure_hysteria() { 100 | get_user_input 101 | generate_config 102 | 103 | echo -e "${YELLOW}重启服务以应用新配置...${NC}" 104 | service hysteria stop 105 | /usr/local/bin/hysteria server --config /etc/hysteria/config.yaml --disable-update-check 106 | if [ $? -eq 0 ]; then 107 | service hysteria start 108 | echo -e "${GREEN}配置修改成功${NC}" 109 | else 110 | echo -e "${RED}配置有误,启动失败${NC}" 111 | fi 112 | } 113 | 114 | # Install function 115 | install_hysteria() { 116 | # 检查是否已安装 117 | if [ -f "/usr/local/bin/hysteria" ] || [ -f "/etc/init.d/hysteria" ]; then 118 | echo -e "${YELLOW}检测到已安装 Hysteria 2${NC}" 119 | echo -e "请选择操作:" 120 | echo "1. 卸载重装" 121 | echo "2. 返回主菜单" 122 | read -p "请输入选项 [1-2]: " choice 123 | case "$choice" in 124 | 1) uninstall_hysteria ;; 125 | 2) show_menu ;; 126 | *) echo "无效选项" && sleep 2 && show_menu ;; 127 | esac 128 | fi 129 | 130 | echo -e "${GREEN}开始安装 Hysteria 2...${NC}" 131 | 132 | # 检查必要命令 133 | if ! command -v wget >/dev/null 2>&1; then 134 | apk add wget 135 | fi 136 | 137 | # Install dependencies 138 | install_dependencies 139 | configure_hysteria # 使用配置函数 140 | 141 | # Download Hysteria 2 142 | wget -O /usr/local/bin/hysteria https://download.hysteria.network/app/latest/hysteria-linux-amd64 143 | chmod +x /usr/local/bin/hysteria 144 | 145 | # Create config directory 146 | mkdir -p /etc/hysteria/ 147 | 148 | # Generate self-signed cert if no domain provided 149 | if [ -z "$DOMAIN" ]; then 150 | openssl req -x509 -nodes -newkey ec:<(openssl ecparam -name prime256v1) \ 151 | -keyout /etc/hysteria/server.key -out /etc/hysteria/server.crt \ 152 | -subj "/CN=bing.com" -days 36500 153 | fi 154 | 155 | generate_config 156 | generate_service 157 | generate_hy2_command 158 | 159 | # Enable and start service 160 | rc-update add hysteria default 161 | service hysteria start 162 | 163 | # 验证安装 164 | if [ -f "/usr/local/bin/hy2" ] && [ -x "/usr/local/bin/hy2" ]; then 165 | echo -e "${GREEN}Hysteria 2 安装完成!${NC}" 166 | echo -e "${YELLOW}配置信息:${NC}" 167 | echo "端口: $PORT" 168 | echo "密码: $PASSWORD" 169 | echo "域名: ${DOMAIN:-bing.com}" 170 | echo -e "\n使用 'hy2' 命令管理 Hysteria 2" 171 | echo -e "运行 'hy2' 显示管理菜单\n" 172 | else 173 | echo -e "${RED}安装失败,请检查错误信息${NC}" 174 | exit 1 175 | fi 176 | 177 | sleep 3 178 | show_menu 179 | } 180 | 181 | # Check if Hysteria 2 is already installed 182 | check_installed() { 183 | if [ -f "/usr/local/bin/hysteria" ] || [ -f "/etc/init.d/hysteria" ]; then 184 | echo -e "${YELLOW}检测到已安装 Hysteria 2${NC}" 185 | echo -e "请选择操作:" 186 | echo "1. 卸载重装" 187 | echo "2. 返回主菜单" 188 | read -p "请输入选项 [1-2]: " choice 189 | case "$choice" in 190 | 1) uninstall_hysteria && return 0 ;; 191 | 2) return 1 ;; 192 | *) echo "无效选项" && return 1 ;; 193 | esac 194 | fi 195 | } 196 | 197 | # Uninstall function 198 | uninstall_hysteria() { 199 | echo -e "${YELLOW}开始卸载 Hysteria 2...${NC}" 200 | service hysteria stop 201 | rc-update del hysteria default 202 | rm -f /usr/local/bin/hysteria 203 | rm -f /usr/local/bin/hy2 204 | rm -f /etc/init.d/hysteria 205 | rm -rf /etc/hysteria 206 | echo -e "${GREEN}卸载完成${NC}" 207 | } 208 | 209 | # Install dependencies 210 | install_dependencies() { 211 | echo -e "${YELLOW}安装依赖...${NC}" 212 | apk update 213 | apk add wget curl git openssh openssl openrc 214 | # 单独安装并验证 qrencode 215 | if ! apk add libqrencode-tools; then 216 | echo -e "${RED}安装 qrencode 失败,尝试从社区仓库安装${NC}" 217 | apk add --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community libqrencode-tools 218 | fi 219 | 220 | # 验证 qrencode 是否安装成功 221 | if ! command -v qrencode >/dev/null 2>&1; then 222 | echo -e "${YELLOW}警告: qrencode 安装失败,二维码功能将不可用${NC}" 223 | fi 224 | } 225 | 226 | # Get user input with default values 227 | get_user_input() { 228 | echo -e "${YELLOW}请输入端口 [默认: $DEFAULT_PORT]:${NC}" 229 | read PORT 230 | PORT=${PORT:-$DEFAULT_PORT} 231 | 232 | echo -e "${YELLOW}请输入密码 [默认: $DEFAULT_PASSWORD]:${NC}" 233 | read PASSWORD 234 | PASSWORD=${PASSWORD:-$DEFAULT_PASSWORD} 235 | 236 | echo -e "${YELLOW}请选择 TLS 验证方式:${NC}" 237 | echo "1. 自定义证书 (适用于 NAT VPS 或自定义证书)" 238 | echo "2. ACME HTTP 验证 (需要 80 端口)" 239 | echo "3. Cloudflare DNS 验证" 240 | read -p "请选择 [1-3]: " TLS_TYPE 241 | 242 | case "$TLS_TYPE" in 243 | 1) 244 | echo -e "${YELLOW}请输入证书路径:${NC}" 245 | read CERT_PATH 246 | echo -e "${YELLOW}请输入私钥路径:${NC}" 247 | read KEY_PATH 248 | ;; 249 | 2) 250 | echo -e "${YELLOW}请输入域名:${NC}" 251 | read DOMAIN 252 | if [ -z "$DOMAIN" ]; then 253 | echo "域名不能为空" 254 | exit 1 255 | fi 256 | ;; 257 | 3) 258 | echo -e "${YELLOW}请输入域名:${NC}" 259 | read DOMAIN 260 | echo -e "${YELLOW}请输入邮箱:${NC}" 261 | read EMAIL 262 | echo -e "${YELLOW}请输入 Cloudflare API Token (在 Cloudflare 面板中: 我的个人资料->API令牌->创建Token->使用 Edit zone DNS 模板->权限类型:Zone / DNS / Edit,资源:Include / Specific zone / 选择你的域名,如 baidu.com):${NC}" 263 | echo -e "${YELLOW}如果没有令牌,请先在 Cloudflare 面板中创建${NC}" 264 | read CF_TOKEN 265 | if [ -z "$DOMAIN" ] || [ -z "$EMAIL" ] || [ -z "$CF_TOKEN" ]; then 266 | echo "所有字段都不能为空" 267 | exit 1 268 | fi 269 | ;; 270 | *) 271 | 272 | echo "无效选项" 273 | exit 1 274 | ;; 275 | esac 276 | 277 | echo -e "${YELLOW}请输入伪装站点 [默认: $DEFAULT_MASQ_SITE]:${NC}" 278 | read MASQ_SITE 279 | MASQ_SITE=${MASQ_SITE:-$DEFAULT_MASQ_SITE} 280 | } 281 | 282 | # Generate config based on TLS type 283 | generate_config() { 284 | case "$TLS_TYPE" in 285 | 1) 286 | cat > /etc/hysteria/config.yaml << EOF 287 | listen: :$PORT 288 | 289 | tls: 290 | cert: $CERT_PATH 291 | key: $KEY_PATH 292 | sni_guard: dns-san 293 | 294 | auth: 295 | type: password 296 | password: $PASSWORD 297 | 298 | masquerade: 299 | type: proxy 300 | proxy: 301 | url: $MASQ_SITE 302 | rewriteHost: true 303 | EOF 304 | ;; 305 | 2) 306 | cat > /etc/hysteria/config.yaml << EOF 307 | listen: :$PORT 308 | 309 | acme: 310 | domains: 311 | - $DOMAIN 312 | email: admin@$DOMAIN 313 | 314 | auth: 315 | type: password 316 | password: $PASSWORD 317 | 318 | masquerade: 319 | type: proxy 320 | proxy: 321 | url: $MASQ_SITE 322 | rewriteHost: true 323 | EOF 324 | ;; 325 | 3) 326 | cat > /etc/hysteria/config.yaml << EOF 327 | listen: :$PORT 328 | 329 | acme: 330 | domains: 331 | - $DOMAIN 332 | email: $EMAIL 333 | type: dns 334 | dns: 335 | name: cloudflare 336 | config: 337 | cloudflare_api_token: $CF_TOKEN 338 | 339 | auth: 340 | type: password 341 | password: $PASSWORD 342 | 343 | masquerade: 344 | type: proxy 345 | proxy: 346 | url: $MASQ_SITE 347 | rewriteHost: true 348 | EOF 349 | ;; 350 | esac 351 | } 352 | 353 | # Generate OpenRC service file with proper server mode and logging 354 | generate_service() { 355 | cat > /etc/init.d/hysteria << EOF 356 | #!/sbin/openrc-run 357 | 358 | name="hysteria" 359 | command="/usr/local/bin/hysteria" 360 | command_args="server --config /etc/hysteria/config.yaml" 361 | command_background="yes" 362 | pidfile="/var/run/\${name}.pid" 363 | output_log="/var/log/hysteria.log" 364 | error_log="/var/log/hysteria.error.log" 365 | 366 | start_pre() { 367 | checkpath -f \$output_log 368 | checkpath -f \$error_log 369 | chmod 644 \$output_log 370 | chmod 644 \$error_log 371 | } 372 | 373 | depend() { 374 | need net 375 | after firewall 376 | } 377 | 378 | start() { 379 | ebegin "Starting \$name" 380 | start-stop-daemon --start --quiet --background \ 381 | --make-pidfile --pidfile \$pidfile \ 382 | --stdout \$output_log --stderr \$error_log \ 383 | --exec \$command -- \$command_args 384 | eend \$? 385 | } 386 | EOF 387 | chmod +x /etc/init.d/hysteria 388 | } 389 | 390 | # Generate hy2 command 391 | generate_hy2_command() { 392 | cat > /usr/local/bin/hy2 << 'EOF' 393 | #!/bin/sh 394 | 395 | PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 396 | 397 | # Colors for output 398 | RED='\033[0;31m' 399 | GREEN='\033[0;32m' 400 | YELLOW='\033[0;33m' 401 | NC='\033[0m' 402 | 403 | show_menu() { 404 | clear 405 | echo -e "${GREEN}Hysteria 2 管理菜单${NC}" 406 | echo "------------------------" 407 | echo "1. 更新 Hysteria 2" 408 | echo "2. 卸载 Hysteria 2" 409 | echo "3. 启动服务" 410 | echo "4. 停止服务" 411 | echo "5. 重启服务" 412 | echo "6. 查看状态" 413 | echo "7. 查看配置" 414 | echo "8. 修改配置" 415 | echo "9. 查看日志" 416 | echo "10. 查看分享链接" 417 | echo "11. 显示分享二维码" 418 | echo "0. 退出" 419 | echo "------------------------" 420 | read -p "请选择操作 [0-11]: " choice 421 | 422 | case "$choice" in 423 | 1) 424 | echo -e "${YELLOW}更新 Hysteria 2...${NC}" 425 | wget -O /usr/local/bin/hysteria https://download.hysteria.network/app/latest/hysteria-linux-amd64 426 | chmod +x /usr/local/bin/hysteria 427 | service hysteria restart 428 | echo -e "${GREEN}更新完成${NC}" 429 | ;; 430 | 2) 431 | echo -e "${YELLOW}卸载 Hysteria 2...${NC}" 432 | service hysteria stop 433 | rc-update del hysteria default 434 | rm -f /usr/local/bin/hysteria 435 | rm -f /usr/local/bin/hy2 436 | rm -f /etc/init.d/hysteria 437 | rm -rf /etc/hysteria 438 | echo -e "${GREEN}卸载完成${NC}" 439 | exit 0 440 | ;; 441 | 3) 442 | echo -e "${YELLOW}启动服务...${NC}" 443 | service hysteria stop >/dev/null 2>&1 # 先停止服务以防端口占用 444 | /usr/local/bin/hysteria server --config /etc/hysteria/config.yaml --disable-update-check 445 | if [ $? -eq 0 ]; then 446 | service hysteria start 447 | else 448 | echo -e "${RED}启动失败${NC}" 449 | fi 450 | ;; 451 | 4) 452 | echo -e "${YELLOW}停止服务...${NC}" 453 | service hysteria stop 454 | ;; 455 | 5) 456 | echo -e "${YELLOW}重启服务...${NC}" 457 | service hysteria stop 458 | /usr/local/bin/hysteria server --config /etc/hysteria/config.yaml --disable-update-check 459 | if [ $? -eq 0 ]; then 460 | service hysteria start 461 | else 462 | echo -e "${RED}启动失败${NC}" 463 | fi 464 | ;; 465 | 6) 466 | echo -e "${YELLOW}服务状态:${NC}" 467 | service hysteria status 468 | if [ -f "/var/run/hysteria.pid" ]; then 469 | echo -e "\n${YELLOW}程序输出:${NC}" 470 | /usr/local/bin/hysteria server --config /etc/hysteria/config.yaml --disable-update-check 471 | fi 472 | ;; 473 | 7) cat /etc/hysteria/config.yaml ;; 474 | 8) 475 | echo -e "${YELLOW}修改配置...${NC}" 476 | configure_hysteria 477 | ;; 478 | 9) 479 | if [ -f "/var/log/hysteria.log" ]; then 480 | tail -f /var/log/hysteria.log 481 | else 482 | echo "日志文件不存在" 483 | fi 484 | ;; 485 | 10|11) 486 | PASSWORD=$(grep "password:" /etc/hysteria/config.yaml | awk '{print $NF}') 487 | PORT=$(grep listen /etc/hysteria/config.yaml | awk -F: '{print $3}') 488 | DOMAIN=$(grep domains -A 1 /etc/hysteria/config.yaml | grep - | awk '{print $2}') 489 | [ -z "$DOMAIN" ] && DOMAIN="bing.com" 490 | SHARE_LINK="hysteria2://${PASSWORD}@${DOMAIN}:${PORT}/?sni=${DOMAIN}&insecure=0#${DOMAIN}" 491 | echo 492 | echo "分享链接:" 493 | echo "$SHARE_LINK" 494 | if [ "$choice" = "11" ]; then 495 | echo 496 | echo "QR Code:" 497 | command -v qrencode >/dev/null 2>&1 && { 498 | qrencode -t ANSIUTF8 "$SHARE_LINK" 499 | } || echo "qrencode not found. Please install with: apk add libqrencode-tools" 500 | fi 501 | ;; 502 | 0) exit 0 ;; 503 | *) 504 | echo "无效选项" 505 | sleep 2 506 | show_menu 507 | ;; 508 | esac 509 | 510 | if [ "$choice" != "0" ] && [ "$choice" != "2" ]; then 511 | echo 512 | read -p "按回车键返回主菜单" 513 | show_menu 514 | fi 515 | } 516 | 517 | show_menu 518 | EOF 519 | chmod +x /usr/local/bin/hy2 520 | } 521 | 522 | # Main installation process 523 | main() { 524 | # 检查是否已安装 525 | check_installed 526 | 527 | echo -e "${GREEN}开始安装 Hysteria 2...${NC}" 528 | 529 | install_dependencies 530 | get_user_input 531 | 532 | # Download Hysteria 2 533 | echo -e "${YELLOW}下载 Hysteria 2...${NC}" 534 | wget -O /usr/local/bin/hysteria https://download.hysteria.network/app/latest/hysteria-linux-amd64 535 | chmod +x /usr/local/bin/hysteria 536 | 537 | # Create config directory 538 | mkdir -p /etc/hysteria/ 539 | 540 | # Generate self-signed cert if needed 541 | if [ "$TLS_TYPE" = "1" ]; then 542 | echo -e "${YELLOW}使用自定义证书...${NC}" 543 | # 检查证书文件是否存在 544 | if [ ! -f "$CERT_PATH" ] || [ ! -f "$KEY_PATH" ]; then 545 | echo -e "${RED}证书文件不存在${NC}" 546 | exit 1 547 | fi 548 | fi 549 | 550 | echo -e "${YELLOW}生成配置文件...${NC}" 551 | generate_config 552 | 553 | echo -e "${YELLOW}配置系统服务...${NC}" 554 | generate_service 555 | generate_hy2_command 556 | 557 | # Enable and start service 558 | echo -e "${YELLOW}启动服务...${NC}" 559 | rc-update add hysteria default 560 | service hysteria start 561 | 562 | # 等待服务启动并获取日志 563 | sleep 2 564 | if [ -f "/var/log/hysteria.log" ]; then 565 | echo -e "${YELLOW}服务启动日志:${NC}" 566 | tail -n 10 /var/log/hysteria.log 567 | fi 568 | 569 | # 验证安装 570 | if [ -f "/usr/local/bin/hy2" ] && [ -x "/usr/local/bin/hy2" ]; then 571 | echo -e "${GREEN}Hysteria 2 安装完成!${NC}" 572 | echo -e "${YELLOW}配置信息:${NC}" 573 | echo "端口: $PORT" 574 | echo "密码: $PASSWORD" 575 | echo "域名: ${DOMAIN:-bing.com}" 576 | echo -e "\n使用 'hy2' 命令管理 Hysteria 2" 577 | echo -e "运行 'hy2' 显示管理菜单\n" 578 | else 579 | echo -e "${RED}安装失败,请检查错误信息${NC}" 580 | exit 1 581 | fi 582 | } 583 | # 直接运行主函数 584 | main 585 | 586 | --------------------------------------------------------------------------------