Linux – Unable to make outbound SNMP connections when IPTables is enabled

centosiptableslinuxsnmp

I have a bunch of windows servers configured with the windows SNMP agent. Each server has four IP addresses and SNMP listens on all of them.

There is something very odd with my monitoring server (which is Centos 5.5 32 bit with net-snmp 5.3.2.2). If I have iptables turned off then I have no problems performing snmp queries on any IP address on any of these servers.

If I turn on IPtables then I am only able to query on what appears to be just one specific IP address on each of these servers. The snmpget just times out with Timeout: No Response from x.x.x.x.

There's no pattern to this behaviour with regards to which IP addresses I'm allowed to connect to. But it's one and only one IP address per machine.

This is my iptables config:

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT

-A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT

-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

-A RH-Firewall-1-INPUT -s 172.16.3.0/24 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -i lo -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

-A RH-Firewall-1-INPUT -s 172.16.3.0/24 -m state --state NEW -m tcp -p tcp --dport 5668 -j ACCEPT
-A RH-Firewall-1-INPUT -i lo -m state --state NEW -m tcp -p tcp --dport 5668 -j ACCEPT

-A RH-Firewall-1-INPUT -s 172.16.3.0/24 -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A RH-Firewall-1-INPUT -i lo -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

-A RH-Firewall-1-INPUT -s 172.16.3.0/24 -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A RH-Firewall-1-INPUT -i lo -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT

-A RH-Firewall-1-INPUT -s 172.16.3.0/24 -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT
-A RH-Firewall-1-INPUT -i lo -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT

I have no trouble connecting outbound to any other server, for example using wget to grab RPM's.

I did try adding this as a last resort, but no joy either:

-A OUTPUT -p udp -s 0/0 --sport 1024:65535 -d 0/0 --dport 161:162 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -p udp -s 0/0 --sport 161:162 -d 0/0 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT

This is the output from iptables -L:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
RH-Firewall-1-INPUT  all  --  anywhere             anywhere
ACCEPT     udp  --  anywhere             anywhere            udp spts:snmp:snmptrap dpts:1024:65535 state ESTABLISHED

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
RH-Firewall-1-INPUT  all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     udp  --  anywhere             anywhere            udp spts:1024:65535 dpts:snmp:snmptrap state NEW,ESTABLISHED

Chain RH-Firewall-1-INPUT (2 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     icmp --  anywhere             anywhere            icmp any
ACCEPT     udp  --  anywhere             224.0.0.251         udp dpt:mdns
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  172.16.3.0/24        anywhere            state NEW tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
ACCEPT     tcp  --  172.16.3.0/24        anywhere            state NEW tcp dpt:5668
ACCEPT     udp  --  172.16.3.0/24        anywhere            state NEW udp dpt:5668
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:5668
ACCEPT     udp  --  anywhere             anywhere            state NEW udp dpt:5668
ACCEPT     tcp  --  172.16.3.0/24        anywhere            state NEW tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:http
ACCEPT     tcp  --  172.16.3.0/24        anywhere            state NEW tcp dpt:https
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:https
ACCEPT     tcp  --  172.16.3.0/24        anywhere            state NEW tcp dpt:mysql
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:mysql
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited

Best Answer

You must put

ACCEPT     udp  --  anywhere             anywhere            udp spts:snmp:snmptrap dpts:1024:65535 state ESTABLISHED

before RH-Firewall-1-INPUT because of on RH-Firewall-1-INPUT rules there is REJECT on the end of line, the iptables read from top to down.

 Chain INPUT (policy ACCEPT)
 target     prot opt source               destination
 1 RH-Firewall-1-INPUT  all  --  anywhere             anywhere
 2 ACCEPT     udp  --  anywhere             anywhere            udp spts:snmp:snmptrap dpts:1024:65535 state ESTABLISHED

If you want to add using command line, you can use:

 iptables -I OUTPUT 1 -p udp -s 0/0 --sport 1024:65535 -d 0/0 --dport 161:162 -m state --state NEW,ESTABLISHED -j ACCEPT
 iptables -I INPUT 1 -p udp -s 0/0 --sport 161:162 -d 0/0 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT

It should be like:

 Chain INPUT (policy ACCEPT)
 target     prot opt source               destination
 1 ACCEPT     udp  --  anywhere             anywhere            udp spts:snmp:snmptrap dpts:1024:65535 state ESTABLISHED
 2 RH-Firewall-1-INPUT  all  --  anywhere             anywhere