Problems with Stateful Inspection of TCP Connections

The problem with using a stateful firewall is that if the applications that go through it have a slightly different concept of what proper TCP state should be, or if the firewall makes invalid assumptions, some services will cease to function. The following subsections explain what some of those errors are and how to fix them.

6.20 TCP Packet Out of State

The "TCP Packet out of state" error message means that FireWall-1 sees a TCP ACK packet for which it does not have a matching state table entry. This may occur because the connection was inactive for a period of time or the connections tables were flushed (e.g., because of a policy installation or restart).

A little history is in order here. In FireWall-1 4.0 and earlier, if FireWall-1 received a TCP ACK packet that didn't match an entry in the connections tables, it would strip off the data portion of the packet (thus making it harmless), change the TCP sequence number, and forward the packet to its final destination. Because the destination host would see an unexpected sequence number, it would send a SYN packet to resynchronize the connection. The SYN packet would then go through the rulebase. If the rulebase permitted the packet, the entries in the connections tables would be recreated and the connection would continue.

In FireWall-1 4.1 and FireWall-1 4.1 SP1, FireWall-1 allows the unsolicited TCP ACK packet only if it comes from the server. If the TCP ACK packet comes from the client (i.e., the machine that originated the connection), the TCP ACK packet is dropped.

Then someone figured out that this handling of ACK packets could be used to cause a DoS attack against both the firewall and the host behind it. Since FireWall-1 4.1 SP2, by default FireWall-1 drops ACK packets for which there are no entries in the state tables. However, in NG FP3 and above, you can revert back to the pre-4.1 SP2 behavior by going into the Global Properties frame, Stateful Inspection tab, and unchecking the "Drop out of state TCP Packets" box. In NG FP2 and before, use dbedit as described in FAQ 4.2 and enter the following commands:

dbedit> modify properties firewall_properties
               fw_allow_out_of_state_tcp 1
dbedit> update properties firewall_properties



FireWall-1 NG FP2 does have the option in the GUI to make this change. However, the option doesn't entirely work due to a coding error that still uses the NG FP1 method.

6.21 Configuring FireWall-1 to Allow Out-of-State Packets for Specific TCP Services

Some application vendors use TCP connections in ways that do not follow the standards documented in RFC793. Since FireWall-1 attempts to enforce strict adherence to the standards, applications that do not comply will have difficulties communicating through FireWall-1 or any other stateful packet filter. NG FP2 and above provide a functionality that allows TCP packets for a specific port number even if they do not conform to Check Point's idea of state. This allows out-of-state TCP packets for specific services provided the packets would normally be passed by the rulebase. To do this, edit $FWDIR/lib/user.def on the management station and add a line of code (set in bold) within the following context:

#ifndef __user_def__
#define __user_def__

// User-defined INSPECT code

deffunc user_accept_non_syn() { dport = 22 };

#endif /* __user_def__ */

The INSPECT code between the curly braces defines the service(s) you wish to allow. The preceding example is SSH (TCP port 22). To define multiple services?for example, SSH (port 22), https (port 443), and ldap (port 389)?replace the bold line in the preceding example with this one:

deffunc user_accept_non_syn() { dport=22 or dport=443 or dport=389 };

To permit non-SYN packets between hosts a.b.c.d and x.y.z.w in addition to non-SYN packets on port 22, use the following:

deffunc user_accept_non_syn() { (src=x.y.z.w, dst=a.b.c.d) or
                                (src=a.b.c.d, dst=x.y.z.w) or
                                dport=22 };

(See Chapter 14 for more information on INSPECT.) If the rulebase is constructed carefully enough, the firewall should be relatively safe from an ACK-type DoS attack because all packets allowed by this change must still pass the rulebase.

6.22 SmartView Tracker Log Error: Rule 0: Reason: Violated Unidirectional Connection

FireWall-1 can mark a connection in the connections table to allow traffic to pass in one direction only. This can either be a connection that started from the inside, in which case FireWall-1 would mark the table to read that only outbound packets are allowed, or it can be a connection that originated from the outside, in which case FireWall-1 would mark the table to read that only in bound packets are allowed. This means that data can pass in only one direction (ACK packets as part of normal TCP are acceptable). When a packet violates a unidirectional connection, Check Point logs an entry into SmartView Tracker/Log Viewer.

UDP services have an option to set a service to accept replies. In a sense, that is unidirectional. Unidirectional TCP connections occur with FTP. Some programs that use FTP do so in a nonstandard way that requires all the connections used by the FTP connection to be bidirectional.

To allow for bidirectional FTP connections in FireWall-1 NG, perform the following steps.

  1. Stop the FireWall-1 management station with cpstop.

  2. Edit $FWDIR/lib/base.def on the management station. Add the following bolded lines within the context shown:

    deffunc ftp_port_code() {
    ftp_intercept_port(CONN_ONEWAY_EITHER) or (IS_PASV_MSG,reject or 1)
    deffunc ftp_pasv_code() {
    ftp_intercept_pasv(CONN_ONEWAY_EITHER) or (IS_PORT_CMD,reject or 1)
    deffunc ftp_bidir_code() {
    deffunc ftp_code() {
  3. Edit $FWDIR/conf/tables.C on the management station as follows (changes are set in bold):

    : (protocols
           :table-type (confobj-dynamic)
           :location (protocols)
           :read_permission (0x00000000)
           :write_permission (0x00040000)
           :queries (
                  :all (*)

    Note that table-type will be changed from confobj-static to confobj-dynamic.

  4. Start the FireWall-1 management station with cpstart.

  5. Use dbedit to enter the following commands:

    dbedit> create tcp_protocol FTP_BI
    dbedit> update protocols FTP_BI
    dbedit> modify protocols FTP_BI handler ftp_bidir_code
    dbedit> modify protocols FTP_BI match_by_seqack true
    dbedit> modify protocols FTP_BI res_type ftp
    dbedit> update protocols FTP_BI
    dbedit> quit

    This allows you to create the bidirectional FTP service.

  6. Open up SmartDashboard/Policy Editor and create a new service of type TCP. It will be on port 21. Give it a name other than FTP_BI (e.g., ftp_bidir). Click the Advanced button and select FTP_BI as the protocol type.

  7. Use the new service in a rule. Install the security policy.

6.23 th_flags X message_info SYN Packet for Established Connection

This error can be seen in SmartView Tracker/Log Viewer when FireWall-1 receives a new connection from a source to a destination over the same port/service as a connection that was recently closed with a FIN or RST. FireWall-1 hangs onto these connections until the TCP end timeout is reached, which defaults to 60 seconds. This behavior is normal and expected.

The first step in alleviating this issue is to lower the TCP end timeout to see if that helps remove the connection from the connections table in time for the new connection to be received without a conflict. In FireWall-1 NG FP2 and later, the TCP end timeout can be modified via the GUI in the Stateful Inspection frame of the Global Properties section.

If the problem still occurs, the solution is to use TCP Sequence Verifier in NG FP3 to enable FireWall-1 to see the connection as a new connection, not an established one. For this to work properly, you need to run NG FP3 or above. On Nokia platforms, ensure that you have disabled flows. Contact Nokia Support for assistance.

Another option exists in hotfix SHF_FW1_FP3_0114, which is included in NG FP3 HFA-311 and above. You can change the behavior by modifying the value of the kernel variable fw_reuse_established_conn in three ways: change it to the TCP port number on which you need this behavior, change it to -1 for all ports, or change it to -2 to disable the behavior. See FAQ 6.1 for instructions on how to edit FireWall-1 kernel variables.

6.24 TCP Flags Do Not Make Sense

These errors show up in SmartView Tracker in FireWall-1 NG FP3 and above. SmartDefense is dropping packets with the SYN and RST flags set as malformed instead of as a normal RST packet.

Check Point provides a fix for this issue in hot fix SHF_FW1_FP3_0114. This fix is included in NG FP3 HFA-311 and above. After applying the fix, you can change the behavior by modifying the value of the kernel variable fw_accept_syn_rst to the TCP port number on which you need this behavior, to -1 for all ports, or to -2 to disable the behavior. See FAQ 6.1 for instructions on how to edit FireWall-1 kernel variables.

6.25 Unexpected SYN Response

These error messages show up in SmartView Tracker on FireWall-1 NG FP3 and above when the firewall receives unexpected SYN-ACK packets. To allow these packets, change the kernel variable fw_allow_out_of_state_syn_resp to 1. FAQ 6.1 explains how to change kernel variables.

6.26 Enabling the TCP Sequence Verifier

Prior to FireWall-1 NG FP1, FireWall-1 did not perform any checking of TCP sequence numbers. NG FP1 introduced this functionality, which validates the TCP sequence numbers used in a connection. It provides better tracking of the state of TCP connections. Enabling this feature can eliminate certain kinds of error messages in the logs and possibly create others.

To enable TCP Sequence Verifier on NG FP3 or above, in SmartDashboard, select SmartDefense from the Policy menu. The option is listed under TCP as Sequence Verifier.

To enable TCP Sequence Verifier on NG FP2, check the "Drop out of sequence packets" option under TCP Sequence Verifier in the Stateful Inspection frame in the Global Properties section.

To enable TCP Sequence Verifier on NG FP1, use dbedit to edit the following property to true in the objects_5_0.C file:

dbedit> modify properties firewall_properties fw_tcp_seq_verify 1
dbedit> update properties firewall_properties

6.27 Adjusting TCP or UDP Timeouts on a Per-Service Basis

In FireWall-1 NG, you can set these timeouts in the GUI directly. For both TCP and UDP services, go into the Advanced section of the service in question. For TCP services, edit the session timeout. For UDP services, edit the virtual session timeout. Reinstall the security policy.

6.28 Disabling TCP Timeouts

It is usually better to use some of the other tricks discussed to permit TCP packets that are out of state, such as the method described in FAQ 6.21. I don't even want to think about the security implications of leaving idle TCP connections open forever, but my gut tells me that this is not a good idea.

If you absolutely need to disable timeouts for a service because the vendor of your application refuses to implement a mechanism for periodically checking to see whether a connection is alive, this is how you would do it with dbedit:

dbedit> modify services service-name timeout 2147483647
dbedit> update services service-name

The value specified in the preceding example is used internally by the kernel to specify connections that do not time out. However, if you set any smaller number slightly less than 2,147,483,647, you still get connections that should last many years, assuming you do not stop your firewall for that long.