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:
- Go to Policy & Objects → Health Check.
- Click Create New.
- Enter a name in the Name field.
- Specify the HTTP type in the Type field.
- Enter a port in the Port field (the default for HTTP traffic is 80).
- Enter your search phrase in the Matched content field.
- 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:
- Go to Policy & Objects → Virtual Servers.
- Click Create New.
- Enter a name in the Name field, specify the HTTP type in the Type field, and the interface in the Interface field.
- Specify the external IP address and port to which requests will be received in the Virtual server IP and Virtual server port fields
- From the Load balancing method drop-down menu, select the load balancing method that suits your case.
- Enable Persistence to persist session data by selecting the HTTP Cookie value.
- Select the Health check health monitor created earlier by clicking +.
- 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.
- 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:
- In the Policy & Objects → Virtual Servers section, where the Virtual Server configuration continues, create Real Servers.
- Click Create New in the Real Servers table.
- 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.
- Click OK.
- Add all servers involved in load balancing by repeating steps 1-4.
- 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:
- Go to System → Certificates.
- Make sure Certificates is enabled in System → Feature Visibility.
- Select Import → Local Certificate.
- Set Type — Certificate in the new window and upload Certificate file and Key file for your certificate.
- 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:
- Go to Policy & Objects → Pv4 Policy.
- Click Create New.
- Enter the policy name in the Name field.
- Specify the Incoming interface and the Outgoing interface behind which the servers are connected.
- Select the all object in the Source field by pressing +.
- 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.
- Disable NAT mode so that the servers can “see” the IP addresses of the connecting clients.
- 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.
- 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 Monitor → Load 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