0

I´m trying to block all traffic using iptables, but I have some exceptions:

  • DNS
  • my own server (I'm only using port 80)
  • Teamviewer (port 5938)
  • port 5555 to allow adb connections

At the moment I have these lines of code, but it is not working as I need:

// Allow my own server - this seems to work
iptables -A INPUT -s 1.1.1.1 -j ACCEPT
iptables -A OUTPUT -d 1.1.1.1 -j ACCEPT

// Allow DNS requests - dont know if it´s correct
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT

// Allow Teamviewer - same as above - dont know if it´s correct
iptables -A INPUT -p tcp --dport 5938 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 5938 -j ACCEPT
iptables -A OUTPUT -p udp --dport 5938 -j ACCEPT
iptables -A INPUT -p udp --dport 5938 -j ACCEPT

// Allow ADB - same as above - dont know if it´s correct
iptables -A INPUT -p tcp --dport 5555 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 5555 -j ACCEPT
iptables -A OUTPUT -p udp --dport 5555 -j ACCEPT
iptables -A INPUT -p udp --dport 5555 -j ACCEPT

// Block all other requests
iptables -P INPUT DROP
iptables -P OUTPUT DROP

Teamviewer won't connect, nor the name resolution works, adb doesn't connect either. There is something wrong there, don't really know what. Only thing working is the connection to my own server if I hardcode the domain at /etc/hosts.

Can one of the iptables gurus here help me out?

5
  • Can't you use firewalld instead?
    – Ezwig
    Commented Jul 16, 2018 at 12:25
  • No, I think not. Im doing this on android devices. Commented Jul 16, 2018 at 12:41
  • You should anyway use stateful rules to avoid redundent rules and avoid security issues. Take a look in any of these.
    – A.B
    Commented Jul 16, 2018 at 13:06
  • DNS uses UDP if the answer fits into a single UDP package, and TCP for longer answers. Modern cloud services and Content Delivery Networks may sometimes have a large number of DNS records associated with a single name. Use of DNSSEC can also make DNS query answers longer.
    – telcoM
    Commented Jun 17, 2021 at 5:15
  • Also, your DNS query is transmitted from some local source port number X (where X > 1023 and will vary) to remote destination port 53. The response must come from remote source port 53 to local destination port X. So the iptables -A INPUT -p udp --dport 53 -j ACCEPT is wrong, it should use --sport instead of --dport and that rule should apply to incoming packets from configured DNS nameservers only. But using stateful rules as A.B mentioned would be better (more secure).
    – telcoM
    Commented Jun 17, 2021 at 5:19

2 Answers 2

0

What isn't working? Actually, the first iptable entry would allow all traffic tcp/udp if I'm right. So the other ACEs wont hit either. If you only want HTTP traffic you should allow only TCP port 80.

IPtables are working from top to down. Your server got the IP address 1.1.1.1 and all packets will get a source of 1.1.1.1. Otherwise all incoming traffic got the source x.x.x.x and destination 1.1.1.1 so your first two entries will match all traffic. For your needs you should configure it without the first two rules. DNS traffic will get allowed with this:

iptables -A OUTPUT -p udp --sport 1024:65535 --dport 53 -j ACCEPT

HTTP / HTTPS traffic for your server you should set with:

iptables -A OUTPUT -p tcp --sport 1024:65535 -m multiport --dports 80,443 -j ACCEPT

Teamviewer is priority to get an TCP connection through 5938 so it should look like that:

iptables -A OUTPUT -o eth0 -p tcp --dport 5938 -m state --state NEW -j ACCEPT

For ADB I'm not sure because never touched it. But if it is an TCP stream you should make:

iptables -A OUTPUT -p tcp --dport 5555 -j ACCEPT
3
  • Teamviewer wont connect, nor the name resolution works, adb doesnt connect either. There is something wrong there, dont really know what. Only thing working is the connection to my own server if I hardcode the domain at /etc/hosts. Commented Jul 16, 2018 at 12:40
  • 1
    You appear to have two different accounts with the same name, "Scoobithepirate". I'd suggest that you log in as one and merge the other so that you can easily edit your own posts. Commented Jul 16, 2018 at 13:04
  • No, with your rules all traffic is allowed. Commented Jul 18, 2018 at 15:18
0

You are correctly allowing outbound traffic, but you are blocking reply packets because you confuse source ports with destination ports.

When you connect to a service on a remote system, you will usually open a socket with the destination port of that service, and the source port left undefined, which means the kernel will randomly assign a source port for you. The answers from the remote service will then be sent back in a network packet that has your source port as the destination port, and your destination port as the source port. However, your rules use the service destination port as the destination port on return traffic, too, which won't match the actual traffic and therefore won't work.

While you could theoretically use --sport to match the source port on return traffic, I wouldn't recommend that. Doing so will allow anyone to send traffic to any service on your server, as long as they make sure to use port 53 as the source port (or any of the other services you left open).

Instead, I would recommend you use the connection tracking module:

iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

explanation:

  • -m conntrack: tell iptables to load the conntrack module, which tracks the state of known connections
  • --ctstate RELATED,ESTABLISHED: match only on packets that are sent as part of a known network connection (ESTABLISHED) or that create a new but expected connection (RELATED). RELATED is useful for things like FTP which use more than one network connection; I don't think it is relevant for the protocols that you're using, so you might drop it if you want (but then I'm also not 100% sure, so...)

Once you added this rule, you only need to worry about adding rules for the initial connection:

iptables -A INPUT -m conntrack --ctstate NEW -p tcp --dport 5938 -j ACCEPT

(repeat for all protocols you want to allow)

Note that you can use conntrack on the OUTPUT chain, too, if you want to block outgoing traffic.

Finally, note that there is an INVALID state as well which you can match on. That one will trigger when a packet arrives that claims to be part of a network connection, but for which iptables can't find any state. This may be because the state table ran out of memory, or it may be because an attacker is trying to bypass your firewall. You probably want to log something and drop the packet.

You must log in to answer this question.

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