Compare commits

..
7 Commits
Author SHA1 Message Date
orohi 6206697e3b Remove Cascade double-VPN (v2.3.0).
Drop cascade manager, API, server UI, and i18n keys after unstable egress/routing behavior.
2026-07-27 05:08:18 +03:00
orohi 4c19099b04 Fix i18n: strip UTF-8 BOM so translations load again.
PowerShell rewrites had added a BOM that made Python json.load fail, so the UI showed raw keys like nav_servers.
2026-07-27 04:40:44 +03:00
orohi 80160d0ef4 Fix Cascade egress verify to bind awg0 IP (v2.2.1).
Use client-subnet policy routing for curl checks instead of cascade peer Address; soft-warn when echo services fail but the route is OK.
2026-07-27 04:27:00 +03:00
orohi ac76a0e540 Release v2.2.0: restore safe Cascade double-VPN for servers.
Reintroduce entry-to-exit AmneziaWG/WireGuard cascade inspired by ryderams/amneziawg-cascade, with handshake and egress checks and no remote curl|bash.
2026-07-27 04:09:16 +03:00
orohi bf7bd16fcd Release v2.1.0: mark NaiveProxy stable with client notes.
Stable NaiveProxy; note that v2rayN must not be used, Karing is confirmed, other clients are untested.
2026-07-26 11:23:10 +03:00
orohiandCursor 24e793d943 Add NaiveProxy client hint for v2rayN IPv6 DNS failures.
Show guidance when copying config if latency fails due to Google DNS over IPv6.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-26 10:31:41 +03:00
orohiandCursor 415cfea5eb Fix NaiveProxy share links to always include port 443.
v2rayN treated links without an explicit port as invalid/80 and failed TLS.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-26 10:26:37 +03:00
9 changed files with 2782 additions and 2734 deletions
+21 -2
View File
@@ -63,7 +63,7 @@ Configuration panel for system parameters and preferences:
* **Classic WireGuard**: Standard, high-performance WireGuard protocol for unmatched speed and broad device compatibility with traffic monitoring support.
* **Xray (XTLS-Reality)**: Stealthy protocol that masks VPN traffic as standard HTTPS browsing. Pinned to **Xray-core v26.x**; transparently reads both the **panel layout** (`meta.json` + `clientsTable.json`) and the **native Amnezia client layout** (`xray_*.key` files + `clientsTable`), so a node first installed via the official mobile/desktop app can be attached to the panel without re-installation.
* **Hysteria 2**: QUIC/HTTP3 proxy from [apernet/hysteria](https://github.com/apernet/hysteria) via `tobyxdd/hysteria:v2` — Let's Encrypt TLS, salamander obfuscation, password auth, `hy2://` share links. Per-server SSL domain/email defaults, renew from settings; install requires free TCP **80** and **443**.
* **NaiveProxy**: HTTPS/HTTP2 camouflage proxy via [klzgrad/naiveproxy](https://github.com/klzgrad/naiveproxy) (Caddy + [klzgrad/forwardproxy](https://github.com/klzgrad/forwardproxy) naïve fork). ACME TLS on the domain, per-client basic auth, `naive+https://` share links. Requires free TCP **80** and **443**.
* **NaiveProxy** (stable): HTTPS/HTTP2 camouflage proxy via [klzgrad/naiveproxy](https://github.com/klzgrad/naiveproxy) (Caddy + [klzgrad/forwardproxy](https://github.com/klzgrad/forwardproxy) naïve fork). ACME TLS on the domain, per-client basic auth, `naive+https://` share links. Requires free TCP **80** and **443**. **Use Karing** as the client — do **not** use v2rayN; other clients are untested.
* **Telemt (Telegram MTProxy)**: High-performance Telegram MTProxy with TLS emulation and comprehensive management (quotas, IP limits, real-time session tracking). Robust install path that auto-configures Docker's official apt/yum repository when needed.
* **Cloudflare WARP**: Add and manage WARP-powered connectivity from the panel for routing and network flexibility.
* **🛠 Services**:
@@ -222,6 +222,25 @@ GitHub Actions workflows in `.github/workflows/`:
## 📋 Fix / changelog (this fork)
### v2.3.0
* **Cascade removed** — double-VPN feature dropped from the panel (manager, API, UI, i18n).
### v2.2.1
* **Cascade egress verify fix**: bind curl to ENTRY `awg0`/`wg0` IP (client-subnet policy route), not cascade peer Address.
* Soft-warn (no rollback) when policy route via `cascade` is OK but public-IP echo services fail.
### v2.2.0
* **Cascade (double VPN) restored** — later removed in **v2.3.0**.
* Inspired by [ryderams/amneziawg-cascade](https://github.com/ryderams/amneziawg-cascade); logic ran over panel SSH (**no remote curl|bash**).
### v2.1.0
* **NaiveProxy — stable**: production-ready install (Caddy + klzgrad/forwardproxy), share links always include `:443`.
* **Client notes (important)**:
* **Do not use v2rayN** with NaiveProxy (broken DNS/IPv6 behaviour → latency 1 ms even when the server is fine).
* **Karing** — confirmed working.
* Other clients — untested / use at your own risk.
* Share-link and config UI hints updated accordingly.
### v2.0.0-beta
* **NaiveProxy** (Beta): install [klzgrad/naiveproxy](https://github.com/klzgrad/naiveproxy) server via Caddy + naïve [forwardproxy](https://github.com/klzgrad/forwardproxy) — domain TLS (ACME), per-client basic auth, `naive+https://` share links.
* Marketplace / server page / users / invites / Telegram / backups include NaiveProxy.
@@ -245,7 +264,7 @@ GitHub Actions workflows in `.github/workflows/`:
### v1.6.0
* **3x-ui multi-panel**: register several 3x-ui servers in Settings; pick a panel and load VLESS inbounds over its API when creating users/invites (share link comes from 3x-ui).
* **Docker / CI**: refreshed `Dockerfile` + compose, `.env.example`, CI checks, GHCR image workflow.
* **Cascade removed** for now (pending redesign — showed active while internet often did not work).
* **Cascade** was temporarily removed in this release (briefly restored in v2.2.x, removed again in **v2.3.0**).
* **WG/AWG backups**: ZIP export of client `.conf` + restore with loading feedback.
* **API performance**: in-memory data cache, faster server check/stats.
* **Share / guest**: one-tap “Copy key”.
+4 -4
View File
@@ -101,7 +101,7 @@ else:
application_path = os.path.dirname(__file__)
DATA_FILE = os.path.join(application_path, 'data.json') # legacy JSON; used only for one-shot import / export
CURRENT_VERSION = "v2.0.0-beta"
CURRENT_VERSION = "v2.3.0"
RELEASES_REPO_URL = "https://git.evilfox.cc/test2/Amnezia-Web-Panel-main"
RELEASES_API_LATEST = "https://git.evilfox.cc/api/v1/repos/test2/Amnezia-Web-Panel-main/releases/latest"
BIN_DIR = os.environ.get('TUNNEL_BIN_DIR', os.path.join(application_path, 'bin'))
@@ -151,7 +151,7 @@ def load_translations():
if f.endswith('.json'):
lang = f.split('.')[0]
try:
with open(os.path.join(trans_dir, f), 'r', encoding='utf-8') as tf:
with open(os.path.join(trans_dir, f), 'r', encoding='utf-8-sig') as tf:
TRANSLATIONS[lang] = json.load(tf)
except Exception as e:
logger.error(f"Error loading translation {f}: {e}")
@@ -1742,7 +1742,6 @@ class HysteriaSettingsRequest(BaseModel):
email: Optional[str] = None
renew_ssl: bool = False
class ProtocolRequest(BaseModel):
protocol: str = 'awg'
@@ -2300,7 +2299,7 @@ async def server_detail(request: Request, server_id: int):
return RedirectResponse(url='/')
server = data['servers'][server_id]
users_list = data.get('users', [])
return tpl(request, 'server.html', server=server, server_id=server_id, users=users_list, all_servers=data['servers'])
return tpl(request, 'server.html', server=server, server_id=server_id, users=users_list)
@app.get('/users', response_class=HTMLResponse, tags=["System Templates"])
@@ -3231,6 +3230,7 @@ async def api_hysteria_update_settings(request: Request, server_id: int, req: Hy
return JSONResponse({'error': str(e)}, status_code=500)
@app.post('/api/servers/{server_id}/uninstall', tags=["Protocols"])
async def api_uninstall_protocol(request: Request, server_id: int, req: ProtocolRequest):
if not _check_admin(request):
+23 -13
View File
@@ -232,9 +232,13 @@ class NaiveProxyManager:
# Keep a non-shared bootstrap user so the proxy is never open
auth_lines = [f' basic_auth bootstrap {_rand_token(24)}']
auth_block = '\n'.join(auth_lines)
# probe_resistance looks like a fake domain to browsers
probe = (probe_path or _rand_token(12)).strip('/')
if '.' not in probe:
probe = f'{probe}.com'
return f"""{{
order forward_proxy before file_server
admin off
log {{
exclude http.log.error
}}
@@ -242,16 +246,14 @@ class NaiveProxyManager:
:443, {domain} {{
tls {email}
encode
route {{
forward_proxy {{
forward_proxy {{
{auth_block}
hide_ip
hide_via
probe_resistance {probe}
}}
file_server {{
root /var/www/html
}}
hide_ip
hide_via
probe_resistance {probe}
}}
file_server {{
root /var/www/html
}}
}}
"""
@@ -398,13 +400,21 @@ CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile
self._start_container()
def _build_share_uri(self, domain, username, password, name, port=443):
"""v2rayN / NekoRay / sing-box compatible share link.
Always include an explicit port without `:443` v2rayN often treats
the port as empty/80 and shows «Свойство Порт недопустимо» / SSL errors.
"""
# Keep credentials unescaped when alphanumeric (our generator); quote otherwise.
user = quote(username or '', safe='')
pw = quote(password or '', safe='')
host = domain or ''
host = (domain or '').strip().lower()
port = int(port or 443)
authority = f'{user}:{pw}@{host}' if port == 443 else f'{user}:{pw}@{host}:{port}'
fragment = quote(name or 'naiveproxy', safe='')
return f'naive+https://{authority}#{fragment}'
if port < 1 or port > 65535:
port = 443
# Remark: ASCII-safe, no spaces that break some importers
remark = re.sub(r'[^\w.\-]+', '-', (name or 'naiveproxy').strip())[:48] or 'naiveproxy'
return f'naive+https://{user}:{pw}@{host}:{port}#{remark}'
# ===================== INSTALL / REMOVE =====================
+20 -6
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "base.html" %}
{% from "macros/icons.html" import icon %}
{% block title_extra %} — {{ server.name }}{% endblock %}
@@ -325,10 +325,11 @@
<div class="protocol-icon">{{ icon('link') }}</div>
<div class="flex gap-sm" id="naiveproxy-ctrl" style="display:none!important;"></div>
</div>
<div class="protocol-name">NaiveProxy</div>
<div class="protocol-desc">
{{ _('naiveproxy_desc') }}
</div>
<div class="protocol-name">NaiveProxy <span
style="font-size:0.65rem; background:var(--success, #16a34a); color:#fff; padding:2px 6px; border-radius:8px; vertical-align:middle;">STABLE</span></div>
<div class="protocol-desc">
{{ _('naiveproxy_desc') }}
</div>
<div class="protocol-status" id="naiveproxy-status">
<span class="badge badge-warn"><span class="badge-dot"></span> {{ _('not_checked') }}</span>
</div>
@@ -743,6 +744,7 @@
</div>
<div class="form-hint">{{ _('naiveproxy_install_hint') }}</div>
<div class="form-hint" style="margin-top: var(--space-sm);">{{ _('naiveproxy_port_hint') }}</div>
<div class="form-hint" style="margin-top: var(--space-sm); padding: var(--space-sm) var(--space-md); border-radius: var(--radius-sm); background: rgba(234,179,8,0.12); border: 1px solid rgba(234,179,8,0.35);">{{ _('naiveproxy_client_hint') }}</div>
</div>
<div class="modal-footer">
@@ -986,6 +988,7 @@
<div class="config-panel active" id="panel-conf">
<div class="config-display">
<div class="config-text" id="configText"></div>
<div class="form-hint hidden" id="configClientHint" style="margin-top: var(--space-sm);"></div>
<div class="config-actions">
<button class="btn btn-secondary btn-sm" onclick="copyToClipboard(currentConfig)" style="flex:1">
{{ _('copy') }}
@@ -1097,7 +1100,7 @@
{ proto: 'xray', category: 'protocols', icon: 'zap', title: 'Xray (VLESS-Reality)', descKey: 'xray_desc' },
{ proto: 'telemt', category: 'protocols', icon: 'plane', title: 'Telemt (Telegram Proxy)', descKey: 'telemt_desc' },
{ proto: 'hysteria', category: 'protocols', icon: 'refresh', title: 'Hysteria 2', descKey: 'hysteria_desc' },
{ proto: 'naiveproxy', category: 'protocols', icon: 'link', title: 'NaiveProxy', descKey: 'naiveproxy_desc' },
{ proto: 'naiveproxy', category: 'protocols', icon: 'link', title: 'NaiveProxy', descKey: 'naiveproxy_desc', badge: 'STABLE' },
{ proto: 'wireguard', category: 'protocols', icon: 'lock', title: 'WireGuard', descKey: 'wireguard_desc' },
{ proto: 'dns', category: 'services', icon: 'search', title: 'AmneziaDNS', descKey: 'dns_desc' },
{ proto: 'adguard', category: 'services', icon: 'shield-check', title: 'AdGuard Home', descKey: 'adguard_desc' },
@@ -2840,6 +2843,16 @@
document.getElementById('configModalTitle').textContent = `${_('config')} — ${connName}`;
document.getElementById('configText').textContent = result.config;
document.getElementById('vpnLinkText').textContent = currentVpnLink;
const hintEl = document.getElementById('configClientHint');
if (hintEl) {
if (protoBase(proto) === 'naiveproxy') {
hintEl.textContent = _('naiveproxy_client_hint');
hintEl.classList.remove('hidden');
} else {
hintEl.textContent = '';
hintEl.classList.add('hidden');
}
}
switchConfigTab('conf');
openModal('configModal');
generateQR(result.config);
@@ -2952,6 +2965,7 @@
}
// ========== Init ==========
applyInstalledAppsVisibility();
checkServer();
+577 -576
View File
File diff suppressed because it is too large Load Diff
+520 -519
View File
File diff suppressed because it is too large Load Diff
+520 -519
View File
File diff suppressed because it is too large Load Diff
+577 -576
View File
File diff suppressed because it is too large Load Diff
+520 -519
View File
File diff suppressed because it is too large Load Diff