mirror of
https://github.com/fosrl/olm.git
synced 2026-10-01 18:29:08 +02:00
Also exclude the dns servers from the tunnel
This commit is contained in:
@@ -266,6 +266,7 @@ func (o *Olm) handleConnect(msg websocket.WSMessage) {
|
||||
// "olm/wg/connect" message - so push in whatever hole-punch bypass
|
||||
// endpoints it already recorded now that there's somewhere to put them.
|
||||
o.flushPendingHolepunchBypassEndpoints()
|
||||
o.flushPendingDNSBypassEndpoints()
|
||||
|
||||
if o.dnsProxy != nil {
|
||||
if err := o.dnsProxy.Start(); err != nil { // start DNS proxy first so there is no downtime
|
||||
|
||||
@@ -26,6 +26,7 @@ func (o *Olm) applyDNSConfigUpdate(cfg DNSConfigUpdate) {
|
||||
if o.dnsProxy != nil {
|
||||
o.dnsProxy.SetUpstreamDNS(cfg.UpstreamDNS)
|
||||
}
|
||||
o.updateDNSBypassEndpoints(cfg.UpstreamDNS)
|
||||
}
|
||||
|
||||
if len(cfg.MatchDomains) > 0 {
|
||||
|
||||
@@ -214,6 +214,66 @@ func (o *Olm) flushPendingHolepunchBypassEndpoints() {
|
||||
}
|
||||
}
|
||||
|
||||
// updateDNSBypassEndpoints diffs servers (the DNS proxy's upstream/primary
|
||||
// and secondary DNS servers - see TunnelConfig.UpstreamDNS and
|
||||
// dns.DNSProxy.SetUpstreamDNS) against the currently-registered set and
|
||||
// adds/removes gateway bypass routes for the difference, via the same
|
||||
// AddGatewayBypassEndpoint/RemoveGatewayBypassEndpoint machinery used for
|
||||
// hole-punch endpoints above. This keeps the DNS proxy's own outbound queries
|
||||
// to its real upstream resolvers off the gateway default-route-equivalent, so
|
||||
// they reach the real servers directly instead of looping back through the
|
||||
// tunnel. Called from StartTunnel (initial value and dynamic system-DNS
|
||||
// updates, including SetSystemDNS pushes) and applyDNSConfigUpdate (live
|
||||
// server-pushed overrides). Safe to call before the peer manager exists (see
|
||||
// flushPendingDNSBypassEndpoints) and safe to call repeatedly with the same
|
||||
// servers (no-op).
|
||||
func (o *Olm) updateDNSBypassEndpoints(servers []string) {
|
||||
pm := o.getPeerManager()
|
||||
|
||||
newBypassEndpoints := make(map[string]bool, len(servers))
|
||||
for _, server := range servers {
|
||||
newBypassEndpoints[server] = true
|
||||
}
|
||||
|
||||
o.dnsBypassMu.Lock()
|
||||
defer o.dnsBypassMu.Unlock()
|
||||
if pm != nil {
|
||||
for server := range newBypassEndpoints {
|
||||
if !o.dnsBypassEndpoints[server] {
|
||||
pm.AddGatewayBypassEndpoint(server)
|
||||
}
|
||||
}
|
||||
for server := range o.dnsBypassEndpoints {
|
||||
if !newBypassEndpoints[server] {
|
||||
pm.RemoveGatewayBypassEndpoint(server)
|
||||
}
|
||||
}
|
||||
}
|
||||
o.dnsBypassEndpoints = newBypassEndpoints
|
||||
}
|
||||
|
||||
// flushPendingDNSBypassEndpoints re-registers every currently-known upstream
|
||||
// DNS bypass endpoint with the peer manager. Mirrors
|
||||
// flushPendingHolepunchBypassEndpoints: updateDNSBypassEndpoints typically
|
||||
// runs before the peer manager exists (the initial UpstreamDNS value is
|
||||
// applied in StartTunnel, and a DNS config override may arrive at the very
|
||||
// start of handleConnect - see olm/dns_config.go - both well before
|
||||
// handleConnect constructs the peer manager further down), so whatever was
|
||||
// recorded needs to be pushed in once it becomes available.
|
||||
// AddGatewayBypassEndpoint is idempotent.
|
||||
func (o *Olm) flushPendingDNSBypassEndpoints() {
|
||||
pm := o.getPeerManager()
|
||||
if pm == nil {
|
||||
return
|
||||
}
|
||||
|
||||
o.dnsBypassMu.Lock()
|
||||
defer o.dnsBypassMu.Unlock()
|
||||
for server := range o.dnsBypassEndpoints {
|
||||
pm.AddGatewayBypassEndpoint(server)
|
||||
}
|
||||
}
|
||||
|
||||
// extractControlEndpointHost returns the bare host (no scheme/port) of the
|
||||
// Pangolin server olm is registered against, for gateway bypass-route
|
||||
// purposes. Falls back to the raw endpoint string on parse failure -
|
||||
|
||||
+20
@@ -81,6 +81,18 @@ type Olm struct {
|
||||
hpBypassEndpoints map[string]bool
|
||||
hpBypassMu sync.Mutex
|
||||
|
||||
// dnsBypassEndpoints tracks the "host:port" upstream DNS servers (see
|
||||
// TunnelConfig.UpstreamDNS / dns.DNSProxy's upstreamDNS - the DNS proxy's
|
||||
// primary/secondary real resolvers) currently registered as gateway bypass
|
||||
// targets, so the proxy's own outbound DNS queries aren't captured by the
|
||||
// gateway default-route-equivalent and end up looping back through the
|
||||
// tunnel. Diffed against every update - the initial value in StartTunnel, a
|
||||
// live server-pushed DNS config override, or system DNS detection/
|
||||
// SetSystemDNS - so stale entries are unregistered and new ones protected
|
||||
// while gateway mode is active. Mirrors hpBypassEndpoints.
|
||||
dnsBypassEndpoints map[string]bool
|
||||
dnsBypassMu sync.Mutex
|
||||
|
||||
// primaryTunnelIP is the site tunnel's own address (wgData.TunnelIP), set once
|
||||
// per connect in handleConnect. It's the interface's first/primary address -
|
||||
// on macOS/iOS NetworkExtension, an unbound outbound socket's source gets
|
||||
@@ -526,6 +538,7 @@ func (o *Olm) StartTunnel(config TunnelConfig) {
|
||||
if o.dnsProxy != nil {
|
||||
o.dnsProxy.SetUpstreamDNS(servers)
|
||||
}
|
||||
o.updateDNSBypassEndpoints(servers)
|
||||
} else {
|
||||
logger.Debug("Not updating UpstreamDNS: statically configured to %v", config.UpstreamDNS)
|
||||
}
|
||||
@@ -549,6 +562,13 @@ func (o *Olm) StartTunnel(config TunnelConfig) {
|
||||
if len(o.tunnelConfig.UpstreamDNS) == 0 {
|
||||
o.tunnelConfig.UpstreamDNS = []string{"8.8.8.8:53"}
|
||||
}
|
||||
// Register the startup upstream DNS servers as gateway bypass targets
|
||||
// regardless of how they were determined (statically configured, defaulted
|
||||
// above, or already applied from a dynamic detection callback a moment
|
||||
// ago) - the peer manager doesn't exist yet at this point, so this only
|
||||
// records intent; flushPendingDNSBypassEndpoints (called from
|
||||
// handleConnect) pushes it in once the peer manager is created.
|
||||
o.updateDNSBypassEndpoints(o.tunnelConfig.UpstreamDNS)
|
||||
|
||||
// Reset terminated status when tunnel starts
|
||||
o.apiServer.SetTerminated(false)
|
||||
|
||||
Reference in New Issue
Block a user