Yuri Slobodyanyuk Blog on Information Security 2024年09月12日
Fortigate virtual IP server load balancing configuration and debug
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

文章介绍了Fortigate的多种配置,包括服务器类型、负载均衡算法、VIP设置、NAT启用等内容

🎯Fortigate的可用服务器类型众多,如http、https等,且部分服务器类型在特定模式下可用。负载均衡算法多样,每种算法的分配方式不同。

💻创建VIP进行负载均衡的步骤详细,包括健康检查监视器配置、VIP创建、真实服务器设置以及在安全规则中使用VIP等。

🔒启用NAT可隐藏客户端IP,通过在安全规则中设置实现。此外,还介绍了针对HTTPS的负载均衡配置及相关设置。

📋提供了VIP显示过滤器的相关信息,包括多种过滤参数及操作。

The general workflow is:

Facts to know:

Case 1: Load balance incoming UDP port 53 DNS requests to IP 192.168.13.55 between 2 servers 10.10.10.13 & 10.10.10.14. Use weighted load balancing algorithm, assign 1st server twice as many connections.

Step 1. Health checking monitor.
I configure all the needed for the next examples monitors here, but will use ping ICMP monitor only.

config firewall ldb-monitor    edit "PING_MNTR"        set type ping        set timeout 1    next    edit "HTTP_MNTR"        set type http        set http-get "/monitor.txt"        set http-match "Success"  <-- Case sensitive! Looks at the CONTENTS of the page returned, no regexes, exact string match.                                  <-- You don't have to set http-match, in such                                   <-- a case, Fortigate will verify to get 200 Ok when asking for the                                  <-- URL "/monitor.txt"    next    edit "TCP_MNTR"        set type tcp    nextend

Step 2. Create the VIP for incoming to 192.168.13.55 connections. Create real servers inside the VIP.

config firewall vip    edit "LDC_UDP_PORT_53"        set type server-load-balance        set extip 192.168.13.55        set extintf "port1"        set server-type udp        set monitor "PING_MNTR"   <-- I don't set individual monitors in each server, so this one will be used by default        set ldb-method weighted        set extport 53        config realservers            edit 1                set ip 10.10.10.13                set port 53                set weight 2            next            edit 2                set ip 10.10.10.14                set port 53     <-- no weight shown here as left the default = 1            next        end    nextend      

Step 3. Use the VIP in security rule.

config firewall policy    edit 1        set srcintf "port1"        set dstintf "port2"        set srcaddr "all"        set dstaddr "LDC_UDP_PORT_53"        set action accept        set schedule "always"        set service "DNS"        set logtraffic all    nextend

GUI: Feature visibility -> Load Balancing.
Policy & Objects -> Health Check.
Policy & Objects -> Virtual Servers.

Verification and debug

diagnose firewall vip realserver list

alloc=3------------------------------vf=0 name=LDC_UDP_PORT_53/2 class=4 type=2 192.168.13.55:(53-53), protocol=17total=2 alive=2 power=3 ptr=1013716ip=10.10.10.13-10.10.10.13/53 adm_status=0 holddown_interval=300 max_connections=0 weight=2 option=01   alive=1 total=1 enable=00000001 alive=00000001 power=2   src_sz=0   id=0 status=up ks=9 us=0 events=1 bytes=720 rtt=0ip=10.10.10.14-10.10.10.14/53 adm_status=0 holddown_interval=300 max_connections=0 weight=1 option=01   alive=1 total=1 enable=00000001 alive=00000001 power=1   src_sz=0   id=0 status=up ks=5 us=0 events=1 bytes=374 rtt=0

GUI:
Monitoring -> Load Balance Monitor.

I block incoming ICMP packets on 1st server 10.10.10.13. Status of the monitor/server changes to down:

# diagnose firewall vip realserver listalloc=3------------------------------vf=0 name=LDC_UDP_PORT_53/2 class=4 type=2 192.168.13.55:(53-53), protocol=17total=2 alive=1 power=1 ptr=1013716ip=10.10.10.13-10.10.10.13/53 adm_status=0 holddown_interval=300 max_connections=0 weight=2 option=01   alive=0 total=1 enable=00000001 alive=00000000 power=0   src_sz=0        id=0 status=down ks=0 us=0 events=2 bytes=720 rtt=0ip=10.10.10.14-10.10.10.14/53 adm_status=0 holddown_interval=300 max_connections=0 weight=1 option=01   alive=1 total=1 enable=00000001 alive=00000001 power=1   src_sz=0   id=0 status=up ks=0 us=0 events=1 bytes=374 rtt=0

General stats:

# get test ipldb 2num of vf=1--------dump ipldb vf=0----------num of vips=1num of registered monitor types=4num of ping monitors=0num of ping monitors=2num of tcp monitors=0num of http monitors=0

Best verification is packet sniffer. In this sniffer on Fortigate we can see that packets distribution follows (roughly) weights I assignedeach server:

# diagnose sniffer  pa port2  ' port 53' 4    interfaces=[port2]filters=[ port 53]15.257112 port2 -- 192.168.13.17.2785 -> 10.10.10.13.53: udp 016.258720 port2 -- 192.168.13.17.2786 -> 10.10.10.13.53: udp 017.259267 port2 -- 192.168.13.17.2787 -> 10.10.10.14.53: udp 018.259394 port2 -- 192.168.13.17.2788 -> 10.10.10.13.53: udp 019.259734 port2 -- 192.168.13.17.2789 -> 10.10.10.13.53: udp 020.260002 port2 -- 192.168.13.17.2790 -> 10.10.10.14.53: udp 021.260136 port2 -- 192.168.13.17.2791 -> 10.10.10.13.53: udp 022.260786 port2 -- 192.168.13.17.2792 -> 10.10.10.13.53: udp 023.261635 port2 -- 192.168.13.17.2793 -> 10.10.10.14.53: udp 024.261417 port2 -- 192.168.13.17.2794 -> 10.10.10.13.53: udp 0

7 packets out of 10 are sent to 10.10.10.13 and 3 packets to 10.10.10.14, almost the desired 2 to 1 ratio.

diagnose firewall vip virtual-server filter

diagnose firewall vip virtual-server filter ?list        Display the current filter.clear       Erase the current filter.name        VIP name to filter by.src         Source address range to filter by.dst         Destination address range to filter by.src-port    Source port range to filter by.dst-port    Destination port range to filter by.vd          Index of virtual domain. -1 matches all.negate      Negate the specified filter parameter.

Case 1.1: To the configuration above also ensure to hide clients' IPs from the servers behind the Fortigate

I haven't enabled NAT in the security rule, so servers can see real source IP of the connecting client. It is easy to fix - just enable NAT in security rule.

config firewall policy     edit 1        set srcintf "port1"        set dstintf "port2"        set srcaddr "all"        set dstaddr "LDC_UDP_PORT_53"        set action accept        set schedule "always"        set service "DNS"        set logtraffic all        set nat enable   <--- Enable interface based NAT    nextend

BEFORE (sniffer on server 2):

root@ubuntu2:~# tcpdump -n -i ens34 port 53 and host 10.10.10.14listening on ens34, link-type EN10MB (Ethernet), capture size 262144 bytes09:52:10.405443 IP 192.168.13.17.1362 > 10.10.10.14.53: domain [length 0 < 12] (invalid)09:52:11.407252 IP 192.168.13.17.1363 > 10.10.10.14.53: domain [length 0 < 12] (invalid)

AFTER:

root@ubuntu2:~# tcpdump -n -i ens34 port 53 and host 10.10.10.14listening on ens34, link-type EN10MB (Ethernet), capture size 262144 bytes09:53:07.391346 IP 10.10.10.91.63343 > 10.10.10.14.53: domain [length 0 < 12] (invalid)09:53:08.391830 IP 10.10.10.91.63344 > 10.10.10.14.53: domain [length 0 < 12] (invalid)

Case 2: Load balance HTTPS for the web site, making servers to see Fortigate as source IP of requests, but sending the real client's IP in X-Forwarded-For header

I will configure Fortigate to serve the domain yurisk.com via HTTPS on port 443 and IP of 192.168.13.56 to clients. At the same time, from Fortigate to the real servers the connections will be un-encrypted to the port 80 of the servers.

I will use SSL certificate issued by trusted CA provider to prevent browser error messages.

Step 1: Import SSL certificate for the yurisk.com domain to Fortigate.
System -> Certificates -> Import -> Local Certificate -> Certificate -> Upload ....
In this case the certificate is named yurisk_com.crt.

Step 2: Switch (if not already) to Proxy mode from Flow mode.

        config system setting           set inspection-mode proxy        end

Step 3: Create VIP as the load balancer setting HTTPS as server type. Monitor I created earlier, see above.

config firewall vip    edit "HTTPS_LDB"        set type server-load-balance        set extip 192.168.13.56        set extintf "port1"        set server-type https        set http-ip-header enable  <-- Causes Fortigate to send X-Forwarded-For header with the real IP of client        set color 3        set ldb-method round-robin        set persistence http-cookie <-- enables persistence by inserting own cookie        set extport 443        config realservers            edit 1                set ip 10.10.10.13                set port 80                set healthcheck enable                set monitor "HTTP_MNTR"            next            edit 2                set ip 10.10.10.14                set port 80                set healthcheck enable                set monitor "HTTP_MNTR"            next        end        set http-multiplex enable <-- prerequisite for X-Forwarded-For header sending        set ssl-certificate "yurisk_com" <-- Sets certificate to present clients        set ssl-mode half   <-- encrypt only client-to-Fortigate connection, leave Fortigate-to-server in clear text    nextend

In GUI the final result looks (not all options are available in GUI, e.g. health monitor for each server we can only set in CLI):

Step 4: Use the VIP in the security rule:

config firewall policy    edit 2        set name "HTTPS_LDB"        set uuid 8d77d4dc-a62f-51ea-27ab-61a3f99fe71b        set srcintf "port1"        set dstintf "port2"        set srcaddr "all"        set dstaddr "HTTPS_LDB"        set action accept        set schedule "always"        set service "ALL"        set fsso disable        set nat enable    nextend

Verification

Sniffer on real server 10.10.10.14, the client 192.168.13.17 is browsing to https://yurisk.com:

02:01:07.132439 IP 10.10.10.91.22815 > 10.10.10.14.80: <-- As NAT is enabled, Fortigate sends                                                       <-- requests with its own IP as sourceGET / HTTP/1.1 Host:yurisk.com    User-Agent: Mozilla/5 0 (X11; Linux x86_64; rv: 77.0) Gecko/20100101 Firefox/77.0  Accept: image /webp,*/*  Accept-Language: en-US,en;q=05  Accept-Encoding: gzip, deflate, br    DNT: 1  Connection: keep-alive    Cookie: FGTServer=F541F452FE3E1121DC3229A7362B3680731BE80C73AEAD68701A70FEDC4152D55F  Pragma: no-cache  Cache-Control: no-cache    X-Forwarded-For : 192.168.13.17   <-- This is the real IP of the client browsing to the website

The monitoring HTTP service looks on the server side like that:

GET /monitor.txt HTTP/1.0  User-Agent: FortiGate (FortiOS 4.0)

In diagnose debug flow session it looks like:

# id=20085 trace_id=6 func=print_pkt_detail line=5517 msg="vd-root:0 received a packet(proto=6, 192.168.13.17:60904->192.168.13.56:443) from port1. flag [S], seq 2924331034, ack 0, win 64240"id=20085 trace_id=6 func=init_ip_session_common line=5682 msg="allocate a new session-000054d0"id=20085 trace_id=6 func=fw_pre_route_handler line=183 msg="VIP-10.10.10.14:80, outdev-port1"id=20085 trace_id=6 func=__ip_session_run_tuple line=3359 msg="DNAT 192.168.13.56:443->10.10.10.14:80"id=20085 trace_id=6 func=vf_ip_route_input_common line=2591 msg="find a route: flag=04000000 gw-10.10.10.14 via port2"id=20085 trace_id=6 func=fw_forward_handler line=753 msg="Allowed by Policy-2: AV"id=20085 trace_id=6 func=av_receive line=305 msg="send to application layer"

Case 3: Load balancing SSH connections

FG3-AS1680 # config firewall ldb-monitor    edit "PING_MNTR"        set type ping    nextend
config firewall vip    edit "LOAD_BALANCE_IN"        set type server-load-balance        set extip 192.168.13.55        set extintf "port2"        set server-type tcp        set ldb-method round-robin        set extport 22        config realservers            edit 1                set ip 10.10.10.13                set port 22                set healthcheck enable                set monitor "PING_MNTR"            next            edit 2                set ip 10.10.10.14                set port 22                set healthcheck enable                set monitor "PING_MNTR"            next        end    nextend   

Verification.

port2 in 13.13.13.6.2625 -> 192.168.13.55.22: port1 out 13.13.13.6.2625 -> 10.10.10.13.22: port2 in 13.13.13.6.2626 -> 192.168.13.55.22: port1 out 13.13.13.6.2626 -> 10.10.10.14.22: 

Resources

Follow me on https://www.linkedin.com/in/yurislobodyanyuk/ not to miss what I publish on Linkedin, Github, blog, and more.

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Fortigate 负载均衡 NAT VIP设置
相关文章