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.
byotova
Staff
Staff
Article Id 192123
Purpose
This article describes how to configure SCTP source NAT in a multihoming environment.


Diagram

Expectations, Requirements
Expectations:

  -  The SCTP client has 2 separate paths (SCTP multihoming) through 2 Fortigates in FGSP.
  -  The client IP must be translated (SNAT) with the following IPs :
    -  primary path (green) : 100.0.0.10
    -  secondary path (blue) :  200.0.0.10
  -  FGSP is configured in order to synchronize the sessions between the FortiGate.


Configuration
In this setup the INIT / INIT_ACK messages are sent over the primary path only. The primary FortiGate will then sync the sessions and the session expectations to the Secondary FortiGate.

The following HA configuration is required (FGSP configuration is out of the scope of this article):
config system ha
    set hbdev "port1" 50
    set session-pickup enable
    set session-pickup-connectionless enable
    set session-pickup-expectation enable
    set session-pickup-nat enable
    set override disable
end
With regards to the source NAT, two kinds of NAT configuration are needed:
  -  SNAT for the primary path:
     The SNAT is applied according to IP pool configuration.
  -  SNAT for the secondary path:
     The SNAT is applied according to IP translation configuration. If no IP translation is configured for the secondary path, the source IP may be translated incorrectly.

The following configurations need to be applied:

FGT-PRI:
config firewall ip-translation
    edit 1
        set startip 10.0.0.10
        set endip 10.0.0.10
        set map-startip 100.0.0.10
    next
    edit 2
        set startip 20.0.0.10
        set endip 20.0.0.10
        set map-startip 200.0.0.10
    next
end

config firewall ippool
    edit "CLIENT_PRI_IPPOOL"
        set type one-to-one
        set startip 100.0.0.10
        set endip 100.0.0.10
    next
end

config firewall policy
    edit 1
        set name "CLIENT->SERVER_PRI"
        set srcintf "port1"
        set dstintf "port2"
        set srcaddr "CLIENT_PRI_10.0.0.10"
        set dstaddr "SERVER_PRI_100.0.0.100"
        set action accept
        set schedule "always"
        set service "ALL"
        set nat enable
        set ippool enable
        set poolname "CLIENT_PRI_IPPOOL"
    next
end

FGT-SEC:
config firewall ip-translation
    edit 1
        set startip 10.0.0.10
        set endip 10.0.0.10
        set map-startip 100.0.0.10
    next
    edit 2
        set startip 20.0.0.10
        set endip 20.0.0.10
        set map-startip 200.0.0.10
    next
end

config firewall ippool
    edit "CLIENT_SEC_IPPOOL"
        set type one-to-one
        set startip 200.0.0.10
        set endip 200.0.0.10
    next
end

config firewall policy
    edit 1
        set name "CLIENT->SERVER_SEC"
        set srcintf "port1"
        set dstintf "port2"
        set srcaddr "CLIENT_SEC_20.0.0.10"
        set dstaddr "SERVER_SEC_200.0.0.100"
        set action accept
        set schedule "always"
        set service "ALL"
        set nat enable
        set ippool enable
        set poolname "CLIENT_SEC_IPPOOL"
    next
end
Note: The firewall policy on FGT-SEC is not mandatory, it has been added to the configuration in case the session is initialized through the secondary path.

Verification
FGT-PRI:
FGT-PRI # diag sys session filter  proto 132
FGT-PRI # diag sys session list

session info: proto=132 proto_state=01 duration=211 expire=3599 timeout=3600 flags=00000000 sockflag=00000000 sockport=0 av_idx=0 use=11
origin-shaper=
reply-shaper=
per_ip_shaper=
ha_id=0 policy_dir=0 tunnel=/ vlan_cos=0/255
state=log may_dirty npu dst-vis synced f00 complex
statistic(bytes/packets/allow_err): org=3632/34/1 reply=2296/33/1 tuples=2
tx speed(Bps/kbps): 0/0 rx speed(Bps/kbps): 0/0
orgin->sink: org pre->post, reply pre->post dev=65->64/64->65 gwy=100.0.0.100/10.0.0.10
hook=post dir=org act=snat 10.0.0.10:5002→100.0.0.100:3868(100.0.0.10:5002)
hook=pre dir=reply act=dnat 100.0.0.100:3868->100.0.0.10:5002(10.0.0.10:5002)
dst_mac=5e:dc:81:0b:60:b1
misc=0 policy_id=4 auth_info=0 chk_client_info=0 vd=1
serial=000108f6 tos=ff/ff app_list=0 app=0 url_cat=0
dd_type=0 dd_mode=0
npu_state=00000000
npu info: flag=0x00/0x00, offload=0/0, ips_offload=0/0, epid=0/0, ipid=0/0, vlan=0x0000/0x0000
vlifid=0/0, vtag_in=0x0000/0x0000 in_npu=0/0, out_npu=0/0, fwd_en=0/0, qid=0/0
no_ofld_reason:
ofld_fail_reason(kernel, drv): not-established/not-established, none(0)/none(0)
npu_state_err=04/04
sctp: ctx_st=3 saddr=(10.0.0.10=>100.0.0.10, 20.0.0.10=>200.0.0.10)(2) daddr=(100.0.0.100, 200.0.0.100)(2)

FGT-PRI # diag sniffer packet any 'proto 132' 4 20
interfaces=[any]
filters=[proto 132]
3.266145 port2 in 100.0.0.100 -> 100.0.0.10:  ip-proto-132 64
3.266157 port1 out 100.0.0.100 -> 10.0.0.10:  ip-proto-132 64
3.266279 port1 in 10.0.0.10 -> 100.0.0.100:  ip-proto-132 64
3.266291 port2 out 100.0.0.10 -> 100.0.0.100:  ip-proto-132 64
FGT-SEC:
FGT-SEC # diag sys session filter  proto 132
FGT-SEC # diag sys session list

session info: proto=132 proto_state=01 duration=366 expire=3593 timeout=3600 flags=00000000 sockflag=00000000 sockport=0 av_idx=0 use=56
origin-shaper=
reply-shaper=
per_ip_shaper=
ha_id=0 policy_dir=0 tunnel=/ vlan_cos=0/255
state=log may_dirty npu f00 syn_ses complex
statistic(bytes/packets/allow_err): org=0/0/0 reply=0/0/0 tuples=2
tx speed(Bps/kbps): 0/0 rx speed(Bps/kbps): 0/0
orgin->sink: org pre->post, reply pre->post dev=58->59/59->58 gwy=0.0.0.0/0.0.0.0
hook=post dir=org act=snat 10.0.0.10:5002→100.0.0.100:3868(100.0.0.10:5002)
hook=pre dir=reply act=dnat 100.0.0.100:3868->100.0.0.10:5002(10.0.0.10:5002)
misc=0 policy_id=4 auth_info=0 chk_client_info=0 vd=1
serial=000108f6 tos=ff/ff app_list=0 app=0 url_cat=0
dd_type=0 dd_mode=0
npu_state=00000000
npu info: flag=0x00/0x00, offload=0/0, ips_offload=0/0, epid=0/0, ipid=0/0, vlan=0x0000/0x0000
vlifid=0/0, vtag_in=0x0000/0x0000 in_npu=0/0, out_npu=0/0, fwd_en=0/0, qid=0/0
no_ofld_reason:
sctp: ctx_st=3 saddr=(10.0.0.10=>100.0.0.10, 20.0.0.10=>200.0.0.10)(2) daddr=(100.0.0.100, 200.0.0.100)(2)
Above session has been synchronized from the FGT-PRI but doesn’t process any traffic on FGT-SEC
Below session comes from an expectation, it has been created upon reception of HEARTBEAT packet in the reverse direction on the secondary path (server → client) :
session info: proto=132 proto_state=00 duration=366 expire=never timeout=never flags=00000000 sockflag=00000000 sockport=0 av_idx=0 use=4
origin-shaper=
reply-shaper=
per_ip_shaper=
ha_id=0 policy_dir=0 tunnel=/ vlan_cos=255/255
state=log npu synced complex
statistic(bytes/packets/allow_err): org=1932/23/1 reply=1932/23/1 tuples=2
tx speed(Bps/kbps): 5/0 rx speed(Bps/kbps): 5/0
orgin->sink: org pre->post, reply pre->post dev=59->58/58->59 gwy=20.0.0.10/200.0.0.100
hook=pre dir=org act=dnat 200.0.0.100:3868→200.0.0.10:5002(20.0.0.10:5002)
hook=post dir=reply act=snat 20.0.0.10:5002→200.0.0.100:3868(200.0.0.10:5002)
misc=0 policy_id=4 auth_info=0 chk_client_info=0 vd=1
serial=000108f6 tos=ff/ff app_list=0 app=0 url_cat=0
dd_type=0 dd_mode=0
npu_state=0x000c00
npu info: flag=0x81/0x81, offload=8/8, ips_offload=0/0, epid=440/444, ipid=444/440, vlan=0x0067/0x0066
vlifid=444/440, vtag_in=0x0067/0x0066 in_npu=4/3, out_npu=4/3, fwd_en=0/0, qid=17/17

FGT-SEC # diag sniffer packet any 'proto 132' 4
interfaces=[any]
filters=[proto 132]
10.485112 port2 in 200.0.0.100 -> 200.0.0.10:  ip-proto-132 64
10.485125 port1 out 200.0.0.100 -> 20.0.0.10:  ip-proto-132 64
10.485294 port1 in 20.0.0.10 -> 200.0.0.100:  ip-proto-132 64
10.485303 port2 out 200.0.0.10 -> 200.0.0.100:  ip-proto-132 64

Related Articles

Configuration Guide: FortiGate Session Life Support Protocol (FGSP)

Contributors