metal-stack / firewall-controller

A kubernetes controller running on bare-metal firewalls, creating nftables rules, configures suricata, collects network metrics
MIT License
47 stars 4 forks source link

DNS based policy for egress #79

Closed GrigoriyMikhalkin closed 1 year ago

GrigoriyMikhalkin commented 3 years ago

Support DNS based policies for egress. Similar to DNS based policies in cilium. As part of the solution we also need to implement DNS proxy.

majst01 commented 3 years ago

There is already another implementation which acts as a dns proxy and put the entries into a ipset:

majst01 commented 3 years ago

After reading nftables documentation i think we can not use ipset, instead nft sets/maps/verdict maps must be used. We already use the in the accounting logic. General approach is still the same.

see: http://wiki.nftables.org/wiki-nftables/index.php/Sets

mwindower commented 3 years ago

Nice hint to nadoo/glider! We really must capture&cache all DNS traffic. Not only queries that target the current set of toFQDNs of all ClusterwideNetworkPolicies. In a running setup we want to be able to change those rules and get them applied immediately and don't want to wait for DNS requests coming by (with systemd-resolved and CoreDNS in Kubernetes we have two "caches").

GrigoriyMikhalkin commented 3 years ago

So we can have architecture like this:

CWNP Controller <--- reads DNS entries from cache --- DNS Cache <--- writes DNS data to cache --- DNS Proxy

Where DNS Proxy is based on glider. It monitors and caches all DNS data in DNS Cache. And then CWNP controller, when it receives resource with toFQDN field, looks up entries for domain names in DNS Cache. One problem is with matchPatterns -- it looks like the only way in that case is to do a brute search for domain names(i.e. iterate over all entries in DNS Cache).

GrigoriyMikhalkin commented 3 years ago

I can also create named sets via DNS Proxy(probably will unload controller to some extent). But still, i need to store associations to these named sets in DNS Cache(because set names are very limited, for example no longer than 16 chars). And then tie them to rules in CWNP Controller.

GrigoriyMikhalkin commented 3 years ago

Cilium uses miekg/dns, which, IMO, looks much simpler than glider.

Also, cilium blocks DNS requests in proxy. Would it be redundant in our case?

mwindower commented 3 years ago

So we can have architecture like this:

CWNP Controller <--- reads DNS entries from cache --- DNS Cache <--- writes DNS data to cache --- DNS Proxy

Where DNS Proxy is based on glider. It monitors and caches all DNS data in DNS Cache. And then CWNP controller, when it receives resource with toFQDN field, looks up entries for domain names in DNS Cache. One problem is with matchPatterns -- it looks like the only way in that case is to do a brute search for domain names(i.e. iterate over all entries in DNS Cache).

Cilium does the same: https://github.com/cilium/cilium/blob/641c0f9b3072a014c9541ecaa4e00a2b24c98d97/pkg/fqdn/cache.go#L425

Gerrit91 commented 2 years ago

Let's make an appoint for reviewing this one please. @majst01 Can you maybe schedule something in the next time when you think you have some time left? It would be so nice to finish this up...

majst01 commented 2 years ago

Let's make an appoint for reviewing this one please. @majst01 Can you maybe schedule something in the next time when you think you have some time left? It would be so nice to finish this up...

Sure, lets schedule for next week

majst01 commented 1 year ago

done with #82