Hi,
I'm very new to everything related to networking and I've been trying to make some sort of "parental control" app for macOS where if the user tries to access some website domain (e.g youtube.com) the request is denied and the user can't access the website.
Turns out I used NEFilterDataProvider and NEDNSProxyProvider to achieve that but it's not 100% bullet proof.
First problem I had is that most of the time I can't access the hostname in the NEFilterDataProvider when trying to extract it from the socketFlow.remoteEndpoint. Most of the time I get the ipv4. And the problem is : I don't know the IPV4 behind the domains, specially when they're changing frequently.
if let socketFlow = flow as? NEFilterSocketFlow {
let remoteEndpoint = socketFlow.remoteFlowEndpoint
switch remoteEndpoint {
case .hostPort(let host, _):
switch host {
case .name(let hostname, _):
log.info("🌿 Intercepted hostname: \(hostname, privacy: .public)")
case .ipv4(let ipv4):
let ipv4String = ipv4.rawValue.map { String($0) }.joined(separator: ".")
log.info("🌿 Intercepted IPV4: \(ipv4String, privacy: .public)")
So that's why I used the DNSProxyProvider. With it I can get the domains. I succeeded to drop some of the flows by not writing the datagrams when I see a domain to block, but that does not work 100% of the time and sometimes, for youtube.com for example then the website is still reachable (and sometimes it works successfully and I can't access it). I guess because the IP behind the domain has already been resolved and so it's cached somewhere and the browser does not need to send an UDP request anymore to know the IP behind the domain?
Is there a 100% bullet proof way to block traffic to specific domains? Ideally I would like to get rid of the DNSProxyProvider and use only the NEFilterDataProvider but if I can't access the hostnames then I don't see how to do it.