---
title: "Configure HTTP load balancing for servers behind a FortiGate firewall"
sidebar_label: "Configure load balancing"
sidebar_position: 2
description: "How to configure HTTP load balancing for servers behind a FortiGate firewall"
---

import Formbricks from '@theme/MDXComponents/Formbricks'
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
import {TabItemLabel} from '@selectel/docux/components'
import PlusIcon from '@selectel/docux/icons/plus'

# Configure HTTP load balancing for servers behind a FortiGate firewall

:::info

This guide provides an example of how to configure HTTP traffic load balancing between servers behind a firewall.

:::

:::info

These instructions are relevant for FortiOS versions 6.x and 7.x. If you have a different version of FortiOS, you can find instructions in the official [FortiGate](https://docs.fortinet.com) documentation.

:::

1. If you have not yet connected the FortiGate to the servers, [connect the FortiGate firewall to the servers in the Selectel infrastructure](#create-network-fortigate-to-servers).
2. [Create a health check](#create-health-check).
3. [Create a virtual server](#create-virtual-server).
4. [Create a security policy](#create-security-policy).
5. [Verify load balancing operation](#check-load-balancer).

## 1. Connect the FortiGate firewall to the servers in the Selectel infrastructure \{#create-network-fortigate-to-servers}

Follow the instructions in [Connecting products and services via a global router](/global-router/create-network/create-global-router-network.mdx).

## 2. Create a health check \{#create-health-check}

Health Check determines the operability of a server behind the firewall based on configured parameters. If a server behind the firewall stops responding, FortiGate will redirect requests to available servers.

<Tabs queryString="create-health-check">
  <TabItem value="graphic">
    <TabItemLabel>
      Graphical interface
    </TabItemLabel>

    1. [Connect to the firewall](/firewalls/fortigate/connect-to-firewall.mdx).
    2. Make sure that in the **System** → **Feature Visibility** section, the **Load Balance** toggle is enabled. If the toggle is disabled, the sections for load balancing settings will not be displayed.
    3. Go to **Policy & Objects** → **Health Check**.
    4. Click **Create New**.
    5. In the **Name** field, enter the name of the health check.
    6. In the **Type** field, select the **HTTP** health check protocol.
    7. In the **Interval** field, enter the frequency of server health checks in seconds or leave the default value.
    8. In the **Timeout** field, enter the maximum time to wait for a response from the server behind the firewall in seconds or leave the default value.
    9. In the **Retry** field, enter the number of failed health checks after which the server behind the firewall will be excluded from load balancing or leave the default value.
    10. In the **Port** field, enter the port for checking the server behind the firewall. The default port is 80.
    11. In the **URL** field, enter the path to the file on the server behind the firewall where FortiGate will send the GET request to verify the server status. For example, `/health.html`.
    12. In the **Matched content** field, enter the text that FortiGate will look for in the GET request response body. For example, `OK`.
    13. Click **OK**.
  </TabItem>

  <TabItem value="cli">
    <TabItemLabel>
      CLI
    </TabItemLabel>

    1. [Connect to the firewall](/firewalls/fortigate/connect-to-firewall.mdx).
    2. Create a health check:

       ```bash
       config firewall ldb-monitor
           edit <health_check_name>
               set type http
               set port <health_check_port>
               set http-get "<url>"
               set http-match "<text>"
               set interval <interval>
               set timeout <timeout>
               set retry <retry>
           next
       end
       ```

       Specify:

       * `<health_check_name>` — the name of the health check;
       * `<health_check_port>` — the port for checking the server behind the firewall. The default port is 80;
       * `<url>` — the path to the file on the server behind the firewall where FortiGate will send the GET request to verify the server status. For example, `/health.html`;
       * `<text>` — the text that FortiGate will look for in the GET request response body. For example, `OK`;
       * `<interval>` — the frequency of server health checks in seconds;
       * `<timeout>` — the maximum time to wait for a response from the server behind the firewall in seconds;
       * `<retry>` — the number of failed health checks after which the server behind the firewall will be excluded from load balancing.
  </TabItem>
</Tabs>

## 3. Create a virtual server \{#create-virtual-server}

A Virtual Server accepts incoming traffic and redirects it to real servers (Real Server) — the IP address and port of the server behind the firewall. You can add multiple real servers so that FortiGate automatically distributes the load between them.

<Tabs queryString="create-virtual-server">
  <TabItem value="graphic">
    <TabItemLabel>
      Graphical interface
    </TabItemLabel>

    1. [Connect to the firewall](/firewalls/fortigate/connect-to-firewall.mdx).

    2. Go to **Policy & Objects** → **Virtual Servers**.

    3. Click **Create New**.

    4. In the **Name** field, enter the name of the virtual server.

    5. In the **Type** field, select **HTTP**.

    6. In the **Interface** field, select the firewall interface through which requests to the virtual server will arrive:

       * to have requests arrive via a single interface, select that interface. For example, **wan1**;
       * to have requests arrive via all interfaces, select **any**.

    7. In the **Virtual Server IP** field, enter the public IP address of the firewall that you received in the ticket after [ordering the firewall](/firewalls/order/order-hardware-firewall.mdx).

    8. In the **Virtual Server Port** field, enter the firewall port to which incoming requests will be directed.

    9. In the **Load Balancing Method** field, select a [load balancing method](/firewalls/fortigate/load-balancing/about-load-balancing.mdx#load-balancing-methods).

    10. Optional: to have all requests from a single user within a session handled by the same server behind the firewall, in the **Persistence** field, select **HTTP Cookie**. Learn more about session persistence in the [Session Persistence](/firewalls/fortigate/load-balancing/about-load-balancing.mdx#session-persistence) subsection of the [Load balancing protocols and methods](/firewalls/fortigate/load-balancing/about-load-balancing.mdx) guide.

    11. In the **Health Check** field, select the health check you [created in Step 2](#create-health-check).

    12. Optional: to use a single TCP connection with a server behind the firewall when processing multiple HTTP requests, enable the **HTTP Multiplexing** toggle.

    13. Optional: to preserve the user's IP address in the `X-Forwarded-For` HTTP header, enable the **Preserve Client IP** toggle.

    14. In the **Real Servers** block, click **Create New**.

    15. In the **IP Address** field, enter the private IP address of the server behind the firewall.

    16. In the **Port** field, enter the port of the server behind the firewall to which requests will be redirected. The default port is 80.

    17. Click **OK**.

    18. Repeat steps 14–17 for every server behind the firewall that you want to add to load balancing.

    19. Click **OK**.
  </TabItem>

  <TabItem value="cli">
    <TabItemLabel>
      CLI
    </TabItemLabel>

    1. [Connect to the firewall](/firewalls/fortigate/connect-to-firewall.mdx).
    2. Create a Virtual Server:

       ```bash
       config firewall vip
          edit "<virtual_server_name>"
             set type server-load-balance
             set ldb-method <load_balancing_method>
             set extip <public_ip_address>
             set extintf "<eth_name>"
             set server-type http
             set extport <public_port>
             set monitor "<health_check_name>"
             config realservers
                edit 1
                   set ip <real_server_ip_1>
                   set port <real_server_port_1>
                next
                edit 2
                   set ip <real_server_ip_2>
                   set port <real_server_port_2>
                next
             end
          next
       end
       ```

       Specify:

       * `<virtual_server_name>` — the name of the virtual server;

       * `<load_balancing_method>` — the [load balancing method](/firewalls/fortigate/load-balancing/about-load-balancing.mdx#load-balancing-methods):

         * `static` — Static;
         * `round-robin` — Round Robin;
         * `weighted` — Weighted;
         * `least-session` — Least Session;
         * `least-rtt` — Least RTT;
         * `first-alive` — First Alive;
         * `http-host` — HTTP Host;

       * `<public_ip_address>` — the public IP address of the firewall you received in the ticket after [ordering the firewall](/firewalls/order/order-hardware-firewall.mdx);

       * `<eth_name>` — the name of the firewall interface; requests will arrive only through this interface. You can view the list of interfaces using the `show system interface` command. To have requests arrive via all interfaces, specify `any`;

       * `<public_port>` — the port on the firewall to which incoming requests will be directed;

       * `<health_check_name>` — the name of the health check you [created in Step 2](#create-health-check);

       * optional: `set persistence http-cookie` — enables session persistence; all requests from a single user within a session will be handled by the same server behind the firewall. Learn more about session persistence in the [Session Persistence](/firewalls/fortigate/load-balancing/about-load-balancing.mdx#session-persistence) subsection of the [Load balancing protocols and methods](/firewalls/fortigate/load-balancing/about-load-balancing.mdx) guide. The feature is disabled by default;

       * optional: `set http-multiplex enable` — enables the use of a single TCP connection with the server behind the firewall when processing multiple HTTP requests. The feature is disabled by default;

       * optional: `set http-ip-header enable` — enables preservation of the user's IP address in the `X-Forwarded-For` HTTP header. The feature is disabled by default;

       * `<real_server_ip_1>`, `<real_server_ip_2>` — private IP addresses of servers behind the firewall;

       * `<real_server_port_1>`, `<real_server_port_2>` — ports of the servers behind the firewall to which requests will be redirected. The default port is 80.

       If you need to add more real servers, specify them in the `config realservers` code block, each on a new line. For example:

       ```bash
       config realservers
          edit 1
             set ip <real_server_ip_1>
             set port <real_server_port_1>
          next
          edit 2
             set ip <real_server_ip_2>
             set port <real_server_port_2>
          next
          edit 3
             set ip <real_server_ip_3>
             set port <real_server_port_3>
          next
       end
       ```
  </TabItem>
</Tabs>

## 4. Create a security policy \{#create-security-policy}

A security policy determines what traffic the firewall will allow between its interfaces. For example, you can use a policy to allow HTTP traffic to a virtual server. If no security policies are created, all traffic is dropped.

<Tabs queryString="create-security-policy">
  <TabItem value="graphic">
    <TabItemLabel>
      Graphical interface
    </TabItemLabel>

    <Tabs queryString="firmware-version">
      <TabItem value="fortios-6">
        <TabItemLabel>
          FortiOS 6.x
        </TabItemLabel>

        1. [Connect to the firewall](/firewalls/fortigate/connect-to-firewall.mdx).
        2. Go to **Policy & Objects** → **IPv4 Policy**.
        3. Click **Create New**.
        4. In the **Name** field, enter the name of the security policy.
        5. In the **Incoming Interface** field, select the firewall's public interface.
        6. In the **Outgoing Interface** field, select the firewall's private interface.
        7. In the **Source** field, select **all**.
        8. In the **Destination** field, select the virtual server that you [created in Step 3](#create-virtual-server).
        9. In the **Schedule** field, select **always**.
        10. In the **Service** field, select **HTTP**.
        11. In the **Action** field, select **Accept**.
        12. In the **Inspection Mode** field, select **Proxy-based**.
        13. Disable the **NAT** toggle. Servers behind the firewall will receive the original connection IP addresses.
        14. Click **OK**.
      </TabItem>

      <TabItem value="fortios-7">
        <TabItemLabel>
          FortiOS 7.x
        </TabItemLabel>

        1. [Connect to the firewall](/firewalls/fortigate/connect-to-firewall.mdx).
        2. Go to **Policy & Objects** → **Firewall Policy**.
        3. Click **Create New**.
        4. In the **Name** field, enter the name of the security policy.
        5. In the **Incoming Interface** field, select the firewall's public interface.
        6. In the **Outgoing Interface** field, select the firewall's private interface.
        7. In the **Source** field, select **all**.
        8. In the **Destination** field, select the virtual server that you [created in Step 3](#create-virtual-server).
        9. In the **Schedule** field, select **always**.
        10. In the **Service** field, select **HTTP**.
        11. In the **Action** field, select **Accept**.
        12. In the **Inspection Mode** field, select **Proxy-based**.
        13. Disable the **NAT** toggle. Servers behind the firewall will receive the original connection IP addresses.
        14. Click **OK**.
      </TabItem>
    </Tabs>
  </TabItem>

  <TabItem value="cli">
    <TabItemLabel>
      CLI
    </TabItemLabel>

    1. [Connect to the firewall](/firewalls/fortigate/connect-to-firewall.mdx).

    2. View the used security policy numbers by displaying information about the configured security policies:

       ```bash
       show firewall policy
       ```

       The response will show information about the configured security policies. For example:

       ```bash
       config firewall policy
           edit 1
              set name "my_policy"
              set srcintf "lan"
              set dstintf "wan1"
              set action accept
              set srcaddr "all"
              set dstaddr "all"
              set schedule "always"
              set service "ALL"
              set nat disable
           next
       end
       ```

       Here, `1` is the security policy number.

    3. Create a security policy:

       ```bash
        config firewall policy
            edit <policy_number>
               set name "<policy_name>"
               set inspection-mode proxy 
               set srcintf "<incoming_interface>"
               set dstintf "<outgoing_interface>"
               set srcaddr "all"
               set dstaddr "<virtual_server_name>"
               set action accept
               set schedule "always"
               set service "HTTP"
               set nat disable
            next
        end
       ```

       Specify:

       * `<policy_number>` — a free security policy number;
       * `<policy_name>` — the name of the security policy;
       * `<incoming_interface>` — the name of the firewall's public interface. You can view the list of interfaces using the `show system interface`;
       * `<outgoing_interface>` — the name of the firewall's private interface. You can view the list of interfaces using the `show system interface`;
       * `<virtual_server_name>` — the name of the virtual server that you [created in Step 3](#create-virtual-server).
  </TabItem>
</Tabs>

## 5. Verify load balancing operation \{#check-load-balancer}

<Tabs queryString="check-load-balancer">
  <TabItem value="graphic">
    <TabItemLabel>
      Graphical interface
    </TabItemLabel>

    <Tabs queryString="firmware-ver">
      <TabItem value="fortios-6">
        <TabItemLabel>
          FortiOS 6.x
        </TabItemLabel>

        1. [Connect to the firewall](/firewalls/fortigate/connect-to-firewall.mdx).
        2. Go to **Monitor** → **Load Balance Monitor**.
        3. In the **Real Server** column, next to the real server IP address, click <PlusIcon />.
        4. In the **Status** column, check the status of the servers:

           * `Up` — the server is active, FortiGate is sending requests to it;
           * `Down` — the server is not responding, FortiGate is not sending requests to it.
      </TabItem>

      <TabItem value="fortios-7">
        <TabItemLabel>
          FortiOS 7.x
        </TabItemLabel>

        1. [Connect to the firewall](/firewalls/fortigate/connect-to-firewall.mdx).
        2. Go to **Dashboard** → **Status**.
        3. Click **Add Widget** and select **Load Balance**.
        4. Click **Add Widget**.
        5. On the dashboard page, click **Load Balance**.
        6. In the **Real Server** column, next to the real server IP address, click <PlusIcon />.
        7. In the **Status** column, check the status of the servers:

           * `Up` — the server is active, FortiGate is sending requests to it;
           * `Down` — the server is not responding, FortiGate is not sending requests to it.
      </TabItem>
    </Tabs>
  </TabItem>

  <TabItem value="cli">
    <TabItemLabel>
      CLI
    </TabItemLabel>

    1. [Connect to the firewall](/firewalls/fortigate/connect-to-firewall.mdx).

    2. Check the status of the real servers:

       ```bash
       diagnose firewall vip realserver list
       ```

       The output will display information about the real servers. For example:

       ```bash
       vf=0 name=http_virtual_server/3 class=4 type=1 172.20.120.122:(3080-3080), protocol=6
       total=2 alive=1 power=0 ptr=50980085
       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=0
       src_sz=0
       id=1 status=up ks=5 us=4 events=1 bytes=28540 rtt=12
       ip=192.168.101.3-192.168.101.3/80 adm_status=1 holddown_interval=300 max_connections=0 weight=1 option=01
       alive=0 total=1 enable=00000000 alive=00000000 power=0
       src_sz=0
       id=0 status=down ks=4 us=3 events=1 bytes=21380 rtt=8
       ```

       Here, the `status` parameter shows the current state of the real server:

       * `status=up` — the server is active, FortiGate is sending requests to it;
       * `status=down` — the server is not responding, FortiGate is not sending requests to it.

    3. Verify traffic distribution between the real servers:

       ```bash
       diagnose sniffer packet <interface_name> '<filter>' <verbose>
       ```

       Specify:

       * `<interface_name>` — the name of the firewall interface through which traffic reaches the servers. For example, `wan1`;
       * `<filter>` — a filter for displaying packets. For example, `port 80`;
       * `<verbose>` — output detail level from `1` to `6`. The higher the value, the more information is displayed.
  </TabItem>
</Tabs>

<Formbricks />
