[solved] pass captive portals while using a sys-dns (or a whonix-ws)

I’m using a sys-dns as described here and it works fine in most situations.

However, in hotel wifis or other wifis which enforce a captive portal I have trouble reaching the captive portal.

[user@sys-dns]~% cat /etc/dnscrypt-proxy/captive-portals.txt 
###########################################
#        Captive portal test names        #
###########################################
## [stuff]

captiveportal.somehotel.org		107.201.79.65
## [stuff]

captive.apple.com               17.253.109.201, 17.253.113.202
## [stuff]
[root@sys-dns]~% ss -tunlp
Netid              State                Recv-Q               Send-Q                             Local Address:Port                             Peer Address:Port              Process
udp                UNCONN               0                    0                                      127.0.0.1:53                                    0.0.0.0:*                  users:(("dnscrypt-proxy",pid=566,fd=7))
tcp                LISTEN               0                    4096                                   127.0.0.1:53                                    0.0.0.0:*                  users:(("dnscrypt-proxy",pid=566,fd=8))
[root@sys-dns]~% iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
PR-QBS     all  --  anywhere             anywhere
PR-QBS-SERVICES  all  --  anywhere             anywhere

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
MASQUERADE  all  --  anywhere             anywhere

Chain PR-QBS (1 references)
target     prot opt source               destination

###
## output of iptables stops at this point
## iptables does not finish but hangs
###

At this point of time there is no connectivity because I haven’t authenticated at the captive portal yet. dnscrypt-proxy is listening for a minute or maybe two, then shuts down.

However, since iptables does not redirect dns-requests, a web-redirect from http://1.1.1.1 to http://captiveportal.somehotel.org does not finish as the dns-request for captiveportal.somehotel.org is not resolved.

From my point of view this is not a dnscrypt-proxy issue, it might be an iptables-issue, but I suspect it to be a qubes-issue or the way Qubes implement iptables-rules.

Anyone an idea why iptables does not DNAT/redirect my dns-requests at that point of time?

There’s nothing in that (partial) ruleset to perform any redirection.
I assume that the phantom PR-QBS chain redirects UDP traffic for
10.139.1.1/2 to localhost.

Depending on what sort of portal you are dealing with, and how the
“capture” is implemented, it’s possible that the portal never sees the
Dnscrypt traffic to redirect it.

You’d do better to keep a clear disposable attached to sys-net that you can
use to trigger and register at the portal.

That’s plan B.

Without connectivity dnscrypt-proxy still resolves the hard-coded names in /etc/dnscrypt-proxy/captive-portals.txt.

[user@sys-dns]~% dig neverssl.com @127.0.0.1 +short         
[user@sys-dns]~% dig captiveportal.somehotel.org @127.0.0.1 +short         
107.201.79.65

It is not obvious to me why the kernel does not parse the iptables rules. Or why iptables -L -t nat hangs while the sys-dns qube does not have internet connectivity. The sys-dns qube has uplink and downlink connectivity, even sys-net is connected with it’s uplink (as checked with ip -br a).

That reads like iptables is preforming a reverse lookup for 127.0.0.1(?). And since it does not get an answer it hangs. The article suggests to use iptables -vnL -t nat instead.

I see no reason to think that the kernel isn’t parsing the rules.
The problem is more likely that the portals are blocking on a DNS
redirect, and because you are using Dnscrypt, the portal never sees a
DNS request.(By default traffic is encrypted to port 443)
I don’t know what the content of your rules is, of course.

As you are effectively providing hosts entries for those test addresses,
they will resolve regardless of the state of your network connection.

What you describe as “plan B” is a standard plan A - it’s the equivalent
of Tails providing a clear browser for just such use.

1 Like

Requesting http://1.1.1.1 yields a webserver’s response containing a 302 or some javascript redirect to http://captiveportal.somehotel.org/blafoo or https://captiveportal.somehotel.org/blafoo. Looks like an intercepting transparent webproxy.

You are correct, requesting http://neverssl.com can’t work unless I hard-code this domain name in captive-portals.txt.

However, a dig captiveportal.somehotel.org +short on an uplink qube (sys-firewall, AppVMs) doesn’t work / times out. That’s why I believe the iptables DNAT rule (as described here) doesn’t work. The next time I have to deal with a captive portal I will look into that again.

Thanks, you got a point there.

I shouldn’t call it redirect, more precisely it is DNAT-ing the dns-requests.

https://tails.boum.org/doc/anonymous_internet/unsafe_browser/index.de.html

As this is the standard plan A and doesn’t require to update /etc/dnscrypt-proxy/captive-portals.txt in sys-dns’ template with an entry for each hotel I spare myself the trouble with iptables and go with that solution. And it works for whonix-ws, too. Thanks, @unman.