Compare commits

...

103 Commits
v1.0 ... master

Author SHA1 Message Date
Olia Lisa
f2be5c8720 增加远程脚本 2026-01-17 17:24:22 +08:00
Olia Lisa
771abcf074 重构代码, 统一项目入口为install.sh 2026-01-15 13:25:05 +08:00
Olia Lisa
8d96dab146 重构代码, 将工具函数文件导入语句放在代码文件头部 2026-01-14 23:04:50 +08:00
Olia Lisa
c8e1f27320 update 2026-01-14 22:58:16 +08:00
Olia Lisa
a46c507968 update 2026-01-14 22:45:40 +08:00
Olia Lisa
feda11fb16 update 2026-01-14 22:38:45 +08:00
Olia Lisa
4eb55e029f 重构代码, 将一键脚本封装为main函数 2026-01-14 22:35:56 +08:00
Olia Lisa
4b4e15a7fc 删除函数check_bash_installed 2026-01-14 22:34:04 +08:00
Olia Lisa
de7d6a6b43 修改提示语 2026-01-14 22:32:53 +08:00
Olia Lisa
ba26eaed8a 修改域名和修改端口操作增加重启docker容器 2026-01-14 22:30:51 +08:00
Olia Lisa
43e9dfa65c 增加函数, 重启docker容器 2026-01-14 22:28:01 +08:00
Olia Lisa
0cb300ea5c 删除验证配置文件逻辑 2026-01-14 22:26:19 +08:00
Olia Lisa
9de686ad28 优化生成端口函数 2026-01-14 22:24:21 +08:00
Olia Lisa
8bcb6b488e 简化文档 2026-01-11 22:30:50 +08:00
Olia Lisa
4ccef4cb1a 新增域名修改脚本,更新安装脚本以支持域名修改功能,并添加配置文件检查 2026-01-11 16:31:31 +08:00
Olia Lisa
a97a5bc02a update 2026-01-11 16:20:20 +08:00
Olia Lisa
af2ca1e4f4 修改安装脚本菜单选项,调整操作顺序并更新描述 2026-01-11 16:16:16 +08:00
Olia Lisa
4f8babb80a 优化代码, 修改获取脚本文件夹 2026-01-02 23:06:25 +08:00
Olia Lisa
40909440b8 增加绿色字体输出函数 2026-01-02 23:04:03 +08:00
Olia Lisa
87f8155210 fix bug 2025-12-31 01:59:45 +08:00
Olia Lisa
569365cc81 fix bug 2025-12-31 01:48:13 +08:00
Olia Lisa
f8df65b4c7 删除文件 2025-12-31 01:13:03 +08:00
Olia Lisa
c86b1e54a6 修改tls文件存放位置 2025-12-31 01:10:52 +08:00
Olia Lisa
4d3c9975fb update 2025-12-31 01:02:51 +08:00
Olia Lisa
519e042d66 update 2025-12-31 00:58:02 +08:00
Olia Lisa
59fba3f6aa fix bug 2025-12-31 00:55:11 +08:00
Olia Lisa
cd1b4628ea update 2025-12-31 00:54:08 +08:00
Olia Lisa
8b32dc3ebe 重构代码, 抽取变量 2025-12-31 00:52:06 +08:00
Olia Lisa
0fcb985e2d 增加acme文件夹配置 2025-12-31 00:43:34 +08:00
Olia Lisa
35cd281724 修改create_config.sh脚本,允许邮箱输入留空并设置默认值 2025-12-30 13:02:47 +08:00
Olia Lisa
b55d17c821 修改acme证书目录映射 2025-12-30 13:00:27 +08:00
Olia Lisa
0c860eb78d 重构代码, 抽取变量 2025-12-30 12:48:43 +08:00
Olia Lisa
542c7e8994 修改配置文件模板和配置文件位置 2025-12-30 12:43:36 +08:00
Olia Lisa
a404a704da fix byg 2025-12-30 12:23:07 +08:00
Olia Lisa
9ac2058ebd update 2025-12-30 12:21:21 +08:00
Olia Lisa
ee772fa9b5 update 2025-12-30 12:17:52 +08:00
Olia Lisa
58268e16ed 增加检查配置文件 2025-12-30 12:11:32 +08:00
Olia Lisa
8421475b36 分享链接添加变量"是否跳过证书验证" 2025-12-30 12:07:26 +08:00
Olia Lisa
40dbfdb75e fix bug 2025-12-29 19:05:41 +08:00
Olia Lisa
4f309a881a fix bug 2025-12-29 18:47:56 +08:00
Olia Lisa
adc8b8c1ad 增加速度限制 2025-12-29 17:38:01 +08:00
Olia Lisa
792defdd42 update 2025-12-09 16:35:04 +08:00
Olia Lisa
4f090bd873 update 2025-12-09 16:26:00 +08:00
Olia Lisa
a2da384dfd fix bug 2025-11-26 09:59:49 +08:00
Olia Lisa
b5f20b9aac feat(docker): set hysteria container name to project name
Update docker-compose.yml to use "${COMPOSE_PROJECT_NAME}" for the hysteria service container name, making it dynamic based on the project folder name for easier identification and to avoid naming conflicts in multi-project Docker deployments.
2025-11-26 09:52:18 +08:00
Olia Lisa
f6d6ae5b27 update 2025-11-21 21:36:47 +08:00
Olia Lisa
bf8f6cd148 update 2025-11-20 20:43:47 +08:00
Olia Lisa
0edefe7692 修改菜单号码 2025-11-20 20:33:40 +08:00
Olia Lisa
d5d8160629 修改文件名和函数名字 2025-11-20 20:31:36 +08:00
Olia Lisa
9feddc1c80 更新提示语 2025-11-20 19:24:36 +08:00
Olia Lisa
33c4e7eabd 取消跟踪config.json文件 2025-11-20 19:20:47 +08:00
Olia Lisa
90f2d5c093 update 2025-11-20 19:19:48 +08:00
Olia Lisa
c91e4935c3 fix: enhance config file checks to prevent errors on missing or empty files
Add checks using `-s` flag to verify config.json existence and non-emptiness before processing passwords,
avoiding potential script failures when the file is absent or zero-length, improving robustness.
2025-11-20 19:04:15 +08:00
Olia Lisa
ed4a86997d 删除旧的创建配置文件 2025-11-20 18:36:36 +08:00
Olia Lisa
210597c0f1 udpate 2025-11-20 18:34:01 +08:00
Olia Lisa
21e587e023 fix bug 2025-11-20 18:32:53 +08:00
Olia Lisa
955e3d7cb6 整理代码 2025-11-20 18:09:56 +08:00
Olia Lisa
99e53a1680 update 2025-11-20 12:32:36 +08:00
Olia Lisa
0203cc0c10 update 2025-11-20 12:19:26 +08:00
Olia Lisa
4b16f5dde9 fix bug 2025-11-20 12:19:02 +08:00
Olia Lisa
1a092c8887 fix bug 2025-11-20 09:35:43 +08:00
Olia Lisa
5a6d943dd9 update 2025-11-08 11:54:48 +08:00
Olia Lisa
40b8135701 update update_password.sh and base.sh 2025-11-08 11:48:13 +08:00
Olia Lisa
be91ff8272 feat: create update_obfs_password.sh add 2025-11-08 11:47:14 +08:00
Olia Lisa
b0c322e595 update 2025-11-08 11:46:45 +08:00
Olia Lisa
40fdb573b1 特显分享链接 2025-10-09 22:20:37 +08:00
Olia Lisa
c1a92809a0 增加提示语 2025-10-09 22:14:19 +08:00
Olia Lisa
0004e13e1a update 2025-10-09 22:12:57 +08:00
Olia Lisa
66dd349643 增加函数 - 查找空闲端口 2025-10-09 21:54:23 +08:00
Olia Lisa
3cdbad243f update update_password.sh 2025-10-09 15:28:23 +08:00
Olia Lisa
a84ff6292a update update_docker_images.sh 2025-10-09 15:25:53 +08:00
Olia Lisa
589db04e8e update set_domain.sh 2025-10-09 15:23:28 +08:00
Olia Lisa
d1a6deaab6 update run.sh 2025-10-09 15:20:21 +08:00
Olia Lisa
5ac3ce9ae9 重构代码为单个函数 2025-10-09 15:13:03 +08:00
Olia Lisa
9bbaacfb98 调整代码位置 2025-10-09 15:05:24 +08:00
Olia Lisa
90e49e9cf3 修改注释 2025-10-09 15:02:11 +08:00
Olia Lisa
cde7a106f1 fix: 修复安装脚本中缺少的echo语句 2025-02-09 23:27:50 +08:00
Olia Lisa
bd44bc0b9d feat: 添加安装并启动功能 2025-02-09 23:24:17 +08:00
Olia Lisa
488cb36e66 fix: 优化 Bash 安装检查逻辑 2025-02-09 15:08:27 +08:00
Olia Lisa
aab132a900 feat: 增加检查bash是否安装的功能 2025-02-09 15:03:47 +08:00
Olia Lisa
6c97e405c9 feat: 添加 Bash 安装检查功能 2025-02-09 15:03:38 +08:00
Olia Lisa
8f61e632f1 feat: 添加 Bash 安装检查函数 2025-02-09 15:01:47 +08:00
Olia Lisa
626f561b3f fix: 修复错误的config_dir变量 2025-02-08 23:00:32 +08:00
Olia Lisa
3a22d6f18a feat(core): 添加安装脚本菜单功能 2025-02-08 22:51:15 +08:00
Olia Lisa
6a39dc7b17 fix: 增加jq安装检查并修正密码读取逻辑 2025-02-08 22:50:41 +08:00
Olia Lisa
bb7409ceed refactor: 添加检查jq安装和容器启动逻辑 2025-02-08 22:50:27 +08:00
Olia Lisa
cdc84896c8 refactor: 添加base.sh并简化jq检查 2025-02-08 22:43:16 +08:00
Olia Lisa
24574b135a feat: 添加系统包管理器检测及jq安装脚本 2025-02-08 22:41:06 +08:00
Olia Lisa
fb1829898d feat: 添加更新端口脚本 2025-02-08 22:40:11 +08:00
Kiolow
0bb8c83e28 update 2025-01-11 14:25:41 +08:00
Kiolow
5b19c1842f update 2025-01-11 14:24:09 +08:00
Kiolow
ee9e10d31c update, 增加脚本 2025-01-11 14:18:18 +08:00
Kiolow
228b56445c update 2025-01-11 14:13:03 +08:00
Kiolow
8239162506 update 2025-01-11 14:08:27 +08:00
Kiolow
49ea55c4f9 update 2025-01-11 13:14:03 +08:00
Kiolow
afcc5d177e fix bug, 修改"删除无用镜像命令" 2025-01-11 13:06:24 +08:00
Kiolow
f85e319b75 update 2024-11-21 10:32:34 +08:00
Kiolow
863592de8d update 2024-11-21 10:20:35 +08:00
Kiolow
a0be76b3bf update 2024-11-21 10:15:42 +08:00
Kiolow
ea58e5de38 增加混淆密码 2024-10-26 09:55:56 +08:00
Kiolow
b537262c3d update 2024-07-05 14:44:56 +08:00
Kiolow
a5083db693 fix bug 2024-06-07 13:08:37 +08:00
Kiolow
b887abc50a fix bug 2024-06-07 13:08:00 +08:00
24 changed files with 703 additions and 251 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
config/config.json
acme/

107
README.md
View File

@ -1,114 +1,43 @@
# 使用说明
项目使用自有证书搭建, 无需要准备域名.
默认使用`bing.com`域名作为伪装.
## 项目描述
基于 docker 容器的 hysteria2 服务器端节点搭建
## 快速开始
### 部署服务器端
确认安装好下列软件
- docker
- docker-compose
提前安装下列软件
- wget
- git
- curl
下载项目代码
```bash
git clone https://gittea.wingogo.top/William/hysteria_docker.git
git clone https://gitea.9001001.xyz/William/hysteria_docker.git
```
进入项目目录
```bash
cd hysteria_docker
```
配置初始化, **第一次运行必须执行**
运行安装脚本,选择选项 1一键部署
```bash
bash ./bin/init.sh
bash ./install.sh
```
启动项目
```bash
docker-compose up -d
```
### 电脑配置客户端
查看日志
```bash
docker-compose logs | head -n 50
```
### 查看分享链接
进入项目目录, 执行以下命令
```bash
bash ./bin/print_share_link.sh
```
### 客户端配置
客户端软件(选择其中一种)
- [v2rayN](https://github.com/2dust/v2rayN/releases)
- [nekoray](https://github.com/MatsuriDayo/nekoray/releases)
客户端配置
- (方法1)把分享链接直接粘贴到客户端
- (方法2)手工输入配置
无域名使用IP搭建download-bandwidth 根据实际填写
```yaml
地址: 服务器ip
端口: 8443 # 服务器端端口
密码: RhCLi%T&MFe5&de # 服务器端密码
传输安全层: tls
SNI: bing.com # 伪装域名
跳过证书验证: true
download-bandwidth=200
```
## 服务器端,修改域名
如果需要修改其他伪装域名, 进入项目目录, 执行以下命令
```bash
bash ./bin/set_domain.sh expedia.com
```
## 服务器端,修改端口
修改`config.json`配置文件
```json
{
"listen": ":9999", // 改为其他端口
// 省略其他代码...
}
```
## 服务器端, 升级镜像
```bash
bash ./bin/update_docker_images.sh
```
## 文件解析
### 文件`set_domain.sh`
用来生成自签证书和设置伪装域名
```bash
# 生成自签名的 ECDSA 证书并设置有效期为 100 年
# 使用 OpenSSL 的证书请求工具
openssl req \
-x509 \ # 生成自签名的X.509证书
-nodes \ # 不使用加密算法保护私钥
-newkey ec:<(openssl ecparam -name prime256v1) \ # 生成 ECDSA 私钥和公钥,使用 prime256v1 曲线
-keyout /etc/hysteria/server.key \ # 将生成的私钥保存到指定路径
-out /etc/hysteria/server.crt \ # 将生成的自签名证书保存到指定路径
-subj "/CN=bing.com" \ # 设置证书的主题字段CN是 Common Name (CN)
-days 36500 \ # 设置证书的有效期为 36500 天约100年
```
- `openssl`是一个开源的加密工具包提供了一系列用于处理安全通信的命令和库。它支持多种加密算法、数字证书和相关的功能包括生成和签名证书、创建和验证数字签名、加解密数据等。常见用途包括创建和管理SSL/TLS证书、进行加密通信以及执行与加密相关的各种操作。
- `-subj `参数用于在 OpenSSL 命令中设置证书主题字段,其中 "/CN=example.com" 指定了通用名称 (Common Name, CN),表示证书关联的主机名。
### 文件`server.crt`和`server.key`是证书文件
### 文件`config.json`是服务器端配置文件
- [V2rayN](https://github.com/2dust/v2rayN/releases)
- [Nekoray](https://github.com/MatsuriDayo/nekoray/releases)
## 参考
- https://v2.hysteria.network/zh/docs/getting-started/Server/
- https://v2rayssr.com/hysteria2.html
- https://www.iiiam.in/articles/server/deploy-hysteria2

110
bin/create_config.sh Normal file
View File

@ -0,0 +1,110 @@
#!/bin/bash
create_config_with_tls_cert() {
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local config_dir="$script_dir/../config"
local config_file="$config_dir/config.json"
cp "$config_dir/template/tls_cert_config.json" "$config_file"
# 设置端口
change_port
# 设置密码
update_password
# 设置混淆密码
update_obfs_password
# 获取邮箱
read -p "请输入你的邮箱(可留空): " user_email
if [[ -z "$user_email" ]]; then
user_email="example@example.com"
fi
# 获取域名
read -p "请输入你的域名 (例如: example.com): " user_domain
while [[ -z "$user_domain" ]]; do
echo "[错误] 域名不能为空"
read -p "请输入你的域名: " user_domain
done
# 获取 Cloudflare API Token
read -p "请输入你的 Cloudflare API Token: " cloudflare_token
while [[ -z "$cloudflare_token" ]]; do
echo "[错误] Cloudflare API Token 不能为空"
read -p "请输入你的 Cloudflare API Token: " cloudflare_token
done
# 使用 sed 替换邮箱
sed -i "s/你的邮箱/$user_email/g" "$config_file"
# 替换域名 (在 domains 数组和 masquerade url 中)
sed -i "s/你的域名/$user_domain/g" "$config_file"
# 替换 Cloudflare API Token
sed -i "s/你的cloudflare_api_token/$cloudflare_token/g" "$config_file"
green "创建配置成功"
}
create_self_tls_config() {
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local config_dir="$script_dir/../config"
cp "$config_dir/template/self_cert_config.json" "$config_dir/config.json"
# 设置端口
change_port
# 设置密码
update_password
# 设置混淆密码
update_obfs_password
# 生成自签名证书和设置域名
gen_self_tls "bing.com"
green "创建配置成功"
}
create_config(){
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local config_file="$script_dir/../config/config.json"
# 如果配置文件不存在, 创建空白配置文件
if [ ! -e "$config_file" ]; then
touch "$config_file"
fi
local config_password=$(jq -r '.auth.password' "$config_file")
if [ -s "$config_file" ] && [ "$config_password" != "你的密码" ]; then
local regenerate
read -p "检测到配置已存在,是否重新生成配置?(y/n): " regenerate
if [ "$regenerate" != "y" ] && [ "$regenerate" != "Y" ]; then
echo "取消重新生成配置."
return
fi
fi
echo "请选择配置类型:"
echo "1. 自签名证书配置"
echo "2. tls证书配置"
local choice
read -p "输入您的选择: " choice
case $choice in
1)
echo "重置为自签名证书配置..."
create_self_tls_config
;;
2)
echo "重置为tls证书配置..."
create_config_with_tls_cert
;;
*)
echo "无效的选择, 请重新选择."
;;
esac
}

21
bin/gen_self_tls.sh Normal file
View File

@ -0,0 +1,21 @@
#!/bin/bash
# 生成自签名证书
gen_self_tls() {
local domain="${1:-bing.com}"
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local key_dir="$script_dir/../tls/self-tls"
# 生成自签名证书
mkdir -p "$key_dir"
openssl req -x509 -nodes -newkey ec:<(openssl ecparam -name prime256v1) \
-keyout "$key_dir/server.key" \
-out "$key_dir/server.crt" \
-subj "/CN=$domain" \
-days 36500
# 更新config.json文件中的域名信息
local config_file="$script_dir/../config/config.json"
modify_json_file "$config_file" "masquerade.proxy.url" "https://$domain"
}

View File

@ -1,12 +0,0 @@
#!/bin/bash
script_dir=$(cd "$(dirname "$0")"; pwd) # 脚本绝对路径
# 更新密码
bash "$script_dir/update_password.sh"
# 更新证书和设置域名
bash "$script_dir/set_domain.sh" "bing.com"
# 打印分享链接
bash "$script_dir/print_share_link.sh"

View File

@ -1,26 +1,47 @@
#!/bin/bash
# 检查 jq 命令是否可用
if ! command -v jq &> /dev/null
then
echo "jq 命令未安装,请先安装 jq。"
print_share_link() {
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local config_dir=$(readlink -f "$script_dir/../config")
local config_file="$config_dir/config.json"
# 检查jq是否安装
check_jq
# 检查配置文件是否存在
if [ ! -f "$config_file" ]; then
red "error: 配置文件未生成, 查看配置失败"
echo '请选择"生成配置 / 重置配置"'
exit 1
fi
# 获取脚本所在目录的上级目录路径
script_dir=$(cd "$(dirname "$0")"; pwd)
# 检查是否已启动过容器
local password=$(jq -r '.auth.password' "$config_file")
if [ "$password" = "你的密码" ]; then
red "error: 容器未启动过, 查看配置失败"
echo '请选择"启动容器"'
exit 1
fi
# 读取 config.json 文件
config=$(cat "$script_dir/../config.json")
# 检查是否使用ACME证书
local allowInsecure=1 # 默认跳过证书验证
if jq -e 'has("acme")' "$config_file" > /dev/null 2>&1; then
allowInsecure=0 # 不跳过证书验证
fi
# 读取配置文件内容
local config=$(cat "$config_file")
# 提取所需信息
password=$(echo "$config" | jq -r '.auth.password')
sni=$(echo "$config" | jq -r '.masquerade.proxy.url' | awk -F'/' '{print $3}')
ipv4=$(curl -4 -sSL --connect-timeout 3 --retry 2 ip.sb || echo "null") # 本机IPV4地址
port=$(echo "$config" | jq -r '.listen' | cut -d':' -f2) # 端口号
local sni=$(echo "$config" | jq -r '.masquerade.proxy.url' | awk -F'/' '{print $3}')
local ipv4=$(curl -4 -sSL --connect-timeout 3 --retry 2 ip.sb || echo "null")
local port=$(echo "$config" | jq -r '.listen' | cut -d':' -f2)
local obfs_password=$(echo "$config" | jq -r '.obfs.salamander.password')
# 构建分享链接
share_link="hysteria2://${password}@${ipv4}:${port}/?sni=${sni}&insecure=1#${ipv4}"
local share_link="hysteria2://${password}@${ipv4}:${port}/?sni=${sni}&insecure=1&obfs-password=${obfs_password}&allowInsecure=${allowInsecure}#Hysteria2节点"
# 输出分享链接
echo -e "\033[32m"
@ -28,5 +49,8 @@ echo "IPV4: $ipv4"
echo "port: $port"
echo "password: $password"
echo "sni: $sni"
echo "混淆密码: $obfs_password"
echo ""
echo "分享链接: $share_link"
echo -e "\033[0m"
}

3
bin/remote/README.md Normal file
View File

@ -0,0 +1,3 @@
## 说明
这个文件夹的文件用于被其他主机(本地电脑)远程调用. 不要导入使用.

View File

@ -0,0 +1,28 @@
#!/bin/bash
update_docker_images(){
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../" # 脚本文件绝对路径
local docker_compose_file="$script_dir/../docker-compose.yml" # docker-compose.yml文件路径
# 检查是否存在 docker-compose.yml 文件
if [ ! -f $docker_compose_file ]; then
echo "Error: docker-compose.yml 文件不存在."
exit 1
fi
echo "正在关闭容器.."
docker-compose -f $docker_compose_file down
echo "正在更新镜像.."
docker-compose -f $docker_compose_file pull
echo "正在删除未使用的镜像..."
docker image prune -f
echo "正在启动容器.."
docker-compose -f $docker_compose_file up -d
}
update_docker_images

16
bin/run.sh Normal file
View File

@ -0,0 +1,16 @@
#!/bin/bash
run() {
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local compose_file="$script_dir/../docker-compose.yml"
# 如果容器已经启动, 则先停止容器
if docker-compose -f "$compose_file" ps | grep -q "Up"; then
docker-compose -f "$compose_file" down
fi
# 启动docker容器
docker-compose -f "$compose_file" up -d
}

View File

@ -1,27 +0,0 @@
#!/bin/bash
# 当前脚本所在目录的绝对路径
script_dir="$(dirname "$(realpath "$0")")"
# 导入utils文件夹中的jq_util.sh脚本
source "$script_dir/utils/jq_util.sh"
gen_cert() {
local domain="$1"
local key_dir="$script_dir/../key" # key目录绝对路径
# 使用openssl生成自签名证书设置密钥和有效期并指定域名信息
openssl req -x509 -nodes -newkey ec:<(openssl ecparam -name prime256v1) -keyout "$key_dir/server.key" -out "$key_dir/server.crt" -subj "/CN=$domain" -days 36500
}
update_config() {
local domain="$1"
local config_file="$script_dir/../config.json" # config.json文件路径
# 使用jq_util.sh脚本中的modify_json_file函数修改config.json文件中的域名信息
modify_json_file $config_file "masquerade.proxy.url" "https://$domain"
}
domain="${1:-bing.com}" # 域名, 默认为"bing.com"
gen_cert "$domain" # 生成证书
update_config "$domain" # 更新config.json文件

View File

@ -1,19 +1,25 @@
#!/bin/bash
script_dir="$(dirname "$(realpath "$0")")" # 当前脚本所在目录的绝对路径
docker_compose_file=$(readlink -f "$script_dir/../docker-compose.yml") # docker-compose.yaml文件路径
# 更新容器的函数
update_docker_images() {
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local docker_compose_file=$(readlink -f "$script_dir/../docker-compose.yml")
# 检查是否存在 docker-compose.yml 文件
if [ ! -f $docker_compose_file ]; then
if [ ! -f "$docker_compose_file" ]; then
echo "Error: docker-compose.yml 文件不存在."
exit 1
fi
echo "正在关闭容器.."
docker-compose -f $docker_compose_file down
docker-compose -f "$docker_compose_file" down
echo "正在更新镜像.."
docker-compose -f $docker_compose_file pull
docker-compose -f "$docker_compose_file" pull
echo "正在删除未使用的镜像..."
docker image prune -f
echo "正在启动容器.."
docker-compose -f $docker_compose_file up -d
docker-compose -f "$docker_compose_file" up -d
}

31
bin/update_domain.sh Normal file
View File

@ -0,0 +1,31 @@
#!/bin/bash
# 修改域名
update_domain(){
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 脚本文件夹绝对路径
local config_file="$script_dir/../config/config.json"
# 检查jq是否安装
check_jq
# 输入新的domain
local domain
read -p "请输入新的域名: " domain
# 如果输入为空,退出脚本
if [[ -z "$domain" ]]; then
echo "输入域名为空,退出脚本"
exit 1
fi
modify_json_file "$config_file" ".masquerade.proxy.url" "https://$domain"
# 是否存在acme域名, 存在则修改
local acme_exists=$(jq -r 'has("acem")' "$config_file")
if [[ "$acme_exists" == "true" ]]; then
modify_json_file "$config_file" ".acme.domains[0]" "$domain"
fi
echo "修改域名成功"
}

View File

@ -0,0 +1,18 @@
#!/bin/bash
# 更新密码的函数
update_obfs_password() {
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local config_file="$script_dir/../config/config.json"
# 检查jq是否安装
check_jq
# 生成一个长度为16的随机密码
local new_password=$(gen_password 16)
# 使用jq_util.sh中的modify_json_file函数修改config.json文件中的auth.password字段
modify_json_file "$config_file" 'obfs.salamander.password' "$new_password"
echo "更新混淆密码成功"
}

View File

@ -1,36 +1,18 @@
#!/bin/bash
# 检查是否安装了jq命令
if ! command -v jq &> /dev/null; then
echo "Error: jq command not found. Please install jq first."
exit 1
fi
# 更新密码的函数
update_password() {
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local config_file="$script_dir/../config/config.json"
# 当前脚本所在目录的绝对路径
script_dir="$(dirname "$(realpath "$0")")"
# 加载jq_util.sh脚本
source $script_dir/utils/jq_util.sh
# 函数生成随机密码
gen_random_pass() {
local pass_length=$1 # 密码长度作为第一个参数
local chars='[:alnum:]' # 只允许出现字母和数字
local rand
rand=$(< /dev/urandom tr -dc "$chars" | head -c "$pass_length")
echo "$rand"
}
# 检查jq是否安装
check_jq
# 生成一个长度为16的随机密码
new_password=$(gen_random_pass 16)
# 更新config.json文件中的auth.password字段
config_file="$script_dir/../config.json"
local new_password=$(gen_password 16)
# 使用jq_util.sh中的modify_json_file函数修改config.json文件中的auth.password字段
modify_json_file "$config_file" '.auth.password' "$new_password"
modify_json_file "$config_file" 'auth.password' "$new_password"
echo "New password: $new_password"
echo "config.json file updated with new password."
echo "设置密码成功"
}

84
bin/update_port.sh Normal file
View File

@ -0,0 +1,84 @@
#!/bin/bash
# 查找随机空闲端口
# 用途:
# 在指定端口范围内随机选择一个当前未被监听TCP/UDP的端口
# 参数:
# $1: 起始端口(默认 10001
# $2: 结束端口(默认 65535
# $3: 最大随机尝试次数(默认 100
find_free_port() {
local start="${1:-10001}"
local max="${2:-65535}"
local attempts="${3:-100}"
# ------------------------------------------------------------
# 收集当前正在监听的端口TCP + UDP
# 优先使用 ss其次 netstat
# ------------------------------------------------------------
local used_ports raw
if command -v ss >/dev/null 2>&1; then
# ss 输出示例:
# LISTEN 0 128 0.0.0.0:22
raw=$(ss -lntu 2>/dev/null || true)
used_ports=$(printf "%s\n" "$raw" \
| awk '{print $5}' \
| sed -E 's/.*[:]//g')
elif command -v netstat >/dev/null 2>&1; then
# netstat 输出示例:
# tcp 0 0 0.0.0.0:22
raw=$(netstat -lntu 2>/dev/null || true)
used_ports=$(printf "%s\n" "$raw" \
| awk '{print $4}' \
| sed -E 's/.*[:]//g')
else
echo "Error: ss or netstat is required to check listening ports." >&2
return 2
fi
# ------------------------------------------------------------
# 将已占用端口存入关联数组,便于 O(1) 判断
# 需要 bash 4+
# ------------------------------------------------------------
declare -A used_map
local p
for p in $used_ports; do
# 过滤非数字字段(如 *、:::
if [[ $p =~ ^[0-9]+$ ]]; then
used_map["$p"]=1
fi
done
# ------------------------------------------------------------
# 随机尝试若干次
# 每次随机生成一个端口,只要未被监听就立即返回
# ------------------------------------------------------------
local port i
for ((i=0; i<attempts; i++)); do
# 在 [start, max] 范围内生成随机端口
port=$(( RANDOM % (max - start + 1) + start ))
# 如果端口不在已监听表中,则认为可用
if [[ -z "${used_map[$port]}" ]]; then
echo "$port"
return 0
fi
done
# ------------------------------------------------------------
# 多次随机尝试后仍未找到可用端口
# 通常意味着端口范围过小或已被大量占用
# ------------------------------------------------------------
echo "Error: no free port found after $attempts random attempts." >&2
return 1
}
change_port(){
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local config_dir=$(readlink -f "$script_dir/../config")
local config_file="$config_dir/config.json"
local port=$(find_free_port)
modify_json_file "$config_file" ".listen" ":$port"
echo "已分配新的空闲端口, 设置端口成功"
}

105
bin/utils/base.sh Normal file
View File

@ -0,0 +1,105 @@
#!/bin/bash
red(){
echo -e "\033[31m$1\033[0m"
}
green(){
echo -e "\033[32m$1\033[0m"
}
# 获取系统包管理器
get_package_manager(){
if command -v apt-get &> /dev/null; then
echo "apt-get"
elif command -v yum &> /dev/null; then
echo "yum"
else
echo "未知的系统包管理器"
return 1 # 返回错误状态码
fi
}
# 检查 jq 是否已安装
check_jq(){
if command -v jq &> /dev/null; then
return 0 # jq 已安装,返回成功
fi
echo "jq 未安装,正在安装..."
install_package jq
}
# 动态安装软件包
install_package() {
local package_name=$1
if command -v "$package_name" &> /dev/null; then
echo "$package_name 已安装, 跳过."
return 0
fi
echo "安装 $package_name..."
package_manager=$(get_package_manager)
if [ "$package_manager" == "apt-get" ]; then
sudo apt-get update
sudo apt-get install -y "$package_name"
elif [ "$package_manager" == "yum" ]; then
sudo yum install -y "$package_name"
else
echo "未知的包管理器, 请手动安装 $package_name."
return 1
fi
}
# 生成密码
gen_password() {
local pass_length=$1 # 密码长度作为第一个参数
local chars='[:alnum:]' # 只允许出现字母和数字
local rand
rand=$(< /dev/urandom tr -dc "$chars" | head -c "$pass_length")
echo "$rand"
}
# 检查配置文件
check_config_file(){
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../" # 脚本文件夹绝对路径
local config_file="$script_dir/../config/config.json"
# 检查配置文件是否存在
if [ ! -e "$config_file" ]; then
echo "配置文件不存在, 请先生成配置文件."
exit 1
fi
# 检查配置文件是否为有效的JSON格式
if ! jq '.' "$config_file" >/dev/null 2>&1; then
echo "配置文件不是有效的JSON格式, 请重新生成配置文件."
exit 1
fi
}
restart_docker() {
# 如果容器未运行,提示启动
local running_count=$(docker-compose -f ./docker-compose.yml ps -q | wc -l)
if [ "$running_count" -eq 0 ]; then
read -p "容器未启动,是否启动容器?(y/n): " choice
case "$choice" in
Y|y)
docker-compose -f ./docker-compose.yml up -d
return
;;
*)
echo "已取消启动"
return
;;
esac
fi
echo "正在重启容器..."
docker-compose -f ./docker-compose.yml down
docker-compose -f ./docker-compose.yml up -d
}

View File

@ -7,6 +7,11 @@ function modify_json_file() {
local key=$2 # 要修改的key
local value=$3 # 要修改的value
#如果key的值是.开头, 则去掉.号
if [[ ${key} == "."* ]]; then
key=${key:1}
fi
jq ".${key} = \"${value}\"" ${json_file} > ${json_file}.tmp
mv ${json_file}.tmp ${json_file}
}

View File

@ -1,18 +0,0 @@
{
"listen": ":8443",
"tls": {
"cert": "/etc/hysteria/server.crt",
"key": "/etc/hysteria/server.key"
},
"auth": {
"type": "password",
"password": "La4AdWOoE57OdtwY"
},
"masquerade": {
"type": "proxy",
"proxy": {
"url": "https://bing.com",
"rewriteHost": true
}
}
}

View File

@ -0,0 +1,28 @@
{
"listen": ":8004",
"tls": {
"cert": "/tls/self-tls/server.crt",
"key": "/tls/self-tls/server.key"
},
"auth": {
"type": "password",
"password": "你的密码"
},
"obfs": {
"type": "salamander",
"salamander": {
"password": "你的混淆密码"
}
},
"masquerade": {
"type": "proxy",
"proxy": {
"url": "https://你的域名",
"rewriteHost": true
}
},
"bandwidth": {
"up": "50 mbps",
"down": "100 mbps"
}
}

View File

@ -0,0 +1,38 @@
{
"listen": ":8445",
"acme": {
"domains": [
"你的域名"
],
"email": "你的邮箱",
"dir":"/tls/acme",
"type": "dns",
"dns": {
"name": "cloudflare",
"config": {
"cloudflare_api_token": "你的cloudflare_api_token"
}
}
},
"auth": {
"type": "password",
"password": "你的密码"
},
"obfs": {
"type": "salamander",
"salamander": {
"password": "你的混淆密码"
}
},
"masquerade": {
"type": "proxy",
"proxy": {
"url": "https://你的域名",
"rewriteHost": true
}
},
"bandwidth": {
"up": "50 mbps",
"down": "100 mbps"
}
}

View File

@ -1,17 +1,11 @@
version: "3.9"
services:
hysteria:
image: tobyxdd/hysteria:latest
container_name: hysteria
container_name: "${COMPOSE_PROJECT_NAME}" # 容器名为文件夹名称
restart: always
network_mode: "host"
volumes:
- acme:/acme
- ./config.json:/etc/hysteria/config.json
- ./key/server.crt:/etc/hysteria/server.crt
- ./key/server.key:/etc/hysteria/server.key
- ./tls:/tls
- ./config/config.json:/etc/hysteria/config.json
command: ["server", "-c", "/etc/hysteria/config.json"]
volumes:
acme:

101
install.sh Normal file
View File

@ -0,0 +1,101 @@
#!/bin/bash
# 导入依赖脚本文件
BASE_DIR="$(cd "$(dirname "$0")" && pwd)"
for f in "$BASE_DIR"/bin/utils/*.sh; do
[ -f "$f" ] && source "$f"
done
for f in "$BASE_DIR"/bin/*.sh; do
[ -f "$f" ] && source "$f"
done
install(){
if ! command -v curl >/dev/null 2>&1; then
install_package curl
fi
if ! command -v wget >/dev/null 2>&1; then
install_package wget
fi
if ! command -v jq >/dev/null 2>&1; then
install_package jq
fi
if ! command -v docker >/dev/null 2>&1; then
echo 安装docker...
curl -fsSL https://get.docker.com | bash -s docker
fi
if ! command -v docker-compose >/dev/null 2>&1; then
echo 安装docker-compose...
wget -O /usr/local/bin/docker-compose https://github.com/docker/compose/releases/download/v2.29.0/docker-compose-linux-x86_64
chmod +x /usr/local/bin/docker-compose
fi
}
main(){
# 显示菜单
echo "请选择一个操作:"
echo "1. 一键部署"
echo "2. 生成配置 / 重置配置"
echo "3. 查看分享链接"
echo "4. 启动容器"
echo "5. 停止容器"
echo "6. 更新镜像"
echo "7. 修改域名"
echo "8. 修改端口"
# 读取用户选择
read -p "输入您的选择: " choice
# 根据用户选择执行相应的操作
case $choice in
1)
# 一键部署
install
create_config
run
print_share_link
;;
2)
# 生成配置
create_config
;;
3)
# 查看分享链接
check_config_file
print_share_link
;;
4)
# 启动容器
run
print_share_link
;;
5)
# 停止容器
docker-compose -f ./docker-compose.yml down
;;
6)
# 更新镜像
update_docker_images
;;
7)
# 修改域名
check_config_file
update_domain
restart_docker
;;
8)
# 修改端口
check_config_file
change_port
restart_docker
;;
*)
echo "无效的选择, 请重新选择."
;;
esac
}
main

View File

@ -1,11 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIBfTCCASOgAwIBAgIUR65F9ix0BBWiw284NXIW5RoGvgwwCgYIKoZIzj0EAwIw
EzERMA8GA1UEAwwIYmluZy5jb20wIBcNMjQwMTMwMDQwNTIwWhgPMjEyNDAxMDYw
NDA1MjBaMBMxETAPBgNVBAMMCGJpbmcuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D
AQcDQgAEwRtxXqEGibaVkK5eVWjzag7UaCG4z48wRb6Kg8N/HQo2hxU/EivPmCB3
+hcj2dlZNFSGojOdr21mhI6Oqe/s0aNTMFEwHQYDVR0OBBYEFCkfq4KFllbH2zEO
GeCeBXOOJccXMB8GA1UdIwQYMBaAFCkfq4KFllbH2zEOGeCeBXOOJccXMA8GA1Ud
EwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgbQoaD89WuimuPuVZJDX17kJc
br9bR0nl91eLuTrWfAYCIQC2OyHg4BWcw6W+lvRw/wH1OpIqqC7+Mk8zOgor4d0C
tg==
-----END CERTIFICATE-----

View File

@ -1,5 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgukBlJTuRZPhgqQA9
ruBWkS9onZJCJ/NzyMDARwXOC8ShRANCAATBG3FeoQaJtpWQrl5VaPNqDtRoIbjP
jzBFvoqDw38dCjaHFT8SK8+YIHf6FyPZ2Vk0VIaiM52vbWaEjo6p7+zR
-----END PRIVATE KEY-----