diff options
Diffstat (limited to 'mds/DNS.txt')
-rw-r--r-- | mds/DNS.txt | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/mds/DNS.txt b/mds/DNS.txt new file mode 100644 index 0000000..d2bc173 --- /dev/null +++ b/mds/DNS.txt @@ -0,0 +1,243 @@ +== What to do with your DNS when ODoH’s Trust-Me-Bruh Model doesn’t work for you + +DNS. Domain Name System. + +We all use it. We all need it. But most people are still using it like +its the early 2000s. What do I mean by that? Ye good ole UDP on port 53. + +And your ISP will tell ya you don’t need to worry about your privacy +because they swear on boy scout honor that they don’t log your DNS +queries. Right …. + +It’s 2024. We have come a long way. We have DoH, DoT, ODoH, DNSCrypt and +more. + +We’re going to talk about all of these for a little bit and then finally +I’m going to share what I am doing right now. + +=== Problem Statement + +Plain jane DNS, i.e., sending your request using UDP without any sort of +encryption, has been the norm for almost ever. Even right now that is +what most people are doing. That might have been oh-so-cool in the 80s +but It doesn’t fly anymore. So we ended up with DoH and DoT. +DNS-over-HTTPS and DNS-over-TLS. They are both self-explanatory. Instead +of doing unencrypted requests over UDP, we do a TCP request using HTTPS +or TLS. So far so good. DoH and DoT are definitely improvements over +https://www.rfc-editor.org/rfc/rfc1035[RFC 1035] but let’s take a step +back and see what we are trying to defend against. Without a structure, +we are not doing much more than just magic granted to us by the flying +spaghetti monster. + +Let’s review our threat model.What are we trying to achieve here? What +are the threats and who are the threat actors? Who are we safeguarding +our DNS queries against? Men-in-the-middle? Our internet provider? The +authoritative DNS server that we use? + +*_Statement_*: We want to have a *_private_* and *_anonymous_* DNS +solution. That means: + +*_Requirement 001_*: + +* The DNS queries shall only be viewed by the authoritative DNS +server(We can up this requirement later by running our own authoritative +DNS server but for now we are going to stick with our current +requirement). + +This naturally means that your internet provider and other +men-in-the-middle are not allowed to snoop on what we are querying. + +*_Requirement 002_*: + +* The DNS queries shall be anonymous. This means the authoritative DNS +server that is getting our DNS queries shall not be able to identify the +source of the query. + +There is more than one way to ``identify'' the source of the query. We +only mean the source as in the IP address that made the DNS query. + +This second requirement is what ODoH is trying to solve. ODoH tries to +separate the identity of the source of the DNS query from the query +itself. ODoH stands for oblivous DoH. It add an ``oblivious'' proxy in +middle of the source of the DNS query and the server. This way the proxy +can send the queries in bulk for example to try to mask who sent what +when. I’m summarizing here but what ODoH is trying to do can be +summarized by this: + +* ODoH tries to separate the identity of the source of the query from +the query itself by adding a proxy in the middle + +Below you can see + +.... + --- [ Request encrypted with Target public key ] --> + +---------+ +-----------+ +-----------+ + | Client +-------------> Oblivious +-------------> Oblivious | + | <-------------+ Proxy <-------------+ Target | + +---------+ +-----------+ +-----------+ + <-- [ Response encrypted with symmetric key ] --- +.... + +https://datatracker.ietf.org/doc/rfc9230/[ripped straight from RFC 9230] + +The main problem with this sort of a solution is that there is always an +element of ``trust-me-bruh'' to the whole situation. + +* How can we trust that the proxy provider and the server are not +colluding? + +We could run our own oblivious proxy but then if it’s just you and your +friends using the proxy, then your proxy is not obfuscating much, is it +now? And then there is the ``oblivious'' aspect of the solution. How can +we enforce that? How can you verify that? + +.... +Trust Me Bruh. We don't Log anything ... +.... + +We have cryptography, We have zk. I think we can do better than just +blind trust. + +Objectively speaking, and I’m not accusing anyone of anything so it’s +just a hypothetical but if someone would give me some money and they +asked me to come up with a system which let’s them practically +monopolize access to DNS queries, I would propose ODoH. + +It has enough mumbo jumbo tech jargon(end-to-end-encrypted, …) to throw +off your average layman and lul them into a false sense of security and +privacy but it doesnt prevent the proxy and server provider from +colluding. After all the technnical jargon, you end up with ``it’s +safe'' and ``it’s private'' because ``you can trust us''. + +Now we can see that DoH, DoT and ODoH are all better than baseline DNS +queries over UDP without encryption but they can’t satisfy both of our +requirements. + +=== Solution + +Now let’s talk about the solution I at the time of writing this blog +post. + +DoH or DoT is good enough to satisfy `Requirement001` but they need +something a little extra to be able to satisfy `Requirement002`. + +For that, we use an anonymizing network like tor. DoT and DoH both work +over TCP so we can use any SOCKS5 proxy here that ends up being a Tor +proxy. What I mean is you can use a the Tor running on your host or you +can use `ssh -L` to use Tor running on a VPS. That way, your internet +proviedr can’t know you’re using Tor at all. With your DNS queries going +over Tor, we can satisfy `Requirement002`. Tor is not the only solution +here but I use Tor. There is more than one anonimyzing network out there +and there are protocols that do this also. + +Right now we have an outline in our head: + +* We need to only use TCP for DNS and send everything over a Tor SOCKS5 +proxy. +* we will be using DoT or DoH. This will be useful in two ways. One we +ensure we are using TCP for DNS which is what most SOCKS5 +implementations support(even though they should support UDP because it’s +SOCKS5 and not SOCKS4 but that’s another can of worms) + +There is more than one way to do this but I have decided to use +https://github.com/DNSCrypt/dnscrypt-proxy[dnscrypt-proxy]. We will not +be using dnscrypt for the dnscrypt protocol though you could elect to +use that as the underlying DNS protocol. `dnscrypt-proxy` lets’s us use +a SOCKS5 proxy through which the DNS queries will be sent. We will use a +Tor SOCKS5 proxy here. You can choose which protocols should be enabled +and which ones should be disabled. There are two points: + +* one, enable the tcp only option, since we dont want to use plain jane +UDP queries. +* two, I have asked `dnscrypt-proxy` to only use DNS servers that +support DNSSEC. + +I recommend going through all the available options in the +`dnscrypt-proxy.toml` file. It is one of those config files with +comments so it’s pretty sweet. There are quite a few useful options in +there that you might care about depending on your needs. + +==== Implementation + +Right now I run `dnscrypt-proxy` on a small alpine linux VM. I made it +fancier by running the VM on a tmpfs storage pool. Basically mine is +running entirely on RAM. I used to have `dnscrypt-proxy` running on a +raspberry pi and had my openwrt router forward DNS queries to that +raspberry pi. There is obviously no best solution here. Just pick one +that works for you. Here you can find the vagrantfile I use for the DNS +VM I use: + +[source,ruby] +---- +ENV['VAGRANT_DEFAULT_PROVIDER'] = 'libvirt' +Vagrant.require_version '>= 2.2.6' +Vagrant.configure('2') do |config| + config.vm.box = 'generic/alpine319' + config.vm.box_version = '4.3.12' + config.vm.box_check_update = false + config.vm.hostname = 'virt-dns' + + # ssh + config.ssh.insert_key = true + config.ssh.keep_alive = true + config.ssh.keys_only = true + + # timeouts + config.vm.boot_timeout = 300 + config.vm.graceful_halt_timeout = 60 + config.ssh.connect_timeout = 30 + + # shares + config.vm.synced_folder '.', '/vagrant', type: 'nfs', nfs_version: 4, nfs_udp: false + + config.vm.network :private_network, :ip => '192.168.121.93' , :libvirt__domain_name => 'devidns.local' + + config.vm.provider 'libvirt' do |libvirt| + libvirt.storage_pool_name = 'ramdisk' + libvirt.default_prefix = 'dns-' + libvirt.driver = 'kvm' + libvirt.memory = '256' + libvirt.cpus = 2 + libvirt.sound_type = nil + libvirt.qemuargs value: '-nographic' + libvirt.qemuargs value: '-nodefaults' + libvirt.qemuargs value: '-no-user-config' + libvirt.qemuargs value: '-serial' + libvirt.qemuargs value: 'pty' + libvirt.random model: 'random' + end + + config.vm.provision 'reqs', type: 'shell', name: 'reqs-install', inline: <<-SHELL + sudo apk update &&\ + sudo apk upgrade &&\ + sudo apk add tor dnscrypt-proxy privoxy tmux + SHELL + + config.vm.provision 'reqs-priv', type: 'shell', name: 'reqs-priv-install', privileged: true, inline: <<-SHELL + cp /vagrant/torrc /etc/tor/torrc + cp /vagrant/dnscrypt-proxy.toml /etc/dnscrypt-proxy/dnscrypt-proxy.toml + #cp /vagrant/config /etc/privoxy/config + rc-service tor start + sleep 1 + #rc-service privoxy start + #sleep 1 + rc-service dnscrypt-proxy start + SHELL +end +---- + +It’s pretty straightforward. We use an alpine linux VM as base. Make a +new interface on the VM with a static IP and have `dnscrypt-proxy` +receive DNS queries through that interface and IP only. I don’t change +the port number(53) because of certain applications(you know who you +are) refusing to accept port for a DNS server’s address. You could also +make it spicier by using `privoxy`. Maybe I make a post about that +later. + +timestamp:1708814484 + +version:1.0.0 + +https://blog.terminaldweller.com/rss/feed + +https://raw.githubusercontent.com/terminaldweller/blog/main/mds/DNS.md |