From 321900bc1a223e658ba76d6a5eefef5c2e3c4c3a Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Wed, 12 Feb 2025 21:20:58 +0330 Subject: [PATCH 01/13] Use kernel for UUID generation --- core/scripts/hysteria2/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/scripts/hysteria2/install.sh b/core/scripts/hysteria2/install.sh index a68f525..ed2e466 100644 --- a/core/scripts/hysteria2/install.sh +++ b/core/scripts/hysteria2/install.sh @@ -53,7 +53,7 @@ EOF echo "Generating passwords and UUID..." obfspassword=$(pwgen -s 32 1) - UUID=$(uuidgen) + UUID=$(cat /proc/sys/kernel/random/uuid) chown hysteria:hysteria /etc/hysteria/ca.key /etc/hysteria/ca.crt chmod 640 /etc/hysteria/ca.key /etc/hysteria/ca.crt From aba9d893b94e6ffd74378d30aa2026143ea53dbe Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Wed, 12 Feb 2025 21:23:23 +0330 Subject: [PATCH 02/13] Removed uuid-runtime dependency --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index f95bacf..5bdefb8 100644 --- a/install.sh +++ b/install.sh @@ -31,7 +31,7 @@ fi check_os_version -REQUIRED_PACKAGES=("jq" "qrencode" "curl" "pwgen" "uuid-runtime" "python3" "python3-pip" "python3-venv" "git" "bc" "zip" "cron" "lsof") +REQUIRED_PACKAGES=("jq" "qrencode" "curl" "pwgen" "python3" "python3-pip" "python3-venv" "git" "bc" "zip" "cron" "lsof") MISSING_PACKAGES=() heavy_checkmark=$(printf "\xE2\x9C\x85") From e9ba5e32a510f48f33736981bd525b153fe7b00e Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Wed, 12 Feb 2025 22:53:39 +0330 Subject: [PATCH 03/13] Update app.py --- core/scripts/webpanel/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/scripts/webpanel/app.py b/core/scripts/webpanel/app.py index 9d04819..3458831 100644 --- a/core/scripts/webpanel/app.py +++ b/core/scripts/webpanel/app.py @@ -71,7 +71,7 @@ if __name__ == '__main__': config = Config() config.debug = CONFIGS.DEBUG - config.bind = ['127.0.0.1:8080'] + config.bind = ['127.0.0.1:28260'] config.accesslog = '-' config.errorlog = '-' From edc4568e4d376faa55a040d94e7f6a4e3f45f75c Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Wed, 12 Feb 2025 22:54:29 +0330 Subject: [PATCH 04/13] Change Port --- core/scripts/webpanel/webpanel_shell.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/scripts/webpanel/webpanel_shell.sh b/core/scripts/webpanel/webpanel_shell.sh index 2f8ad23..f69588d 100644 --- a/core/scripts/webpanel/webpanel_shell.sh +++ b/core/scripts/webpanel/webpanel_shell.sh @@ -83,9 +83,9 @@ $DOMAIN:$PORT { # We don't strip the ROOT_PATH('/$ROOT_PATH/') from the request # uri strip_prefix /$ROOT_PATH - # We are proxying all requests under the ROOT_PATH to FastAPI at 127.0.0.1:8080 + # We are proxying all requests under the ROOT_PATH to FastAPI at 127.0.0.1:28260 # FastAPI handles these requests because we set the 'root_path' parameter in the FastAPI instance. - reverse_proxy http://127.0.0.1:8080 + reverse_proxy http://127.0.0.1:28260 } # Any request that doesn't start with the ROOT_PATH('/$ROOT_PATH/') will be blocked and no response will be sent to the client @@ -181,7 +181,7 @@ start_service() { # Check if the web panel is running if systemctl is-active --quiet hysteria-webpanel.service; then - echo -e "${green}Hysteria web panel setup completed. The web panel is running locally on: http://127.0.0.1:8080/${NC}" + echo -e "${green}Hysteria web panel setup completed. The web panel is running locally on: http://127.0.0.1:28260/${NC}" else echo -e "${red}Error: Hysteria web panel service failed to start.${NC}" return 1 From 45b8a2f2401ddb5c92214d7bef959064dfbc2f84 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Wed, 12 Feb 2025 22:54:57 +0330 Subject: [PATCH 05/13] Update install.sh --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 5bdefb8..bd2b6d0 100644 --- a/install.sh +++ b/install.sh @@ -53,7 +53,7 @@ else echo "All required packages are already installed." fi -git clone https://github.com/ReturnFI/Hysteria2 /etc/hysteria +git clone -b beta https://github.com/ReturnFI/Hysteria2 /etc/hysteria cd /etc/hysteria python3 -m venv hysteria2_venv From cb8ed7bd36f0e25b0800582387aac4a7e7dcceb7 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Wed, 12 Feb 2025 23:43:58 +0330 Subject: [PATCH 06/13] Added userinfo --- core/scripts/normalsub/normalsub.py | 52 +++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/core/scripts/normalsub/normalsub.py b/core/scripts/normalsub/normalsub.py index 04b15bc..8fca5ea 100644 --- a/core/scripts/normalsub/normalsub.py +++ b/core/scripts/normalsub/normalsub.py @@ -4,6 +4,7 @@ import subprocess import time import re import shlex +import json # Import the json module from aiohttp import web from aiohttp.web_middlewares import middleware from dotenv import load_dotenv @@ -62,11 +63,37 @@ async def handle(request): def get_user_uri(username): try: + user_info_command = [ + 'python3', + '/etc/hysteria/core/cli.py', + 'get-user', + '-u', username + ] + safe_user_info_command = [shlex.quote(arg) for arg in user_info_command] + user_info_output = subprocess.check_output(safe_user_info_command).decode() + user_info = json.loads(user_info_output) + + + upload = user_info.get('upload_bytes', 0) + download = user_info.get('download_bytes', 0) + total = user_info.get('max_download_bytes', 0) + creation_date_str = user_info.get('account_creation_date', '') + expiration_days = user_info.get('expiration_days', 0) + if creation_date_str and expiration_days > 0: + try: + creation_date = time.strptime(creation_date_str, "%Y-%m-%d") + expiration_timestamp = int(time.mktime(creation_date)) + (expiration_days * 24 * 60 * 60) + except ValueError: + expiration_timestamp = 0 + else: + expiration_timestamp = 0 + + # Get URI command = [ - 'python3', - '/etc/hysteria/core/cli.py', - 'show-user-uri', - '-u', username, + 'python3', + '/etc/hysteria/core/cli.py', + 'show-user-uri', + '-u', username, '-a' ] safe_command = [shlex.quote(arg) for arg in command] @@ -74,9 +101,20 @@ def get_user_uri(username): output = re.sub(r'IPv4:\s*', '', output) output = re.sub(r'IPv6:\s*', '', output) + subscription_info = ( + f"//subscription-userinfo: upload={upload}; download={download}; total={total}; expire={expiration_timestamp}\n" + ) + + profile_lines = f"//profile-title: {username}-Hysteria2🚀\n//profile-update-interval: 1\n" + output = profile_lines + subscription_info + output + return output except subprocess.CalledProcessError: - raise RuntimeError("Failed to get URI.") + raise RuntimeError("Failed to get URI or user info.") + except json.JSONDecodeError: + raise RuntimeError("Failed to parse user info JSON.") + except ValueError: + raise RuntimeError("expiration_timestamp OR account_creation_date in config file is invalid") async def handle_404(request): print(f"404 Not Found: {request.path}") @@ -84,7 +122,7 @@ async def handle_404(request): if __name__ == '__main__': app = web.Application(middlewares=[rate_limit_middleware]) - + app.add_routes([web.get('/sub/normal/{username}', handle)]) app.router.add_route('*', '/sub/normal/{tail:.*}', handle_404) @@ -92,5 +130,5 @@ if __name__ == '__main__': 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) From c213d908cb39b3bf2c4d5cbf49cfcf1218454ccc Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Wed, 12 Feb 2025 23:47:57 +0330 Subject: [PATCH 07/13] Fix:Backup Caddy Config --- upgrade.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/upgrade.sh b/upgrade.sh index fe7aa88..c7d9594 100644 --- a/upgrade.sh +++ b/upgrade.sh @@ -13,6 +13,7 @@ FILES=( "/etc/hysteria/core/scripts/singbox/.env" "/etc/hysteria/core/scripts/normalsub/.env" "/etc/hysteria/core/scripts/webpanel/.env" + "/etc/hysteria/core/scripts/webpanel/Caddyfile" ) echo "Backing up and stopping all cron jobs" From 4594db82d3ae68b919de4531dc2bb007f67ad4f8 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Wed, 12 Feb 2025 23:50:26 +0330 Subject: [PATCH 08/13] typo --- core/scripts/normalsub/normalsub.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/scripts/normalsub/normalsub.py b/core/scripts/normalsub/normalsub.py index 8fca5ea..f24fd44 100644 --- a/core/scripts/normalsub/normalsub.py +++ b/core/scripts/normalsub/normalsub.py @@ -105,7 +105,7 @@ def get_user_uri(username): f"//subscription-userinfo: upload={upload}; download={download}; total={total}; expire={expiration_timestamp}\n" ) - profile_lines = f"//profile-title: {username}-Hysteria2🚀\n//profile-update-interval: 1\n" + profile_lines = f"//profile-title: 🚀 {username}-Hysteria2 🚀\n//profile-update-interval: 1\n" output = profile_lines + subscription_info + output return output From 117e86b5914ed252e3b868ede4a37686431ff461 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Wed, 12 Feb 2025 23:53:39 +0330 Subject: [PATCH 09/13] Update changelog --- changelog | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/changelog b/changelog index 5e0cc37..97b74c2 100644 --- a/changelog +++ b/changelog @@ -1,13 +1,17 @@ ### API-CLI -1. Added get_hysteria2_port and get_hysteria2_sni in cli_api +1. Add: get_hysteria2_port and get_hysteria2_sni in cli_api 2. Chg: API function names -3. Restart hysteria-server.service after updating config file through API +3. Fix: Restart hysteria-server.service after updating config file through API ### WebPanel 1. Add: Interact with users when config file restored in config.html -2. Added documents and logo +2. Add: documents and logo 3. Add: Change port & Fill sni domain field on loading DOM & Adopt previous +4. Chg: Change Webpanel Port ### Main -1. Restart Caddy service -2. Improve Hysteria2 uninstallation script for complete removal +1. Fix: Restart Caddy service +2. Fix: Improve Hysteria2 uninstallation script for complete removal +3. Fix: Skip missing IPs while generating URI and QR codes +4. Add: Use kernel for UUID generation and Removed uuid-runtime dependency +5. Add: Userinfo on normalsub From 07b186b062c3c18281aba452a68cdd22faef6d89 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Wed, 12 Feb 2025 23:58:01 +0330 Subject: [PATCH 10/13] Fixed blocked path --- core/scripts/webpanel/webpanel_shell.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/scripts/webpanel/webpanel_shell.sh b/core/scripts/webpanel/webpanel_shell.sh index f69588d..9d232de 100644 --- a/core/scripts/webpanel/webpanel_shell.sh +++ b/core/scripts/webpanel/webpanel_shell.sh @@ -90,7 +90,7 @@ $DOMAIN:$PORT { # Any request that doesn't start with the ROOT_PATH('/$ROOT_PATH/') will be blocked and no response will be sent to the client @blocked { - not path /fd31b4edc70619d5d39edf3c2da97e2c/* + not path /$ROOT_PATH/* } # Abort the request, effectively dropping the connection without a response for invalid paths From 0fdbf67769769f0912785a158233253b89e2252c Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Thu, 13 Feb 2025 00:10:09 +0330 Subject: [PATCH 11/13] Better output --- core/scripts/normalsub/normalsub.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/scripts/normalsub/normalsub.py b/core/scripts/normalsub/normalsub.py index f24fd44..7739e0f 100644 --- a/core/scripts/normalsub/normalsub.py +++ b/core/scripts/normalsub/normalsub.py @@ -105,7 +105,7 @@ def get_user_uri(username): f"//subscription-userinfo: upload={upload}; download={download}; total={total}; expire={expiration_timestamp}\n" ) - profile_lines = f"//profile-title: 🚀 {username}-Hysteria2 🚀\n//profile-update-interval: 1\n" + profile_lines = f"//profile-title: {username}-Hysteria2 🚀\n//profile-update-interval: 1\n" output = profile_lines + subscription_info + output return output From 22fa1c688e886ef91c21f7067e45c911cc35dc25 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Thu, 13 Feb 2025 00:11:07 +0330 Subject: [PATCH 12/13] Clone Main --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index bd2b6d0..5bdefb8 100644 --- a/install.sh +++ b/install.sh @@ -53,7 +53,7 @@ else echo "All required packages are already installed." fi -git clone -b beta https://github.com/ReturnFI/Hysteria2 /etc/hysteria +git clone https://github.com/ReturnFI/Hysteria2 /etc/hysteria cd /etc/hysteria python3 -m venv hysteria2_venv From 5e7dac9953b8c8ec776e1b10e0f5183f2aed77ad Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Thu, 13 Feb 2025 00:11:53 +0330 Subject: [PATCH 13/13] Update changelog --- changelog | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog b/changelog index 97b74c2..1ffd1cb 100644 --- a/changelog +++ b/changelog @@ -8,6 +8,7 @@ 2. Add: documents and logo 3. Add: Change port & Fill sni domain field on loading DOM & Adopt previous 4. Chg: Change Webpanel Port +5. Fix: blocked path ### Main 1. Fix: Restart Caddy service