@@ -278,6 +278,10 @@ async def cleanup_expired_proxies_and_sync_caddy(
278278 model = Proxies ,
279279 )
280280 for proxy in expired :
281+ if not proxy .ssh_public_key :
282+ captured_key = _extract_authorized_key (settings , proxy )
283+ if captured_key :
284+ proxy .ssh_public_key = captured_key
281285 proxy .status = "expired"
282286 await update_proxies (proxy )
283287 _remove_authorized_key (settings , proxy )
@@ -309,6 +313,15 @@ async def cleanup_expired_proxies_and_sync_caddy(
309313 model = Proxies ,
310314 )
311315
316+ # 2b) Ensure authorized_keys contains entries for active tunnels
317+ for proxy in active :
318+ if not proxy .ssh_public_key :
319+ proxy .ssh_public_key = _extract_authorized_key (settings , proxy )
320+ if proxy .ssh_public_key :
321+ await update_proxies (proxy )
322+ if proxy .ssh_public_key :
323+ _add_authorized_key (settings , proxy , proxy .ssh_public_key )
324+
312325 # 3) Rewrite Caddy tunnels file
313326 try :
314327 os .makedirs (os .path .dirname (settings .caddy_tunnels_file ), exist_ok = True )
@@ -437,6 +450,9 @@ async def payment_received_for_payments(payment: Payment) -> bool:
437450 logger .warning ("reverse_proxy: invalid price_per_day_sats in settings" )
438451 return False
439452
453+ if not proxy .ssh_public_key :
454+ proxy .ssh_public_key = _extract_authorized_key (settings , proxy )
455+
440456 days_to_extend = (payment .amount / 1000 ) / price_per_day
441457
442458 now = datetime .now (timezone .utc )
@@ -447,6 +463,9 @@ async def payment_received_for_payments(payment: Payment) -> bool:
447463 proxy .status = "active"
448464 await update_proxies (proxy )
449465
466+ if proxy .ssh_public_key :
467+ _add_authorized_key (settings , proxy , proxy .ssh_public_key )
468+
450469 payments .paid = True
451470 await update_payments (payments )
452471
@@ -495,13 +514,16 @@ async def _process_payment_with_setup(payment: Payment, setup: dict) -> bool:
495514 subdomain = setup .get ("subdomain" , random_subdomain ()),
496515 remote_port = remote_port ,
497516 ssh_user = setup .get ("ssh_user" , settings .ssh_user ),
517+ ssh_public_key = pubkey ,
498518 expires_at = expires_at ,
499519 status = "pending" ,
500520 public_id = public_id ,
501521 client_note = setup .get ("client_note" , "" ),
502522 ),
503523 proxies_id = proxy_id ,
504524 )
525+ if pubkey :
526+ proxy .ssh_public_key = pubkey
505527 if getattr (proxy , "status" , "" ) != "active" :
506528 proxy .status = "active"
507529
@@ -544,6 +566,31 @@ def _authorized_keys_path(settings: ExtensionSettings) -> str:
544566 return os .path .join ("/home" , settings .ssh_user , ".ssh" , "authorized_keys" )
545567
546568
569+ def _extract_authorized_key (settings : ExtensionSettings , proxy : Proxies ) -> str | None :
570+ """
571+ Try to read the stored public key for this proxy from authorized_keys.
572+ """
573+ ak_path = _authorized_keys_path (settings )
574+ marker = f"reverse_proxy:{ proxy .id } "
575+ if not os .path .exists (ak_path ):
576+ return None
577+
578+ try :
579+ with open (ak_path , "r" , encoding = "utf-8" ) as f :
580+ for line in f :
581+ if marker not in line :
582+ continue
583+ parts = line .strip ().split ()
584+ if len (parts ) < 3 or parts [- 1 ] != marker :
585+ continue
586+ return " " .join (parts [1 :- 1 ])
587+ except Exception as exc :
588+ logger .error (
589+ f"reverse_proxy: failed to read authorized_key for { proxy .id } : { exc } "
590+ )
591+ return None
592+
593+
547594def _add_authorized_key (settings : ExtensionSettings , proxy : Proxies , pubkey : str ) -> None :
548595 """
549596 Append a restricted SSH key for this proxy.
0 commit comments