Recently we had a new starter on our team (yay!) and I was helping him get set up with VPN access and lab access. Now our setup is somewhat intricate: you use an OpenConnect VPN to get to the company, and then you need an extra step to get to the isolated lab network. There are certain DNS names that only resolve within the company, and then there are DNS names that resolve only within the lab.
My connection strategy looks like this: I have Ubuntu on my laptop, I connect to the VPN with a terrifying openconnect
commandline, and then I do sshuttle --dns -r lab-gateway.corporation.com LAB_IPS/SUBNET
. This all works, I can access corporate DNS, lab DNS, corporate IPs and lab IPs.
Our intrepid new starter set up Fedora on his laptop, connected to the corporate VPN with NetworkManager, and then attempted to get to the lab network with sshuttle. However, he could not resolve lab DNS through the browser. He could resolve DNS through tools like dig
or nslookup
.
A bit of monkeying around with tcpdump
and watching the output of sshuttle -v
and we realised that DNS requests from the browser simply weren’t hitting sshuttle
‘s DNS redirection.
Eventually it clicked: while sshuttle
intercepts and proxies requests that go to servers in resolv.conf
, systemd provides a different interface for making DNS queries. We could reproduce the issue by asking systemd-resolve
or resolvectl
to resolve a name inside the lab network: they failed to resolve the name, and no traffic hit sshuttle
. If you do strace resolvectl query google.com
, you can see that it does the query over dbus, rather than by sending a query to something listed in resolv.conf
.
The dbus query goes to systemd-resolved
, and systemd-resolved
queries its own list of nameservers. To resolve this, we need to tell sshuttle to also intercept and proxy DNS requests that would go to DNS servers that systemd-resolved
knows about for the VPN. Assuming your VPN is managed by NetworkManager and the interface is called vpn0
, you can do something like this:
sshuttle -r lab-gateway.corporation.com LAB_IPS/SUBNET -v --dns --ns-hosts $(resolvectl dns vpn0 | awk '{print $4","$5}')
With that, sshuttle captures and redirects DNS queries sent to both:
- nameservers listed in
resolv.conf
– so it will capture the 127.0.0.53 stub resolver used by regular programs; and - queries that
systemd-resolved
sends directly to the nameservers from the VPN – so it will capture requests that come over dbus.
This seems to resolve my coworker’s issue!