From df015e4d5a529e1e697e26648f9193858fef5e64 Mon Sep 17 00:00:00 2001 From: Niranjan Date: Tue, 7 Apr 2026 12:00:10 +0530 Subject: [PATCH] new changes --- .../app/api/__pycache__/ssl.cpython-314.pyc | Bin 23297 -> 25939 bytes YakPanel-server/backend/app/api/ssl.py | 44 ++++++++++++++++-- .../frontend/src/pages/DomainsPage.tsx | 30 ++++++++++++ 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/YakPanel-server/backend/app/api/__pycache__/ssl.cpython-314.pyc b/YakPanel-server/backend/app/api/__pycache__/ssl.cpython-314.pyc index ce1ca25c5d54cc661716d709dacb42abfd3ad91c..1943f038aa7700c4114c6002c6130eaa7ddde6c3 100644 GIT binary patch delta 5875 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 QT-|LqFC6Ny;|tUO0zr3y@&Et; delta 3433 zcma)8ZERE58NSEY*B^-;=hOKz_D$^AG5I8MK2Rwon`mv40=)@gK!Y*%4Y}ah-nrKh zf;y+&s%}tL*y&Vh5^U1MwyOIv$TtqE7$ZMZp?5;bv;;o;ntsEyYdb)4H1_3;LyfpbTqG2Ub} zaqdibM zG=c$P&fXy?HHxR7D79l2d<;P_LQ2HwQtFxorM_9n)*4}@0eBJr#S7rFE{f#z=+EIXZ+n-$S#8uV%v*r46=f$E~s?wr*?mGzoA$A80nrd17Kk zZ1loW2iBK7Fev`7cEgimk2xv;8_JIy)sOdQ+n({29=_)=Q95CH@R8*Mk38=BJ(SRc zcesBA*rf}02|u#SphAK|w0n7UU+UQIR8GyxeKPyda*0@3Q4Fw4;+G`Ker`P@1z>-F zd01+)ksg+){yy2rZdGq3epcu5O53@z*Yzt)Un@}B2Jj}KJ{Y2eZh%3@SI|lQfE2gl zFvp0;N93~KvqGwOpj1Zivo~w~zDb~S@UOc8R)jUH=sZL|6D7$;W%jSy*Z1N{rX_RO zv}f{*Nt!=l+6z=$Owp74{HR1FSV0{K4G4H0+79rzJI%A}bz9+1?)nMQ8^p!6rd?f9 z(?vt2Hr%0sWtw)hJpt6TX*pe`Mzo4Pi<+GXyV#YcG2;J`w^LGKK3|S_-y$Q=0F8>K zWE2Zo)wCYY=d)kyo>R=;(nVy}*Rs+ESB~NqgrYm>gU))lB_tgM;VHJ(;)Uho{{7py zZ(QjjrE1Pd7U7cohEWTxLvwV@X=OhP`nuzwfTzPyGu_E#I-An#G zGIR3&^F&2%_WybLB0JX=126xjYtBVBvEWby(rI#Nn7qYGL+_Jdd2+aq)SraYO(}Oo z%PncWkVQ0HJ{|jn1eQQfQAw8(tO(cz=q7|7c6PKivLC2vqq;%00zHfJM_!zQvVH8@ zXrR=Hl)t@xWIS0gtSALA9gC@BYDS|v9Yfi61k6yXqSmG^8EP&=t5GtH5JMP67)KZZ zFm1Y#fk5PAzGy@P^kvjlf`J_y+eCJ<3u8mX%WjN~LVdB1N63%az_^#3V^5EFgLCrZ zUgVn<%yjiSW3&UPUTY>H6!!bl+*d# zymq8WQ-+q$$yzR*EoM|*PRX&@u$TGkCMo0aENT2}9s^9400 z&wO*Yj1`7kz#hheD({+>=QXOHNWt1vE+eP2`C?{Z7VK+usL50_PRd7UzF1)2nmIEn zEoeDIhroIu5%AU*5O`Q)MpPo&PSrv-l~(ClHo3=F!mu_S5XAZk%~+u52|9$}LcnTI z7XVBPRUv@Y6iqMCizwwWUxVy_1^zEkaR~uaAlh6B*IxoRow^F$AelO>(;EV$FTKhB zvnNDeX3et;BO7srm^-pWpF-o`;MAHaE*9wDklM3qGOHa|%_<-Ts_IbY^=5WswymR5 zH9fp)YN;bRh!8EU(|?0m4Q4@4*}eCaSa+vNaQOc2aKGmIfoshoxDT)|_Yc&0&NZ#o zIbF6j!7179esRpg;s??t0(LJ=G|beJKYAy&!tjnapag|?Muvd@xqG4&hQC@SqA#wHJ;Q-o zlPvMR6o!wYeTPPOpTReXUo?p&|^X#WwyKM;5*V-c^!GY@4G zrtpE3Wgj1EYU1Z%XVxWv_14RrsdniO%)e8Prb0yCWZIL^hSSMp<&b}Zif%^WVL!-T zIQ+Y?=}Hv}{i%Z1pDIEUc|dJ?P_&rOs9C+Ae~8qvWV*>#kERW5IUQKU&I4TvS^{*3 zEhyiPaId}4qd4X1YaqkMjNc+q`mh=B(586R2S1B&jbjU(Tg<9ksU7?Ve}dl4YBOFI s&G>8|3;L>{v*$8nmbEJOdgi5i> tuple[bool, str]: return nginx_reload_all_known(timeout=60) +def _localhost_accepts_tcp(port: int, timeout: float = 2.0) -> bool: + """True if something accepts a TCP connection on this machine (checks IPv4 loopback).""" + try: + with socket.create_connection(("127.0.0.1", port), timeout=timeout): + return True + except OSError: + return False + + +def _ss_reports_listen_443() -> bool | None: + """Parse ss/netstat output; None if the probe could not run.""" + out, _ = exec_shell_sync("ss -tln 2>/dev/null || netstat -tln 2>/dev/null", timeout=5) + if not out or not out.strip(): + return None + return bool(re.search(r":443\b", out)) + + @router.get("/domains") async def ssl_domains( current_user: User = Depends(get_current_user), @@ -362,9 +380,27 @@ async def ssl_diagnostics(current_user: User = Depends(get_current_user)): "Add the include below (or symlink this directory into /etc/nginx/conf.d/)." ) - if effective_listen_443: + localhost_443_open = _localhost_accepts_tcp(443) + ss_443 = _ss_reports_listen_443() + + if not localhost_443_open and not effective_listen_443: hints.append( - "Loaded nginx configuration includes a 443 listener. If HTTPS still fails, open TCP port 443 on the OS firewall and cloud/VPS security group." + "This server is not accepting TCP on 127.0.0.1:443 — nothing is listening on 443 yet. " + "Fix nginx (listen 443 ssl + include panel vhosts) first; opening only the cloud firewall will not fix ERR_CONNECTION_REFUSED until nginx binds 443." + ) + elif effective_listen_443 and localhost_443_open: + hints.append( + "Nginx loads HTTPS and 127.0.0.1:443 accepts connections on this host. " + "If browsers off this machine still see connection refused, allow inbound TCP 443: " + "sudo ufw allow 443/tcp && sudo ufw reload (or firewalld), and your VPS Security Group / provider firewall." + ) + elif effective_listen_443 and not localhost_443_open: + hints.append( + "nginx -T reports listen 443, but connecting to 127.0.0.1:443 failed — check nginx error.log; nginx may have failed to bind (permission or address already in use)." + ) + elif localhost_443_open and not effective_listen_443: + hints.append( + "127.0.0.1:443 accepts TCP, but nginx -T from panel binaries did not show listen 443 — another process may own 443; check ss -tlnp and which nginx serves port 80." ) return { @@ -375,6 +411,8 @@ async def ssl_diagnostics(current_user: User = Depends(get_current_user)): "nginx_effective_listen_443": effective_listen_443, "panel_vhost_path_in_nginx_t": panel_include_in_effective_config, "nginx_t_probe_errors": nginx_t_errors, + "localhost_443_accepts_tcp": localhost_443_open, + "ss_reports_443_listen": ss_443, "hints": hints, } diff --git a/YakPanel-server/frontend/src/pages/DomainsPage.tsx b/YakPanel-server/frontend/src/pages/DomainsPage.tsx index 7dc1bc42..04d03294 100644 --- a/YakPanel-server/frontend/src/pages/DomainsPage.tsx +++ b/YakPanel-server/frontend/src/pages/DomainsPage.tsx @@ -25,6 +25,10 @@ interface SslDiagnostics { nginx_effective_listen_443: boolean panel_vhost_path_in_nginx_t: boolean nginx_t_probe_errors: string[] + /** Something accepted TCP when connecting to 127.0.0.1:443 from the panel process */ + localhost_443_accepts_tcp: boolean + /** ss/netstat reported :443 in listen table, or null if probe unavailable */ + ss_reports_443_listen: boolean | null hints: string[] } @@ -114,6 +118,32 @@ export function DomainsPage() { ) : null}
Include YakPanel vhosts inside the http block of the nginx process that serves your sites:
{diag.include_snippet} +
+ Port 443 on this machine +
    +
  • + Localhost TCP (127.0.0.1:443):{' '} + {diag.localhost_443_accepts_tcp ? ( + accepting connections + ) : ( + refused / nothing listening + )} +
  • +
  • + Kernel listen table (ss):{' '} + {diag.ss_reports_443_listen === null ? ( + not checked + ) : diag.ss_reports_443_listen ? ( + 443 in LISTEN + ) : ( + no 443 in LISTEN + )} +
  • +
+

+ The panel cannot see your cloud provider firewall. If localhost shows open but browsers off-network fail, open TCP 443 in the VPS control panel (security group) and OS firewall. +

+
{diag.vhosts.length > 0 ? (
Panel configs scanned:{' '}