Blocking outgoing connections for certain web sites

Hello
I have recently started learning basics of Network Extensions. And currently investigating SimpleFirewall app source code. The app blocks incoming connections for certain port - 8888. I have tried to change firewall work logic, so it asks user to connect to certain web sites or not. I have changed startFilter() function in the FilterDataProvider class. And now it looks like

Code Block Swift
 override func startFilter(completionHandler: @escaping (Error?) -> Void) {
        let filterRules = ["example.com"].map {address -> NEFilterRule in
            os_log("Initailize rule with: %@", address)
            let endpoint = NWHostEndpoint(hostname: address, port: "0")
            let rule = NENetworkRule(destinationHost: endpoint, protocol: .any)
            return NEFilterRule(networkRule: rule, action: .filterData)
        }
   
        // Allow all flows that do not match the filter rules.
        let filterSettings = NEFilterSettings(rules: filterRules, defaultAction: .allow)
        
        apply(filterSettings) { error in
            if let applyError = error {
                os_log("Failed to apply filter settings: %@", applyError.localizedDescription)
            }
            completionHandler(error)
        }
    }

But this implementation doesn't works at all. Could someone explain is it enough to change filter rules to get expected app behaviour or not?

Answered by Systems Engineer in 665014022

Could someone explain is it enough to change filter rules to get expected app behaviour or not?

Yes and no. Sometimes it's helpful to change the filter and then look at what you are getting right away in the handleNewFlow method. This should tell you whether your flows are being delivered from your NEFilterSettings. Try something like this:

Code Block swift
override func startFilter(completionHandler: @escaping (Error?) -> Void) {
let anyTCPRule = NENetworkRule(
remoteNetwork: NWHostEndpoint(hostname: "example.com", port: "0"),
remotePrefix: 0,
localNetwork: nil,
localPrefix: 0,
protocol: .TCP,
direction: .any
)
let filterRule = NEFilterRule(networkRule: anyTCPRule, action: .filterData)
let filterSettings = NEFilterSettings(rules: [filterRule], defaultAction: .allow)
apply(filterSettings) { error in
completionHandler(error)
}
}
override func handleNewFlow(_ flow: NEFilterFlow) -> NEFilterNewFlowVerdict {
let url = flow.url?.absoluteString ?? "No URL"
os_log(.debug, log: self.log, "Received a new flow: %{public}@ with url %{public}@", flow.description, url)
}



Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Accepted Answer

Could someone explain is it enough to change filter rules to get expected app behaviour or not?

Yes and no. Sometimes it's helpful to change the filter and then look at what you are getting right away in the handleNewFlow method. This should tell you whether your flows are being delivered from your NEFilterSettings. Try something like this:

Code Block swift
override func startFilter(completionHandler: @escaping (Error?) -> Void) {
let anyTCPRule = NENetworkRule(
remoteNetwork: NWHostEndpoint(hostname: "example.com", port: "0"),
remotePrefix: 0,
localNetwork: nil,
localPrefix: 0,
protocol: .TCP,
direction: .any
)
let filterRule = NEFilterRule(networkRule: anyTCPRule, action: .filterData)
let filterSettings = NEFilterSettings(rules: [filterRule], defaultAction: .allow)
apply(filterSettings) { error in
completionHandler(error)
}
}
override func handleNewFlow(_ flow: NEFilterFlow) -> NEFilterNewFlowVerdict {
let url = flow.url?.absoluteString ?? "No URL"
os_log(.debug, log: self.log, "Received a new flow: %{public}@ with url %{public}@", flow.description, url)
}



Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Thank you for response, Matt! With your example I have achieved the goal.

Thank you for response, Matt! With your example I have achieved the goal.

Great news!


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Blocking outgoing connections for certain web sites
 
 
Q