Can i create firewall rule from a wildcard dns entry?
-
I would like to define a firewall rule from a wildcard DNS entry. This can be achieved in linux iptables.
Lets consider the scenario where I would like to block all outgoing traffic from a host, but allow only *.update.microsoft.com
In linux this can be achieved in the following way:
- client asks for somerandomstring.update.microsoft.com from dnsmasq
- dnsmasq looks up the name, returns it to the client and adds it to an ipset list according to its whitelist
- firewall iptables rule is configured to allow traffic according to the ipset list
ipset lists can be updated "behind the scenes" without any firewall reload.
Can something similar be achieved in pf?
-
Ok, so you want to "block all outgoing traffic from a host," unless the devices asks for a host name first.
Or : what use has it : blocking everything except the host names requested ??
To make a long story short : Don't do this.A couple of years ago, RFC DNS rules changed : wildcard DNS requests like
dig update.microsoft.com ANY
are refused these days.
I just tested it against my own zone records : I got my my 3 NS and a RRSIG.
If you want an IP (A or AAAA record, or any record for that matter) you have to ask it specifically.And this one : update.microsoft.com : it points to many (a huge number of) IP's. You will get one back, or a couple. A couple of minutes later : another IP will get returned. See it as a pool of IPs. IP's are taken out of this pool, and added and removed every second or so.
So you have an IP ? Nice. You have to update the request for update.microsoft.com because the IP changed. Reload the firewall rule set.
microsoft load balances its servers. As Google, Facebook, Twitter, Instagram, Toktik, etc etc do.
You can't get a list of IP from them. That won't work well.pfSense permit you to create firewall aliases.
These rare resolved to IP addresses every 5 minutes or so.
But you are warned : do not try to get an IP from the big servers.
The doc tells you this : Using Hostnames in Aliases (pfSense)
You saw the big yellow warning ?And I didn't mentioned CDNs ....
Two other aspects :
A process running on some device requests to resolve a host name.
The local DNS kicks in, send sends a DNS request to the known upstream resolver in the network. pfSense receives the request. This could be unbound by default, or dnsmasq, or bind if you want to.
These know nothing about the request, so they start asking one of the 13 big bosses about a DNS TLD server - or ask some other upstream resolver like 8.8.8.8, as dnsmasq has to do.
One of the the TLD DNS servers will give the list of 2 (at least) de domain name servers. A domain name server is contacted, and the answer comes back.
The originating LAN host in informed. The get_host() function in our initial process got an IP, and can now continue processing.
And in the background, meanwhile, on the the pfSense firewall, this process has to be monitored, like a MITM, a new rule has be be created, or added to an a table, and the rules then get reloaded to take in account the new "pass for IP a.b.c.d" ?
I for see timing issues, big overall delays, race conditions, the big total.The filtered "I want to know the host name first so I can create firewall rule accordingly" I never saw that one before.
A question : your solution, is a a home made script ? Known tool ? Can you show it ?
The idea of crating your DNSBL only the fly, pruning later on the 'bad' host names, or have it compared with a known bad list, why not. It would be usable for a school, prison or other severely controlled environment.
It could be done with unbound, the pfSense resolver also. It always boils down to the same core question and answer : how good is your xxx (here : python) script knowledge ?I still think you have to baby sit this one, if you get something up and running.
You had a look at what pfBlocker-devel can do for you ?
-
@gertjan i think i described pretty concisely what i want to achieve. I want to block all traffic from my network except the one going to *.somedomain.com. I do not know what is the host name in advance and i do not know the ip and the ip's change and are not under my control. I don't care what the dns answers technically. As dnsmasq is quite capable of giving the ip to the client upon dns query, no matter how "big" the answer is, i want allow the same ip(s) to be allowed through the firewall.
It IS doable in linux iptables exactly as i described it. No need for ANY scripts.
In fact, it appears that it is also quite doable in pf.
I know I am essentially replying to myself here, but maybe someone else needs this. It appears that dnsmasq ipset functions work (albeit totally undocumented) in BSD as well and write to a pf table using the same configuration syntax. So all i needed to do is:
add to dnsmasq conf:
ipset=/somedomain.com/ALLOWTHISand create a pf rule to pass anything to <ALLOWTHIS> and block the rest.
When a client does a dns lookup, dnsmasq adds the ip to a pf table ALLOWTHIS. This does not require any firewall reload or anything and the already existing rule is applied.
Thank you for your attention.
-
@gertjan said in Can i create firewall rule from a wildcard dns entry?:
A couple of years ago, RFC DNS rules changed : wildcard DNS requests like
dig update.microsoft.com ANY
are refused these days.
By the way, dns request of ANY type does not have anything to do with wildcards, but rather that you request any type (A, TXT, CNAME) of dns record.