mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
feat(apple): pass-through search domain to VPN resolver config (#8421)
In order to have the system expand search domains for us, we need to set a very peculiar combination of configuration options in the `NEDNSSettings` of the VPN configuration: - We need to include our search domains in the list of `matchDomains` - We need to set `matchDomainsNoSearch = false` - We need to set the `searchDomains` field Technically, we don't even need to set `searchDomains` by itself. Reading the docs in more detail for the `matchDomainsNoSearch` flag explains why: > A Boolean that specifies if the domains in the matchDomains list should not be appended to the resolver’s list of search domains. The double-negative here is confusing but essentially, what this says is: > If false, append the list of match domains to the resolver's search domains. That is exactly what we want. We want a search domain of e.g. `example.com` to append to the list of search domains for the primary resolver of non-scoped DNS queries. I tested without setting `searchDomains` and it does still work: The system will still expand the domain for us und send us a FQDN query of e.g. `foo.example.com`. However, I figured not setting `searchDomains` at all is quite confusing so I left it in there. Related: #8410 (Fixes it for MacOS) --------- Signed-off-by: Thomas Eizinger <thomas@eizinger.io> Co-authored-by: thomas <firezone@firezones-MacBook-Air.fritz.box> Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
This commit is contained in:
@@ -88,6 +88,7 @@ mod ffi {
|
||||
&self,
|
||||
tunnelAddressIPv4: String,
|
||||
tunnelAddressIPv6: String,
|
||||
searchDomain: Option<String>,
|
||||
dnsAddresses: String,
|
||||
routeListv4: String,
|
||||
routeListv6: String,
|
||||
@@ -128,7 +129,7 @@ impl Callbacks for CallbackHandler {
|
||||
tunnel_address_v4: Ipv4Addr,
|
||||
tunnel_address_v6: Ipv6Addr,
|
||||
dns_addresses: Vec<IpAddr>,
|
||||
_search_domain: Option<DomainName>,
|
||||
search_domain: Option<DomainName>,
|
||||
route_list_v4: Vec<Ipv4Network>,
|
||||
route_list_v6: Vec<Ipv6Network>,
|
||||
) {
|
||||
@@ -141,6 +142,7 @@ impl Callbacks for CallbackHandler {
|
||||
self.inner.on_set_interface_config(
|
||||
tunnel_address_v4.to_string(),
|
||||
tunnel_address_v6.to_string(),
|
||||
search_domain.map(|s| s.to_string()),
|
||||
dns_addresses,
|
||||
route_list_4,
|
||||
route_list_6,
|
||||
|
||||
@@ -363,6 +363,7 @@ extension Adapter: CallbackHandlerDelegate {
|
||||
public func onSetInterfaceConfig(
|
||||
tunnelAddressIPv4: String,
|
||||
tunnelAddressIPv6: String,
|
||||
searchDomain: String?,
|
||||
dnsAddresses: [String],
|
||||
routeListv4: String,
|
||||
routeListv6: String
|
||||
@@ -393,6 +394,7 @@ extension Adapter: CallbackHandlerDelegate {
|
||||
networkSettings.dnsAddresses = dnsAddresses
|
||||
networkSettings.routes4 = routes4
|
||||
networkSettings.routes6 = routes6
|
||||
networkSettings.setSearchDomain(domain: searchDomain)
|
||||
|
||||
networkSettings.apply()
|
||||
}
|
||||
@@ -474,7 +476,7 @@ extension Adapter {
|
||||
let semaphore = DispatchSemaphore(value: 0)
|
||||
|
||||
// Set tunnel's matchDomains to a dummy string that will never match any name
|
||||
networkSettings.matchDomains = ["firezone-fd0020211111"]
|
||||
networkSettings.setDummyMatchDomain()
|
||||
|
||||
// Call apply to populate /etc/resolv.conf with the system's default resolvers
|
||||
networkSettings.apply {
|
||||
@@ -484,7 +486,7 @@ extension Adapter {
|
||||
resolvers = BindResolvers().getservers().map(BindResolvers.getnameinfo)
|
||||
|
||||
// Restore connlib's DNS resolvers
|
||||
networkSettings.matchDomains = [""]
|
||||
networkSettings.clearDummyMatchDomain()
|
||||
networkSettings.apply { semaphore.signal() }
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ public protocol CallbackHandlerDelegate: AnyObject {
|
||||
func onSetInterfaceConfig(
|
||||
tunnelAddressIPv4: String,
|
||||
tunnelAddressIPv6: String,
|
||||
searchDomain: String?,
|
||||
dnsAddresses: [String],
|
||||
routeListv4: String,
|
||||
routeListv6: String
|
||||
@@ -34,6 +35,7 @@ public class CallbackHandler {
|
||||
func onSetInterfaceConfig(
|
||||
tunnelAddressIPv4: RustString,
|
||||
tunnelAddressIPv6: RustString,
|
||||
searchDomain: RustString?,
|
||||
dnsAddresses: RustString,
|
||||
routeListv4: RustString,
|
||||
routeListv6: RustString
|
||||
@@ -43,6 +45,7 @@ public class CallbackHandler {
|
||||
CallbackHandler.onSetInterfaceConfig:
|
||||
IPv4: \(tunnelAddressIPv4.toString())
|
||||
IPv6: \(tunnelAddressIPv6.toString())
|
||||
SearchDomain: \(String(describing: (searchDomain?.toString())))
|
||||
DNS: \(dnsAddresses.toString())
|
||||
IPv4 routes: \(routeListv4.toString())
|
||||
IPv6 routes: \(routeListv6.toString())
|
||||
@@ -57,6 +60,7 @@ public class CallbackHandler {
|
||||
delegate?.onSetInterfaceConfig(
|
||||
tunnelAddressIPv4: tunnelAddressIPv4.toString(),
|
||||
tunnelAddressIPv6: tunnelAddressIPv6.toString(),
|
||||
searchDomain: searchDomain?.toString(),
|
||||
dnsAddresses: dnsArray,
|
||||
routeListv4: routeListv4.toString(),
|
||||
routeListv6: routeListv6.toString()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@_cdecl("__swift_bridge__$CallbackHandler$on_set_interface_config")
|
||||
func __swift_bridge__CallbackHandler_on_set_interface_config (_ this: UnsafeMutableRawPointer, _ tunnelAddressIPv4: UnsafeMutableRawPointer, _ tunnelAddressIPv6: UnsafeMutableRawPointer, _ dnsAddresses: UnsafeMutableRawPointer, _ routeListv4: UnsafeMutableRawPointer, _ routeListv6: UnsafeMutableRawPointer) {
|
||||
Unmanaged<CallbackHandler>.fromOpaque(this).takeUnretainedValue().onSetInterfaceConfig(tunnelAddressIPv4: RustString(ptr: tunnelAddressIPv4), tunnelAddressIPv6: RustString(ptr: tunnelAddressIPv6), dnsAddresses: RustString(ptr: dnsAddresses), routeListv4: RustString(ptr: routeListv4), routeListv6: RustString(ptr: routeListv6))
|
||||
func __swift_bridge__CallbackHandler_on_set_interface_config (_ this: UnsafeMutableRawPointer, _ tunnelAddressIPv4: UnsafeMutableRawPointer, _ tunnelAddressIPv6: UnsafeMutableRawPointer, _ searchDomain: UnsafeMutableRawPointer?, _ dnsAddresses: UnsafeMutableRawPointer, _ routeListv4: UnsafeMutableRawPointer, _ routeListv6: UnsafeMutableRawPointer) {
|
||||
Unmanaged<CallbackHandler>.fromOpaque(this).takeUnretainedValue().onSetInterfaceConfig(tunnelAddressIPv4: RustString(ptr: tunnelAddressIPv4), tunnelAddressIPv6: RustString(ptr: tunnelAddressIPv6), searchDomain: { let val = searchDomain; if val != nil { return RustString(ptr: val!) } else { return nil } }(), dnsAddresses: RustString(ptr: dnsAddresses), routeListv4: RustString(ptr: routeListv4), routeListv6: RustString(ptr: routeListv6))
|
||||
}
|
||||
|
||||
@_cdecl("__swift_bridge__$CallbackHandler$on_update_resources")
|
||||
|
||||
@@ -23,12 +23,36 @@ class NetworkSettings {
|
||||
public var dnsAddresses: [String] = []
|
||||
public var routes4: [NEIPv4Route] = []
|
||||
public var routes6: [NEIPv6Route] = []
|
||||
public var matchDomains: [String] = [""]
|
||||
|
||||
// Private to ensure we append the search domain if we set it.
|
||||
private var matchDomains: [String] = [""]
|
||||
private var searchDomains: [String] = [""]
|
||||
|
||||
init(packetTunnelProvider: PacketTunnelProvider?) {
|
||||
self.packetTunnelProvider = packetTunnelProvider
|
||||
}
|
||||
|
||||
func setSearchDomain(domain: String?) {
|
||||
guard let domain = domain else {
|
||||
self.matchDomains = [""]
|
||||
self.searchDomains = [""]
|
||||
return;
|
||||
}
|
||||
|
||||
self.matchDomains = ["", domain]
|
||||
self.searchDomains = [domain]
|
||||
}
|
||||
|
||||
func setDummyMatchDomain() {
|
||||
self.matchDomains = ["firezone-fd0020211111"]
|
||||
}
|
||||
|
||||
func clearDummyMatchDomain() {
|
||||
self.matchDomains = [""]
|
||||
|
||||
self.matchDomains.append(contentsOf: self.searchDomains)
|
||||
}
|
||||
|
||||
func apply(completionHandler: (() -> Void)? = nil) {
|
||||
// We don't really know the connlib gateway IP address at this point, but just using 127.0.0.1 is okay
|
||||
// because the OS doesn't really need this IP address.
|
||||
@@ -46,7 +70,8 @@ class NetworkSettings {
|
||||
ipv4Settings.includedRoutes = routes4
|
||||
ipv6Settings.includedRoutes = routes6
|
||||
dnsSettings.matchDomains = matchDomains
|
||||
dnsSettings.matchDomainsNoSearch = true
|
||||
dnsSettings.searchDomains = searchDomains
|
||||
dnsSettings.matchDomainsNoSearch = false
|
||||
tunnelNetworkSettings.ipv4Settings = ipv4Settings
|
||||
tunnelNetworkSettings.ipv6Settings = ipv6Settings
|
||||
tunnelNetworkSettings.dnsSettings = dnsSettings
|
||||
|
||||
Reference in New Issue
Block a user