Configuring a Load Balancer

In this configuration, the load balancer distributes HTTP traffic from the Internet to three web servers on the internal network. HTTP sessions are accepted at the wan1 interface with destination IP 172.20.120.121 on TCP port 3080 and forwarded from the internal interface to the web servers. When forwarded, the destination address of the sessions is translated to the IP address of one of the web servers. Balancing HTTPS traffic is performed similarly.

Adding Health Check

HTTP

To add a health check, create a Health Check at the HTTP level for which the /index.html URL and ctel content can be fine-tuned.

To configure Health Check, which sends get requests to http://<real_server_IP_address>/index.html and searches the returned web page for the «Selectel» phrase, follow these steps:

  1. Go to Policy & ObjectsHealth Check.
  2. Click Create New.
  3. Enter a name in the Name field.
  4. Specify the HTTP type in the Type field.
  5. Enter a port in the Port field (the default for HTTP traffic is 80).
  6. Enter your search phrase in the Matched content field.
  7. If necessary, specify other parameters similar to the image below.

HTTPS

A similar Health Check is added to monitor the server health at the HTTPS level, only without a detailed check of the content and URL.

Creating a Virtual Server

HTTP

Virtual Server for HTTP

To create a Virtual server that will receive HTTP requests:

  1. Go to Policy & ObjectsVirtual Servers.
  2. Click Create New.
  3. Enter a name in the Name field, specify the HTTP type in the Type field, and the interface in the Interface field.
  4. Specify the external IP address and port to which requests will be received in the Virtual server IP and Virtual server port fields
  5. From the Load balancing method drop-down menu, select the load balancing method that suits your case.
  6. Enable Persistence to persist session data by selecting the HTTP Cookie value.
  7. Select the Health check health monitor created earlier by clicking +.
  8. Enable HTTP multiplexing if you need to use a single TCP connection between the web client and the server, including for incoming unrelated requests and responses.
  9. Enable Preserve client IP to store the client’s IP address in the X-Forwarded-For HTTP header. This can be useful when enabling HTTP multiplexing, if you need to keep the original IP address of the client on the real servers, for example, in log messages.

Connecting Real Servers to a Virtual Server

To connect real servers to a virtual one:

  1. In the Policy & ObjectsVirtual Servers section, where the Virtual Server configuration continues, create Real Servers.
  2. Click Create New in the Real Servers table.
  3. Add the IP address and port of the server that you want to connect to, in the new window. In this case, the HTTP server is deployed on port 80.
  4. Click OK.
  5. Add all servers involved in load balancing by repeating steps 1-4.
  6. Save the Virtual Server settings by clicking OK.

HTTPS

You need to upload an SSL certificate for the FortiGate load balancer to work.

Importing an SSL Certificate

To add a certificate:

  1. Go to SystemCertificates.
  2. Make sure Certificates is enabled in SystemFeature Visibility.
  3. Select ImportLocal Certificate.
  4. Set Type — Certificate in the new window and upload Certificate file and Key file for your certificate.
  5. Enter your password in the Password field.

After that, the server certificate will appear in the Certificates list.

Virtual Server for HTTPS

For HTTPS, a virtual server is created in the same way as for HTTP, specifying the Virtual Server type in the Type field to HTTPS.

You can set Persistence to an SSL Session ID (in addition to HTTP Cookie).

To speed up the SSL connection, select the required mode in the Mode field in the SSL Offloading subsection, thus defining which network segment will be offloaded: Client-FortiGate or Full.

Also select the SSL certificate you imported earlier from the drop-down menu in the Certificate field.

Connecting Real Servers to a Virtual Server

In the Real Servers subsection, similarly add the real servers between which the load will be balanced. Specify the correct ports on which the web servers are deployed for HTTPS traffic (port 443 by default).

Creating a Policy

To create a security policy that includes the load balance virtual server as the destination address:

  1. Go to Policy & ObjectsPv4 Policy.
  2. Click Create New.
  3. Enter the policy name in the Name field.
  4. Specify the Incoming interface and the Outgoing interface behind which the servers are connected.
  5. Select the all object in the Source field by pressing +.
  6. Select the virtual load balancer you created earlier in the Destination field. Please note that it is important that the Inspection mode is set to Proxy-based in the policy settings. If the mode is set to Flow-based, then the virtual server will be unavailable.
  7. Disable NAT mode so that the servers can “see” the IP addresses of the connecting clients.
  8. For the HTTP and HTTPS load balancer, policies are created in the same way. The only difference is the selection of the virtual server in the Destination field.
  9. Click OK to save the policy settings.

Result

HTTP traffic load balancing between three servers was configured in this example.

Requests received at the virtual server address 172.20.120.121:3080 are redirected to the real servers one by one according to the selected method.

The following shows how switching between servers occurs when accessing the same address. For clarity, the content on each server is different.

To enable display of the balancer server statuses, go to the MonitorLoad Balance Monitor section (for FortiOS version 6.2):

You can use the following console diagnostic commands to view the status for virtual and real load-balanced servers:

# diagnose firewall vip realserver ?
list           list
up             Change address up.
down           Change address down.
healthcheck    Server health check.
clear          Clear firewall VIP, VIP6, VIP46, VIP64 real server statistics.
#diagnose firewall vip virtual-server ?
real-server    Real-server diagnostics.
stats          Statistics.
filter         Filter for various virtual server diagnostics.

For example, the following commands list and display information about the status of all real servers:

# diagnose firewall vip virtual-server real-server
vd root/0  vs HTTP_Virtual_Server/8  addr 192.168.101.2:80  status 2/1 (process 3400)
  conn: max 0  active 0  attempts 0  success 0  drop  0  fail 0

vd root/0  vs HTTP_Virtual_Server/8  addr 192.168.101.3:80  status 2/1 (process 3400)
  conn: max 0  active 0  attempts 0  success 0  drop  0  fail 0

vd root/0  vs HTTP_Virtual_Server/8  addr 192.168.101.4:80  status 2/1 (process 3400)
  conn: max 0  active 0  attempts 0  success 0  drop  0  fail 0
...
# diagnose firewall vip realserver list 
alloc=4
------------------------------
vf=0 name=HTTP_Virtual_Server/8 class=4 type=1 213.232.199.178:(3080-3080), protocol=6
total=3 alive=3 power=3 ptr=190910308
ip=192.168.101.2-192.168.101.2/80 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=33522 rtt=0
ip=192.168.101.3-192.168.101.3/80 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=90135 rtt=0
ip=192.168.101.4-192.168.101.4/80 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=46431 rtt=0

Many diagnostic commands involve retrieving information about one or more virtual servers. To control which servers are requested, you can define a filter:

# diagnose firewall vip virtual-server filter ?
	vd: any
	virtual-server: any
	source ip: any
	dest ip: any
	source port: any
	dest port: any

The most obvious test is the packet sniffer. Using the following command in FortiGate, you can track the traffic distribution with the installed port and interface filters:

# diagnose sniffer pa lan ' port 80 ' ?
<verbose>    
1: print header of packets
2: print header and data from ip of packets
3: print header and data from ethernet of packets (if available)
4: print header of packets with interface name
5: print header and data from ip of packets with interface name
6: print header and data from ethernet of packets (if available) with intf name
# diagnose sniffer  pa lan  ' port 80' 4
interfaces=[lan]
filters=[ port 80]
5.311722 lan -- 192.168.100.99.5006 -> 192.168.101.4.80: ack 3239918662 
5.311743 lan -- 192.168.101.3.80 -> 192.168.100.99.10948: syn 2478242486 ack 1197038930 
5.311796 lan -- 192.168.100.99.10948 -> 192.168.101.3.80: ack 2478242487 
5.311805 lan -- 192.168.100.99.5006 -> 192.168.101.4.80: psh 298401776 ack 3239918662 
5.311882 lan -- 192.168.100.99.10948 -> 192.168.101.3.80: psh 1197038930 ack 2478242487 
5.311896 lan -- 192.168.101.2.80 -> 192.168.100.99.3235: syn 63859594 ack 3621132829 
...
# diagnose sniffer  pa lan  ' port 80' 5
…
5.823857 lan -- 192.168.101.4.80 -> 192.168.100.99.6445: psh 144329992 ack 2029802169 
0x0000	 4500 0244 acb0 4000 3e06 434b c0a8 6504	E..D..@.>.CK..e.
0x0010	 c0a8 6463 0050 192d 089a 4d08 78fc 52b9	..dc.P.-..M.x.R.
0x0020	 8018 00eb 5cbb 0000 0101 080a 0265 4801	....\........eH.
0x0030	 0c5d 6f29 4854 5450 2f31 2e31 2032 3030	.]o)HTTP/1.1.200
0x0040	 204f 4b0d 0a44 6174 653a 2046 7269 2c20	.OK..Date:.Fri,.
0x0050	 3233 204f 6374 2032 3032 3020 3133 3a31	23.Oct.2020.13:1
0x0060	 373a 3233 2047 4d54 0d0a 5365 7276 6572	7:23.GMT..Server
0x0070	 3a20 4170 6163 6865 2f32 2e34 2e31 3820	:.Apache/2.4.18.
0x0080	 2855 6275 6e74 7529 0d0a 4c61 7374 2d4d	(Ubuntu)..Last-M
0x0090	 6f64 6966 6965 643a 2054 6875 2c20 3031	odified:.Thu,.01
0x00a0	 204f 6374 2032 3032 3020 3132 3a34 373a	.Oct.2020.12:47:
0x00b0	 3238 2047 4d54 0d0a 4554 6167 3a20 2264	28.GMT..ETag:."d
0x00c0	 642d 3562 3039 6236 6233 3836 3161 3422	d-5b09b6b3861a4"
0x00d0	 0d0a 4163 6365 7074 2d52 616e 6765 733a	..Accept-Ranges:
0x00e0	 2062 7974 6573 0d0a 436f 6e74 656e 742d	.bytes..Content-
0x00f0	 4c65 6e67 7468 3a20 3232 310d 0a56 6172	Length:.221..Var
0x0100	 793a 2041 6363 6570 742d 456e 636f 6469	y:.Accept-Encodi
0x0110	 6e67 0d0a 4b65 6570 2d41 6c69 7665 3a20	ng..Keep-Alive:.
0x0120	 7469 6d65 6f75 743d 352c 206d 6178 3d31	timeout=5,.max=1
0x0130	 3030 0d0a 436f 6e6e 6563 7469 6f6e 3a20	00..Connection:.
0x0140	 4b65 6570 2d41 6c69 7665 0d0a 436f 6e74	Keep-Alive..Cont
0x0150	 656e 742d 5479 7065 3a20 7465 7874 2f68	ent-Type:.text/h
0x0160	 746d 6c0d 0a0d 0a3c 2144 4f43 5459 5045	tml....<!DOCTYPE
0x0170	 2068 746d 6c3e 0a3c 6874 6d6c 3e0a 2020	.html>.<html>...
0x0180	 3c68 6561 643e 0a20 2020 203c 7469 746c	<head>.....<titl
0x0190	 653e 4d59 2057 4542 2053 4552 5645 5220	e>MY.WEB.SERVER.
0x01a0	 3321 3c2f 7469 746c 653e 0a20 203c 2f68	3!</title>...</h
0x01b0	 6561 643e 0a20 203c 626f 6479 3e0a 2020	ead>...<body>...
0x01c0	 2020 3c63 656e 7465 723e 0a20 2020 2020	..<center>......
0x01d0	 2020 203c 696d 6720 7372 633d 222f 6963	...<img.src="/ic
0x01e0	 6f6e 732f 7562 756e 7475 2d6c 6f67 6f2e	ons/ubuntu-logo.
0x01f0	 706e 6722 2f3e 0a20 2020 2020 2020 203c	png"/>.........<
0x0200	 6831 3e53 656c 6563 7465 6c3a 204d 7920	h1>Selectel:.My.
0x0210	 7765 6220 7365 7276 6572 2033 213c 2f68	web.server.3!</h
0x0220	 313e 0a20 2020 203c 2f63 656e 7465 723e	1>.....</center>
0x0230	 0a20 203c 2f62 6f64 793e 0a3c 2f68 746d	...</body>.</htm
0x0240	 6c3e 0a0a                              	l>..
...

You can also monitor traffic on the server itself, for example, using the tcpdump command. The following shows the traffic with NAT disabled when configuring the policy for the load balancer on FortiGate so that the client’s outgoing IP address can be tracked:

root@server1:~# tcpdump -n -i eth1 port 80 and host 192.168.101.2
6:59:19.400119 IP 37.134.185.89.32924 > 192.168.101.2.80: Flags [P.], seq 1:577, ack 1, win 11, options [nop,nop,TS val 200141474 ecr 21914156], length 576: HTTP: GET / HTTP/1.1
16:59:19.400134 IP 192.168.101.2.80 > 95.213.254.17.32924: Flags [.], ack 577, win 236, options [nop,nop,TS val 21914156 ecr 200141474], length 0
16:59:19.400556 IP 192.168.101.2.80 > 95.213.254.17.32924: Flags [P.], seq 1:508, ack 577, win 236, options [nop,nop,TS val 21914156 ecr 200141474], length 507: HTTP: HTTP/1.1 200 OK
16:59:19.401566 IP 95.213.254.17.32924 > 192.168.101.2.80: Flags [.], ack 508, win 11, options [nop,nop,TS val 200141474 ecr 21914156], length 0
16:59:22.805985 IP 192.168.101.2.80 > 192.168.100.99.9742: Flags [F.], seq 529, ack 216, win 235, options [nop,nop,TS val 21915007 ecr 200141319], length 0

When NAT is enabled, the FortiGate address is displayed as the outgoing IP address:

root@server1:~# tcpdump -n -i eth1 port 80 and host 192.168.101.2
17:29:26.994943 IP 192.168.100.99.11512 > 192.168.101.2.80: Flags [P.], seq 1:216, ack 1, win 11, options [nop,nop,TS val 200322233 ecr 22366034], length 215: HTTP: GET /index.html HTTP/1.1
17:29:26.994984 IP 192.168.101.2.80 > 192.168.100.99.11512: Flags [.], ack 216, win 235, options [nop,nop,TS val 22366055 ecr 200322233], length 0
17:29:26.995400 IP 192.168.101.2.80 > 192.168.100.99.11512: Flags [P.], seq 1:529, ack 216, win 235, options [nop,nop,TS val 22366055 ecr 200322233], length 528: HTTP: HTTP/1.1 200 OK
17:29:26.996429 IP 192.168.100.99.11512 > 192.168.101.2.80: Flags [.], ack 529, win 11, options [nop,nop,TS val 200322233 ecr 22366055], length 0
17:29:31.986638 IP 192.168.101.2.80 > 192.168.100.99.11512: Flags [F.], seq 529, ack 216, win 235, options [nop,nop,TS val 22367303 ecr 200322233], length 0