2

I have my iptables set up to drop everything by default in the INPUT, OUTPUT, and FORWARD rulebooks. But I need to allow connections through port 80 (HTTP) and all incoming TCP/UDP requests on port 53 (DNS). I have the following setup:

Chain INPUT (policy DROP)
target      prot opt source            destination 
ACCEPT      tcp  --  anywhere          anywhere           tcp dpt:http
ACCEPT      udp  --  anywhere          anywhere           udp dpt:http  
ACCEPT      udp  --  anywhere          anywhere           udp dpt:domain
ACCEPT      tcp  --  anywhere          anywhere           tcp dpt:domain

Chain FORWARD (policy DROP)
target      prot opt source            destination 

Chain OUTPUT (policy DROP)
target      prot opt source            destination 
ACCEPT      udp  --  anywhere          anywhere           udp dpt:http
ACCEPT      tcp  --  anywhere          anywhere           tcp dpt:http  
ACCEPT      tcp  --  anywhere          anywhere           tcp dpt:domain
ACCEPT      udp  --  anywhere          anywhere           udp dpt:domain

However, when I try and run sudo apt-get install apache2, the package is found, but it then hangs on actually downloading the package. Through my research, apt-get only needs HTTP and DNS ports to work in most cases. Am I missing anything? I tried to reference this post but to no avail.

Err:1 http://us.archive.ubuntu.com/ubuntu xenial/main amd64 libapr1 amd64 1.5.2-3
  Temporary failure resolving ‘us.archive.ubuntu.com’
Err:2 http://us.archive.ubuntu.com/ubuntu xenial/main amd64 libaprutil1 amd64 1.5.4-1build1
  Temporary failure resolving ‘us.archive.ubuntu.com’
0% [Connecting to us.archive.ubuntu.com]

System Information:
Distributor ID: Ubuntu
Description: Ubuntu 16.04.3 LTS
Release: 16.04
Codename: xenial


Update: Solution Doesn't Work

I followed tomasz's answer below again, but it did not work. apt-get is still stuck downloading like in the example above (e.g. apache2) (i.e. no change). Here is my new iptables that I tried used:

Chain INPUT (policy DROP)
target      prot opt source            destination 
ACCEPT      all  --  anywhere          anywhere           state RELATED,ESTABLISHED

Chain FORWARD (policy DROP)
target      prot opt source            destination 

Chain OUTPUT (policy DROP)
target      prot opt source            destination 
ACCEPT      tcp  --  anywhere          anywhere           tcp dpt:http state NEW,RELATED,ESTABLISHED
ACCEPT      tcp  --  anywhere          anywhere           tcp dpt:domain state NEW,RELATED,ESTABLISHED
ACCEPT      udp  --  anywhere          anywhere           udp dpt:domain state NEW,RELATED,ESTABLISHED

I tried versions in the OUTPUT rulebook with and without the state information to no success.

Code Doggo
  • 121
  • 1
  • 5
  • What does your `/etc/resolv.conf` show? I'm seeing errors in name resolution, which usually means that the DNS server that you're accessing isn't working for some reason. – ErikF Mar 21 '18 at 00:46
  • Include the contents of your `/etc/resolv.conf` file as an edit to this question. The domain name resolution errors suggest that your DNS may be misconfigured. I replicated your `iptables` rules locally in a container and was able to get updates without issue, and I have DNS set to use 8.8.8.8 or 8.8.4.4 (Google DNS) directly; this suggests, therefore that *your* environment doesn't have a proper DNS setup. – Thomas Ward Mar 26 '18 at 19:15

3 Answers3

2

I don't know why you need INPUT open on 53 and 80, but if that's for receiving responses of DNS and HTTP, then that's wrong. This is done by the following line:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 

(Just as in this answer to the post you mention.)

  • Why is that wrong? I send out DNS and HTTP responses (OUTPUT), but I need to receive a response back (INPUT) (e.g. a resolved DNS and HTTP data). INPUT and OUTPUT go hand-in-hand, I thought? – Code Doggo Mar 20 '18 at 21:33
  • 1
    @DanHoynoski If you get an HTTP response then not the destination but the source port is 80/443. Changing that would make your system completely open to anyone who uses that source port. You want a stateful firewall (i.e. conntrack). – Hauke Laging Mar 20 '18 at 21:36
  • @DanHoynoski No, they don't. The numbers you're sticking to are the standard server ports. Not the client ports. These are high above 1000 and random. See `netstat -t` on a working client machine. –  Mar 20 '18 at 21:36
  • @DanHoynoski https://wiki.centos.org/HowTos/Network/IPTables#head-724ed81dbcd2b82b5fd3f648142796f3ce60c730 –  Mar 20 '18 at 21:42
  • @DanHoynoski this is why you need the `ESTABLISHED,RELATED` state tracker bits, because it'll allow responses back for traffic related to the connections you've already established outbound. It's critical to have that `ESTABLISHED,RELATED` state matching. – Thomas Ward Mar 20 '18 at 21:49
  • @tomasz I tried this line, but it did not work. Take a look at my update above. – Code Doggo Mar 20 '18 at 23:22
  • @ThomasWard After reading your comment and looking into it myself, I completely understand, but even after adding the appropriate state information (e.g. tomasz's answer), I still have no change; nothing is getting through. Take a look at my update in my answer. – Code Doggo Mar 20 '18 at 23:29
  • @DanHoynoski Have you tried to test theses services (DNS, HTTP) with some other tools? Eg. a browser for HTTP and `dig` for DNS? If you can, you might test `apt` with INPUT and OUTPUT set to default with ACCEPT. Have you done anything with the other tables (raw, security)? Take a look at the counters with `iptables -L -v`. –  Mar 21 '18 at 08:36
1

I've dug into the specifics of this with a test system.

I was able to properly configure iptables with the following ruleset and get apt-get to go outbound properly:

Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED

Chain FORWARD (policy DROP)
target     prot opt source               destination         

Chain OUTPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 state NEW,RELATED,ESTABLISHED
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:53 state NEW,RELATED,ESTABLISHED
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:53 state NEW,RELATED,ESTABLISHED

This mirrors your latest configuration that you stated above. I am able to get apt-get to work properly, and to also make DNS queries without issue.

However, it's of importance to note that your system is having issues resolving the hostnames to IP addresses, and is giving you resolution errors.

Make sure that your /etc/resolv.conf is properly configured, and contains at the bare minimum something like this:

nameserver 8.8.8.8
nameserver 8.8.4.4

With an /etc/resolv.conf set up this way, with the same iptables rulesets you have in place, I am able to, without issue, reach out and get proper DNS resolution on my Internet-facing systems and within my own LAN subnets which can go out to the Internet from inside the network.

It sounds more to me like your /etc/resolv.conf is not set up correctly, and the misconfiguration is resulting in your system failing to configure DNS properly.

Thomas Ward
  • 2,600
  • 2
  • 18
  • 31
1

Hi guys after breaking my poor head on this issue and goingthough user147505's answer 100's of times i finally figured out why it didnt work for me this was my setup before:-

root@myserver:~# iptables -L --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:3652
2    ACCEPT     udp  --  anywhere             anywhere             udp dpt:51234
3    DROP       icmp --  anywhere             anywhere
4    DROP       all  --  anywhere             anywhere
5    ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     all  --  anywhere             anywhere
2    ACCEPT     all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination

AS you can see above the "iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT" Rule was added after the drop all traffic rule "iptables -A INPUT -j DROP " Because of this apt update did not work

so finally all i did was switch them like below and everything then worked amazingly :-

num  target     prot opt source               destination
1    ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:3652
2    ACCEPT     udp  --  anywhere             anywhere             udp dpt:51234
3    DROP       icmp --  anywhere             anywhere
4    ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
5    DROP       all  --  anywhere             anywhere

Guess i learned something about iptables, hopefully will take a course later on to understand this jaba huba

user
  • 11
  • 1
  • Why do you have a "drop all traffic rule", that's what the policy is for, and then you won't have problems with it coming too soon in your ruleset. – Henrik supports the community Aug 12 '21 at 15:01
  • @henrik-supports-the-community, oh that makes sense lol – user Aug 13 '21 at 22:03
  • I like to use an "ACCEPT" policy and put a DROP or REJECT for all traffic at the end of my list. For me it's just easier to see what is happening in my file, but Henrik's comment is a good one. – Patrick Taylor Aug 15 '21 at 19:38