new changes

This commit is contained in:
Niranjan
2026-04-07 10:47:27 +05:30
parent 8a08a95a17
commit cc45fac342
3 changed files with 61 additions and 26 deletions

View File

@@ -7,6 +7,7 @@ from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select from sqlalchemy import select
from pydantic import BaseModel from pydantic import BaseModel
from typing import Optional
from app.core.database import get_db from app.core.database import get_db
from app.core.config import get_runtime_config from app.core.config import get_runtime_config
@@ -98,6 +99,27 @@ def _certbot_missing_message() -> str:
) )
async def _le_hostnames_for_domain_row(db: AsyncSession, dom_row: Optional[Domain], primary: str) -> list[str]:
"""All distinct hostnames for the site (for -d flags). Falls back to primary."""
if not dom_row:
return [primary] if primary else []
result = await db.execute(select(Domain).where(Domain.pid == dom_row.pid).order_by(Domain.id))
rows = result.scalars().all()
seen: set[str] = set()
out: list[str] = []
for d in rows:
n = (d.name or "").strip()
if not n:
continue
key = n.lower()
if key not in seen:
seen.add(key)
out.append(n)
if primary and primary.lower() not in seen:
out.insert(0, primary)
return out if out else ([primary] if primary else [])
def _reload_panel_and_common_nginx() -> None: def _reload_panel_and_common_nginx() -> None:
"""Reload nginx so new vhost (ACME path) is live before certbot HTTP-01.""" """Reload nginx so new vhost (ACME path) is live before certbot HTTP-01."""
cfg = get_runtime_config() cfg = get_runtime_config()
@@ -189,41 +211,53 @@ async def ssl_request_cert(
if not prefix: if not prefix:
raise HTTPException(status_code=500, detail=_certbot_missing_message()) raise HTTPException(status_code=500, detail=_certbot_missing_message())
cmd = prefix + [ hostnames = await _le_hostnames_for_domain_row(db, dom_row, dom)
"certonly",
"--webroot", base_flags = [
"-w",
webroot_norm,
"-d",
dom,
"--non-interactive", "--non-interactive",
"--agree-tos", "--agree-tos",
"--email", "--email",
body.email, body.email,
"--preferred-challenges",
"http",
"--no-eff-email", "--no-eff-email",
] ]
cmd_webroot = prefix + ["certonly", "--webroot", "-w", webroot_norm, *base_flags]
for h in hostnames:
cmd_webroot.extend(["-d", h])
cmd_webroot.extend(["--preferred-challenges", "http"])
cmd_nginx = prefix + ["certonly", "--nginx", *base_flags]
for h in hostnames:
cmd_nginx.extend(["-d", h])
env = environment_with_system_path() env = environment_with_system_path()
proc: subprocess.CompletedProcess[str] | None = None
last_err = ""
for cmd, label in ((cmd_webroot, "webroot"), (cmd_nginx, "nginx")):
try: try:
proc = subprocess.run( proc = subprocess.run(
cmd, cmd,
capture_output=True, capture_output=True,
text=True, text=True,
timeout=180, timeout=300,
env=env, env=env,
) )
except FileNotFoundError: except FileNotFoundError:
raise HTTPException(status_code=500, detail=_certbot_missing_message()) from None raise HTTPException(status_code=500, detail=_certbot_missing_message()) from None
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
raise HTTPException(status_code=500, detail="certbot timed out (180s)") from None raise HTTPException(status_code=500, detail="certbot timed out (300s)") from None
if proc.returncode == 0:
break
chunk = (proc.stderr or proc.stdout or "").strip() or f"exit {proc.returncode}"
last_err = f"[{label}] {chunk}"
if proc.returncode != 0: if proc is None or proc.returncode != 0:
msg = (proc.stderr or proc.stdout or "").strip() or f"certbot exited with code {proc.returncode}" msg = last_err or "certbot failed"
hint = ( hint = (
" Check: DNS A/AAAA for this domain points to this server; port 80 is reachable; " " Webroot and nginx plugins both failed. Check: "
"the website is enabled in YakPanel; nginx on port 80 loads this sites vhost (same server as panel nginx if used)." "DNS A/AAAA for every -d name points to this server; port 80 reaches the nginx that serves these hosts; "
"site is enabled; install python3-certbot-nginx if the nginx method reports a missing plugin. "
"If you use a CDN proxy, pause it or use DNS validation instead."
) )
raise HTTPException(status_code=500, detail=(msg + hint)[:8000]) raise HTTPException(status_code=500, detail=(msg + hint)[:8000])

View File

@@ -22,6 +22,7 @@ celery>=5.3.0
# Let's Encrypt (optional if system certbot/snap not used; enables python -m certbot from panel venv) # Let's Encrypt (optional if system certbot/snap not used; enables python -m certbot from panel venv)
certbot>=3.0.0 certbot>=3.0.0
certbot-nginx>=3.0.0
# Utils # Utils
psutil>=5.9.0 psutil>=5.9.0