remove singbox sub
This commit is contained in:
@ -1,225 +0,0 @@
|
|||||||
{
|
|
||||||
"log": {
|
|
||||||
"level": "warn",
|
|
||||||
"output": "box.log",
|
|
||||||
"timestamp": true
|
|
||||||
},
|
|
||||||
"dns": {
|
|
||||||
"servers": [
|
|
||||||
{
|
|
||||||
"tag": "dns-remote",
|
|
||||||
"address": "udp://1.1.1.1",
|
|
||||||
"address_resolver": "dns-direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tag": "dns-direct",
|
|
||||||
"address": "1.1.1.1",
|
|
||||||
"address_resolver": "dns-local",
|
|
||||||
"detour": "direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tag": "dns-local",
|
|
||||||
"address": "local",
|
|
||||||
"detour": "direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tag": "dns-block",
|
|
||||||
"address": "rcode://success"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"independent_cache": true
|
|
||||||
},
|
|
||||||
"inbounds": [
|
|
||||||
{
|
|
||||||
"type": "tun",
|
|
||||||
"tag": "tun-in",
|
|
||||||
"address": [
|
|
||||||
"172.18.0.1/30",
|
|
||||||
"fdfe:dcba:9876::1/126"
|
|
||||||
],
|
|
||||||
"mtu": 9000,
|
|
||||||
"auto_route": true,
|
|
||||||
"auto_redirect": false,
|
|
||||||
"strict_route": true,
|
|
||||||
"route_address": [
|
|
||||||
"0.0.0.0/1",
|
|
||||||
"128.0.0.0/1",
|
|
||||||
"::/1",
|
|
||||||
"8000::/1"
|
|
||||||
],
|
|
||||||
|
|
||||||
"route_exclude_address": [
|
|
||||||
"192.168.0.0/16",
|
|
||||||
"fc00::/7"
|
|
||||||
],
|
|
||||||
"sniff": true,
|
|
||||||
"sniff_override_destination": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "direct",
|
|
||||||
"tag": "dns-in",
|
|
||||||
"listen": "127.0.0.1",
|
|
||||||
"listen_port": 6450
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"outbounds": [
|
|
||||||
{
|
|
||||||
"type": "selector",
|
|
||||||
"tag": "select",
|
|
||||||
"outbounds": [
|
|
||||||
"auto",
|
|
||||||
"{username}-Hysteria2"
|
|
||||||
],
|
|
||||||
"default": "auto"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "urltest",
|
|
||||||
"tag": "auto",
|
|
||||||
"outbounds": [
|
|
||||||
"{username}-Hysteria2"
|
|
||||||
],
|
|
||||||
"url": "http://connectivitycheck.gstatic.com/generate_204",
|
|
||||||
"interval": "10m0s",
|
|
||||||
"idle_timeout": "1h40m0s"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "hysteria2",
|
|
||||||
"tag": "{username}-Hysteria2",
|
|
||||||
"server": "{ip}",
|
|
||||||
"server_port": "{port}",
|
|
||||||
"obfs": {
|
|
||||||
"type": "salamander",
|
|
||||||
"password": "{obfs_password}"
|
|
||||||
},
|
|
||||||
"password": "{username}:{password}",
|
|
||||||
"tls": {
|
|
||||||
"enabled": true,
|
|
||||||
"server_name": "{sni}",
|
|
||||||
"insecure": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "direct",
|
|
||||||
"tag": "direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "direct",
|
|
||||||
"tag": "bypass"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"route": {
|
|
||||||
"rules": [
|
|
||||||
{
|
|
||||||
"inbound": "tun-in",
|
|
||||||
"action": "sniff"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"action": "reject",
|
|
||||||
"rule_set": "geosite-category-ads-all"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"action": "reject",
|
|
||||||
"rule_set": "geosite-malware"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"action": "reject",
|
|
||||||
"rule_set": "geosite-phishing"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"action": "reject",
|
|
||||||
"rule_set": "geosite-cryptominers"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"action": "reject",
|
|
||||||
"rule_set": "geoip-malware"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"action": "reject",
|
|
||||||
"rule_set": "geoip-phishing"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"action": "hijack-dns",
|
|
||||||
"protocol": "dns"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"action": "route",
|
|
||||||
"rule_set": "geosite-ir",
|
|
||||||
"outbound": "direct"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"action": "route",
|
|
||||||
"rule_set": "geoip-ir",
|
|
||||||
"outbound": "direct"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
"rule_set": [
|
|
||||||
{
|
|
||||||
"type": "remote",
|
|
||||||
"tag": "geosite-ir",
|
|
||||||
"format": "binary",
|
|
||||||
"url": "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/rule-set/geosite-ir.srs",
|
|
||||||
"download_detour": "direct",
|
|
||||||
"update_interval": "72h0m0s"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "remote",
|
|
||||||
"tag": "geosite-category-ads-all",
|
|
||||||
"format": "binary",
|
|
||||||
"url": "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/rule-set/geosite-category-ads-all.srs",
|
|
||||||
"download_detour": "direct",
|
|
||||||
"update_interval": "72h0m0s"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "remote",
|
|
||||||
"tag": "geosite-malware",
|
|
||||||
"format": "binary",
|
|
||||||
"url": "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/rule-set/geosite-malware.srs",
|
|
||||||
"download_detour": "direct",
|
|
||||||
"update_interval": "72h0m0s"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "remote",
|
|
||||||
"tag": "geosite-phishing",
|
|
||||||
"format": "binary",
|
|
||||||
"url": "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/rule-set/geosite-phishing.srs",
|
|
||||||
"download_detour": "direct",
|
|
||||||
"update_interval": "72h0m0s"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "remote",
|
|
||||||
"tag": "geosite-cryptominers",
|
|
||||||
"format": "binary",
|
|
||||||
"url": "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/rule-set/geosite-cryptominers.srs",
|
|
||||||
"download_detour": "direct",
|
|
||||||
"update_interval": "72h0m0s"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "remote",
|
|
||||||
"tag": "geoip-ir",
|
|
||||||
"format": "binary",
|
|
||||||
"url": "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/rule-set/geoip-ir.srs",
|
|
||||||
"download_detour": "direct",
|
|
||||||
"update_interval": "72h0m0s"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "remote",
|
|
||||||
"tag": "geoip-malware",
|
|
||||||
"format": "binary",
|
|
||||||
"url": "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/rule-set/geoip-malware.srs",
|
|
||||||
"download_detour": "direct",
|
|
||||||
"update_interval": "72h0m0s"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "remote",
|
|
||||||
"tag": "geoip-phishing",
|
|
||||||
"format": "binary",
|
|
||||||
"url": "https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/rule-set/geoip-phishing.srs",
|
|
||||||
"download_detour": "direct",
|
|
||||||
"update_interval": "72h0m0s"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"auto_detect_interface": true,
|
|
||||||
"override_android_vpn": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,182 +0,0 @@
|
|||||||
import os
|
|
||||||
import ssl
|
|
||||||
import json
|
|
||||||
import subprocess
|
|
||||||
from aiohttp import web
|
|
||||||
from aiohttp.web_middlewares import middleware
|
|
||||||
from urllib.parse import unquote, parse_qs
|
|
||||||
import re
|
|
||||||
import time
|
|
||||||
import shlex
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
|
|
||||||
load_dotenv()
|
|
||||||
|
|
||||||
# Environment variables
|
|
||||||
DOMAIN = os.getenv('HYSTERIA_DOMAIN')
|
|
||||||
CERTFILE = os.getenv('HYSTERIA_CERTFILE')
|
|
||||||
KEYFILE = os.getenv('HYSTERIA_KEYFILE')
|
|
||||||
PORT = int(os.getenv('HYSTERIA_PORT', '3324'))
|
|
||||||
|
|
||||||
def load_sni_from_env():
|
|
||||||
sni = "bts.com"
|
|
||||||
try:
|
|
||||||
with open('/etc/hysteria/.configs.env', 'r') as env_file:
|
|
||||||
for line in env_file:
|
|
||||||
if line.startswith('SNI='):
|
|
||||||
sni = line.strip().split('=')[1]
|
|
||||||
break
|
|
||||||
except FileNotFoundError:
|
|
||||||
print("Warning: /etc/hysteria/.configs.env not found. Using default SNI.")
|
|
||||||
return sni
|
|
||||||
|
|
||||||
SNI = load_sni_from_env()
|
|
||||||
|
|
||||||
RATE_LIMIT = 100
|
|
||||||
RATE_LIMIT_WINDOW = 60
|
|
||||||
|
|
||||||
rate_limit_store = {}
|
|
||||||
|
|
||||||
@middleware
|
|
||||||
async def rate_limit_middleware(request, handler):
|
|
||||||
client_ip = request.headers.get('X-Forwarded-For', request.remote)
|
|
||||||
current_time = time.time()
|
|
||||||
|
|
||||||
if client_ip in rate_limit_store:
|
|
||||||
requests, last_request_time = rate_limit_store[client_ip]
|
|
||||||
if current_time - last_request_time < RATE_LIMIT_WINDOW:
|
|
||||||
if requests >= RATE_LIMIT:
|
|
||||||
return web.Response(status=429, text="Rate limit exceeded.")
|
|
||||||
if current_time - last_request_time >= RATE_LIMIT_WINDOW:
|
|
||||||
rate_limit_store[client_ip] = (1, current_time)
|
|
||||||
else:
|
|
||||||
rate_limit_store[client_ip] = (requests + 1, last_request_time)
|
|
||||||
else:
|
|
||||||
rate_limit_store[client_ip] = (1, current_time)
|
|
||||||
|
|
||||||
return await handler(request)
|
|
||||||
|
|
||||||
def sanitize_input(value, pattern):
|
|
||||||
if not re.match(pattern, value):
|
|
||||||
raise ValueError(f"Invalid value: {value}")
|
|
||||||
return shlex.quote(value)
|
|
||||||
|
|
||||||
async def handle(request):
|
|
||||||
try:
|
|
||||||
username = sanitize_input(request.match_info.get('username', ''), r'^[a-zA-Z0-9_-]+$')
|
|
||||||
ip_version = sanitize_input(request.match_info.get('ip_version', ''), r'^[46]$')
|
|
||||||
fragment = request.query.get('fragment', '')
|
|
||||||
|
|
||||||
if not username:
|
|
||||||
return web.Response(status=400, text="Error: Missing 'username' parameter.")
|
|
||||||
|
|
||||||
if not ip_version:
|
|
||||||
return web.Response(status=400, text="Error: Missing 'ip' parameter.")
|
|
||||||
|
|
||||||
if ip_version not in ['4', '6']:
|
|
||||||
return web.Response(status=400, text="Error: Invalid 'ip' parameter. Must be '4' or '6'.")
|
|
||||||
|
|
||||||
config = generate_singbox_config(username, ip_version, fragment)
|
|
||||||
config_json = json.dumps(config, indent=4, sort_keys=True)
|
|
||||||
|
|
||||||
return web.Response(text=config_json, content_type='application/json')
|
|
||||||
except ValueError as e:
|
|
||||||
return web.Response(status=400, text=f"Error: {str(e)}")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Internal Server Error: {str(e)}")
|
|
||||||
return web.Response(status=500, text="Error: Internal server error.")
|
|
||||||
|
|
||||||
def generate_singbox_config(username, ip_version, fragment):
|
|
||||||
try:
|
|
||||||
username = sanitize_input(username, r'^[a-zA-Z0-9_-]+$')
|
|
||||||
ip_version = sanitize_input(ip_version, r'^[46]$')
|
|
||||||
|
|
||||||
command = [
|
|
||||||
'python3',
|
|
||||||
'/etc/hysteria/core/cli.py',
|
|
||||||
'show-user-uri',
|
|
||||||
'-u', username,
|
|
||||||
'-ip', ip_version
|
|
||||||
]
|
|
||||||
|
|
||||||
uri = subprocess.check_output(command).decode().strip()
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
raise RuntimeError("Failed to get URI.")
|
|
||||||
|
|
||||||
if ip_version == '4':
|
|
||||||
components = extract_uri_components(uri, 'IPv4:')
|
|
||||||
else:
|
|
||||||
components = extract_uri_components(uri, 'IPv6:')
|
|
||||||
|
|
||||||
config = load_singbox_template()
|
|
||||||
hysteria_tag = f"{username}-Hysteria2"
|
|
||||||
config['outbounds'][2]['tag'] = hysteria_tag
|
|
||||||
config['outbounds'][2]['server'] = components['ip']
|
|
||||||
config['outbounds'][2]['server_port'] = int(components['port'])
|
|
||||||
config['outbounds'][2]['obfs']['password'] = components['obfs_password']
|
|
||||||
config['outbounds'][2]['password'] = f"{username}:{components['password']}"
|
|
||||||
|
|
||||||
config['outbounds'][2]['tls']['server_name'] = fragment if fragment else SNI
|
|
||||||
|
|
||||||
config['outbounds'][0]['outbounds'] = ["auto", hysteria_tag]
|
|
||||||
config['outbounds'][1]['outbounds'] = [hysteria_tag]
|
|
||||||
|
|
||||||
return config
|
|
||||||
|
|
||||||
def extract_uri_components(uri, prefix):
|
|
||||||
if uri.startswith(prefix):
|
|
||||||
uri = uri[len(prefix):].strip()
|
|
||||||
|
|
||||||
decoded_uri = unquote(uri)
|
|
||||||
pattern = re.compile(
|
|
||||||
r'^hy2://([^:]+):([^@]+)@(\[?[^\]]+?\]?):(\d+)\?([^#]+)(?:#([^/]+))?$'
|
|
||||||
)
|
|
||||||
match = pattern.match(decoded_uri)
|
|
||||||
|
|
||||||
if not match:
|
|
||||||
raise ValueError("Could not parse URI.")
|
|
||||||
|
|
||||||
username = match.group(1)
|
|
||||||
password = match.group(2)
|
|
||||||
ip = match.group(3)
|
|
||||||
port = match.group(4)
|
|
||||||
query_params = match.group(5)
|
|
||||||
fragment = match.group(6)
|
|
||||||
|
|
||||||
if ip.startswith('[') and ip.endswith(']'):
|
|
||||||
ip = ip[1:-1]
|
|
||||||
|
|
||||||
params = parse_qs(query_params)
|
|
||||||
obfs_password = params.get('obfs-password', [''])[0]
|
|
||||||
|
|
||||||
return {
|
|
||||||
'username': username,
|
|
||||||
'password': password,
|
|
||||||
'ip': ip,
|
|
||||||
'port': port,
|
|
||||||
'obfs_password': obfs_password,
|
|
||||||
}
|
|
||||||
|
|
||||||
def load_singbox_template():
|
|
||||||
try:
|
|
||||||
with open('/etc/hysteria/core/scripts/singbox/singbox.json', 'r') as f:
|
|
||||||
return json.load(f)
|
|
||||||
except IOError:
|
|
||||||
raise RuntimeError("Failed to load template.")
|
|
||||||
|
|
||||||
async def handle_404(request):
|
|
||||||
print(f"404 Not Found: {request.path}")
|
|
||||||
return web.Response(status=404, text="Not Found")
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
app = web.Application(middlewares=[rate_limit_middleware])
|
|
||||||
|
|
||||||
app.add_routes([web.get('/sub/singbox/{username}/{ip_version}', handle)])
|
|
||||||
app.router.add_route('*', '/sub/singbox/{tail:.*}', handle_404)
|
|
||||||
|
|
||||||
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
|
||||||
ssl_context.load_cert_chain(certfile=CERTFILE, keyfile=KEYFILE)
|
|
||||||
ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2
|
|
||||||
ssl_context.set_ciphers('AES256+EECDH:AES256+EDH')
|
|
||||||
|
|
||||||
web.run_app(app, port=PORT, ssl_context=ssl_context)
|
|
||||||
@ -1,126 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
source /etc/hysteria/core/scripts/utils.sh
|
|
||||||
define_colors
|
|
||||||
|
|
||||||
# install_dependencies() {
|
|
||||||
# echo "Installing necessary dependencies..."
|
|
||||||
# apt-get install certbot -y > /dev/null 2>&1
|
|
||||||
# if [ $? -ne 0 ]; then
|
|
||||||
# echo -e "${red}Error: Failed to install certbot. ${NC}"
|
|
||||||
# exit 1
|
|
||||||
# fi
|
|
||||||
# echo -e "${green}Certbot installed successfully. ${NC}"
|
|
||||||
# }
|
|
||||||
|
|
||||||
update_env_file() {
|
|
||||||
local domain=$1
|
|
||||||
local port=$2
|
|
||||||
local cert_dir="/etc/letsencrypt/live/$domain"
|
|
||||||
|
|
||||||
cat <<EOL > /etc/hysteria/core/scripts/singbox/.env
|
|
||||||
HYSTERIA_DOMAIN=$domain
|
|
||||||
HYSTERIA_PORT=$port
|
|
||||||
HYSTERIA_CERTFILE=$cert_dir/fullchain.pem
|
|
||||||
HYSTERIA_KEYFILE=$cert_dir/privkey.pem
|
|
||||||
EOL
|
|
||||||
}
|
|
||||||
|
|
||||||
create_service_file() {
|
|
||||||
cat <<EOL > /etc/systemd/system/hysteria-singbox.service
|
|
||||||
[Unit]
|
|
||||||
Description=Singbox Python Service
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart=/bin/bash -c 'source /etc/hysteria/hysteria2_venv/bin/activate && /etc/hysteria/hysteria2_venv/bin/python /etc/hysteria/core/scripts/singbox/singbox.py'
|
|
||||||
WorkingDirectory=/etc/hysteria/core/scripts/singbox
|
|
||||||
EnvironmentFile=/etc/hysteria/core/scripts/singbox/.env
|
|
||||||
Restart=always
|
|
||||||
User=root
|
|
||||||
Group=root
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOL
|
|
||||||
}
|
|
||||||
|
|
||||||
start_service() {
|
|
||||||
local domain=$1
|
|
||||||
local port=$2
|
|
||||||
|
|
||||||
if systemctl is-active --quiet hysteria-singbox.service; then
|
|
||||||
echo "The hysteria-singbox.service is already running."
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# install_dependencies
|
|
||||||
# systemctl stop caddy.service > /dev/null 2>&1 # We stopped caddy service just after its installation
|
|
||||||
|
|
||||||
echo "Generating SSL certificates for $domain..."
|
|
||||||
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d "$domain"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo -e "${red}Error: Failed to generate SSL certificates. ${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
update_env_file "$domain" "$port"
|
|
||||||
create_service_file
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo -e "${red}Error: Failed to create the service file. ${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
chown -R hysteria:hysteria "/etc/letsencrypt/live/$domain"
|
|
||||||
chown -R hysteria:hysteria /etc/hysteria/core/scripts/singbox
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl enable hysteria-singbox.service > /dev/null 2>&1
|
|
||||||
systemctl start hysteria-singbox.service > /dev/null 2>&1
|
|
||||||
# systemctl restart caddy.service > /dev/null 2>&1 # We stopped caddy service just after its installation
|
|
||||||
systemctl daemon-reload > /dev/null 2>&1
|
|
||||||
|
|
||||||
if systemctl is-active --quiet hysteria-singbox.service; then
|
|
||||||
echo -e "${green}Singbox service setup completed. The service is now running on port $port. ${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${red}Singbox setup completed. The service failed to start. ${NC}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
stop_service() {
|
|
||||||
if [ -f /etc/hysteria/core/scripts/singbox/.env ]; then
|
|
||||||
source /etc/hysteria/core/scripts/singbox/.env
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$HYSTERIA_DOMAIN" ]; then
|
|
||||||
echo -e "${yellow}Deleting SSL certificate for domain: $HYSTERIA_DOMAIN...${NC}"
|
|
||||||
certbot delete --cert-name "$HYSTERIA_DOMAIN" --non-interactive > /dev/null 2>&1
|
|
||||||
else
|
|
||||||
echo -e "${red}HYSTERIA_DOMAIN not found in .env. Skipping certificate deletion.${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
systemctl stop hysteria-singbox.service > /dev/null 2>&1
|
|
||||||
systemctl disable hysteria-singbox.service > /dev/null 2>&1
|
|
||||||
systemctl daemon-reload > /dev/null 2>&1
|
|
||||||
|
|
||||||
rm -f /etc/hysteria/core/scripts/singbox/.env
|
|
||||||
|
|
||||||
echo -e "${yellow}Singbox service stopped and disabled. .env file removed.${NC}"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
start)
|
|
||||||
if [ -z "$2" ] || [ -z "$3" ]; then
|
|
||||||
echo -e "${red}Usage: $0 start <DOMAIN> <PORT> ${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
start_service "$2" "$3"
|
|
||||||
;;
|
|
||||||
stop)
|
|
||||||
stop_service
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo -e "${red}Usage: $0 {start|stop} <DOMAIN> <PORT> ${NC}"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
define_colors
|
|
||||||
51
menu.sh
51
menu.sh
@ -601,56 +601,7 @@ telegram_bot_handler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
singbox_handler() {
|
singbox_handler() {
|
||||||
while true; do
|
echo -e "${red} Deprecated${NC}"
|
||||||
echo -e "${cyan}Merged with Normal-Sub sublink.${NC}"
|
|
||||||
# echo -e "${cyan}1.${NC} Start Singbox service"
|
|
||||||
echo -e "${red}2.${NC} Stop Singbox service"
|
|
||||||
echo "0. Back"
|
|
||||||
read -p "Choose an option: " option
|
|
||||||
|
|
||||||
case $option in
|
|
||||||
# 1)
|
|
||||||
# if systemctl is-active --quiet hysteria-singbox.service; then
|
|
||||||
# echo "The hysteria-singbox.service is already active."
|
|
||||||
# else
|
|
||||||
# while true; do
|
|
||||||
# read -e -p "Enter the domain name for the SSL certificate: " domain
|
|
||||||
# if [ -z "$domain" ]; then
|
|
||||||
# echo "Domain name cannot be empty. Please try again."
|
|
||||||
# else
|
|
||||||
# break
|
|
||||||
# fi
|
|
||||||
# done
|
|
||||||
|
|
||||||
# while true; do
|
|
||||||
# read -e -p "Enter the port number for the service: " port
|
|
||||||
# if [ -z "$port" ]; then
|
|
||||||
# echo "Port number cannot be empty. Please try again."
|
|
||||||
# elif ! [[ "$port" =~ ^[0-9]+$ ]]; then
|
|
||||||
# echo "Port must be a number. Please try again."
|
|
||||||
# else
|
|
||||||
# break
|
|
||||||
# fi
|
|
||||||
# done
|
|
||||||
|
|
||||||
# python3 $CLI_PATH singbox -a start -d "$domain" -p "$port"
|
|
||||||
# fi
|
|
||||||
# ;;
|
|
||||||
2)
|
|
||||||
if ! systemctl is-active --quiet hysteria-singbox.service; then
|
|
||||||
echo "The hysteria-singbox.service is already inactive."
|
|
||||||
else
|
|
||||||
python3 $CLI_PATH singbox -a stop
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
0)
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid option. Please try again."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
normalsub_handler() {
|
normalsub_handler() {
|
||||||
|
|||||||
Reference in New Issue
Block a user