Monday, December 31, 2012

fortigate Session Timeouts

The Fortinet platform like most other stateful firewalls keeps track of open TCP connections. Each established session is assigned a timer which gets reset every time there is activity. If the timer expires due to inactivity the session is removed from the firewall tables and you will have to re-establish the connection. The session can also be cleared without waiting for the timer to expire if the firewall sees a FIN or RST packet for a given session.

Imagine you have a telnet connection on port 23 to a server in your DMZ. There is a script which executes periodically to poll some data using the telnet session. You notice that when the script hasn't executed in 60 minutes the telnet session is lost and you have to re-establish the session.

The easy answer is to increase the session ttl (time-to-live or timeout). This can be done on the CLI on a global basis for all ports or only for specific ports. Keep in mind that raising the timeout values for all ports can significantly increase the amount of system resources (especially RAM) consumed. This is due to the fact that the firewall now has to potentially keep track of the same number of sessions for a longer period of time. The default value of 60 minutes/3600 seconds should be ok for most applications.

The following example sets the timeout value for all TCP services to 3000 seconds but increases the timeout for telnet (port 23) to 7200 seconds.

config system session-ttl
set default 3000
config port
edit 23
set timeout 7200
next
end
end

2 comments:

  1. That is a valid countermeasure to prevent the undesirable "killing" of TCP sessions.

    However, it has two drawbacks:

    a) complexity: one application needs 7'200s. Another needs 13'000s. Yet another wants to run for 48hrs straight. So you risk to implement and maintain more and more of these optimisations - while actually only masquerading, but not solving the problem.

    b) session table size. On large firewalls with lots of resources, this might not harm, but on a smaller box with scarce ressources, it can be an issue.


    From experience, I would recommend that any user who wants to run "sleeper" sessions (in extenso: TCP sessions that fall silent for extended periods of time >3600s) are gently forced to use a mechanism to keep their TCP session alive.

    1) configure the software they use to periodically exchange a "hello" or "no-op" message with the server; this is by all means the preferred way. Most terminal emulations can do this, and I've even seen this as default in some financial/transactional applications (using the FIX Protocol).

    2a) on the operating system: reducing the "TCP Keepalive Interval" to a value <3600s (default on most OSs seems to be 7200s).
    2b) configure the software they use to set the SO_KEEPALIVE option when establishing the TCP Session.

    Unconventional measures to persuade the users to comply may be necessary: , gentle hits to the head with their software handbook, stakes, torches, pincers and even thumb screws ;-)

    Cheers, Marc.

    ReplyDelete
  2. I think you are missing some lines for telnet - specifically the port - you are merely creating and editing a profile called "23".

    Correct: Set protocol to 6 (tcp) and set port to 23 (telnet)

    config system session-ttl
    set default 3000
    config port
    edit 23
    set protocol 6
    set start-port 23
    set end-port 23
    set timeout 7200
    next
    end
    end

    ReplyDelete