Tomato using 1.1.1.1 for PPPoE connect-on-demand

Discussion in 'Tomato Firmware' started by koitsu, Apr 3, 2018.

  1. koitsu

    koitsu Network Guru Member

    While digging through code last night, I came across this in rc/services.c (I was looking at kille72, but it doesn't matter):

    https://bitbucket.org/kille72/tomat...m&fileviewer=file-view-default#services.c-722

    Code:
    if (dns->count == 0) {
            // Put a pseudo DNS IP to trigger Connect On Demand
            if (nvram_match(strcat_r(wan_prefix, "_ppp_demand", tmp), "1")) {
                    switch (get_wanx_proto(wan_prefix)) {
                    case WP_PPPOE:
                    case WP_PPP3G:
                    case WP_PPTP:
                    case WP_L2TP:
                            dnslog(LOG_DEBUG, "*** dns_to_resolv: no servers for %s: put a pseudo DNS IP 1.1.1.1 to trigger Connect On Demand", wan_prefix);
                            fprintf(f, "nameserver 1.1.1.1\n");
                            break;
                    }
            }
    }
    
    Toastman firmware also does this, and certainly Shibby too, so it'll need to be improved there as well. With Toastman, I think it needs to be brought in to ARM, ARM7, RT-AC, and NRT; I've forgotten what all the different branches are at this point.

    This code is literally from the very original Tomato code from Jon Zarate: https://github.com/tomatofirmware/tomato/blob/tomato/release/src/router/rc/services.c#L306 -- there's no way he would have been able to predict what has happened today, so technically it's nobody's fault, other than Jon badly choosing an IP. :)

    Details:

    Starting as of a few days ago, 1.1.1.1 (and also 1.0.0.1) are legitimate public recursive DNS servers managed by CloudFlare alongside APNIC. They're part of 1.1.1.0/24 and 1.0.0.0/24. As such, probably shouldn't use 1.1.1.1 as an IP to trigger PPPoE/3G/PPTP/L2TP connect-on-demand capability.

    The idea here, best I can tell, was that since 1.1.1.1 is an IP address without a local route, that a DNS lookup done by a LAN client would induce dnsmasq issuing an outbound packet via WAN going "somewhere" (in this case, 1.1.1.1 -- which up until a few days ago went no where), thus triggering connect-on-demand. Once the PPPoE/etc. layers were established, related protocols would actually popular /etc/resolv.dnsmasq with proper nameservers (or set whatever the user chose).

    Also, it was discovered that 1.1.1.1 has "special meaning" at certain ISPs and is used internally on some Internet devices (AT&T is one, Orange (France) is another), which means for those setups connect-on-demand would possibly never get triggered on these ISPs (though I'm not sure what kind of WAN connection these services offer, so maybe not true).

    I'd suggest using 198.51.100.1 or 198.18.0.1 instead, and the code be commented to explain why (or just a comment with a reference to this post of mine). Some ISPs will drop/blackhole 198.51.100.0/24 or 198.18.0.0/15 at border routers and that's OK (the packet still goes out the WAN to trigger connect-on-demand), others will let it flow out onto the backbone where it's often dropped/blackholed. ARIN's IPv4 address space list is here (note the [11] note on the far right).

    The point is to bring up the WAN link. We don't want dnsmasq reattempting a DNS lookup for a record that will eventually hit a real recursive server -- that was never the intention. The intention was to have whatever the DNS lookup was go off into lala land/get thrown away, just enough to trigger bringing up the WAN link.
     
    Elfew and srouquette like this.
  2. AndreDVJ

    AndreDVJ LI Guru Member

    I'd use an IP as described in RFC5737 (e.g. 198.51.100.1) as per the following paragraph:
    More votes anyone? 1.1.1.1 is actually a legit routable IP address.
     
    maurer likes this.
  3. PetervdM

    PetervdM Network Guru Member

  4. koitsu

    koitsu Network Guru Member

    This in general is a good thing to be doing. I believe this is part of BCP 38. I was quite aware of this when I wrote this post, believe it or not -- it was constantly on my mind. I kept thinking of different networks that ISPs tend to filter at egress border routers thus wouldn't actually make it out onto the Internet.

    Some kind of packet must exit the WAN interface for connect-on-demand to be used. You don't want that packet to reach a real-world-used destination (especially if it's DNS, or a TCP-based protocol, because the software or stack will continue to retry it for some time).

    Using 1.1.1.1 means CloudFlare is going to see and get some DNS requests that they otherwise shouldn't (and that may include things like people's own domain name for LANs -- this is bad/disclosure of private network information. dnsmasq is semi-notorious for this, and it's the main reason I myself don't use it). Using something that's IANA reserved and not locally routed/assigned means it would work for most people except those filtering egress packets on the WAN interface that are for IANA reserved CIDRs.

    We're screwed if we do and screwed if we don't. I don't know how else to get connect-on-demand to work.

    BTW, to make it easier on folks, the IANA reserved CIDR list is as follows:

    Code:
    10.0.0.0/8
    100.64.0.0/10
    127.0.0.0/8
    169.254.0.0/16
    172.16.0.0/12
    192.0.0.0/24
    192.0.2.0/24
    192.88.99.0/24
    192.168.0.0/16
    198.18.0.0/15
    198.51.100.0/24
    203.0.113.0/24
    224.0.0.0/4
    
    If you have ideas, I'm all ears.
     
  5. PetervdM

    PetervdM Network Guru Member

    two ideas, actually.
    if the only reason for the dns query is to open the connection and we are not interested in the result, we can use any public address with a bogus port - fi 54.
    the other possibility is to query the wan gateway with the standard port. almost for sure that gateway won't run a dns server.
    i don't have access to a ppp connection, so i can't try.

    for the IANA reserved address list you may add:
    Code:
    0.0.0.0/8
    240.0.0.0/4
    255.255.255.255/32
     
  6. koitsu

    koitsu Network Guru Member

    You can't "query the WAN gateway": PPPoE/PPTP/L2TP has not negotiated yet. You don't know the remote end's IP address at this time.

    Using a "bogus port" isn't possible or feasible without using iptables to redirect (or rewrite) the traffic to a different destination port, which would be a temporary situation you'd have to undo (firewall-wise) later, which could be tricky timing-wise. libc resolvers only talk DNS via port 53 (read: you cannot use something like nameserver 1.1.1.1:54 in /etc/resolv.conf).

    Remember: the idea Tomato uses here is that dnsmasq is up and functional (though it has no Internet connectivity) -- DNS queries from LAN clients hit dnsmasq, which in turn punts the requests to 1.1.1.1, triggering connect-on-demand. Technically any kind of outbound NAT'd packet across the WAN interface should trigger connect-on-demand (ex. LAN client ICMP pinging 8.8.8.8), but Jon made the decision early on to ensure that DNS traffic also did it, hence the "bogus" 1.1.1.1 address, which at the time was not a legitimate (and recursive!) resolver.

    For sake of example, using 3.3.3.3 (that's in Amazon's space BTW) would accomplish the same task, and we know there's not a recursive DNS server there... as of this writing. ;-) That's why I'm discussing all of this. I'm trying to "think ahead" so that this subject doesn't have to get re-visited if someone was to go and put a recursive DNS server up on 3.3.3.3.

    I guess what I'm asking is: is there a publicly-routed IP address or netblock that is literally throwing away all traffic which could be safely used for this purpose? Someone asked exactly this on superuser.com. Apparently IPv6 has this (100::/64) but IPv4 does not: https://superuser.com/questions/698244/ip-address-that-is-the-equivalent-of-dev-null -- note that the top-voted answer basically equates to what I'm discussing here, and why I proposed use of some IP in 198.51.100.0/24 or 198.18.0.0/15 space.

    Off-topic, but as for your IANA reserved list additions:

    Readers should be aware that the script linked to uses iptables -d for the IP matching, which means what's being looked at is the destination address. That's what's being discussed below. It matters.

    240.0.0.0/4 is for multicast. This is actually used by several different companies, especially those offering IPTV service. My general advice is not to filter this unless you know definitively your ISP and service packages are not offering multicast-aware service. It's fine to add otherwise.

    0.0.0.0/8 has been debated for some time. It's technically a broadcast-esque address (or at least was used this way in older BSD days, IIRC). This subject comes up from time to time and there's really been no "definitive" answer. The best I was ever able to find was this, referencing several RFCs: https://superuser.com/questions/388...s-from-the-network-0-0-0-0-8-used-in-practice . Generally speaking Internet-bound packets should not be within 0.0.0.0 to 0.255.255.255 space, but because software treats 0.0.0.0 uniquely, I've always opted to not filter this.

    It should be noted that 0.0.0.0/8 (note the netmask) is different from 0.0.0.0/0. The latter is the default gateway placeholder. Also, in software nomenclature, a source address of 0.0.0.0 is treated uniquely to act as an INADDR_ANY binding.

    255.255.255.255/32 always surprises me when I see it. This is actually used by DHCP/BOOTP in DISCOVER phase; initial DHCP advertisements come from source address 0.0.0.0 port 68, with a destination address of 255.255.255.255 (broadcast) port 67. So unless you have preceding firewall rules allowing destination port 67 (or alternately source port 68) traffic, I imagine this would cause problems if using an ISP which offers IP via DHCP (which, as a matter of fact, I do). I also have always opted not to filter this. Reference (last 3 paragraphs, including the quoted): http://seclists.org/nanog/2016/Sep/501
     
    Last edited: Apr 4, 2018
  7. PetervdM

    PetervdM Network Guru Member

    if bogus port and/or wan gateway are not possible, i agree that an address in one of the test nets is the only way to go. i would prefer an address in the 198.51.100.0 range, the 198.18.0.0/15 range *could* be re-assigned in the future because of the number of addresses it holds
    for outgoing filtering in general: i suppose someone implementing it would have enough knowledge and means to test and debug it.
     
    koitsu likes this.
  8. koitsu

    koitsu Network Guru Member

    This may be something I ask the folks on NANOG (as much as that mailing list is something I read, *talking* on it is a whole other ball game). If there are folks who would know the answer to this, it would be them.

    I thought about how to ask the question and this is what I came up with: is there a known IPv4 address that's publicly routed (or part of a publicly routed network) that's also known to discard any/all packets sent to it?

    That is essentially what Jon chose with 1.1.1.1. It just so happens it's now an actual recursive resolver. *chuckle*

    Regardless, whatever IP address is chosen, I fully agree that if connect-on-demand is checked, somewhere in the GUI should tell the user something like "Note: wwhen the WAN link is down, DNS queries directed at the router from the LAN side will be sent to address 192.51.100.1 (to allow DNS queries to trigger connect-on-demand) until the WAN comes up." Without this, serious network administrators would have no idea what exception to add to their firewall to allow the feature to work.
     
  9. AndreDVJ

    AndreDVJ LI Guru Member

  10. Sean B.

    Sean B. LI Guru Member

    What about adding an nvram variable ( such as "demand_DNSIP" ) that is set with the WAN IP anytime the WAN interface comes up and does not get replaced with an empty or NULL value when the WAN goes down, so the only time it would be an empty variable would be the very first boot ( more if a WAN connection is never made, but then what's the point for connect-on-demand anyway? ). I don't really see any case where the first WAN connection would be connect-on-demand initiated. But to be safe, protect it with a conditional that would gracefully fail a connect-on-demand attempt if demand_DNSIP is empty. Alternatively, give the variable an initial IP in defaults.c that is most likely to be a decent backup. After the WAN goes up, connect-on-demand would result in either A: you're sending the DNS demand-connect query to, what will be, your own WAN IP upon reconnect. Or B: to someone who obtained your previous WAN IP and is unlikely to be a recursive DNS server themselves, as that is rather uncommon on a dynamic IP based connection.

    Even if the majority of people that use this end up with a different WAN IP upon reconnect, no single IP would be the target of every Tomato on-demand connect query. So it spreads the bad netiquette out in a non-intrusive fashion.

    **NOTE** The existing variable "wan_ipaddr" may work for this, but I don't remember if it stays populated upon WAN disconnect.
     
    Last edited: Apr 7, 2018
    Elfew likes this.
  11. Elfew

    Elfew Network Guru Member

  12. BikeHelmet

    BikeHelmet Addicted to LI Member

    Semi-related question to this very important thread deserving a bump.

    What Tomato firmware supports encrypted DNS? (Ex: From Google, OpenDNS, or CloudFlare) Shibby? Some others? I need to know for flashing/updating my RT-AC3200.
     
  13. koitsu

    koitsu Network Guru Member

    I think the most recent Toastman and Shibby, and definitely kille72, support DNSSEC if that's your thing. If you're wanting DNSCrypt, I'm not sure, other than knowing kille72 supports it.
     
  14. kille72

    kille72 LI Guru Member

    DNS over TLS built into FreshTomato will arrive in the near future. So far, you can install Stubby (DNSoTLS) from Entware or use DNSCrypt + DNSSEC.
     
    Last edited: Apr 24, 2018
    Onee-chan likes this.
  15. The Master

    The Master Network Guru Member

    What is "better" DNSCrypt + DNSSEC or DNS over TLS. What i read i think DNS over TLS is the Better Solution.
     
  16. kille72

    kille72 LI Guru Member

    I think DNS over TLS is more future-proof than DNScrypt when it comes to Tomato. Version 2.x of DNScrypt is not supported by Tomato.

    I use DNSoTLS (Cloudflare) myself and I'm very satisfied! Ping to the nearest servers is 3 ms! No DNS leaks.

    P.S. Sorry for spamming in wrong thread...
     
    Last edited: Apr 24, 2018
    Onee-chan and pharma like this.
  17. The Master

    The Master Network Guru Member

    THX. But kille you are teasing me :(. I hope you realease the new FW soon so the "Waiting PAIN" is over for me and my R7000 Router :D :D :D :D
     
    kille72 likes this.
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice