Can I get dnsmasq to drop/reject/redirect any address queries except one?

7,438

Solution 1

Sure! Redirect all name resolutions to one address with the command:

address=/#/10.0.0.101

That is the entry required in the /etc/dnsmasq.conf file. Which I recommend using as that will enforce such configuration if the server is reboot for any reason.

On the command line, the option is called:

-A, --address=/<domain>[/<domain>...]/[<ipaddr>]  

A copy of the dnsmasq manual for address= is below.

However, even if it may seem reasonable to set -i vlan (to the expected interface to be used) and -a 10.6.66.1 (to the address in which it is expected that dnsmasq will listen for DNS resolution). Do not do that!.

Allow dnsmasq to bind in wildcard mode to any and all the server addresses on port 53. That way any request to the server about DNS resolution will be answered by dnsmasq.

The three modes are "wildcard", "bind-interfaces" and "bind-dynamic".
In "wildcard" mode, dnsmasq binds the wildcard IP address (0.0.0.0 or ::). This allows it to receive all the packets sent to the server on the relevant port. Access control (--interface, --except-interface, --listen-address, etc) is implemented by dnsmasq: it queries the kernel to determine the interface on which a packet was received and the address to which it was sent, and applies the configured rules. Wildcard mode is the default if neither of the other modes are specified.

Use port 53 (as external clients will expect that by default):

port=53   # It is set to be 53 by default, not really needed.

Turn off (and disallow) both avahi-dns and systemd.resolved

Make sure that no other program/service is listening on ports 53 or 5353.

$ netstat -pantu | grep ':53'

Also set this options to enforce that names like mylocaldomain (no dots) are resolved with an error (NXDOMAIN) by the dnsmasq DNS resolver and that (some) name resolutions are not forwarded to any other server:

# Never forward plain names (without a dot or domain part)
domain-needed
# Never forward addresses in the non-routed address spaces.
bogus-priv

Ensure that any server set in /etc/resolv.conf is not used:

no-resolv
no-poll

All the above will configure the DNS side of dnsmasq to resolve all domains to one simple address. It is still possible to add any other name to resolve other needed addresses by including it in the /etc/hosts file, like

127.0.0.1
10.0.3.101   linum

This last address should be the address to the web-server for the survey.
The initial address above (10.0.0.101) should be the error page that explain what to do to access the survey page.

But that is not all. You also need to configure the DHCP server to supply a nameserver option with the address of the dnsmasq DNS resolver (d not use option number 5, it is obsolete (and should have been for more than 20 years)):

dhcp-option=6,10.0.0.101

Plus all the other needed configurations for the DHCP part of dnsmasq.

That will allow a computer (tablet or phone also) to get a DHCP given address with a defined DNS server. All protocol compliant computers will follow such configured options and be unable to resolve any other address.

However, it is also possible that a device may try to access directly a IP number (no DNS resolution requested). That must be avoided using IPFilter configuration on the router that serve the local network.


From man dnsmasq:

-A, --address=/[/...]/[]
Specify an IP address to return for any host in the given domains. Queries in the domains are never forwarded and always replied to with the specified IP address which may be IPv4 or IPv6. To give both IPv4 and IPv6 addresses for a domain, use repeated -A flags. To include multiple IP addresses for a single query, use --addn- hosts= instead. Note that /etc/hosts and DHCP leases override this for individual names. A common use of this is to redirect the entire doubleclick.net domain to some friendly local web server to avoid banner ads. The domain specification works in the same was as for --server, with the additional facility that /#/ matches any domain. Thus --address=/#/1.2.3.4 will always return 1.2.3.4 for any query not answered from /etc/hosts or DHCP and not sent to an upstream nameserver by a more specific --server directive. As for --server, one or more domains with no address returns a no-such-domain answer, so --address=/example.com/ is equivalent to --server=/example.com/ and returns NXDOMAIN for example.com and all its subdomains.

Also read:

Add forged DNS entries
Bind configuration to resolve all queries to only one address

Solution 2

First I would focus in the solution working normally with the client writing a simple name URL as http://lime to make debugging easier.

As you might not need to provide Internet access, you might not need entirely to implement a captive portal, as you will eventually answer any DNS answer that you give will point out to your page, with dnsmasq.

So the easiest way is in your web server, to create the intended vhost, and the default listening socket (*) redirecting any request to that vhost.

However, and it is a big however, Androids and iOS devices are a bit adamant on getting access to some URLs to think they are connected. Nonetheless, I would place those URLs on your site, and be done with it.

Share:
7,438

Related videos on Youtube

r0berts
Author by

r0berts

I am a hobbyist in statistical programming and my main field is psychological medicine. I like the StackExchange community. What else - oh, yes, I am a linux fan and most computers I have run linux on them - Manjaro or Debian.

Updated on September 18, 2022

Comments

  • r0berts
    r0berts almost 2 years

    I am setting up a local survey system. The linux laptop will run limesurvey (on a typical LAMP stack) and will be accessible by 5 tablets given out to conference participants. Tablets are no problem as they would be pre-configured with survey loaded. I would like however to allow the conference participants to access the survey link from their mobile phones too. What I would plan to do is this:

    1. Laptop serves as access point. DNSMASQ gives out IPs after they join the AP. I would give them a simple local address (e.g. http://lime) to access the survey interface and this should be possible because DNSMASQ will function as their DNS server - so it will know how to resolve lime.

    2. I would like to deal with client errors swiftly - e.g. they, after joining the AP, type in a different address by accident (or just want to go on internet e.g. to google.com) - I would like DNSMASQ to immediately return an error, preferably with a redirect to a custom error page giving them the correct link.

    3. Edit: I looked into this; likely I will have to make a captive portal type solution. I still would like the simplest possible way to display the splash page - with survey(s) listed and drop/redirect all other requests to the splash page. I do not need authentication as no internet is going to be offered through this connection; authentication would be just extra clicks in this case but I want people to have access to the survey with no hassle.

    Would this be possible? Would there be better ways how to execute this plan?

  • r0berts
    r0berts about 6 years
    Thanks, this is very helpful. sorry I didn't quite understand client writing name in a portal page or somewhere else? And am I understanding it right, I might implement all of this with dnsmasq and Apache without need to fiddle with firewall rules?
  • Rui F Ribeiro
    Rui F Ribeiro about 6 years
    i rewrote partially the answer, is it intelligible now?
  • r0berts
    r0berts about 6 years
    Thanks Rui, it is intelligible; I was away for a week and now I am back and resuming checking. I will try to implement this over tomorrow, I might ask some further questions.
  • r0berts
    r0berts almost 6 years
    \@Rui would you happen to have a working apache httpd.conf file with redirection rules implemented for andriod and ios devices? Something like that would be much appreciated.
  • r0berts
    r0berts almost 6 years
    at @Isaac This works rather well. I am getting captive portal appear in later Android versions. I am a bit unclear to myself about server in dnsmasq.conf - probably it should be 10.0.0.1. I have implemented several rewrite rules and they seem to work nicely - the only thing is when client requests https page. The rule RewriteCond %{HTTPS} =on RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [L,R=301] does not seem to work - I get ERR_CONNECTION_REFUSED
  • done
    done almost 6 years
    @roberts The server option is the upstream server (like 8.8.8.8) that dnsmasq will use to resolve external names (not needed for the local portal of the original question). As the RewriteCond is an Apache server option it is not part of a dnsmasq answer. You may ask a new question.
  • r0berts
    r0berts almost 6 years
    Thanks, yes, I am glad you confirmed about server. I will formulate another question about things still unclear. But mostly it is working
  • Rui F Ribeiro
    Rui F Ribeiro almost 6 years