Compare commits

..

1 Commits

Author SHA1 Message Date
dichgrem
1aefb1daf8 fix:vless 2025-08-09 16:20:20 +08:00
29 changed files with 2182 additions and 5303 deletions

View File

@@ -4,11 +4,7 @@ Sing-box 是一个现代、高性能、功能强大的跨平台代理核心,
本仓库主要包括singbox示例配置以及快速,智能的部署脚本,可以一键部署以下协议并给出标准链接,具体实现见手动安装部分. 本仓库主要包括singbox示例配置以及快速,智能的部署脚本,可以一键部署以下协议并给出标准链接,具体实现见手动安装部分.
<p align="center"> - 手动安装:见 [Hysteria2](https://github.com/Dichgrem/singbox-example/blob/main/hysteria2.md) / [Reality](https://github.com/Dichgrem/singbox-example/blob/main/singbox.md)
<img src="https://github.com/Dichgrem/singbox-example/blob/main/run.png" width="400">
</p>
- 手动安装:见 [Hysteria2](https://github.com/Dichgrem/singbox-example/blob/main/tutorial/hysteria2.md) / [Reality](https://github.com/Dichgrem/singbox-example/blob/main/tutorial/singbox.md)
- 全自动安装Reality: - 全自动安装Reality:
``wget https://raw.githubusercontent.com/Dichgrem/singbox-example/refs/heads/main/script/singbox.sh``,随后``bash ./singbox.sh`` ``wget https://raw.githubusercontent.com/Dichgrem/singbox-example/refs/heads/main/script/singbox.sh``,随后``bash ./singbox.sh``
- 全自动安装Hysteria2: - 全自动安装Hysteria2:

View File

@@ -0,0 +1,108 @@
{
"dns":
{
"independent_cache": true,
"rules":
[
{ "outbound": "any", "server": "dns-direct" },
{ "query_type": [32, 33], "server": "dns-block" },
{ "domain_suffix": ".lan", "server": "dns-block" },
],
"servers":
[
{
"address": "https://8.8.8.8/dns-query",
"address_resolver": "dns-local",
"detour": "proxy",
"strategy": "",
"tag": "dns-remote",
},
{
"address": "local",
"address_resolver": "dns-local",
"detour": "direct",
"strategy": "",
"tag": "dns-direct",
},
{ "address": "rcode://success", "tag": "dns-block" },
{ "address": "local", "detour": "direct", "tag": "dns-local" },
],
},
"inbounds":
[
{
"domain_strategy": "",
"listen": "127.0.0.1",
"listen_port": 2080,
"sniff": true,
"sniff_override_destination": false,
"tag": "mixed-in",
"type": "mixed",
},
],
"log": { "level": "info" },
"outbounds":
[
{
"domain_strategy": "",
"flow": "xtls-rprx-vision",
"packet_encoding": "",
"server": "服务器IP",
"server_port": 443,
"tag": "proxy",
"tls":
{
"enabled": true,
"reality":
{
"enabled": true,
"public_key": "singbox生成公钥",
"short_id": "singbox生成ID",
},
"server_name": "yahoo.com",
"utls": { "enabled": true, "fingerprint": "chrome" },
},
"type": "vless",
"uuid": "singbox生成UUID",
},
{ "tag": "direct", "type": "direct" },
{ "tag": "bypass", "type": "direct" },
{ "tag": "block", "type": "block" },
{ "tag": "dns-out", "type": "dns" },
],
"route":
{
"final": "proxy",
"rules":
[
{ "outbound": "dns-out", "protocol": "dns" },
{
"domain": [],
"domain_keyword": [],
"domain_regex": [],
"domain_suffix": ["appcenter.ms", "firebase.io", "crashlytics.com"],
"geosite": ["category-ads-all"],
"outbound": "block",
},
{
"domain": [],
"domain_keyword": [],
"domain_regex": [],
"domain_suffix": [],
"geosite": ["cn"],
"outbound": "bypass",
},
{ "geoip": ["cn", "private"], "ip_cidr": [], "outbound": "bypass" },
{
"network": "udp",
"outbound": "block",
"port": [135, 137, 138, 139, 5353],
},
{ "ip_cidr": ["224.0.0.0/3", "ff00::/8"], "outbound": "block" },
{
"outbound": "block",
"source_ip_cidr": ["224.0.0.0/3", "ff00::/8"],
},
],
},
}

View File

@@ -0,0 +1,24 @@
[
{
"tag": "Jp-100G",
"type": "vless",
"server": "服务器IP",
"server_port": 443,
"uuid": "singbox生成UUID",
"tls":
{
"enabled": true,
"server_name": "icloud.com",
"insecure": false,
"reality":
{
"enabled": true,
"public_key": "singbox生成公钥",
"short_id": "singbox生成ID",
},
"utls": { "enabled": true, "fingerprint": "chrome" },
},
"flow": "xtls-rprx-vision",
},
]

View File

@@ -0,0 +1,62 @@
{
"dns":
{
"servers":
[
{ "tag": "google", "address": "tls://8.8.8.8" },
{
"tag": "local",
"address": "https://223.5.5.5/dns-query",
"detour": "direct",
},
],
"rules":
[
{ "outbound": "any", "server": "local" },
{ "clash_mode": "Direct", "server": "local" },
{ "clash_mode": "Global", "server": "google" },
{ "rule_set": "geosite-geolocation-cn", "server": "local" },
{ "clash_mode": "Default", "server": "google" },
{
"type": "logical",
"mode": "and",
"rules":
[
{ "rule_set": "geosite-geolocation-!cn", "invert": true },
{ "rule_set": "geoip-cn" },
],
"server": "local",
},
],
},
"route":
{
"rule_set":
[
{
"type": "remote",
"tag": "geosite-geolocation-cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-cn.srs",
},
{
"type": "remote",
"tag": "geosite-geolocation-!cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-!cn.srs",
},
{
"type": "remote",
"tag": "geoip-cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs",
},
],
},
"experimental":
{
"cache_file": { "enabled": true, "store_rdrc": true },
"clash_api": { "default_mode": "Enhanced" },
},
}

View File

@@ -0,0 +1,61 @@
{
"dns":
{
"servers":
[
{ "tag": "google", "address": "tls://8.8.8.8" },
{
"tag": "local",
"address": "https://223.5.5.5/dns-query",
"detour": "direct",
},
],
"rules": [
{ "outbound": "any", "server": "local" },
{ "clash_mode": "Direct", "server": "local" },
{ "clash_mode": "Global", "server": "google" },
{ "rule_set": "geosite-geolocation-cn", "server": "local" },
{
"type": "logical",
"mode": "and",
"rules":
[
{ "rule_set": "geosite-geolocation-!cn", "invert": true },
{ "rule_set": "geoip-cn" },
],
"server": "google",
"client_subnet": "114.114.114.114/24", #Any China client IP address
},
],
},
"route":
{
"rule_set":
[
{
"type": "remote",
"tag": "geosite-geolocation-cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-cn.srs",
},
{
"type": "remote",
"tag": "geosite-geolocation-!cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-!cn.srs",
},
{
"type": "remote",
"tag": "geoip-cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs",
},
],
},
"experimental":
{
"cache_file": { "enabled": true, "store_rdrc": true },
"clash_api": { "default_mode": "Enhanced" },
},
}

View File

@@ -0,0 +1,48 @@
{
"dns":
{
"servers":
[
{ "tag": "google", "address": "tls://8.8.8.8" },
{ "tag": "local", "address": "223.5.5.5", "detour": "direct" },
{ "tag": "remote", "address": "fakeip" },
],
"rules":
[
{ "outbound": "any", "server": "local" },
{ "query_type": ["A", "AAAA"], "server": "remote" },
],
"fakeip":
{
"enabled": true,
"inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18",
},
"independent_cache": true,
},
"inbounds":
[
{
"type": "tun",
"inet4_address": "172.19.0.1/30",
"inet6_address": "fdfe:dcba:9876::1/126",
"auto_route": true,
"strict_route": true,
},
],
"outbounds": [
# ...
{ "type": "direct", "tag": "direct" },
{ "type": "dns", "tag": "dns-out" },
],
"route":
{
"rules":
[
{ "protocol": "dns", "outbound": "dns-out" },
{ "geoip": ["private"], "outbound": "direct" },
],
"auto_detect_interface": true,
},
} #

View File

@@ -0,0 +1,53 @@
{
"outbounds":
[
{ "type": "direct", "tag": "direct" },
{ "type": "block", "tag": "block" },
],
"route":
{
"rules":
[
{
"type": "logical",
"mode": "or",
"rules": [{ "protocol": "dns" }, { "port": 53 }],
"outbound": "dns",
},
{ "ip_is_private": true, "outbound": "direct" },
{ "clash_mode": "Direct", "outbound": "direct" },
{ "clash_mode": "Global", "outbound": "default" },
{
"type": "logical",
"mode": "or",
"rules":
[
{ "port": 853 },
{ "network": "udp", "port": 443 },
{ "protocol": "stun" },
],
"outbound": "block",
},
{
"rule_set": ["geoip-cn", "geosite-geolocation-cn"],
"outbound": "direct",
},
],
"rule_set":
[
{
"type": "remote",
"tag": "geoip-cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs",
},
{
"type": "remote",
"tag": "geosite-geolocation-cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-cn.srs",
},
],
},
}

View File

@@ -0,0 +1,36 @@
{
"dns":
{
"servers":
[
{ "tag": "google", "address": "tls://8.8.8.8" },
{ "tag": "local", "address": "223.5.5.5", "detour": "direct" },
],
"rules": [{ "outbound": "any", "server": "local" }],
},
"inbounds":
[
{
"type": "tun",
"inet4_address": "172.19.0.1/30",
"inet6_address": "fdfe:dcba:9876::1/126",
"auto_route": true,
"strict_route": false,
},
],
"outbounds": [
# // ...
{ "type": "direct", "tag": "direct" },
{ "type": "dns", "tag": "dns-out" },
],
"route":
{
"rules":
[
{ "protocol": "dns", "outbound": "dns-out" },
{ "geoip": ["private"], "outbound": "direct" },
],
"auto_detect_interface": true,
},
} #

View File

@@ -0,0 +1,36 @@
{
"dns":
{
"servers":
[
{ "tag": "google", "address": "tls://8.8.8.8" },
{ "tag": "local", "address": "223.5.5.5", "detour": "direct" },
],
"rules": [{ "outbound": "any", "server": "local" }],
"strategy": "ipv4_only",
},
"inbounds":
[
{
"type": "tun",
"inet4_address": "172.19.0.1/30",
"auto_route": true,
"strict_route": false,
},
],
"outbounds": [
#// ...
{ "type": "direct", "tag": "direct" },
{ "type": "dns", "tag": "dns-out" },
],
"route":
{
"rules":
[
{ "protocol": "dns", "outbound": "dns-out" },
{ "geoip": ["private"], "outbound": "direct" },
],
"auto_detect_interface": true,
},
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,205 +0,0 @@
{
"dns": {
"servers": [
{
"tag": "local",
"type": "udp",
"server": "223.5.5.5"
},
{
"tag": "public",
"type": "https",
"server": "dns.alidns.com",
"domain_resolver": "local"
},
{
"tag": "foreign",
"type": "https",
"server": "8.8.8.8",
"detour": "Server1"
},
{
"tag": "fakeip",
"type": "fakeip",
"inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18"
}
],
"rules": [
{
"rule_set": "geosite-cn",
"server": "public"
},
{
"query_type": [
"A",
"AAAA"
],
"server": "fakeip",
"rewrite_ttl": 1
}
],
"final": "foreign",
"strategy": "prefer_ipv4",
"independent_cache": true,
"reverse_mapping": true
},
"outbounds": [
{
"tag": "Server1",
"type": "vless",
"server": "xxx.xxx.xxx.xxx",
"server_port": 8443,
"uuid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"tls": {
"enabled": true,
"server_name": "xxxxxxxxxxxx",
"insecure": false,
"reality": {
"enabled": true,
"public_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"short_id": "xxxxxxxxxxxx"
},
"utls": {
"enabled": true,
"fingerprint": "firefox"
}
},
"flow": "xtls-rprx-vision"
},
{
"tag": "Server2",
"type": "vless",
"server": "xxx.xxx.xxx.xxx",
"server_port": 8443,
"uuid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"tls": {
"enabled": true,
"server_name": "xxxxxxxxxxxx",
"insecure": false,
"reality": {
"enabled": true,
"public_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"short_id": "xxxxxxxxxxxx"
},
"utls": {
"enabled": true
}
},
"flow": "xtls-rprx-vision"
},
{
"tag": "GLOBAL",
"type": "selector",
"outbounds": [
"Server1",
"Server2",
"direct"
]
},
{
"tag": "direct",
"type": "direct"
}
],
"route": {
"rules": [
{
"action": "sniff",
"sniffer": [
"http",
"tls",
"quic",
"dns"
]
},
{
"inbound": "dns-in",
"action": "hijack-dns"
},
{
"ip_is_private": true,
"outbound": "direct"
},
{
"rule_set": "geosite-cn",
"outbound": "direct"
},
{
"rule_set": "geoip-cn",
"outbound": "direct"
}
],
"rule_set": [
{
"tag": "geosite-cn",
"type": "remote",
"format": "binary",
"url": "https://gh-proxy.com/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/cn.srs",
"download_detour": "direct"
},
{
"tag": "geoip-cn",
"type": "remote",
"format": "binary",
"url": "https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/srs/cn.srs",
"download_detour": "direct"
}
],
"final": "GLOBAL",
"default_domain_resolver": {
"server": "public"
}
},
"inbounds": [
{
"tag": "dns-in",
"type": "direct",
"listen": "::",
"listen_port": 1053
},
{
"tag": "redirect-in",
"type": "redirect",
"listen": "::",
"listen_port": 7890
},
{
"tag": "tproxy-in",
"type": "tproxy",
"listen": "::",
"listen_port": 7891
},
{
"tag": "tun-in",
"type": "tun",
"interface_name": "momo",
"address": [
"172.31.0.1/30",
"fdfe:dcba:9876::1/126"
],
"auto_route": false,
"auto_redirect": false
}
],
"experimental": {
"cache_file": {
"enabled": true,
"path": "/etc/momo/run/cache.db",
"store_fakeip": true
},
"clash_api": {
"external_controller": "0.0.0.0:9095",
"external_ui": "/etc/momo/run/ui",
"external_ui_download_url": "https://gh-proxy.com/https://github.com/Zephyruso/zashboard/archive/refs/heads/gh-pages.zip",
"external_ui_download_detour": "direct",
"secret": "",
"default_mode": "rule"
}
},
"log": {
"disabled": false,
"level": "info",
"timestamp": true
}
}

View File

@@ -1,204 +0,0 @@
{
"dns": {
"servers": [
{
"tag": "local",
"type": "udp",
"server": "223.5.5.5"
},
{
"tag": "public",
"type": "https",
"server": "dns.alidns.com",
"domain_resolver": "local"
},
{
"tag": "foreign",
"type": "https",
"server": "8.8.8.8",
"detour": "Server1"
},
{
"tag": "fakeip",
"type": "fakeip",
"inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18"
}
],
"rules": [
{
"rule_set": "geosite-cn",
"server": "public"
},
{
"query_type": [
"A",
"AAAA"
],
"server": "fakeip",
"rewrite_ttl": 1
}
],
"final": "foreign",
"strategy": "ipv4_only",
"independent_cache": true,
"reverse_mapping": true
},
"outbounds": [
{
"tag": "Server1",
"type": "vless",
"server": "xxx.xxx.xxx.xxx",
"server_port": 8443,
"uuid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"tls": {
"enabled": true,
"server_name": "xxxxxxxxxxxx",
"insecure": false,
"reality": {
"enabled": true,
"public_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"short_id": "xxxxxxxxxxxx"
},
"utls": {
"enabled": true,
"fingerprint": "firefox"
}
},
"flow": "xtls-rprx-vision"
},
{
"tag": "Server2",
"type": "vless",
"server": "xxx.xxx.xxx.xxx",
"server_port": 8443,
"uuid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"tls": {
"enabled": true,
"server_name": "xxxxxxxxxxxx",
"insecure": false,
"reality": {
"enabled": true,
"public_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"short_id": "xxxxxxxxxxxx"
},
"utls": {
"enabled": true
}
},
"flow": "xtls-rprx-vision"
},
{
"tag": "GLOBAL",
"type": "selector",
"outbounds": [
"Server1",
"Server2",
"direct"
]
},
{
"tag": "direct",
"type": "direct"
}
],
"route": {
"rules": [
{
"action": "sniff",
"sniffer": [
"http",
"tls",
"quic",
"dns"
]
},
{
"inbound": "dns-in",
"action": "hijack-dns"
},
{
"ip_is_private": true,
"outbound": "direct"
},
{
"rule_set": "geosite-cn",
"outbound": "direct"
},
{
"rule_set": "geoip-cn",
"outbound": "direct"
}
],
"rule_set": [
{
"tag": "geosite-cn",
"type": "remote",
"format": "binary",
"url": "https://gh-proxy.com/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/cn.srs",
"download_detour": "direct"
},
{
"tag": "geoip-cn",
"type": "remote",
"format": "binary",
"url": "https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/srs/cn.srs",
"download_detour": "direct"
}
],
"final": "GLOBAL",
"default_domain_resolver": {
"server": "public"
}
},
"inbounds": [
{
"tag": "dns-in",
"type": "direct",
"listen": "0.0.0.0",
"listen_port": 1053
},
{
"tag": "redirect-in",
"type": "redirect",
"listen": "0.0.0.0",
"listen_port": 7890
},
{
"tag": "tproxy-in",
"type": "tproxy",
"listen": "0.0.0.0",
"listen_port": 7891
},
{
"tag": "tun-in",
"type": "tun",
"interface_name": "momo",
"address": [
"172.31.0.1/30"
],
"auto_route": false,
"auto_redirect": false
}
],
"experimental": {
"cache_file": {
"enabled": true,
"path": "/etc/momo/run/cache.db",
"store_fakeip": true
},
"clash_api": {
"external_controller": "0.0.0.0:9095",
"external_ui": "/etc/momo/run/ui",
"external_ui_download_url": "https://gh-proxy.com/https://github.com/Zephyruso/zashboard/archive/refs/heads/gh-pages.zip",
"external_ui_download_detour": "direct",
"secret": "",
"default_mode": "rule"
}
},
"log": {
"disabled": false,
"level": "info",
"timestamp": true
}
}

View File

@@ -1,7 +0,0 @@
{
"log": {
"disabled": false,
"level": "info",
"timestamp": true
}
}

View File

@@ -1,210 +0,0 @@
{
"dns": {
"servers": [
{
"tag": "dns_proxy",
"address": "https://223.5.5.5/dns-query",
"strategy": "ipv4_only",
"address_resolver": "dns_resolver"
},
{
"tag": "dns_direct",
"address": "https://8.8.8.8/dns-query",
"strategy": "ipv4_only",
"address_resolver": "dns_resolver",
"detour": "DIRECT"
},
{
"tag": "dns_fakeip",
"address": "fakeip"
},
{
"tag": "dns_resolver",
"address": "223.5.5.5",
"detour": "DIRECT"
},
{
"tag": "block",
"address": "rcode://success"
},
{
"tag": "local",
"address": "local",
"detour": "DIRECT"
}
],
"rules": [
{
"outbound": [
"any"
],
"server": "dns_direct"
},
{
"clash_mode": "Global",
"server": "dns_fakeip",
"rewrite_ttl": 1
},
{
"clash_mode": "Direct",
"server": "dns_direct"
},
{
"domain": [
"time-ios.apple.com",
"time1.cloud.tencent.com",
"music.163.com",
"musicapi.taihe.com",
"music.taihe.com",
"songsearch.kugou.com",
"trackercdn.kugou.com",
"api-jooxtt.sanook.com",
"api.joox.com",
"joox.com",
"y.qq.com",
"streamoc.music.tc.qq.com",
"mobileoc.music.tc.qq.com",
"isure.stream.qqmusic.qq.com",
"dl.stream.qqmusic.qq.com",
"aqqmusic.tc.qq.com",
"amobile.music.tc.qq.com",
"music.migu.cn",
"localhost.ptlogin2.qq.com",
"localhost.sec.qq.com",
"xnotify.xboxlive.com",
"proxy.golang.org",
"heartbeat.belkin.com",
"mesu.apple.com",
"swscan.apple.com",
"swquery.apple.com",
"swdownload.apple.com",
"swcdn.apple.com",
"swdist.apple.com",
"lens.l.google.com",
"stun.l.google.com",
"na.b.g-tun.com",
"ff.dorado.sdo.com",
"shark007.net",
"adguardteam.github.io",
"adrules.top",
"anti-ad.net",
"local.adguard.org",
"static.adtidy.org",
"ps.res.netease.com"
],
"server": "dns_direct"
},
{
"domain_suffix": [
"lan",
"localdomain",
"example",
"invalid",
"localhost",
"test",
"local",
"home.arpa",
"direct",
"time.edu.cn",
"ntp.org.cn",
"pool.ntp.org",
"music.163.com",
"126.net",
"kuwo.cn",
"y.qq.com",
"xiami.com",
"music.migu.cn",
"msftconnecttest.com",
"msftncsi.com",
"steamcontent.com",
"srv.nintendo.net",
"n.n.srv.nintendo.net",
"cdn.nintendo.net",
"stun.playstation.net",
"battle.net",
"battlenet.com.cn",
"wotgame.cn",
"wggames.cn",
"wowsgame.cn",
"wargaming.net",
"linksys.com",
"linksyssmartwifi.com",
"router.asus.com",
"nflxvideo.net",
"square-enix.com",
"finalfantasyxiv.com",
"ffxiv.com",
"ff14.sdo.com",
"mcdn.bilivideo.cn",
"media.dssott.com",
"market.xiaomi.com",
"cmbchina.com",
"cmbimg.com",
"sandai.net",
"n0808.com",
"3gppnetwork.org",
"uu.163.com",
"oray.com",
"orayimg.com",
"gcloudcs.com",
"gcloudsdk.com"
],
"server": "dns_direct"
},
{
"domain_regex": [
"time.*.com",
"time.*.gov",
"time.*.edu.cn",
"time.*.apple.com",
"time1.*.com",
"time2.*.com",
"time3.*.com",
"time4.*.com",
"time5.*.com",
"time6.*.com",
"time7.*.com",
"ntp.*.com",
"ntp1.*.com",
"ntp2.*.com",
"ntp3.*.com",
"ntp4.*.com",
"ntp5.*.com",
"ntp6.*.com",
"ntp7.*.com",
"localhost.*.weixin.qq.com",
"xbox.*.*.microsoft.com",
".*.*.xboxlive.com",
"xbox.*.microsoft.com",
"stun.*.*",
"stun.*.*.*",
".+.stun.*.*",
".+.stun.*.*.*",
".+.stun.*.*.*.*",
".+.stun.*.*.*.*.*"
],
"server": "dns_direct"
},
{
"geosite": "cn",
"server": "dns_direct"
},
{
"query_type": [
"A",
"AAAA"
],
"server": "dns_fakeip",
"rewrite_ttl": 1
}
],
"final": "dns_proxy",
"independent_cache": true,
"reverse_mapping": true,
"fakeip": {
"enabled": true,
"inet4_range": "198.18.0.0/16",
"inet6_range": "fc00::/16"
}
}
}

View File

@@ -1,9 +0,0 @@
{
"ntp": {
"enabled": true,
"server": "time.apple.com",
"server_port": 123,
"interval": "30m",
"detour": "DIRECT"
}
}

View File

@@ -1,19 +0,0 @@
{
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "0.0.0.0",
"listen_port": 2080
},
{
"type": "tun",
"tag": "tun-in",
"inet4_address": "172.19.0.1/30",
"auto_route": true,
"strict_route": true,
"stack": "mixed",
"sniff": true
}
]
}

View File

@@ -1,94 +0,0 @@
{
"outbounds": [
{
"type": "direct",
"tag": "DIRECT"
},
{
"type": "block",
"tag": "REJECT"
},
{
"type": "dns",
"tag": "dns-out"
},
{
"type": "vless",
"tag": "🇺🇸 US-100G",
"server": "666.666.666.666",
"server_port": 443,
"uuid": "xxxxxxxxxxxxxxxxxxxxx",
"flow": "xtls-rprx-vision",
"tls": {
"enabled": true,
"server_name": "xxxxxxxxxx",
"insecure": true,
"utls": {
"enabled": true,
"fingerprint": "firefox"
},
"reality": {
"enabled": true,
"public_key": "xxxxxxxx",
"short_id": "xxxxxxxx"
}
},
"network": "tcp",
"tcp_fast_open": false
},
{
"type": "selector",
"tag": "🚀 节点选择",
"outbounds": [
"♻️ 自动选择",
"DIRECT",
"🇺🇸 US-100G"
]
},
{
"type": "urltest",
"tag": "♻️ 自动选择",
"outbounds": [
"🇺🇸 US-100G"
],
"url": "http://www.gstatic.com/generate_204",
"interval": "5m",
"tolerance": 50
},
{
"type": "selector",
"tag": "🎯 全球直连",
"outbounds": [
"DIRECT",
"🚀 节点选择",
"♻️ 自动选择"
]
},
{
"type": "selector",
"tag": "🛑 全球拦截",
"outbounds": [
"REJECT",
"DIRECT"
]
},
{
"type": "selector",
"tag": "🐟 漏网之鱼",
"outbounds": [
"🚀 节点选择",
"🎯 全球直连",
"♻️ 自动选择",
"🇺🇸 US-100G"
]
},
{
"type": "selector",
"tag": "GLOBAL",
"outbounds": [
"DIRECT",
"🇺🇸 US-100G"
]
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +0,0 @@
{
"experimental": {
"cache_file": {
"enabled": true,
"store_fakeip": true
},
"clash_api": {
"external_controller": "0.0.0.0:9090",
"external_ui": "/etc/mihomo/ui"
}
}
}

View File

@@ -1,21 +0,0 @@
{
"dns": {
"servers": [
{
"tag": "hosts_local",
"address": "local",
"detour": "DIRECT"
}
],
"rules": [
{
"domain": [
"localhost",
"time.android.com",
"time.facebook.com"
],
"server": "hosts_local"
}
]
}
}

View File

@@ -1,11 +0,0 @@
{
"route": {
"rules": [
{
"inbound": "dns-in",
"outbound": "dns-out"
}
],
"default_mark": 7894
}
}

View File

@@ -1,209 +0,0 @@
{
"dns": {
"servers": [
{
"tag": "local",
"type": "udp",
"server": "223.5.5.5"
},
{
"tag": "public",
"type": "https",
"server": "dns.alidns.com",
"domain_resolver": "local"
},
{
"tag": "foreign",
"type": "https",
"server": "8.8.8.8",
"detour": "Azure-JP"
},
{
"tag": "fakeip",
"type": "fakeip",
"inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18"
}
],
"rules": [
{
"rule_set": "geosite-cn",
"server": "local"
},
{
"query_type": [
"A",
"AAAA"
],
"server": "fakeip",
"rewrite_ttl": 1
}
],
"final": "foreign",
"strategy": "prefer_ipv4",
"independent_cache": true,
"reverse_mapping": false
},
"outbounds": [
{
"tag": "Server1",
"type": "vless",
"server": "xxx.xxx.xxx.xxx",
"server_port": 8443,
"uuid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"tls": {
"enabled": true,
"server_name": "xxxxxxxxxxxx",
"insecure": false,
"reality": {
"enabled": true,
"public_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"short_id": "xxxxxxxxxxxx"
},
"utls": {
"enabled": true,
"fingerprint": "firefox"
}
},
"flow": "xtls-rprx-vision"
},
{
"tag": "Server2",
"type": "vless",
"server": "xxx.xxx.xxx.xxx",
"server_port": 8443,
"uuid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"tls": {
"enabled": true,
"server_name": "xxxxxxxxxxxx",
"insecure": false,
"reality": {
"enabled": true,
"public_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"short_id": "xxxxxxxxxxxx"
},
"utls": {
"enabled": true
}
},
"flow": "xtls-rprx-vision"
},
{
"tag": "GLOBAL",
"type": "selector",
"outbounds": [
"Server1",
"Server2",
"direct"
]
},
{
"tag": "direct",
"type": "direct"
}
],
"route": {
"rules": [
{
"inbound": "tun-in",
"port": 53,
"action": "hijack-dns"
},
{
"inbound": "dns-in",
"action": "hijack-dns"
},
{
"ip_is_private": true,
"outbound": "direct"
},
{
"rule_set": "geosite-cn",
"outbound": "direct"
},
{
"rule_set": "geoip-cn",
"outbound": "direct"
},
{
"action": "sniff",
"sniffer": [
"http",
"tls",
"quic",
"dns"
]
},
{
"outbound": "GLOBAL"
}
],
"rule_set": [
{
"tag": "geosite-cn",
"type": "remote",
"format": "binary",
"url": "https://gh-proxy.com/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/cn.srs",
"download_detour": "direct"
},
{
"tag": "geoip-cn",
"type": "remote",
"format": "binary",
"url": "https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/srs/cn.srs",
"download_detour": "direct"
}
],
"final": "GLOBAL",
"auto_detect_interface": true,
"default_domain_resolver": {
"server": "public"
}
},
"inbounds": [
{
"tag": "dns-in",
"type": "direct",
"listen": "127.0.0.1",
"listen_port": 1053
},
{
"tag": "tun-in",
"type": "tun",
"interface_name": "stun",
"address": [
"172.19.0.1/30",
"fdfe:dcba:9876::1/126"
],
"mtu": 9000,
"auto_route": true,
"auto_redirect": true,
"strict_route": false
},
{
"type": "mixed",
"listen": "127.0.0.1",
"listen_port": 7890
}
],
"experimental": {
"cache_file": {
"enabled": true,
"path": "/var/lib/sing-box/cache.db",
"store_fakeip": true
},
"clash_api": {
"external_controller": "0.0.0.0:9191",
"external_ui": "/var/lib/sing-box/ui",
"external_ui_download_url": "https://gh-proxy.com/https://github.com/Zephyruso/zashboard/archive/refs/heads/gh-pages.zip",
"external_ui_download_detour": "direct",
"secret": "",
"default_mode": "rule"
}
},
"log": {
"disabled": false,
"level": "info",
"timestamp": true
}
}

View File

@@ -1,208 +0,0 @@
{
"dns": {
"servers": [
{
"tag": "local",
"type": "udp",
"server": "223.5.5.5"
},
{
"tag": "public",
"type": "https",
"server": "dns.alidns.com",
"domain_resolver": "local"
},
{
"tag": "foreign",
"type": "https",
"server": "8.8.8.8",
"detour": "Azure-JP"
},
{
"tag": "fakeip",
"type": "fakeip",
"inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18"
}
],
"rules": [
{
"rule_set": "geosite-cn",
"server": "local"
},
{
"query_type": [
"A",
"AAAA"
],
"server": "fakeip",
"rewrite_ttl": 1
}
],
"final": "foreign",
"strategy": "ipv4_only",
"independent_cache": true,
"reverse_mapping": false
},
"outbounds": [
{
"tag": "Server1",
"type": "vless",
"server": "xxx.xxx.xxx.xxx",
"server_port": 8443,
"uuid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"tls": {
"enabled": true,
"server_name": "xxxxxxxxxxxx",
"insecure": false,
"reality": {
"enabled": true,
"public_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"short_id": "xxxxxxxxxxxx"
},
"utls": {
"enabled": true,
"fingerprint": "firefox"
}
},
"flow": "xtls-rprx-vision"
},
{
"tag": "Server2",
"type": "vless",
"server": "xxx.xxx.xxx.xxx",
"server_port": 8443,
"uuid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"tls": {
"enabled": true,
"server_name": "xxxxxxxxxxxx",
"insecure": false,
"reality": {
"enabled": true,
"public_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"short_id": "xxxxxxxxxxxx"
},
"utls": {
"enabled": true
}
},
"flow": "xtls-rprx-vision"
},
{
"tag": "GLOBAL",
"type": "selector",
"outbounds": [
"Server1",
"Server2",
"direct"
]
},
{
"tag": "direct",
"type": "direct"
}
],
"route": {
"rules": [
{
"inbound": "tun-in",
"port": 53,
"action": "hijack-dns"
},
{
"inbound": "dns-in",
"action": "hijack-dns"
},
{
"ip_is_private": true,
"outbound": "direct"
},
{
"rule_set": "geosite-cn",
"outbound": "direct"
},
{
"rule_set": "geoip-cn",
"outbound": "direct"
},
{
"action": "sniff",
"sniffer": [
"http",
"tls",
"quic",
"dns"
]
},
{
"outbound": "GLOBAL"
}
],
"rule_set": [
{
"tag": "geosite-cn",
"type": "remote",
"format": "binary",
"url": "https://gh-proxy.com/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/cn.srs",
"download_detour": "direct"
},
{
"tag": "geoip-cn",
"type": "remote",
"format": "binary",
"url": "https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/srs/cn.srs",
"download_detour": "direct"
}
],
"final": "GLOBAL",
"auto_detect_interface": true,
"default_domain_resolver": {
"server": "public"
}
},
"inbounds": [
{
"tag": "dns-in",
"type": "direct",
"listen": "127.0.0.1",
"listen_port": 1053
},
{
"tag": "tun-in",
"type": "tun",
"interface_name": "stun",
"address": [
"172.19.0.1/30"
],
"mtu": 9000,
"auto_route": true,
"auto_redirect": true,
"strict_route": false
},
{
"type": "mixed",
"listen": "127.0.0.1",
"listen_port": 7890
}
],
"experimental": {
"cache_file": {
"enabled": true,
"path": "/var/lib/sing-box/cache.db",
"store_fakeip": true
},
"clash_api": {
"external_controller": "0.0.0.0:9191",
"external_ui": "/var/lib/sing-box/ui",
"external_ui_download_url": "https://gh-proxy.com/https://github.com/Zephyruso/zashboard/archive/refs/heads/gh-pages.zip",
"external_ui_download_detour": "direct",
"secret": "",
"default_mode": "rule"
}
},
"log": {
"disabled": false,
"level": "info",
"timestamp": true
}
}

View File

@@ -9,20 +9,28 @@
"listen": "::", "listen": "::",
"listen_port": 443, "listen_port": 443,
"users": "users":
[{ "name": "$NAME", "uuid": "$UUID", "flow": "xtls-rprx-vision" }], [
{
"name": "AK-JP-100G",
"uuid": "替换为实际UUID",
"flow": "xtls-rprx-vision",
},
],
"tls": "tls":
{ {
"enabled": true, "enabled": true,
"server_name": "$SNI", "server_name": "s0.awsstatic.com",
"reality": "reality":
{ {
"enabled": true, "enabled": true,
"handshake": { "server": "$SNI", "server_port": 443 }, "handshake":
"private_key": "$PRIVATE_KEY", { "server": "s0.awsstatic.com", "server_port": 443 },
"short_id": "$SHORT_ID", "private_key": "替换为实际私钥",
"short_id": ["替换为实际short_id"],
}, },
}, },
}, },
], ],
"outbounds": [{ "type": "direct" }], "outbounds": [{ "type": "direct" }, { "type": "dns", "tag": "dns-out" }],
"route": { "rules": [{ "protocol": "dns", "outbound": "dns-out" }] },
} }

BIN
run.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

View File

@@ -17,7 +17,6 @@ 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() {
@@ -40,19 +39,11 @@ 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
} }
@@ -64,19 +55,18 @@ 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 开机自启"
} }
# 生成自签名证书 # 生成自签名证书
@@ -87,14 +77,11 @@ generate_self_signed_cert() {
mkdir -p /etc/hysteria mkdir -p /etc/hysteria
# 生成自签名证书 # 生成自签名证书
if ! openssl req -x509 -nodes -newkey ec:<(openssl ecparam -name prime256v1) \ 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; then -days 3650
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 || {
@@ -169,8 +156,6 @@ 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防火墙..."
@@ -184,24 +169,11 @@ 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 $port >/dev/null 2>&1 ufw allow $1 >/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或iptables防火墙,跳过防火墙配置" print_message $YELLOW "未检测到UFW防火墙跳过防火墙配置"
fi fi
} }
@@ -213,15 +185,13 @@ 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 "性能优化完成"
} }
@@ -262,20 +232,7 @@ 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}"
@@ -308,9 +265,6 @@ 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 "=============================================="
} }
@@ -342,19 +296,41 @@ uninstall_hysteria() {
# 检查安装状态 # 检查安装状态
check_installation() { check_installation() {
if command -v hysteria &>/dev/null && systemctl list-unit-files | grep -q "hysteria-server.service"; then if command -v hysteria &>/dev/null && systemctl list-unit-files | grep -q hysteria-server; 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 -sp "请输入认证密码 (留空使用随机密码): " user_password read -p "请输入认证密码 (留空使用随机密码): " 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"
@@ -382,18 +358,12 @@ 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"
break
elif [[ "$user_masquerade" =~ ^https?:// ]]; then
MASQUERADE_URL="$user_masquerade"
break
else else
print_message $RED "请输入有效的URL格式 (如: https://example.com)" MASQUERADE_URL="$user_masquerade"
fi fi
done
} }
# 完整安装流程 # 完整安装流程
@@ -402,10 +372,6 @@ 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
@@ -426,19 +392,8 @@ 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"
@@ -468,28 +423,7 @@ 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

View File

@@ -1,7 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# install_singbox.sh # install_singbox.sh
# 版本号
SCRIPT_VERSION="1.12.17"
set -euo pipefail set -euo pipefail
# 颜色定义 # 颜色定义
@@ -19,102 +17,59 @@ if [[ $EUID -ne 0 ]]; then
exit 1 exit 1
fi fi
# 修复:使用正确的配置目录 CONFIG_DIR=/etc/singbox
CONFIG_DIR=/etc/sing-box
STATE_FILE="$CONFIG_DIR/state.env" STATE_FILE="$CONFIG_DIR/state.env"
BIN_NAME=sing-box BIN_NAME=sing-box
# 检测网络类型
detect_network_type() {
local has_ipv4=false
local has_ipv6=false
# 检测IPv4
if ping -4 -c1 -W2 8.8.8.8 &>/dev/null || curl -4 -s --connect-timeout 3 https://api.ipify.org &>/dev/null; then
has_ipv4=true
fi
# 检测IPv6
if ping -6 -c1 -W2 2001:4860:4860::8888 &>/dev/null || curl -6 -s --connect-timeout 3 https://api64.ipify.org &>/dev/null; then
has_ipv6=true
fi
if $has_ipv4 && $has_ipv6; then
echo "dual"
elif $has_ipv6; then
echo "ipv6"
elif $has_ipv4; then
echo "ipv4"
else
echo "none"
fi
}
# 获取服务器IP地址
get_server_ip() {
local network_type=$(detect_network_type)
local ip=""
case "$network_type" in
"ipv6")
# 纯IPv6环境
ip=$(curl -6 -s --connect-timeout 5 https://api64.ipify.org 2>/dev/null || \
curl -6 -s --connect-timeout 5 https://ifconfig.co 2>/dev/null || \
ip -6 addr show scope global | grep inet6 | head -n1 | awk '{print $2}' | cut -d'/' -f1)
;;
"dual"|"ipv4")
# 双栈或IPv4环境
ip=$(curl -4 -s --connect-timeout 5 https://api.ipify.org 2>/dev/null || \
curl -4 -s --connect-timeout 5 https://ifconfig.me 2>/dev/null || \
ip -4 addr show scope global | grep inet | head -n1 | awk '{print $2}' | cut -d'/' -f1)
;;
*)
# 无法检测到网络
ip=$(ip addr show scope global | grep -oP '(?<=inet6?\s)\S+' | head -n1 | cut -d'/' -f1)
;;
esac
echo "$ip"
}
# 检查本地与远程版本,并提示 # 检查本地与远程版本,并提示
check_update() { check_update() {
if command -v curl &>/dev/null && command -v grep &>/dev/null; then if command -v curl &>/dev/null && command -v grep &>/dev/null; then
LOCAL_VER=$($BIN_NAME version 2>/dev/null | head -n1 | awk '{print $NF}') || LOCAL_VER="未安装" LOCAL_VER=$($BIN_NAME version 2>/dev/null | head -n1 | awk '{print $NF}') || LOCAL_VER="未安装"
LATEST_VER=$(curl -s https://api.github.com/repos/SagerNet/sing-box/releases/latest |
local network_type=$(detect_network_type)
local curl_opts=""
[[ "$network_type" == "ipv6" ]] && curl_opts="-6"
LATEST_VER=$(curl $curl_opts -s --connect-timeout 10 https://api.github.com/repos/SagerNet/sing-box/releases/latest 2>/dev/null |
grep '"tag_name"' | head -n1 | cut -d '"' -f4 | sed 's/^v//') || LATEST_VER="未知" grep '"tag_name"' | head -n1 | cut -d '"' -f4 | sed 's/^v//') || LATEST_VER="未知"
if [[ "$LOCAL_VER" != "$LATEST_VER" ]]; then
if [[ "$LOCAL_VER" != "$LATEST_VER" && "$LATEST_VER" != "未知" ]]; then printf "${YELLOW}检测到新版本:${LATEST_VER},当前版本:${LOCAL_VER}。请选择 6) 升级 Sing-box 二进制。${NC}\n"
printf "${YELLOW}检测到新版本:${LATEST_VER},当前版本:${LOCAL_VER}。请选择 8) 升级 Sing-box 二进制。${NC}\n"
fi fi
fi fi
} }
# 升级/安装 Sing-box 二进制
update_singbox() {
printf "${CYAN}===== 升级/安装 Sing-box 二进制 =====${NC}\n"
if command -v apt-get &>/dev/null; then
bash <(curl -fsSL https://sing-box.app/deb-install.sh)
elif command -v dnf &>/dev/null || command -v yum &>/dev/null; then
bash <(curl -fsSL https://sing-box.app/rpm-install.sh)
elif command -v pacman &>/dev/null; then
bash <(curl -fsSL https://sing-box.app/arch-install.sh)
else
printf "${RED}无法识别发行版,请手动升级 Sing-box 二进制${NC}\n" >&2
return 1
fi
hash -r
NEW_VER=$($BIN_NAME version | head -n1 | awk '{print $NF}')
printf "${GREEN}Sing-box 已升级到版本:%s${NC}\n" "$NEW_VER"
printf "${CYAN}重启服务...${NC}\n"
if systemctl restart sing-box.service; then
printf "${GREEN}服务已重启。${NC}\n"
else
printf "${YELLOW}服务重启失败,请手动检查。${NC}\n"
fi
}
# 安装 Sing-box 并生成配置 # 安装 Sing-box 并生成配置
install_singbox() { install_singbox() {
printf "${CYAN}===== 安装 Sing-box 并生成配置 =====${NC}\n" printf "${CYAN}===== 安装 Sing-box 并生成配置 =====${NC}\n"
printf "${YELLOW}请输入用户名称 (name 字段,例如 AK-JP-100G)${NC}" printf "${YELLOW}请输入用户名称 (name 字段,例如 AK-JP-100G)${NC}"
read -r NAME read -r NAME
[[ -z "$NAME" ]] && { printf "${RED}名称不能为空,退出。${NC}\n" >&2; exit 1; } [[ -z "$NAME" ]] && {
printf "${RED}名称不能为空,退出。${NC}\n" >&2
exit 1
}
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}
while true; do
read -rp "请输入监听端口 (默认: 443范围 1-65535) " PORT
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
BIN_PATH=$(command -v $BIN_NAME || true) BIN_PATH=$(command -v $BIN_NAME || true)
@@ -125,101 +80,36 @@ 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"
# 检查openssl是否安装 UUID=$($BIN_PATH generate uuid)
if ! command -v openssl &>/dev/null; then KEY_OUTPUT=$($BIN_PATH generate reality-keypair)
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)
FP="firefox" FP="chrome"
SERVER_IP=$(get_server_ip) SERVER_IP=$(curl -s https://ifconfig.me)
PORT=443
SPX="/" SPX="/"
mkdir -p "$CONFIG_DIR" mkdir -p "$CONFIG_DIR"
# 根据网络类型选择 DNS
NET_TYPE=$(detect_network_type)
if [[ "$NET_TYPE" == "ipv6" ]]; then
DNS_SERVER1="2606:4700:4700::1111" # Cloudflare IPv6
DNS_SERVER2="2620:fe::fe" # Quad9 IPv6
DNS_STRATEGY="prefer_ipv6"
elif [[ "$NET_TYPE" == "dual" || "$NET_TYPE" == "ipv4" ]]; then
DNS_SERVER1="8.8.8.8"
DNS_SERVER2="1.1.1.1"
DNS_STRATEGY="prefer_ipv4"
else
DNS_SERVER1="8.8.8.8"
DNS_SERVER2="1.1.1.1"
DNS_STRATEGY="prefer_ipv4"
fi
cat >"$CONFIG_DIR/config.json" <<EOF cat >"$CONFIG_DIR/config.json" <<EOF
{ {
"log": { "log": {"level": "info"},
"disabled": false, "dns": {"servers": [{"address": "tls://8.8.8.8"}]},
"level": "info" "inbounds": [{
},
"dns": {
"servers": [
{
"type": "tls",
"server": "$DNS_SERVER1",
"server_port": 853,
"tls": { "min_version": "1.2" }
},
{
"type": "tls",
"server": "$DNS_SERVER2",
"server_port": 853,
"tls": { "min_version": "1.2" }
}
],
"strategy": "$DNS_STRATEGY"
},
"inbounds": [
{
"type": "vless", "type": "vless",
"tag": "VLESSReality", "tag": "VLESSReality",
"listen": "::", "listen": "::",
"listen_port": ${PORT}, "listen_port": 443,
"users": [ "users": [{"name":"$NAME","uuid":"$UUID","flow":"xtls-rprx-vision"}],
{ "tls": {"enabled":true,"server_name":"$SNI","reality":{
"name": "${NAME}",
"uuid": "${UUID}",
"flow": "xtls-rprx-vision"
}
],
"tls": {
"enabled":true, "enabled":true,
"server_name": "${SNI}", "handshake": {"server":"$SNI","server_port":443},
"reality": { "private_key":"$PRIVATE_KEY",
"enabled": true, "short_id":["$SHORT_ID"]
"handshake": { }}
"server": "${SNI}", }],
"server_port": 443 "outbounds": [{"type":"direct"},{"type":"dns","tag":"dns-out"}],
}, "route": {"rules": [{"protocol":"dns","outbound":"dns-out"}]}
"private_key": "${PRIVATE_KEY}",
"short_id": "${SHORT_ID}"
}
}
}
],
"route": {
"rules": [
{ "type": "default", "outbound": "direct" }
]
},
"outbounds": [
{ "type": "direct", "tag": "direct" }
]
} }
EOF EOF
@@ -237,221 +127,7 @@ EOF
systemctl enable sing-box.service systemctl enable sing-box.service
systemctl restart sing-box.service systemctl restart sing-box.service
printf "${GREEN}安装并启动完成DNS 已根据网络类型自动配置${NC}\n" printf "${GREEN}安装并启动完成。${NC}\n"
}
# 查看服务状态
status_singbox() {
printf "${CYAN}===== Sing-box 服务状态 =====${NC}\n"
if systemctl status sing-box.service &>/dev/null; then
systemctl status sing-box.service --no-pager
else
printf "${YELLOW}服务未安装。${NC}\n"
fi
}
# 开启服务
start_singbox() {
systemctl daemon-reload
systemctl enable sing-box.service 2>/dev/null || true
systemctl start sing-box.service 2>/dev/null || true
}
# 停止服务
stop_singbox(){
systemctl stop sing-box.service 2>/dev/null || true
systemctl disable sing-box.service 2>/dev/null || true
systemctl daemon-reload
}
# 显示 VLESS Reality 链接 + 二维码
show_link() {
printf "${CYAN}===== 您的 VLESS Reality 链接 =====${NC}\n"
# 如果状态文件不存在,尝试从 config.json 读取并生成
if [[ ! -f "$STATE_FILE" ]]; then
if [[ -f "$CONFIG_DIR/config.json" ]]; then
# 使用Python解析JSON更可靠避免grep -P兼容性问题
if command -v python3 &>/dev/null; then
NAME=$(python3 -c "import json; print(json.load(open('$CONFIG_DIR/config.json'))['inbounds'][0]['users'][0]['name'])" 2>/dev/null)
UUID=$(python3 -c "import json; print(json.load(open('$CONFIG_DIR/config.json'))['inbounds'][0]['users'][0]['uuid'])" 2>/dev/null)
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"
SERVER_IP=$(get_server_ip)
SPX="/"
# 检查必要字段
[[ -z "$NAME" || -z "$UUID" || -z "$SNI" || -z "$SHORT_ID" || -z "$PORT" ]] && {
printf "${RED}无法从配置文件读取完整信息${NC}\n"
return 1
}
# 保存新的 state.env
mkdir -p "$CONFIG_DIR"
cat >"$STATE_FILE" <<EOF
NAME="$NAME"
SNI="$SNI"
UUID="$UUID"
PUB_KEY="$PUB_KEY"
SHORT_ID="$SHORT_ID"
FP="$FP"
SERVER_IP="$SERVER_IP"
PORT="$PORT"
SPX="$SPX"
EOF
else
printf "${RED}未找到配置文件,请先安装。${NC}\n"
return
fi
fi
# 读取 state.env
source "$STATE_FILE"
local formatted_ip="$SERVER_IP"
if [[ "$SERVER_IP" =~ ":" ]]; then
formatted_ip="[$SERVER_IP]"
fi
LINK="vless://${UUID}@${formatted_ip}:${PORT}?security=reality&sni=${SNI}&fp=${FP}&pbk=${PUB_KEY}&sid=${SHORT_ID}&spx=${SPX}&type=tcp&flow=xtls-rprx-vision&encryption=none#${NAME}"
printf "${GREEN}%s${NC}\n\n" "$LINK"
# 生成二维码
if ! command -v qrencode &>/dev/null; then
printf "${YELLOW}未安装 qrencode正在自动安装...${NC}\n"
apt install -y qrencode &>/dev/null || {
printf "${RED}自动安装失败请手动执行apt install qrencode${NC}\n"
return
}
fi
printf "${CYAN}===== 二维码 =====${NC}\n"
qrencode -t ANSIUTF8 "$LINK"
printf "\n"
}
# 卸载 Sing-box
uninstall_singbox() {
printf "${CYAN}===== 卸载 Sing-box =====${NC}\n"
# 停止并禁用服务
systemctl stop sing-box.service 2>/dev/null || true
systemctl disable sing-box.service 2>/dev/null || true
systemctl daemon-reload
# 删除服务文件
rm -f /etc/systemd/system/sing-box.service
# 删除配置目录
rm -rf /etc/singbox
rm -rf /etc/sing-box
# 删除 Sing-box 可执行文件
rm -f /usr/bin/sing-box
printf "${GREEN}卸载完成。${NC}\n"
}
# 重新安装
reinstall_singbox() {
uninstall_singbox
install_singbox
}
# 升级/安装 Sing-box 二进制
update_singbox() {
printf "${CYAN}===== 升级/安装 Sing-box 二进制 =====${NC}\n"
set -e -o pipefail
# 检测体系架构
ARCH_RAW=$(uname -m)
case "${ARCH_RAW}" in
'x86_64') ARCH='amd64';;
'x86' | 'i686' | 'i386') ARCH='386';;
'aarch64' | 'arm64') ARCH='arm64';;
'armv7l') ARCH='armv7';;
's390x') ARCH='s390x';;
*) echo "❌ 不支持的架构: ${ARCH_RAW}"; return 1;;
esac
# 检测网络类型
local network_type=$(detect_network_type)
echo "🌐 当前网络模式: $network_type"
local curl_opts=""
case "$network_type" in
"ipv6")
curl_opts="-6"
echo "📡 使用 IPv6 连接"
;;
"dual")
echo "📡 双栈网络,优先使用 IPv4"
;;
"ipv4")
curl_opts="-4"
echo "📡 使用 IPv4 连接"
;;
"none")
echo "⚠️ 无法检测到网络连接,尝试默认方式"
;;
esac
# 获取最新版本号
VERSION=$(curl $curl_opts -fsSL --connect-timeout 15 https://api.github.com/repos/SagerNet/sing-box/releases/latest 2>/dev/null |
grep '"tag_name"' | head -n1 | cut -d '"' -f4 | sed 's/^v//') || VERSION=""
if [[ -z "$VERSION" ]]; then
echo "⚠️ 获取版本失败,尝试备用源..."
VERSION=$(curl $curl_opts -fsSL --connect-timeout 15 https://fastly.jsdelivr.net/gh/SagerNet/sing-box@latest/version.txt 2>/dev/null || echo "")
fi
[[ -z "$VERSION" ]] && { echo "❌ 无法获取最新版本号"; return 1; }
echo "🔖 最新版本v${VERSION}"
PKG_URL="https://github.com/SagerNet/sing-box/releases/download/v${VERSION}/sing-box_${VERSION}_linux_${ARCH}.deb"
echo "⬇️ 正在下载 ${PKG_URL}"
curl $curl_opts -fL --connect-timeout 30 -o /tmp/sing-box.deb "$PKG_URL" || {
echo "❌ 下载失败,请检查网络。"
return 1
}
dpkg -i /tmp/sing-box.deb || {
echo "⚠️ dpkg 安装失败,尝试修复依赖..."
apt-get install -f -y
dpkg -i /tmp/sing-box.deb
}
rm -f /tmp/sing-box.deb
NEW_VER=$($BIN_NAME version 2>/dev/null | head -n1 | awk '{print $NF}')
echo "✅ Sing-box 已升级到版本:$NEW_VER"
echo "🔁 正在重载 systemd 并重启服务..."
systemctl daemon-reload
if systemctl restart sing-box.service; then
echo "✅ 服务已重启。"
else
echo "⚠️ 服务重启失败,请手动检查。"
fi
} }
# 更换 SNI 域名 # 更换 SNI 域名
@@ -472,17 +148,11 @@ change_sni() {
return return
} }
# 使用更精确的sed替换避免匹配到错误的字段 # 替换 config.json 中的 SNI 字段
if ! sed -i -E '/"tag": *"VLESSReality"/,/\}/ s/"server_name": *"[^"]*"/"server_name": "'"$NEW_SNI"'"/' "$CONFIG_DIR/config.json"; then sed -i "s/\"server_name\":\s*\"[^\"]*\"/\"server_name\": \"$NEW_SNI\"/" "$CONFIG_DIR/config.json"
printf "${RED}修改 server_name 失败${NC}\n" sed -i "s/\"server\":\s*\"[^\"]*\"/\"server\": \"$NEW_SNI\"/" "$CONFIG_DIR/config.json"
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
# 替换 state.env 中的 SNI
sed -i "s/^SNI=.*/SNI=\"$NEW_SNI\"/" "$STATE_FILE" sed -i "s/^SNI=.*/SNI=\"$NEW_SNI\"/" "$STATE_FILE"
systemctl restart sing-box.service && systemctl restart sing-box.service &&
@@ -490,118 +160,73 @@ change_sni() {
printf "${RED}服务重启失败,请手动检查。${NC}\n" printf "${RED}服务重启失败,请手动检查。${NC}\n"
} }
# 设置BBR算法 # 查看服务状态
set_bbr() { status_singbox() {
if ! sysctl net.ipv4.tcp_available_congestion_control &>/dev/null; then printf "${CYAN}===== Sing-box 服务状态 =====${NC}\n"
echo "❌ 系统不支持 TCP 拥塞控制设置" if systemctl status sing-box.service &>/dev/null; then
return 1 systemctl status sing-box.service --no-pager
fi
echo "📋 支持的 TCP 拥塞控制算法:"
sysctl net.ipv4.tcp_available_congestion_control
current=$(sysctl -n net.ipv4.tcp_congestion_control)
echo "⚡ 当前使用的算法: $current"
if [ "$current" == "bbr" ]; then
echo "✅ 当前已经在使用 BBR"
return 0
fi
read -p "⚠️ 当前使用的不是 BBR是否切换为 BBR(y/n): " confirm
if [[ "$confirm" =~ ^[Yy]$ ]]; then
# 临时生效
sysctl -w net.ipv4.tcp_congestion_control=bbr
echo "✅ 已切换为 BBR临时"
# 永久生效
if ! grep -q "^net.ipv4.tcp_congestion_control" /etc/sysctl.conf; then
echo "net.ipv4.tcp_congestion_control = bbr" | tee -a /etc/sysctl.conf
else else
sed -i "s/^net.ipv4.tcp_congestion_control.*/net.ipv4.tcp_congestion_control = bbr/" /etc/sysctl.conf printf "${YELLOW}服务未安装。${NC}\n"
fi
echo "✅ 已写入 /etc/sysctl.conf重启后永久生效"
else
echo "❌ 未修改 TCP 拥塞控制算法"
fi fi
} }
# 更新脚本自身 # 显示 VLESS Reality 链接
update_self() { show_link() {
local script_path="${BASH_SOURCE[0]}" printf "${CYAN}===== 您的 VLESS Reality 链接 =====${NC}\n"
local tmp_file="/tmp/install_singbox.sh.tmp" [[ -f "$STATE_FILE" ]] || {
printf "${RED}未找到状态文件,请先安装。${NC}\n"
return
}
source "$STATE_FILE"
LINK="vless://${UUID}@${SERVER_IP}:${PORT}?security=reality&sni=${SNI}&fp=${FP}&pbk=${PUB_KEY}&sid=${SHORT_ID}&spx=${SPX}&type=tcp&flow=xtls-rprx-vision&encryption=none#${NAME}"
printf "${GREEN}%s${NC}\n\n" "$LINK"
}
printf "${CYAN}===== 更新脚本自身 =====${NC}\n" # 卸载 Sing-box
if command -v curl &>/dev/null; then uninstall_singbox() {
local url="https://raw.githubusercontent.com/Dichgrem/singbox-example/refs/heads/main/script/singbox.sh" printf "${CYAN}===== 卸载 Sing-box =====${NC}\n"
echo "$url 下载最新脚本..." systemctl stop sing-box.service 2>/dev/null || true
systemctl disable sing-box.service 2>/dev/null || true
# 根据网络类型选择curl参数 rm -rf "$CONFIG_DIR"
local network_type=$(detect_network_type) if command -v apt-get &>/dev/null; then
local curl_opts="" apt-get remove -y sing-box
[[ "$network_type" == "ipv6" ]] && curl_opts="-6" elif command -v yum &>/dev/null; then
yum remove -y sing-box
if curl $curl_opts -fsSL --connect-timeout 15 "$url" -o "$tmp_file"; then elif command -v pacman &>/dev/null; then
echo "下载成功,准备替换本地脚本..." pacman -Rss --noconfirm sing-box
chmod +x "$tmp_file"
mv "$tmp_file" "$script_path"
echo "脚本更新完成。"
echo "重启脚本..."
exec bash "$script_path"
else
echo "${RED}下载失败,无法更新脚本。${NC}"
rm -f "$tmp_file"
fi
else
echo "${RED}未安装 curl无法自动更新脚本。${NC}"
fi fi
printf "${GREEN}卸载完成。${NC}\n"
}
# 重新安装
reinstall_singbox() {
uninstall_singbox
install_singbox
} }
# 菜单主循环 # 菜单主循环
check_update check_update
printf "${BLUE}当前脚本版本:${SCRIPT_VERSION}${NC}\n"
# 显示网络类型
NETWORK_TYPE=$(detect_network_type)
printf "${BLUE}检测到网络类型:${NETWORK_TYPE}${NC}\n"
# 显示 Sing-box 版本
if command -v sing-box >/dev/null 2>&1; then
SINGBOX_VERSION=$(sing-box version 2>/dev/null | head -n 1)
else
SINGBOX_VERSION="未安装"
fi
printf "${BLUE}当前 Sing-box 版本:${SINGBOX_VERSION}${NC}\n"
while true; do while true; do
printf "${BOLD}${BLUE}请选择操作:${NC}\n" printf "${BOLD}${BLUE}请选择操作:${NC}\n"
printf " ${YELLOW}1)${NC} 安装 Sing-box&&Reality\n" printf " ${YELLOW}1)${NC} 安装 Sing-box 并生成配置\n"
printf " ${YELLOW}2)${NC} 查看服务状态\n" printf " ${YELLOW}2)${NC} 查看服务状态\n"
printf " ${YELLOW}3)${NC} 开启服务\n" printf " ${YELLOW}3)${NC} 显示 VLESS Reality 链接\n"
printf " ${YELLOW}4)${NC} 停止服务\n" printf " ${YELLOW}4)${NC} 卸载 Sing-box\n"
printf " ${YELLOW}5)${NC} 卸载服务\n" printf " ${YELLOW}5)${NC} 重新安装 Sing-box\n"
printf " ${YELLOW}6)${NC} 显示节点链接\n" printf " ${YELLOW}6)${NC} 升级 Sing-box 二进制\n"
printf " ${YELLOW}7)${NC} 重新安装 Sing-box\n" printf " ${YELLOW}7)${NC} 更换 SNI 域名\n"
printf " ${YELLOW}8)${NC} 升级 Sing-box 二进制\n" printf " ${YELLOW}8)${NC} 退出\n"
printf " ${YELLOW}9)${NC} 更换 SNI 域名\n" printf "${BOLD}输入数字 [1-8]: ${NC}"
printf " ${YELLOW}10)${NC} 设置 BBR 算法\n"
printf " ${YELLOW}11)${NC} 更新脚本自身\n"
printf " ${YELLOW}0)${NC} 退出\n"
printf "${BOLD}输入数字 [0-11]: ${NC}"
read -r choice read -r choice
case "$choice" in case "$choice" in
1) install_singbox ;; 1) install_singbox ;;
2) status_singbox ;; 2) status_singbox ;;
3) start_singbox ;; 3) show_link ;;
4) stop_singbox ;; 4) uninstall_singbox ;;
5) uninstall_singbox ;; 5) reinstall_singbox ;;
6) show_link ;; 6) update_singbox ;;
7) reinstall_singbox ;; 7) change_sni ;;
8) update_singbox ;; 8)
9) change_sni ;;
10) set_bbr ;;
11) update_self ;;
0)
printf "${GREEN}退出。${NC}\n" printf "${GREEN}退出。${NC}\n"
exit 0 exit 0
;; ;;

View File

@@ -23,8 +23,6 @@ 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
@@ -33,24 +31,15 @@ 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
# 生成密钥对 # 生成密钥对
if [ "$GENERATE_KEY" == true ]; then
ssh-keygen -t rsa -b 4096 -f "$KEY_FILE" -N "" -q ssh-keygen -t rsa -b 4096 -f "$KEY_FILE" -N "" -q
chmod 600 "$KEY_FILE"
fi
# 将公钥添加到授权文件 # 将公钥添加到授权文件
echo -e "${YELLOW}将公钥添加到授权文件...${NC}" echo -e "${YELLOW}将公钥添加到授权文件...${NC}"
if ! grep -q -f "${KEY_FILE}.pub" /root/.ssh/authorized_keys 2>/dev/null; then
cat "${KEY_FILE}.pub" >> /root/.ssh/authorized_keys 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服务器
@@ -63,9 +52,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/^\s*#\?\s*PasswordAuthentication.*/PasswordAuthentication no/g' "$CONFIG_FILE" sed -i 's/#\?PasswordAuthentication yes/PasswordAuthentication no/g' "$CONFIG_FILE"
sed -i 's/^\s*#\?\s*PubkeyAuthentication.*/PubkeyAuthentication yes/g' "$CONFIG_FILE" sed -i 's/#\?PubkeyAuthentication no/PubkeyAuthentication yes/g' "$CONFIG_FILE"
sed -i 's/^\s*#\?\s*PermitRootLogin.*/PermitRootLogin prohibit-password/g' "$CONFIG_FILE" sed -i '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