feat: Let's Encrypt IP address certificate support - #71
Merged
Conversation
adrgs
force-pushed
the
feat/ip-certificate-support
branch
from
February 9, 2026 22:57
29f5403 to
45f8221
Compare
Add HTTPS certificate support for direct IP access (e.g. https://SERVER_IP) using Let's Encrypt's short-lived IP certificates (6-day validity). Key changes: - Upgrade instant-acme 0.7 → 0.8 (new Account builder, async auth iterator, ChallengeHandle, RetryPolicy, Identifier::Ip support) - Add HTTP-01 ACME challenge handler served at /.well-known/acme-challenge/ - Add DualCertResolver with SNI-based cert selection: domain cert when SNI present, IP cert when absent (per RFC 6066) - Separate renewal cycles: domain certs (DNS-01, 12h checks) and IP certs (HTTP-01, 6h checks with 96h renewal threshold) - Add IpCertValidator with hours-level precision for short-lived certs - HTTP server starts before CertManager to ensure challenge endpoint readiness Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
adrgs
force-pushed
the
feat/ip-certificate-support
branch
from
February 10, 2026 00:02
45f8221 to
129b4b8
Compare
- server_ip.unwrap() → .expect() with invariant explanation
- RwLock .unwrap() → .expect("challenge token lock poisoned")
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
https://SERVER_IP) using Let's Encrypt short-lived IP certificates (6-day validity, HTTP-01 challenge)instant-acme0.7 → 0.8 forIdentifier::Ip, ACME profiles, and new async API (Account builder, ChallengeHandle, RetryPolicy)DualCertResolver: serves domain cert when SNI present, IP cert when absent (per RFC 6066)Key changes
New: IP certificate lifecycle
HttpChallengeHandler— in-memory token store shared between HTTP server and CertManagerIpCertValidator— hours-level precision validation for short-lived certs/.well-known/acme-challenge/:tokenroute on HTTP server for ACME validationRefactored: TLS architecture
DualCertResolverimplementsResolvesServerCertwithArcSwapfor hot-reloadTlsManagergainsreload_domain()/reload_ip()(replaces singlereload())Config (env vars)
IP_CERT_ENABLED(default:false) — enable/disable IP certsIP_CERT_CHECK_HOURS(default:6) — check intervalIP_CERT_RENEWAL_HOURS(default:96) — renew when <96h remainingTest plan
cargo build— clean (dev + release)cargo test— 79 passed, 0 failed, 1 ignored (staging)cargo clippy -- -D warnings— zero warningsACME_DIRECTORYto staging URL, verify domain cert (DNS-01) still worksopenssl s_client -connect IP:443shows IP cert,-servername domainshows domain cert🤖 Generated with Claude Code