| 49 | 50 | } |
| 50 | 51 | |
| 51 | 52 | /** |
| 52 | | - * Checks if a string is a valid hostname according to RFC 1123 |
| 53 | | - * @param {string} hostname The string to test |
| 54 | | - * @returns {boolean} True if the string is a valid hostname |
| 55 | | - */ |
| 56 | | -function isValidHostname(hostname) { |
| 57 | | - const hostnameRegex = /^(([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])\.)*([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])$/i; |
| 58 | | - return hostnameRegex.test(hostname); |
| 59 | | -} |
| 60 | | - |
| 61 | | -/** |
| 62 | | - * Checks if a string is an IP address, CIDR notation, or IP wildcard |
| 63 | | - * @param {string} entry The string to test |
| 64 | | - * @returns {boolean} True if the string matches any IP format |
| 65 | | - */ |
| 66 | | -function isIpFormat(entry) { |
| 67 | | - // Match CIDR notation (e.g. 192.168.0.0/24) |
| 68 | | - if (entry.includes('/')) { |
| 69 | | - return true; |
| 70 | | - } |
| 71 | | - |
| 72 | | - // Match exact IP address |
| 73 | | - if (ipRegex({ exact: true }).test(entry)) { |
| 74 | | - return true; |
| 75 | | - } |
| 76 | | - |
| 77 | | - // Match IPv4 with wildcards (e.g. 192.168.*.* or 192.168.0.*) |
| 78 | | - const ipWildcardRegex = /^(\d{1,3}|\*)\.(\d{1,3}|\*)\.(\d{1,3}|\*)\.(\d{1,3}|\*)$/; |
| 79 | | - return ipWildcardRegex.test(entry); |
| 80 | | -} |
| 81 | | - |
| 82 | | -/** |
| 83 | 53 | * Resolves hostnames in the whitelist to IP addresses. |
| 84 | 54 | * This function will modify the whitelist array in place. |
| 85 | 55 | */ |
| 86 | 56 | async function resolveHostnamesaddDockerHostsToWhitelist() { |
| 87 | | - const resolvedWhitelist = []; |
| 57 | + if (!whitelistDockerHosts || !isDocker()) { |
| 88 | | - |
| 89 | | - const promises = whitelist.map(async (entry) => { |
| 90 | | - if (!entry || typeof entry !== 'string') { |
| 91 | 58 | return; |
| 92 | 59 | } |
| 93 | 60 | |
| 94 | | - // Skip if entry appears to be an IP address, CIDR notation, or IP wildcard |
| 61 | + const whitelistHosts = ['host.docker.internal', 'gateway.docker.internal']; |
| 95 | | - if (isIpFormat(entry)) { |
| 96 | | - resolvedWhitelist.push(entry); |
| 97 | | - return; |
| 98 | | - } |
| 99 | 62 | |
| 100 | | - if (isValidHostname(entry)) { |
| 63 | + for (const entry of whitelistHosts) { |
| 101 | 64 | try { |
| 102 | 65 | const result = await dns.promises.lookup(entry); |
| 103 | 66 | console.info(`Resolved whitelist hostname ${color.green(entry)} to IPv${result.family} address ${color.green(result.address)}`); |
| 104 | 67 | resolvedWhitelist whitelist.push(result.address); |
| 105 | 68 | } catch (e) { |
| 106 | 69 | console.warn(`Failed to resolve whitelist hostname ${color.red(entry)}: ${e.message}`); |
| 107 | 70 | } |
| 108 | | - } else { |
| 109 | | - resolvedWhitelist.push(entry); |
| 110 | 71 | } |
| 111 | | - }); |
| 112 | | - |
| 113 | | - await Promise.allSettled(promises); |
| 114 | 72 | } |
| 115 | 73 | |
| 116 | 74 | /** |