9

I've often seen the rule -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT applied. Whilst I'm not an expert, that particular line concerns me. It's pretty obvious that the rule allows all traffic with the only exception that the connection has to have been established or related to an established connection.

Scenario

  • I'll allow connections to the default SSH port 22 from the servers LAN in the subnet 192.168.0.0/16 or whatever.
  • SuperInsecureApp® exposes something on port 1337, which I add to my INPUT chain.
  • I've added the conntrack rule to accept ESTABLISHED and RELATED from all sources
  • Chain policy is DROP

So basically that configuration shoud allow SSH-connections from the LAN only, whilst allowing inbound traffic on port 1337 from world.

This is where my confusion blooms. Would the conntrack in any way expose a security flaw that would allow one to get an established connection on 1337 (since it's world open), and then utilize that connection to gain access to the SSH port (or any other port for that matter)?

8

I would not consider ESTABLISHED and RELATED traffic too open. You may be able to omit RELATED, but should definitely allow ESTABLISHED. Both of these traffic categories use conntrack states.

ESTABLISHED connections have already been validated by another rule. This makes it much simpler to implement unidirectional rules. This only allows you to continue transactions on the same port.

RELATED connects are also validated by another rule. They don't apply to a lot of protocols. Again they make it much simpler to configure rules. They also ensure proper sequencing of connections where they apply. This actually makes your rules more secure. While this may make it possible to connect on a different port, that port should only be part of a related process like an FTP data connection. Which ports are allow are controlled by protocol specific conntrack modules.

By allowing ESTABLISHED and RELATED connections, you can concentrate on which new connections you want the firewall to accept. It also avoids broken rules meant to allow return traffic, but which allow new connections.

Given you have classified the program on port 1337 as insecure, it should be started using a dedicated non-root user-id. This will limit the damage someone can do if they do manage to crack he application and gain enhanced access.

It is highly unlikely a connection on port 1337 could be used to access port 22 remotely, but it is possible that a connection to port 1337 could be used to proxy a connection to port 22.

You may want to ensure SSH is secured in depth:

  • Use hosts.allow to limit access in addition to the firewall restrictions.
  • Prevent root access, or at least require the use of keys and limit their access in the authorized_keys file.
  • Audit login failures. A log scanner can send you periodic reports of unusual activity.
  • Consider using a tool like fail2ban to automatically block access on repeated access failures.
  • Although this was an arbitrary example, the first thing I do on new servers is always disabling root access and plaintext authentication in sshd - that's a very good tip. Also fail2ban is actually already installed on the real-life setup from which the example was inspired. "ESTABLISHED connections have already been validated by another rule" was the exact thing I was unsure about and perfectly answers my question. Thanks for your very clear answer! – Dencker Nov 16 '16 at 6:40
  • Side question: From a performance perspective, does it change anything at all if the conntrack rule is in the beginning or the end of the chain? From how I understand iptables, it'd have to process all rules on established connections if it were in the end, and only that single rule if it was placed in the beginning? – Dencker Nov 16 '16 at 6:45
  • @Dencker You want the ESTABLISHED, RELATED rule first. It will accept by far the most traffic. Beyond that you may want to have the rules that accept the most traffic, although it is best to weigh heavily to readability. My rules are grouped, latency sensitive, high traffic (grouped by type), others. Iptables has counters that allow you to see how much traffic each rule proceses. I use Shorewall, which adds some useful defaults and has an easy to read rules file to build my firewalls. – BillThor Nov 16 '16 at 23:17
2

ESTABLISHED and RELATED are features of "stateful" packet filtering, where filtering does not just depend on a static rule set but also on the context, within which packets are considered. You need ESTABLISHED in order to allow connections to work, and you need RELATED for relevant ICMP messages. Stateful filtering allows to filter more precisely compared to static "stateless" rules.

Let's look at ESTABLISHED first. For instance, consider TCP on port 22. The initiator (client) sends a SYN to serverIPaddr:22. The server returns SYN+ACK to the client. Now it's the client's turn to send an ACK. How should the filtering rule on the server look like, such that only the "matching" ACK is accepted? A general stateless rule would look like

-A INPUT --proto tcp --port 22 -j ACCEPT

which is more liberal than the according stateful rule. The stateless rule allows arbitrary TCP segments, e.g. ACK or FIN without having established a connection first. Port scanners can exploit this kind of behavior for OS fingerprinting.

Now let's have a look at RELATED. This is used for ICMP messages, mostly error messages. For instance, if a packet from the server to the client is dropped, then an error message is sent to the server. This error message is "related" to the previously established connection. Without the RELATED rule one would either need to allow incoming error messages in general (without context), or, as is custom for many sites, drop ICMP altogether and wait for timeouts on the transport layer. (Note that this is a bad idea for IPv6; ICMPv6 plays a more important role for IPv6 than ICMP for IP legacy.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.