Build a Firewall on iOS: System Wide Tracker and Ad Blocking

I hope it’s okay to re-post my own blog post here, in which I ran through the process of setting a system-wide firewall on iOS with an app called Surge, which can block in-app ads and trackers (including YouTube ads in its app). I think this is a less known topic and might interest some of you.

YouTube Guide
———

———

Main Article
———

Build a Firewall to Protect our Privacy on iOS/iPadOS

Introduction

In the recent years, privacy invasion has become one of the most heated topics in the digital era. The online advertisers are trying their very best to gather our private information, build our profiles, and track us across the internet for targeted ad delivery.

With the introduction of App Tracking Transparency in iOS/iPadOS 14.5, we have gained the ability to reject the collection of our IDFAs, which are the device identifiers for advertisers. This is a big step forward to protect our privacy.

However, this identifier is far from the only information collected by the advertisers. I know everyone is slamming on Facebook on this. But it is well deserved so let’s join the crowd. Here is the list of data collected by Facebook as shown on the Privacy Label in the App Store:

  • Purchases
  • Financial Info
  • Contact Info
  • Contacts
  • User Content
  • Search History
  • Browsing History
  • Identifiers
  • Usage Data
  • Diagnostics
  • Other Data

The more concerning issue is that not only the Facebook app itself collects these data, a massive amount of other apps also collect them by implementing the Facebook Platform SDK. The only piece of information we can deny access to on iOS is just one of the identifiers, namely the IDFA.

Traditionally, firewalls are one of the weapons we have to fend ourselves against non-consensual tracking, by denying internet connection to a list of servers belonging to the trackers. However, iOS does not have a built-in firewall. So we need to use some third-party solutions. The app of focus today is Surge [^This article is written in the context of Surge 4.7.0.], which is marketed as an advanced networking toolbox.

I’ll outline how to set up the app as a system wide local firewall in the next section, followed by a brief guide on how to enable DNS over HTTPS.

Firewall

In this section, we’ll set up Surge to block all traffic to a list of IP addresses of known trackers. We’ll use the Steven Black’s Unified Hosts as an example list. But it can be customised to include any address. We’ll walk this whole process once so you understand what is going on.

First, we need to obtain the hosts and convert in into the required format. After downloading it, open it in a regular-expression-capable text editor, say Textastic. We only need the list of IP addresses that we want to block. So we remove the 0.0.0.0 at the beginning of each line, as well as the section of local hosts. This can be done in a single step by using the following regular expression


^(?!#|0\.0\.0\.0\s(?!0\.0\.0\.0)).*|^0\.0\.0\.0\s

to replace the matches with an empty string. Then we save the file as hosts.txt. If this is not something you are comfortable with, I also have the resulting hosts.txt available on GitHub. I’ll try to update it regularly but obviously it won’t be as up-to-date as the original.

The next step is to load this list into the configuration of Surge. First copy the hosts.txt into the profile folder Surge, which is located in “Under My iPhone/iPad” by default. If you have set “Profile Sync” with iCloud Drive in Surge, then obviously this folder is located under “iCloud Drive”. Now we have the block list in place. We just need to add a single line in the configuration file, which can be accessed by tapping the profile name on the top-left in Surge followed by “Edit in Text Mode”. Here we paste the rule


DOMAIN-SET,hosts.txt,REJECT

immediately before the line FINAL,DIRECT. This line basically tells Surge that hosts.txt is a set of domains to reject their connections.

In case you don’t want to go through this process, you can directly add the following rule to the configuration profile instead


DOMAIN-SET,https://raw.githubusercontent.com/Taxyovio/Surge-Firewall/main/hosts.txt,REJECT

which will be kept up to date automatically by Surge. You can also skip editing the profile altogether by directly “Download Profile from URL” in Surge from github.com/Taxyovio/Surge-Firewall/raw/main/Firewall.conf.

In addition to blocking specific domains, Surge can also block traffic from certain apps by matching user agents. For example, the rule


USER-AGENT,Instagram*,REJECT

will reject all traffic from Instagram [^For more rule types, please consult the user manual.]

Finally we want to start up this firewall. First select “Rule-Based Proxy” in the “Outbound Mode” so Surge will process the rule we just added. Next tap on “SETUP” and follow the instructions to set up a local VPN. Now the firewall should be working to reject connections to those trackers and advertisers. A quick test is to visit “amazon.com” and see that fls-na.amazon.com is rejected under “Recent Requests”. In addition to trackers, the firewall will also block most ads served in apps.

We can set up Surge to automatically start after device reboots. This setting can be accessed in Surge under “More – Always On – Turn on Surge Automatically”. You can also hide the “VPN” label on the status bar by turning on “Hide VPN Icon”, although this may cause errors when there’s a shortage of RAM.

DNS over HTTPS

Besides rejecting connections to certain domains, Surge has a lot of advanced features to offer, which are far beyond the scope of this article. But one of them I would like to include is the capability to run DNS over HTTPS (DoH), which is an encrypted protocol to resolve Domain Name System. It adds another layer of security and privacy for web browsing, by preventing DNS queries being eavesdropped or manipulated.

This can be configured by tapping the “DNS Servers” button on the “DNS” card in Surge. You just need to fill in the DoH URL in the “DNS-OVER-HTTPS” section, say https://1.1.1.1/dns-query provided by Cloudflare or https://dns.quad9.net/dns-query by Quad9.

MitM

Surge also has the capability to descrypt and intercept https traffic, by doing a so-called “man-in-the-middle” (MitM), on your own network, from your own device. This can be used to block persistent in-app ads, which usually cannot be blocked without a jailbreak.

For example, the following steps enable ad-blocking for YouTube videos:

  • Enable “MitM” in Surge and follow the instructions to install a certificate. (Do not share the certificate with anyone, unless you know what you are doing.)

  • Add youtube.com and googlevideo.com under the “Hostname” section in the “MitM” card. Surge only performs “MitM” attacks on the hostnames listed here.

  • Download YouTube.sgmodule and YouTube.js from my repository to the Surge configuration folder.

  • Tap on “Modules” on the “Module” card and add YouTube.sgmodule as “New Local Module”. A module is basically an isolated configuration in addition to the main conf file, which can be easily turned on and off.

  • Turn on “Scripting” in Surge, which enables the YouTube.js file as subsection of the module. This step can be skipped. But I find the blockign more reliable when it is on.

Conclusion

Setting up Firewall and DoH drastically improves the security and privacy of surfing the modern web with an iOS device. I am aware that there exist partial alternatives like AdGuard Pro and 1Blocker, which are primarily Safari Content Blockers. There’re also some VPN services bundling a firewall into their app, like Lockdown. But Surge is the best, dedicated tool for this task in terms of both flexibility and performance. The pricing is quite steep on the first sight. But considering its feature set and one-off license nature, it is well worth the cost.

7 Likes

Great! thanks for sharing. It was an easy set up and runs like a charm.

Understand why it uses iOS VPN function to work. I take it that therefore it won’t work with 3rd party VPN services, so I could not run NordVPN and use Surge at the same time.

Well worth the money for Surge Pro app imho.

Is there a similar setup using Surge Pro for Mac?

This sounds really good, but…
since it isn’t open source, what other security issues are there?
Are dns queries being routed through a nefarious server?
Is network traffic monitored?
Are Surge Networks themselves or a third party monitoring traffic?

1 Like

Think the only thing the the Surge app does is using iOS VPN functionality as a defined proxy and allowing management of the whitelist/blacklist. The created certificate and allowed trust is “on-device” so Surge have nothing to do with that.

As far as DNS goes, there is no man-in-the-middle as you either use device DNS (automatic) or set a server yourself in the Surge App and it will lead your traffic there.
To be sure you could set your network DNS to 1.1.1.1 and ask Surge to use device DNS. For now I have kept device DNS automatic and have set up Surge to use 1.1.1.1 and put in https://1.1.1.1/dns-query in DoH and it works very well and fast. I can’t notice any delay in use.

There are no 3rd party servers involved in this set up, so I can’t see traffic being monitored by Surge. You can choose to use host file on device or download updated versions dynamically, but this does not monitor your traffic. It just loads definitions to block. The source file is regularly updated and open source so you can always run a quick comparison in case something doesn’t work as advertised. You can also manually insert or exclude certain servers as needed.

3 Likes

As Mark said, Surge is not a VPN service so there’s no server side operations.

But this probably doesn’t answer your question completely. The short answer is that “I don’t know” and I’m trying to ask the dev if he can clarify this.

For any app on iOS, we can never know if it’s completely secure even if it’s open source. Because you cannot verify if the binary is really compiled from the source code. The burden falls partially to app reviewers. I encountered similar doubts when looking for a password manager. The way to see if there’s malicious traffic is to use a network proxy tool like Surge, Proxyman, and Charles. But it becomes less trustworthy when you are in doubt of these tools themselves.

With iOS 15, there’s a new system function to record app activity, which might help the situation. But currently its GUI is not implemented yet as it only shows a csv file.

3 Likes

@SuperTachyon so far super impressed with this setup.

Will do some traffic isolation on iPhone on a dedicated wifi network behind a firewalla to see what goes through and where

3 Likes

I guess this is the only option to scrutinise Surge. I’m looking forward to your findings.

1 Like

The dev for Surge basically replied the same thing that you can’t really “trust” any pre-compiled ios app, open source, or not. The same problem applies to every app.

But I think you can also probe its traffic using a desktop computer as a proxy server. Here’s a tutorial I found.

2 Likes

Thanks for this. My quick test using isolated vlan (both lan and wifi connections to iPad Pro) and traffic monitoring on firewalla gave me nothing to worry about. Will run this setup for a while to see if anything out of the ordinary happens.

I do have the occassional connection dropouts (cannot connect to the internet), but a.s.a. I retry the site opens or app functionality becomes available. This might be a latency created by scanning the online hosts.txt in my setup. Need to see if it happens if I bring hosts.txt locally on the device

1 Like

Thanks for the tests!

Even if you use the hosts.txt in my repo, the file should still be cached locally. But it’s worth a try.

Do you use iOS 15 and private relay in any chance? Private relay doesn’t work properly for http traffic. Apple declared it being in compatible with VPN apps so probably it’s intended behaviour.

I haven’t noticed any other issues so far for using it over a year, besides incompatibility with relay, and a bug in HomeKit causing failure to connect to cameras on local network.

1 Like

Still iOS 14 here. My network is pretty restrictively managed by Unifi (IPS/IDS) and firewalla, which might give some compatibility issues, hence I have created this new isolated VLAN to test.

It always connects on 2nd attempt on my original network though, so it must be a latency glitch. Other than that very happy with this setup, especially knowing I am not feeding the trackers…