29

I have discovered that my ISP (verizon) is intercepting all DNS traffic on port 53.

Using iptables, I want to redirect all DNS lookup traffic to a specific IP and Port (5353). Any attempt for my computer to connect to another computer on port 53 should be redirected to 23.226.230.72:5353.

To verify the DNS server and port I'm trying to use, I have run this command.

~$ dig +short serverfault.com @23.226.230.72 -p5353
198.252.206.16

This is the iptables rule I'm trying to use.

iptables -t nat -A OUTPUT -p udp -m udp --dport 53 -j DNAT --to-destination 23.226.230.72:5353

After adding that rule, all DNS lookups are not found. Website pings return unknown host. Webpages say 'Server Not Found'.

~$ mtr serverfault.com
Failed to resolve host: Name or service not known

I want my DNS to lookups to be pulled from 23.226.230.72:5353. How can I make the iptables rule work?

EDIT

Demonstration of DNS (port 53) interception by my ISP. Trace output from dig to 23.226.230.72 via port 5353, and then port 53.

~$ dig +trace stackexchange.com @23.226.230.72 -p5353

; <<>> DiG 9.9.5-3-Ubuntu <<>> +trace stackexchange.com @23.226.230.72 -p5353
;; global options: +cmd
.           86395   IN  NS  ns7.opennic.glue.
.           86395   IN  NS  ns4.opennic.glue.
.           86395   IN  NS  ns3.opennic.glue.
.           86395   IN  NS  ns5.opennic.glue.
.           86395   IN  NS  ns2.opennic.glue.
.           86395   IN  NS  ns10.opennic.glue.
.           86395   IN  NS  ns1.opennic.glue.
.           86395   IN  NS  ns6.opennic.glue.
.           86395   IN  NS  ns8.opennic.glue.
dig: couldn't get address for 'ns8.opennic.glue': no more


~$ dig +trace stackexchange.com @23.226.230.72 -p53

; <<>> DiG 9.9.5-3-Ubuntu <<>> +trace stackexchange.com @23.226.230.72 -p53
;; global options: +cmd
.           7440    IN  NS  f.root-servers.net.
.           7440    IN  NS  d.root-servers.net.
.           7440    IN  NS  j.root-servers.net.
.           7440    IN  NS  i.root-servers.net.
.           7440    IN  NS  g.root-servers.net.
.           7440    IN  NS  k.root-servers.net.
.           7440    IN  NS  a.root-servers.net.
.           7440    IN  NS  h.root-servers.net.
.           7440    IN  NS  e.root-servers.net.
.           7440    IN  NS  m.root-servers.net.
.           7440    IN  NS  c.root-servers.net.
.           7440    IN  NS  b.root-servers.net.
.           7440    IN  NS  l.root-servers.net.
;; Received 239 bytes from 23.226.230.72#53(23.226.230.72) in 2948 ms

stackexchange.com.  215 IN  A   198.252.206.16
;; Received 62 bytes from 192.228.79.201#53(b.root-servers.net) in 116 ms

My current iptables. iptables-save

~# iptables-save
# Generated by iptables-save v1.4.21 on Tue Jul 15 23:06:52 2014
*mangle
:PREROUTING ACCEPT [79950528:41742899703]
:INPUT ACCEPT [78748282:41360159554]
:FORWARD ACCEPT [13:5427]
:OUTPUT ACCEPT [85455483:57472640071]
:POSTROUTING ACCEPT [85480442:57475512901]
-A POSTROUTING -o lxcbr0 -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
COMMIT
# Completed on Tue Jul 15 23:06:52 2014
# Generated by iptables-save v1.4.21 on Tue Jul 15 23:06:52 2014
*nat
:PREROUTING ACCEPT [71:18713]
:INPUT ACCEPT [7:474]
:OUTPUT ACCEPT [109:7855]
:POSTROUTING ACCEPT [109:7855]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -d 172.17.0.0/16 -j MASQUERADE
-A POSTROUTING -s 10.0.3.0/24 ! -d 10.0.3.0/24 -j MASQUERADE
COMMIT
# Completed on Tue Jul 15 23:06:52 2014
# Generated by iptables-save v1.4.21 on Tue Jul 15 23:06:52 2014
*filter
:INPUT ACCEPT [78748139:41360144354]
:FORWARD ACCEPT [13:5427]
:OUTPUT ACCEPT [85454926:57472600172]
:fail2ban-ssh - [0:0]
:fail2ban-vsftpd - [0:0]
-A INPUT -p tcp -m multiport --dports 21,20,990,989 -j fail2ban-vsftpd
-A INPUT -p tcp -m multiport --dports 22,6622 -j fail2ban-ssh
-A INPUT -i lxcbr0 -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -i lxcbr0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -i lxcbr0 -p tcp -m tcp --dport 67 -j ACCEPT
-A INPUT -i lxcbr0 -p udp -m udp --dport 67 -j ACCEPT
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A FORWARD -o lxcbr0 -j ACCEPT
-A FORWARD -i lxcbr0 -j ACCEPT
-A fail2ban-ssh -j RETURN
-A fail2ban-vsftpd -j RETURN
COMMIT
9
  • So you're trying to redirect all port 53 traffic to that IP (23.226.230.72) and Port (5353)?
    – tachomi
    Commented Jul 14, 2014 at 14:22
  • please post your iptables rules here
    – Nidal
    Commented Jul 14, 2014 at 14:26
  • @tachomi Correct
    – Rucent88
    Commented Jul 14, 2014 at 14:27
  • Or you could not use your ISP's DNS... Google's public DNS servers are 8.8.8.8 and 8.8.4.4
    – Creek
    Commented Jul 14, 2014 at 15:17
  • @Creek I think you misunderstand. My isp is intercepting all traffic through port 53. Even if I wanted to use google dns servers, I cannot access them.
    – Rucent88
    Commented Jul 14, 2014 at 15:36

5 Answers 5

18
+500

Perform all of these instructions as root (sudo).

Edit this file.

/etc/NetworkManager/NetworkManager.conf

Disable DnsMasq by commenting out the line dns=dnsmasq. Put a # in front of the line

#dns=dnsmasq

Restart your networking.

service network-manager restart

Add these iptable rules.

iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to 23.226.230.72:5353
iptables -t nat -A OUTPUT -p tcp --dport 53 -j DNAT --to 23.226.230.72:5353
1
  • 2
    This solution updates with the OS, and consumes zero resources, and is zero security risk, super easy setup with a boot script, and zero maintenance. The downside is it's not very flexible
    – Rucent88
    Commented Mar 6, 2016 at 18:03
2

Try this:

First you must enable the forwarding option in

/etc/sysctl.conf

Set to one the value of

net.ipv4.ip_forward = 1

Enable the changes

sysctl -p 

Save and run the following:

iptables -t nat -A PREROUTING -p tcp --sport 53 -j DNAT --to-destination 23.226.230.72:5353
iptables -t nat -A POSTROUTING -j MASQUERADE

If you could specify the in-interface (-i eth1) in PREROUTING or/and out-interfect (-o eth0) IN POSTROUTING could be useful.

NOTE: MASQUARADE line is necessary while this mask the destination IP with the main IP.

10
  • I put in sysctl net.ipv4.ip_forward=1 and the iptables rules. DNS is working, but it's still being intercepted by my isp. So that indicates to me that DNS is still being sent through port 53.
    – Rucent88
    Commented Jul 14, 2014 at 15:24
  • I changed your rule to udp, but I got the same results.
    – Rucent88
    Commented Jul 14, 2014 at 15:26
  • Could you please put the output of iptables-save? What I might is that your masking only the specified MASQUERADE all -- 10.0.3.0/24, so If you could disable that line and leave the -A POSTROUTING -j MASQUERADE one, could be helpful
    – tachomi
    Commented Jul 14, 2014 at 17:03
  • I added the information you requested
    – Rucent88
    Commented Jul 14, 2014 at 18:21
  • 2
    I believe it should be dport instead of sport
    – battman622
    Commented Apr 18, 2016 at 4:10
2

It looks as if what you are really after is to be in control of what happens with your DNS queries.

I'm not sure using iptables would be my preferred solution.

Have you thought about setting up a local DNS server which simply forwards your requests to the host and port you want? One example: using the bind9 forwarders option you can add a port to a forwarder.

Such a set-up is much easier to maintain and troubleshoot, and may be much more flexible. Consider the advantage of cacheing, or just consider the case in which your external DNS server is down. You can have multiple forwarders in your DNS configuration, but only one IP in iptables rules... .

There is a good overview of the setup of bind9 in a tutorial at digital ocean. Just add the port to the forwarders and you should be all set.

Bind9 doesn't consume much resources at all and is easily configured (or at least: easier than iptables :-) )

4
  • Ooh, and needless to say, in that setup, do not forget to set your device(s) to use your local, forwarding DNS server. Commented Jul 19, 2014 at 8:13
  • I did have a DNS server running, but it wasn't reliable (junk hardware). Keeping it security updated was a pain. It consumed more time, resources, electricity, and it finally kicked the bucket. If I had hundreds of computers behind a corporate network, then I agree that the DNS server would be a good idea. But I'm just one person with a laptop. A couple iptable rules should be the easiest and lowest resource.
    – Rucent88
    Commented Jul 19, 2014 at 8:32
  • Just add one on your laptop, it consumes almost no resources and it will get updated with your main os (assuming you use distribution packages), and make it listen on localhost. Almost zero security risk. Commented Jul 19, 2014 at 8:53
  • Indeed, IMHO, it's better way to maintain the scenario in 99% of the cases. The only 1% which doesn't apply, is when you're configuring a Captive Portal system, but that's another story.
    – ivanleoncz
    Commented Feb 6, 2018 at 18:07
1

Try this:

iptables -t nat -A OUTPUT -p tcp --dport 53 -j DNAT --to 23.226.230.72:5353;

iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to 23.226.230.72:5353;

iptables -t nat -A POSTROUTING -j MASQUERADE

It means:
1) Any local user contacting out world to port tcp 53 send to 23.226.230.72 at port 5353.
2) Same as 1 but for udp
3) Set the source information on the outgoing packet as coming from us.

1
iptables -t nat -A PREROUTING -p tcp --dport 53 -j DNAT --to XX.XX.XX.XX:5353
iptables -t nat -A PREROUTING -p udp  --dport 53 -j DNAT --to XX.XX.XX.XX:5353
iptables -t nat -A POSTROUTING -j MASQUERADE
5
  • 1
    The fact that this answer doesn’t mention “5353” makes me believe that it’s automatically wrong. Commented Apr 8, 2019 at 4:34
  • corrected.........
    – Zibri
    Commented Apr 9, 2019 at 8:06
  • OK, I’m taking a second look at your answer.  It seems to be very similar to tachomi’s answer except (1) you have changed sport to dport (this was, apparently, an error in tachomi’s answer that battman622 pointed out three years ago, (2) you added a line (command) for udp (this is a legitimate improvement to tachomi’s answer, but one that was already mentioned in a comment … (Cont’d) Commented Apr 11, 2019 at 2:57
  • (Cont’d) … and several other answers), and (3) you replaced --to-destination with --to.  The man page does not say that --to and --to-destination are equivalent; on the contrary, it says that --to is used with the NETMAP target (as opposed to the DNAT target) and that its argument does not include a port number.  (Although I notice that a couple of other answers use --to the way you did.)  Are you sure that --to works the way you use it (with a port number, with the DNAT target)? … (Cont’d) Commented Apr 11, 2019 at 2:57
  • (Cont’d) …  (If so, perhaps somebody should submit a change request to the maintainer(s) of the man pages.) Is --to better than  --to-destination in any way other than brevity? Commented Apr 11, 2019 at 2:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .