+22
-13
@@ -128,16 +128,22 @@ function extractSNI (buf) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the two-label base domain from a hostname.
|
||||
* e.g. "test.haha.wooo" -> "haha.wooo"
|
||||
* "myapp.hole.sail" -> "hole.sail"
|
||||
* Derive the wildcard parent domain for a hostname — i.e. everything except
|
||||
* the leftmost label. This is what the cert's SAN wildcard must cover.
|
||||
*
|
||||
* Examples:
|
||||
* "myapp.hole.sail" -> "hole.sail" (cert: *.hole.sail)
|
||||
* "test.haha.wooo" -> "haha.wooo" (cert: *.haha.wooo)
|
||||
* "i.love.hole.sail" -> "love.hole.sail" (cert: *.love.hole.sail)
|
||||
* "a.b.c.my.internal" -> "b.c.my.internal"
|
||||
*
|
||||
* Returns null if the hostname has fewer than 2 labels.
|
||||
*/
|
||||
function getBaseDomain (hostname) {
|
||||
function getWildcardParent (hostname) {
|
||||
if (!hostname) return null;
|
||||
const parts = hostname.split('.');
|
||||
if (parts.length < 2) return null;
|
||||
return parts.slice(-2).join('.');
|
||||
return parts.slice(1).join('.');
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -366,25 +372,28 @@ function handleRawConnection (rawSocket) {
|
||||
const sni = extractSNI(peekedBuf);
|
||||
debugLog('SNI extracted:', sni);
|
||||
|
||||
const baseDomain = getBaseDomain(sni) || 'hole.sail';
|
||||
// Derive the wildcard parent: strip the leftmost label so the cert's
|
||||
// *.parent SAN exactly covers the SNI hostname at any depth.
|
||||
// e.g. "myapp.hole.sail" -> parent "hole.sail" -> cert *.hole.sail
|
||||
// "i.love.hole.sail" -> parent "love.hole.sail" -> cert *.love.hole.sail
|
||||
const wildcardParent = getWildcardParent(sni) || 'hole.sail';
|
||||
|
||||
// Get or create a wildcard cert for this base domain
|
||||
// Get or create a wildcard cert for this parent domain
|
||||
let certResult = null;
|
||||
if (proxyCertsDirOrCA && typeof proxyCertsDirOrCA.getOrCreateWildcardCert === 'function') {
|
||||
certResult = proxyCertsDirOrCA.getOrCreateWildcardCert(baseDomain);
|
||||
certResult = proxyCertsDirOrCA.getOrCreateWildcardCert(wildcardParent);
|
||||
} else if (proxyCertsDirOrCA && typeof proxyCertsDirOrCA.getOrCreateDomainCert === 'function') {
|
||||
// Fallback: use the old multi-SAN approach with just this domain
|
||||
certResult = proxyCertsDirOrCA.getOrCreateDomainCert(
|
||||
'wildcard.' + baseDomain,
|
||||
'wildcard.' + wildcardParent,
|
||||
[
|
||||
{ type: 2, value: '*.' + baseDomain },
|
||||
{ type: 2, value: baseDomain }
|
||||
{ type: 2, value: '*.' + wildcardParent },
|
||||
{ type: 2, value: wildcardParent }
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
if (!certResult) {
|
||||
if (process.stderr) process.stderr.write('[https-proxy] no cert for baseDomain=' + baseDomain + ', dropping connection\n');
|
||||
if (process.stderr) process.stderr.write('[https-proxy] no cert for wildcardParent=' + wildcardParent + ', dropping connection\n');
|
||||
rawSocket.destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user