FortiGate
FortiGate Next Generation Firewall utilizes purpose-built security processors and threat intelligence security services from FortiGuard labs to deliver top-rated protection and high performance, including encrypted traffic.
gfranceschi
Staff
Staff
Article Id 193124
Purpose
This article describes an example of configuration and troubleshooting commands for SCTP multihoming through a FortiGate cluster (FGCP).

Diagram
SCTP Server
192.168.1.1/24  10.0.1.1/24     
|
|
Port1
FortiGate cluster
Port2
|
198.51.100.0/24  
|
Router
|
|
192.168.2.1/24           10.0.2.1/24     
SCTP Client




Expectations, Requirements
The SCTP association propose 2 paths through a FortiGate cluster:
   - Primary path from client 192.168.2.1 to server 192.168.1.1
   - Secondary path from client 10.0.2.1 to server 10.0.1.1

SCTP Server 192.168.1.1 is NATed by FortiGate to 198.51.100.10 while 10.0.1.1 is NATed to 198.51.100.20.

SCTP sessions are synchronized between the master and slave unit.

Configuration
Configuration is extracted from FortiOS V5.2 based:

SCTP sessions are synchronized between the master and slave unit by enabling session-pickup :
config system ha
    set session-pickup enable

One to one natting is assumed by firewall VIP:
config firewall vip
    edit "VIP1"
        set extip 198.51.100.10
        set extintf "any"
        set portforward enable
        set mappedip "192.168.1.1"
        set protocol sctp
        set extport 1-65535
        set mappedport 1-65535
    next
    edit "VIP2"
        set extip 198.51.100.20
        set extintf "any"
        set portforward enable
        set mappedip "10.0.1.1"
        set protocol sctp
        set extport 1-65535
        set mappedport 1-65535
    next
end

config firewall address
    edit "192.168.1.1"
        set subnet 192.168.1.1 255.255.255.255
    next
    edit "192.168.2.1"
        set subnet 192.168.2.1 255.255.255.255
    next
    edit "10.0.1.1"
        set subnet 10.0.1.1 255.255.255.255
    next
    edit "10.0.2.1"
        set subnet 10.0.2.1 255.255.255.255
    next
end

VIP are used for SNAT or DNAT through firewall policy:
config firewall policy
    edit 3
        set srcintf "port2"
        set dstintf "port1"
        set srcaddr "192.168.2.1" "10.0.2.1"
        set dstaddr "VIP1" "VIP2"
        set action accept
        set schedule "always"
        set service "ALL"
        set logtraffic all
        set logtraffic-start enable
    next
    edit 4
        set srcintf "port1"
        set dstintf "port2"
        set srcaddr "192.168.1.1" "10.0.1.1"
        set dstaddr "192.168.2.1" "10.0.2.1"
        set action accept
        set schedule "always"
        set service "ALL"
        set logtraffic all
        set logtraffic-start enable
        set nat enable
    next



Troubleshooting
Troubleshooting commands and output example:

SCTP session-helper is NOT part of the FortiGate configuration parameter from "config system session-helper".
SCTP session-helper is a kernel feature that can't be disabled in V5.2, V5.4, V5.6 and v6.0.
(It is possible from v6.2, see KB FD48987)

Troubleshooting SCTP via:
   - sniffer on endpoints
   - session table and expectations
   - debug flow


"debug flow" shows the different chunk-type of SCTP packet
diag debug console timestamp en (This option is not activated in the below trace but timestamp could help to match the traffic with the sniffer traces)
diag debug flow filter clear
diag debug flow filter addr 10.0.2.1 192.168.2.1
diag debug flow filter proto 132
diag debug flow show console enable
diag debug flow show function-name enable
diag debug flow trace start 100
diag debug enable


SCTP association is established after a four-way handshakes through the first path.


chunk-type=1 --> INIT     (Initiation)
 
The NAT function is shown in debug flow.

The IP addresses parameter from the SCTP association is displayed showing the SCTP multihoming paths.

FortiGate will open related expectation session for the second path.
id=20085 trace_id=31 func=print_pkt_detail line=4471 msg="vd-root received a packet(proto=132, 192.168.2.1:2905->198.51.100.10:2911) from port2. "
id=20085 trace_id=31 func=init_ip_session_common line=4620 msg="allocate a new session-0000fb2c"
id=20085 trace_id=31 func=fw_pre_route_handler line=184 msg="VIP-192.168.1.1:2911, outdev-unkown"
id=20085 trace_id=31 func=__ip_session_run_tuple line=2604 msg="DNAT 198.51.100.10:2911->192.168.1.1:2911"
id=20085 trace_id=31 func=vf_ip4_route_input line=1597 msg="find a route: flags=00000000 gw-192.168.1.1 via port1"
id=20085 trace_id=31 func=fw_forward_handler line=692 msg="Allowed by Policy-3:"
id=20085 trace_id=31 func=sctp_parse_packet line=108 msg="found chunk-type=1 dir=0 ses id=fb2c has_master=0 master_dir=-1"
id=20085 trace_id=31 func=sctp_parse_packet line=171 msg="org_saddr=192.168.2.1 new_saddr=192.168.2.1 org_daddr=198.51.100.10 new_daddr=192.168.1.1 snat=0 dnat=1 bld_csum=0 port_changed=0"
id=20085 trace_id=31 func=sctp_parse_packet line=188 msg="num_param=1 param4->addr=192.168.2.1"
id=20085 trace_id=31 func=sctp_parse_packet line=188 msg="num_param=2 param4->addr=10.0.2.1"
id=20085 trace_id=31 func=sctp_setup_mapping line=372 msg="sctp_mh: i=0 addr=192.168.2.1 naddr=192.168.2.1 same_as=-1 dir=0 ctx_st=1"
id=20085 trace_id=31 func=sctp_setup_mapping line=372 msg="sctp_mh: i=1 addr=10.0.2.1 naddr=10.0.2.1 same_as=-1 dir=0 ctx_st=1"
id=20085 trace_id=31 func=sctp_help_out line=447 msg="add new exp tuple srcip=10.0.2.1:2905 dstip=198.51.100.10:2911 for ses id=fb2c dir=0"
id=20085 trace_id=31 func=sctp_help_out line=490 msg="add new exp tuple srcip=0.0.0.0:2911 dstip=192.168.2.1:2905 for ses id=fb2c dir=1"
id=20085 trace_id=31 func=sctp_help_out line=490 msg="add new exp tuple srcip=0.0.0.0:2911 dstip=10.0.2.1:2905 for ses id=fb2c dir=1"
id=20085 trace_id=31 func=__ip_session_run_tuple line=2641 msg="run helper-sctp(dir=original)"


chunk-type=2 --> INIT ACK     (Initiation acknowledgement)

The IP addresses parameter from the SCTP association is displayed showing the SCTP multihoming paths.

FortiGate will open related expectation session for the second path.
id=20085 trace_id=32 func=print_pkt_detail line=4471 msg="vd-root received a packet(proto=132, 192.168.1.1:2911->192.168.2.1:2905) from port1. "
id=20085 trace_id=32 func=resolve_ip_tuple_fast line=4534 msg="Find an existing session, id-0000fb2c, reply direction"
id=20085 trace_id=32 func=vf_ip4_route_input line=1597 msg="find a route: flags=00000000 gw-198.51.100.254 via port2"
id=20085 trace_id=32 func=__ip_session_run_tuple line=2590 msg="SNAT 192.168.1.1->198.51.100.10:2911"
id=20085 trace_id=32 func=sctp_parse_packet line=108 msg="found chunk-type=2 dir=1 ses id=fb2c has_master=0 master_dir=-1"
id=20085 trace_id=32 func=sctp_parse_packet line=171 msg="org_saddr=192.168.1.1 new_saddr=198.51.100.10 org_daddr=192.168.2.1 new_daddr=192.168.2.1 snat=1 dnat=0 bld_csum=0 port_changed=0"
id=20085 trace_id=32 func=sctp_parse_packet line=188 msg="num_param=1 param4->addr=192.168.1.1"
id=20085 trace_id=32 func=sctp_parse_packet line=188 msg="num_param=2 param4->addr=10.0.1.1"
id=20085 trace_id=32 func=sctp_setup_mapping line=372 msg="sctp_mh: i=0 addr=192.168.1.1 naddr=198.51.100.10 same_as=-1 dir=1 ctx_st=3"
id=20085 trace_id=32 func=sctp_setup_mapping line=372 msg="sctp_mh: i=1 addr=10.0.1.1 naddr=198.51.100.20 same_as=-1 dir=1 ctx_st=3"
id=20085 trace_id=32 func=sctp_help_in line=639 msg="create exp tuple timeout=70000000 src_int=192.168.2.1:2905 src_ext=192.168.2.1:2905 dst_ext=198.51.100.20:2911 dst_int=10.0.1.1:2911 for ses id=fb2c master_dir=0"
id=20085 trace_id=32 func=sctp_help_in line=662 msg="delete exp tuple srcip=0.0.0.0:2911 dstip=192.168.2.1:2905 for ses id=fb2c dir=1"
id=20085 trace_id=32 func=sctp_help_in line=738 msg="create exp tuple timeout=70000000 src_int=10.0.1.1:2911 src_ext=198.51.100.20:2911 dst_ext=192.168.2.1:2905 dst_int=192.168.2.1:2905 for ses id=fb2c master_dir=1"
id=20085 trace_id=32 func=sctp_help_in line=566 msg="delete exp tuple srcip=10.0.2.1:2905 dstip=198.51.100.10:2911 for ses id=fb2c dir=0"
id=20085 trace_id=32 func=sctp_help_in line=639 msg="create exp tuple timeout=70000000 src_int=10.0.2.1:2905 src_ext=10.0.2.1:2905 dst_ext=198.51.100.10:2911 dst_int=192.168.1.1:2911 for ses id=fb2c master_dir=0"
id=20085 trace_id=32 func=sctp_help_in line=639 msg="create exp tuple timeout=70000000 src_int=10.0.2.1:2905 src_ext=10.0.2.1:2905 dst_ext=198.51.100.20:2911 dst_int=10.0.1.1:2911 for ses id=fb2c master_dir=0"
id=20085 trace_id=32 func=sctp_help_in line=662 msg="delete exp tuple srcip=0.0.0.0:2911 dstip=10.0.2.1:2905 for ses id=fb2c dir=1"
id=20085 trace_id=32 func=sctp_help_in line=738 msg="create exp tuple timeout=70000000 src_int=192.168.1.1:2911 src_ext=198.51.100.10:2911 dst_ext=10.0.2.1:2905 dst_int=10.0.2.1:2905 for ses id=fb2c master_dir=1"
id=20085 trace_id=32 func=sctp_help_in line=738 msg="create exp tuple timeout=70000000 src_int=10.0.1.1:2911 src_ext=198.51.100.20:2911 dst_ext=10.0.2.1:2905 dst_int=10.0.2.1:2905 for ses id=fb2c master_dir=1"
id=20085 trace_id=32 func=__ip_session_run_tuple line=2641 msg="run helper-sctp(dir=reply)"


chunk-type=10 COOKIE ECHO     (State cookie)
id=20085 trace_id=33 func=print_pkt_detail line=4471 msg="vd-root received a packet(proto=132, 192.168.2.1:2905->198.51.100.10:2911) from port2. "
id=20085 trace_id=33 func=resolve_ip_tuple_fast line=4534 msg="Find an existing session, id-0000fb2c, original direction"
id=20085 trace_id=33 func=__ip_session_run_tuple line=2604 msg="DNAT 198.51.100.10:2911->192.168.1.1:2911"
id=20085 trace_id=33 func=sctp_parse_packet line=108 msg="found chunk-type=10 dir=0 ses id=fb2c has_master=0 master_dir=-1"
id=20085 trace_id=33 func=__ip_session_run_tuple line=2641 msg="run helper-sctp(dir=original)"


chunk-type=11 COOKIE ACK     (Cookie acknowledgement)
id=20085 trace_id=34 func=print_pkt_detail line=4471 msg="vd-root received a packet(proto=132, 192.168.1.1:2911->192.168.2.1:2905) from port1. "
id=20085 trace_id=34 func=resolve_ip_tuple_fast line=4534 msg="Find an existing session, id-0000fb2c, reply direction"
id=20085 trace_id=34 func=__ip_session_run_tuple line=2590 msg="SNAT 192.168.1.1->198.51.100.10:2911"
id=20085 trace_id=34 func=sctp_parse_packet line=108 msg="found chunk-type=11 dir=1 ses id=fb2c has_master=0 master_dir=-1"
id=20085 trace_id=34 func=__ip_session_run_tuple line=2641 msg="run helper-sctp(dir=reply)"


The session is now ESTABLISHED (proto_state=01) and the session table displays the SCTP multihoming assocation with the line
"sctp: ctx_st=3 saddr=(192.168.2.1, 10.0.2.1)(2) daddr=(192.168.1.1=>198.51.100.10, 10.0.1.1=>198.51.100.20)(2)"
session info: proto=132 proto_state=01 duration=153 expire=3590 timeout=3600 flags=00000000 sockflag=00000000 sockport=0 av_idx=0 use=9
origin-shaper=
reply-shaper=
per_ip_shaper=
ha_id=0 policy_dir=0 tunnel=/ vlan_cos=0/255
state=may_dirty synced complex
statistic(bytes/packets/allow_err): org=1552/16/1 reply=1532/16/1 tuples=2
orgin->sink: org pre->post, reply pre->post dev=4->3/3->4 gwy=192.168.1.1/198.51.100.254
hook=pre dir=org act=dnat 192.168.2.1:2905->198.51.100.10:2911(192.168.1.1:2911)
hook=post dir=reply act=snat 192.168.1.1:2911->192.168.2.1:2905(198.51.100.10:2911)
misc=0 policy_id=3 auth_info=0 chk_client_info=0 vd=0
serial=0000fb2c tos=ff/ff ips_view=0 app_list=0 app=0
dd_type=0 dd_mode=0
sctp: ctx_st=3 saddr=(192.168.2.1, 10.0.2.1)(2) daddr=(192.168.1.1=>198.51.100.10, 10.0.1.1=>198.51.100.20)(2)

Heartbeat communication using expectation session on crossing endpoints:

chunk-type=4 HEARTBEAT     (Heartbeat request)

id=20085 trace_id=35 func=print_pkt_detail line=4471 msg="vd-root received a packet(proto=132, 192.168.1.1:2911->10.0.2.1:2905) from port1. "
id=20085 trace_id=35 func=resolve_ip_tuple_fast line=4544 msg="Find an EXP session, id-0000fb2c."
id=20085 trace_id=35 func=vf_ip4_route_input line=1597 msg="find a route: flags=00000000 gw-198.51.100.254 via port2"
id=20085 trace_id=35 func=__ip_session_run_tuple line=2590 msg="SNAT 192.168.1.1->198.51.100.10:2911"
id=20085 trace_id=35 func=sctp_parse_packet line=108 msg="found chunk-type=4 dir=0 ses id=fb2c has_master=1 master_dir=0"
id=20085 trace_id=35 func=__ip_session_run_tuple line=2641 msg="run helper-sctp(dir=original)"
chunk-type=5  HEARTBEAT ACK     (Heartbeat acknowledgement)
id=20085 trace_id=36 func=print_pkt_detail line=4471 msg="vd-root received a packet(proto=132, 192.168.2.1:2905->198.51.100.10:2911) from port2. "
id=20085 trace_id=36 func=resolve_ip_tuple_fast line=4534 msg="Find an existing session, id-0000fb2c, original direction"
id=20085 trace_id=36 func=__ip_session_run_tuple line=2604 msg="DNAT 198.51.100.10:2911->192.168.1.1:2911"
id=20085 trace_id=36 func=sctp_parse_packet line=108 msg="found chunk-type=5 dir=0 ses id=fb2c has_master=0 master_dir=-1"
id=20085 trace_id=36 func=__ip_session_run_tuple line=2641 msg="run helper-sctp(dir=original)"
chunk-type=4 HEARTBEAT     (Heartbeat request)
id=20085 trace_id=37 func=print_pkt_detail line=4471 msg="vd-root received a packet(proto=132, 192.168.2.1:2905->198.51.100.20:2911) from port2. "
id=20085 trace_id=37 func=resolve_ip_tuple_fast line=4544 msg="Find an EXP session, id-0000fb2c."
id=20085 trace_id=37 func=__ip_session_run_tuple line=2604 msg="DNAT 198.51.100.20:2911->10.0.1.1:2911"
id=20085 trace_id=37 func=vf_ip4_route_input line=1597 msg="find a route: flags=00000000 gw-192.168.1.1 via port1"
id=20085 trace_id=37 func=sctp_parse_packet line=108 msg="found chunk-type=4 dir=0 ses id=fb2c has_master=1 master_dir=1"
id=20085 trace_id=37 func=__ip_session_run_tuple line=2641 msg="run helper-sctp(dir=original)"

chunk-type=5  HEARTBEAT ACK     (Heartbeat acknowledgement)
id=20085 trace_id=38 func=print_pkt_detail line=4471 msg="vd-root received a packet(proto=132, 192.168.1.1:2911->192.168.2.1:2905) from port1. "
id=20085 trace_id=38 func=resolve_ip_tuple_fast line=4534 msg="Find an existing session, id-0000fb2c, reply direction"
id=20085 trace_id=38 func=__ip_session_run_tuple line=2590 msg="SNAT 192.168.1.1->198.51.100.10:2911"
id=20085 trace_id=38 func=sctp_parse_packet line=108 msg="found chunk-type=5 dir=1 ses id=fb2c has_master=0 master_dir=-1"
id=20085 trace_id=38 func=__ip_session_run_tuple line=2641 msg="run helper-sctp(dir=reply)"


SCTP data exchange on primary path:

chunk-type=0 DATA     (Payload data)
id=20085 trace_id=39 func=print_pkt_detail line=4471 msg="vd-root received a packet(proto=132, 192.168.2.1:2905->198.51.100.10:2911) from port2. "
id=20085 trace_id=39 func=resolve_ip_tuple_fast line=4534 msg="Find an existing session, id-0000fb2c, original direction"
id=20085 trace_id=39 func=__ip_session_run_tuple line=2604 msg="DNAT 198.51.100.10:2911->192.168.1.1:2911"
id=20085 trace_id=39 func=sctp_parse_packet line=108 msg="found chunk-type=0 dir=0 ses id=fb2c has_master=0 master_dir=-1"
id=20085 trace_id=39 func=__ip_session_run_tuple line=2641 msg="run helper-sctp(dir=original)"

chunk-type=3 SACK     (Selective acknowledgement)
id=20085 trace_id=40 func=print_pkt_detail line=4471 msg="vd-root received a packet(proto=132, 192.168.1.1:2911->192.168.2.1:2905) from port1. "
id=20085 trace_id=40 func=resolve_ip_tuple_fast line=4534 msg="Find an existing session, id-0000fb2c, reply direction"
id=20085 trace_id=40 func=__ip_session_run_tuple line=2590 msg="SNAT 192.168.1.1->198.51.100.10:2911"
id=20085 trace_id=40 func=sctp_parse_packet line=108 msg="found chunk-type=3 dir=1 ses id=fb2c has_master=0 master_dir=-1"
id=20085 trace_id=40 func=__ip_session_run_tuple line=2641 msg="run helper-sctp(dir=reply)"



Sessions from the session table and session expectations:

FGT-A # diagnose sys session filter proto 132
FGT-A # diagnose sys session list


session info: proto=132 proto_state=00 duration=153 expire=never timeout=never flags=00000000 sockflag=00000000 sockport=0 av_idx=0 use=3
origin-shaper=
reply-shaper=
per_ip_shaper=
ha_id=0 policy_dir=0 tunnel=/ vlan_cos=255/255
state=synced complex
statistic(bytes/packets/allow_err): org=420/5/1 reply=0/0/0 tuples=2
orgin->sink: org pre->post, reply pre->post dev=0->4/4->0 gwy=198.51.100.254/0.0.0.0
hook=post dir=org act=snat 192.168.1.1:2911->10.0.2.1:2905(198.51.100.10:2911)
hook=pre dir=reply act=dnat 10.0.2.1:2905->198.51.100.10:2911(192.168.1.1:2911)
misc=0 policy_id=3 auth_info=0 chk_client_info=0 vd=0
serial=0000fb2c tos=ff/ff ips_view=0 app_list=0 app=0
dd_type=0 dd_mode=0


session info: proto=132 proto_state=01 duration=153 expire=3590 timeout=3600 flags=00000000 sockflag=00000000 sockport=0 av_idx=0 use=9
origin-shaper=
reply-shaper=
per_ip_shaper=
ha_id=0 policy_dir=0 tunnel=/ vlan_cos=0/255
state=may_dirty synced complex
statistic(bytes/packets/allow_err): org=1552/16/1 reply=1532/16/1 tuples=2
orgin->sink: org pre->post, reply pre->post dev=4->3/3->4 gwy=192.168.1.1/198.51.100.254
hook=pre dir=org act=dnat 192.168.2.1:2905->198.51.100.10:2911(192.168.1.1:2911)
hook=post dir=reply act=snat 192.168.1.1:2911->192.168.2.1:2905(198.51.100.10:2911)
misc=0 policy_id=3 auth_info=0 chk_client_info=0 vd=0
serial=0000fb2c tos=ff/ff ips_view=0 app_list=0 app=0
dd_type=0 dd_mode=0
sctp: ctx_st=3 saddr=(192.168.2.1, 10.0.2.1)(2) daddr=(192.168.1.1=>198.51.100.10, 10.0.1.1=>198.51.100.20)(2)

session info: proto=132 proto_state=00 duration=153 expire=never timeout=never flags=00000000 sockflag=00000000 sockport=0 av_idx=0 use=3
origin-shaper=
reply-shaper=
per_ip_shaper=
ha_id=0 policy_dir=1 tunnel=/ vlan_cos=255/255
state=synced complex
statistic(bytes/packets/allow_err): org=420/5/1 reply=0/0/0 tuples=2
orgin->sink: org pre->post, reply pre->post dev=3->3/3->0 gwy=192.168.1.1/0.0.0.0
hook=pre dir=org act=dnat 192.168.2.1:2905->198.51.100.20:2911(10.0.1.1:2911)
hook=post dir=reply act=snat 10.0.1.1:2911->192.168.2.1:2905(198.51.100.20:2911)
misc=0 policy_id=3 auth_info=0 chk_client_info=0 vd=0
serial=0000fb2c tos=ff/ff ips_view=0 app_list=0 app=0
dd_type=0 dd_mode=0

total session 3


FGT-A # diagnose sys session list expectation

session info: proto=132 proto_state=00 duration=157 expire=never timeout=never flags=00000000 sockflag=00000000 sockport=0 av_idx=0 use=2
origin-shaper=
reply-shaper=
per_ip_shaper=
ha_id=0 policy_dir=1 tunnel=/ vlan_cos=255/255
state=new synced complex
statistic(bytes/packets/allow_err): org=0/0/0 reply=0/0/0 tuples=2
orgin->sink: org pre->post, reply pre->post dev=3->0/4->0 gwy=0.0.0.0/0.0.0.0
hook=pre dir=org act=dnat 10.0.2.1:2905->198.51.100.10:2911(192.168.1.1:2911)
hook=pre dir=org act=noop 0.0.0.0:0->0.0.0.0:0(0.0.0.0:0)
misc=0 policy_id=3 auth_info=0 chk_client_info=0 vd=0
serial=0000fb2c tos=ff/ff ips_view=0 app_list=0 app=0
dd_type=0 dd_mode=0


session info: proto=132 proto_state=00 duration=157 expire=never timeout=never flags=00000000 sockflag=00000000 sockport=0 av_idx=0 use=2
origin-shaper=
reply-shaper=
per_ip_shaper=
ha_id=0 policy_dir=1 tunnel=/ vlan_cos=255/255
state=new synced complex
statistic(bytes/packets/allow_err): org=0/0/0 reply=0/0/0 tuples=2
orgin->sink: org pre->post, reply pre->post dev=3->0/4->0 gwy=0.0.0.0/0.0.0.0
hook=pre dir=org act=dnat 10.0.2.1:2905->198.51.100.20:2911(10.0.1.1:2911)
hook=pre dir=org act=noop 0.0.0.0:0->0.0.0.0:0(0.0.0.0:0)
misc=0 policy_id=3 auth_info=0 chk_client_info=0 vd=0
serial=0000fb2c tos=ff/ff ips_view=0 app_list=0 app=0
dd_type=0 dd_mode=0


session info: proto=132 proto_state=00 duration=157 expire=never timeout=never flags=00000000 sockflag=00000000 sockport=0 av_idx=0 use=2
origin-shaper=
reply-shaper=
per_ip_shaper=
ha_id=0 policy_dir=0 tunnel=/ vlan_cos=255/255
state=new synced complex
statistic(bytes/packets/allow_err): org=0/0/0 reply=0/0/0 tuples=2
orgin->sink: org pre->post, reply pre->post dev=4->0/3->0 gwy=0.0.0.0/0.0.0.0
hook=post dir=org act=snat 10.0.1.1:2911->192.168.2.1:2905(198.51.100.20:2911)
hook=pre dir=org act=noop 0.0.0.0:0->0.0.0.0:0(0.0.0.0:0)
misc=0 policy_id=3 auth_info=0 chk_client_info=0 vd=0
serial=0000fb2c tos=ff/ff ips_view=0 app_list=0 app=0
dd_type=0 dd_mode=0


session info: proto=132 proto_state=00 duration=157 expire=never timeout=never flags=00000000 sockflag=00000000 sockport=0 av_idx=0 use=2
origin-shaper=
reply-shaper=
per_ip_shaper=
ha_id=0 policy_dir=0 tunnel=/ vlan_cos=255/255
state=new synced complex
statistic(bytes/packets/allow_err): org=0/0/0 reply=0/0/0 tuples=2
orgin->sink: org pre->post, reply pre->post dev=4->0/3->0 gwy=0.0.0.0/0.0.0.0
hook=post dir=org act=snat 10.0.1.1:2911->10.0.2.1:2905(198.51.100.20:2911)
hook=pre dir=org act=noop 0.0.0.0:0->0.0.0.0:0(0.0.0.0:0)
misc=0 policy_id=3 auth_info=0 chk_client_info=0 vd=0
serial=0000fb2c tos=ff/ff ips_view=0 app_list=0 app=0
dd_type=0 dd_mode=0


Note that all the sessions have the same serial number, and the flag "state=synced".
state=synced means that this master unit will synchronise/sent the session to the slave.

The slave will show all sessions and session expectations with the flag "syn_ses" (session received from master) like for example:

session info: proto=132 proto_state=01 duration=200 expire=3400 timeout=3600 flags=00000000 sockflag=00000000 sockport=0 av_idx=0 use=9
origin-shaper=
reply-shaper=
per_ip_shaper=
ha_id=0 policy_dir=0 tunnel=/ vlan_cos=0/255
state=dirty may_dirty syn_ses complex
statistic(bytes/packets/allow_err): org=0/0/0 reply=0/0/0 tuples=2
orgin->sink: org pre->post, reply pre->post dev=4->3/3->4 gwy=0.0.0.0/0.0.0.0
hook=pre dir=org act=dnat 192.168.2.1:2905->198.51.100.10:2911(192.168.1.1:2911)
hook=post dir=reply act=snat 192.168.1.1:2911->192.168.2.1:2905(198.51.100.10:2911)
misc=0 policy_id=3 auth_info=0 chk_client_info=0 vd=0
serial=0000fb2c tos=ff/ff ips_view=0 app_list=0 app=0
dd_type=0 dd_mode=0
sctp: ctx_st=3 saddr=(192.168.2.1, 10.0.2.1)(2) daddr=(192.168.1.1=>198.51.100.10, 10.0.1.1=>198.51.100.20)(2)


The SCTP protocol states in the session table are:
0    NONE
1    ESTABLISHED            timeout will depend from the configuration of ttl-session
2    CLOSED                 will be deleted after 10 sec after ABORT or SHUTDOWN
3    COOKIE_WAIT
4    COOKIE_ECHOED
5    SHUTDOWN_SENT
6    SHUTDOWN_RECD
7     SHUTDOWN_ACK_SENT

SCTP performs a three-way handshake to tiredown the session with the following chuncks that will be seen in debug flow ouput:
7       SHUTDOWN                  Shutdown
8       SHUTDOWN ACK              Shutdown acknowledgement
14      SHUTDOWN COMPLETE         Shutdown complete
or the usage of a reset with
6       ABORT                     Abort

Debugging with sniffer

Sniffer on the 2 endpoints:
diag sniffer packet any "host 192.168.2.1 or host 10.0.2.1" 6
SCTP sequence from the sniffer:


The session-helper inspects the SCTP protocol and will replace the NATed IP address from the association.

The INIT-ACK packet seen on the ingress interface of FortiGate:


The INIT-ACK packet seen on the egress interface of FortiGate:


The IPV4 address parameters of the SCTP endpoints displayed inside the packet have been replaced according to the definition of the FortiGate VIP configuration.


Related Articles

Technical Tip: Disable stateful SCTP Inspection

Technical Note: SCTP source NAT in multihoming with FGSP

Contributors