ADC Guide
ADC Guide
This document is intended to provide the SE with a tool to show to the Customers
and Partners the main functionalities of the Fortinet devices with virtual machine.
It has several step by step exercises to configure and setup all the devices and
how to show it to the customer.
1 Prerequisites
The entire laboratory runs inside a ESX located Sunrise’ lab, so you only need a
browser or RDP client to access it.
If you still don’t have the VPN to Sunrise lab, ask for latam_cse@fortinet.com about
how to configure that.
2 Connectivity Diagram
This lab guide will indicate the required access to each VM.
3 Initial Setup
3.1 Start webpage
You can access to the start web page hosted in Router/bastion via
http://10.20.66.xx and there you will find the topology and shortcut to access via
web to all VM, also info about how to access the VMs via RDP or SSH
Check the DNS configuration of the server. Go to cd/etc and edit check the file
resolv.conf. Should have the next ip:
Connect to FAD1 GUI through HTTP with admin and no password.You’ll see a
welcome wizard that helps on initial configuration. Hit cancel since we will not use
it in this lab.
Go to Networking > Interface, then Networking > Routing, and check configuration
(do not change it since it was previously configured as required for this lab):
There’s no need to configure anything, it was previously configured for you. The
intention is just to get familiarized with the FortiADC GUI.
Open SSh session in FAD1 and Test ping to the following IPs from FAD1:
In both FortiADC, go to Log & Report > Log Setting and enable all log options. This
will be necessary for some of the labs in this document:
In this lab we will configure Layer4 Load Balance in FortiADC 1. We will create a
virtual server and load balance TCP traffic between WEB1 and WEB2.
There are some health checks created by default. Go to Shared Resources >
Health Check and see how they are configured. See the LB_HLTHCK_HTTP
details:
Go to Server Load Balance > Real Server Pool > Real Server and create both
webservers:
Now open a RDP session to Router-Bastion, open the web browser and try to
access http://198.51.100.10 and… it does not work!
Why????
To save some time, let’s consider (and that’s true) Router-Bastion and FGT are
correctly configured. So, let’s start with a packet capture in FAD1 through CLI.
Open a SSH session to FAD1 (not with the display option since it does not accept
some characters required here) and run the following command to capture
packets:
Then try accessing it again from Router-Bastion. You might see something like this
(203.0.113.17 is the Router-bastion IP):
Question: what happened? Why you can see traffic arriving at port2, leaving at
port3 to the real servers, but no traffic back from servers?
In our case, the traffic does not return from WebServers to FAD because they do
not have FAD as a default gateway. You could fix that by pointing a route to FAD
port3 IP, but what if you can’t do that for any reason?
By default, FAD L4 SLB Virtual Server uses the DNAT Packet Forwarding Method,
meaning it changes only the destination IP (from the VIP to the real server IP, as
we’ve seen in the packet capture). Another option is to set it as FullNAT, where
the source IP is also changed.
Edit the Virtual Server and change the forwarding method to FullNAT:
Then select it in the Virtual Server Pool List and hit ok:
Note: WebServers are different on purpose for this lab so we can identify
easily where we’ve connected, in real life they should have the same content
since it’s intended to load balance the same application.
In FAD1, go to FortiView > Virtual Server, click over VS_Web_DMZ1 and select
the Session section. You should see the sessions with information on the IP Pool
used as source IP and the webserver it has connected:
From the previous session list, we can see that there’s no persistence, since some
sessions go to WEB1 and others to WEB2.
To configure persistence, edit the Virtual Server and choose one method:
Go to Router Bations, then, run this command to connect to server several times
to see the behavior:
Run the command to connect to server several times to see the behavior:
Go to Log & Report > Log Browsing > Traffic Log > SLB L4. You will also see that
all traffic is going to only one server due to persistence.
In this lab we will change the load balancing to be Layer 7, which enables a few
features compared to Layer 4 SLB. We will use FAD1 only.
Go to Server Load Balance > Virtual Server and edit to change to Layer 7:
Question: notice that there’s no option to define the packet forwarding method, and
the NAT Source Pool is present, do you know why?
That’s because L7 SLB always works as Full Nat. If you do not define a NAT
Source Pool then FAD will use it’s own interface IP when connecting to the
webservers.
Also, notice that there are two new options in the top for Security and Application
Optimization:
curl http://198.51.100.10 -v
Open the log details from the top log event (the last one that happened) and notice
the user agent:
From the Router-Bastion, run the command to connect to server several times to
see the behavior:
Click over VS-Web-DMZ1 link and check all analytics options available:
Question: why is it considered offline when we also defined ping as a valid health
check option to the server?
Review the health check, it should be configured as ping AND http.
Test again navigating in the website from the Router-Bastion browser. Click over
the links in the webserver, then check SLB HTTP Traffic log details.
Wait a few seconds and verify that WEB2 is considered online again. Check logs
to see health check monitoring:
Now let’s suppose the network admin decided to replicate the same environment
in a second datacenter (with DMZ2, FAD2 and WEB3/4). The intention here is not
only having a SLB to local users from LAN2, but also provide redundancy for
external users accessing this service.
Cancel the wizard popup, then go to Server Load Balance > Real Server Pool.
Create two new Real Servers for WEB3 and WEB4:
Notice that the internal network DMZ1,2 is routed in Fortigates and Router, but if
you want to publish the VS in the WAN network or Internet, you can create a VS
with a WAN/Public in order to have a VS with a routed IP, instead of having a VS
with an internal IP that cannot be reached for external users.
In general tab, create the VS with a Public IP assigned linked to WAN3 segment
Add VS:
Crete VIPs that allow traffic to VS published using the Public IP option on VS in
the last step.
Before testing, go to Log & Report > Log Setting and enable all available logs:
Now we can finally configure Global Load Balancing between datacenter1 (where
FAD1 is) and datacenter2 (where FAD2 is).
In a GLB environment, the participant FortiADCs (or another external, which is not
our case here) have to work as the authoritative DNS server for the domain they
are protecting. FortiADCs “talk” each other and validate which servers are up
before sending a DNS response to an external user, thus avoiding them to send
requests to broken/unavailable web servers.
Go to Global Load Balance > Global Object > Server and delete the existing default
DNS-Server object. Then, go to Data Center and check there’s an already created
default datacenter. Delete this one, then create 2 new datacenters named DC1
and DC2 (it will help us understanding GLB better later):
Go to Global Load Balance > Global Object > Server and create two new servers:
The first one is local, we will name it Servers-DMZ1 and enable the Auto Sync
option, so it loads automatically every SLB object (the Virtual Server) created:
In the IP address field you need to set the FAD2 IP, so FAD1 can communicate
with it and get the SLB servers automatically (use the Discover button for that).
If you didn’t have communication with the other FAD, then you’d have to configure
it as Generic and set the virtual server manually.
So far we have already GSLB configured, but only one DNS server, so let’s
configure GSLB in the FAD2.
Go to Global Load Balance > Global Object > Server and delete the existing default
DNS-Server object. Then, go to Data Center and check there’s an already created
default datacenter. Delete this one, then create 2 new datacenters named DC1
and DC2 (it will help us understanding GLB better later):
Go to Global Load Balance > Global Object > Server and create two new servers:
The first one is local, we will name it Servers-DMZ2 and enable the Auto Sync
option, so it loads automatically every SLB object (the Virtual Server) created:
In the IP address field you need to set the FAD1 IP, so FAD2 can communicate
with it and get the SLB servers automatically (use the Discover button for that).
If you didn’t have communication with the other FAD, then you’d have to configure
it as Generic and set the virtual server manually.
Go to Link Load balance > Link Group >Gateway and add a Gateway there
Now the VS from DC1 will be available if the link is available as well base don the
health check configured on the gateway settings.
To the same steps in FAD2, because the Sync option is enabled on GSLB
config, you will see the gateway seting configured on FAD1 in the FAD2
To test that the DNS is working properly, we will use the nslookup tool.
This command queries the DNS server 198.51.100.2 (FAD1) about name
resolution for www.fortilab.local:
Since everything is ok with all FAD and servers, it returns both virtual servers.
Repeat the command several times, and you’ll see that it round-roubin the
sequence of servers:
In that case, FAD1 already discovered that FAD2 virtual server is not reachable,
then it removes this IP from the DNS answers to avoid external users to try
connecting to datacenter2.
Also check FortiView > GLB > Host > fortilabWeb graphs:
Then, go to Log & Report > Log Browsing and verify GLB generated logs:
From the Router-Bastion you won’t be able to reach FAD2 as DNS of course. But
let us check Fortiview on FAD, you will see that from FAD2 point of view, the
unavailable server is FAD1, so it keeps answering with its local IP but removes
FAD1 virtual server from the DNS answers.
Enable FortiGate WAN3,WAN4 interface again and verify that DNS resolution
returns in both virtual servers again.
Go to FAD2 and make unavailable the WEB3 and WEB4 server changing the
health condition on Server Load balance> Real Server Pool. Just add another
Health check condition that real server do not respond as HTTPS HC.
On Fortiview
In this case links are available and both FADC too, but not the Real servers.
Remove the HTTPs Healtch check for the Pool again and restore the GSLB
service.
Enable Ping again on FG1 DMZ1 interface and check all VS are available now.
Go to Link Load balance>Link Group > Gateway and create a gateway for each
link usinh Healtch Check ICMP.
Create the policy that will match to this LLB group created. We are going to redirect
ICMP traffic to this Link Group.
Now we need to create a NAT policy in order to enable outbound traffic to reach
Internet. Go to Networking>NAT>Source
For WAN3
In the last exercise we create GSLB and base balance decision on VS and RS
status, in this exercise we are going to link a VS to a GW in order to make
Balance decision on the link health.
Remember that in the exercise 7.2 we create a VS with the internal IP, but using
the Public IP feature in order to use that routable IP in GSLB, instead of the
internal one. Now we are going to modify those VS using Public IP attached to
the Port 4 and port 5
Go to Server Load Balnace> Virtual Server and Edit VS-DMZ2-WAN4 and VS-
DMZ2-WAN4 to use the public IP as the IP of the VS:
For VS-DMZ2-WAN3
Change the Address to 203.0.113.52, edit the interface to port4 and remove the
Public IPv4 field
Change the Address to 203.0.113.68, edit the interface to port5 and remove the
Public IPv4 field
Go to Global Load Balance > Global Object> Servers and edit Servers DMZ2
Now you have the domain www.illbweb.local published in WAN1 and WAN2 and
balanced among those links.
Now lets simulate that one gateway fails for the Health Check, this could be that
it does not respond for a ping, the service monitored is down, among others, not
Go to Link Load Balance>Link Group> Gateway and edit WAN3. Add a second
health Check as HTTPS and change the Health Check Relationship form OR to
AND
Since our webservers are not exactly equal, we will enable maintain mode in
WEB2 to force all traffic to go to WEB1 and make our labs easier.
Go to FAD1 SLB > Real Server Pool, open the existing pool and enable maintain
in WEB2 (keeping only WEB1):
Now let’s create a rule to redirect someone that eventually tries that to go to
index.php instead of showing an error.
In the FAD1 GUI, go to Server Load Balance > Virtual Server > Content Rewriting
and create a new rule:
Now suppose we really have two different webservices: the default one is WEB2,
but when someone tries to access http://198.51.100.10/setup.php then it should
go to WEB1.
First let’s configure the virtual server to send traffic only to WEB2. We can do that
going to SLB > Real Server Pool, editing the VS_WEB-DMZ1, editing WEB2 and
disabling it:
The first is to route every access to setup.php to the pool with WEB1 (Webpool-
petsite):
IMPORTANT: content routing rules are applied in sequence, so the default must
be the last one!
10 Scripting
Before start this lab, please remove all Content and rewrite rule created before in
the VS FADC1
Go to Server Load Balance > Scripting and create a new script named “Redirect-
curl”:
Here is the same content so you can copy-paste (we’re not that evil):
when HTTP_REQUEST{
agent = HTTP:header_get_value("User-Agent")
if agent:lower():find("curl") then
HTTP:redirect("http://www.fortinet.com")
end
}
Go to Server Load Balance > Virtual Server and edit the VS-Web-DMZ1 virtual
server to add this script:
curl http://198.51.100.10 -v
Now edit the Redirect-curl script and set “mozilla” instead of “curl”:
Try from the web browser and using curl again to see the differences now.
Question 1: where to find which user-agent text to match? Look at the SLB HTTP
logs.
This lab intention is to briefly explain how to start working with scripts. Check the
existing scripts to understand better how they are and have some ideas on what
is possible to do.
FortiADC includes since 5.3 a new set of WAF feature that covers all the OWAP
Top 10 domain, we will test some in the lab.
But before we start, let’s remove the scripts, HTTP rewrite and content routing
from the virtual server – this is only to remove variables and concentrate on
authentication only, but of course they can coexist in real life.
Also, we will keep only WEB1 enabled since this webserver was previously
prepared with lots of vulnerabilities required later in this lab (it is based in DVWA).
Go to Server Load Balance > Virtual Server, edit the VS-Web-DMZ1 and configure
as indicated:
Also test from Router-Bastion, you should see that fluffy cat
FortiADC can force authentication before allowing clients to connect to certain (or
any) section of the website. In our case we will authenticate any access to the
website with a local user.
Edit the VS-Web-DMZ1 virtual server and set the authentication policy in General
Tab:
FortiADC includes a WAF to protect against some common attacks and full
OWASP compliance at webserver, although it does not have all features compared
with a FortiWeb (AI for example as the most important). Our WEB1 VM have a lot
of vulnerabilities, we will test then first, then enable some WAF rules and repeat to
check results.
Before we configure any WAF protection, let’s verify some known vulnerabilities in
our webserver.
11.2.1 SQLInjection
Click in the menu option Search user (SQL Injection).
x' OR '1’=’1
Finally go to Server Load Balance > Virtual Server, edit VS-Web-DMZ1 and include
the WAF profile in the security section:
Now let’s try two XSS attackas, first go to the menu Guestbook(XSS Stored)
<script>alert(Forti)</script>
Lets try to execute some commands form the webserver, go to the Menu Bath
Time (Command injection) and type the command
;cat /etc/passwd
To show the local file passwd
Run the command again in the web server and check the results and logs
To protect against that, you can set a HTTP protocol constraint rule.
Try then accessing the website from Router-Bastion, but using a long URL (does
not matter the text, as long as it has more than 50 characters to trigger the rule):
We won’t test attacks for each option, so try to understand what each one is about
and ask for instructor’s explanation.
Go to WebApplication Firewall > Web Vulnerability Scanner and create a new WVS
Login that indicates no login is required:
Finally, create a WVS Task (it will request you to create a schedule too, that can
be also done in Shared Resources > Schedule Group):
Download and open the report to see al details. Navigate on its options.
11.4 Antidefacement
Now connect to WEB1 via ssh and delete the file index.php
Wait until you see the file restored again in the folder and then see on logs that
the file was restored
First Login into the Router-Bastion via ssh with user root password fortinet. Go to
the Folder /home/Fortinet/Login and run the script ml-test-attack.sh as follow
Check that the Script try to login with several username and password to the
server. Stop it some seconds later.
Check traffic logs to see that those logins arrive to the server:
Now go to WAF profile created previously and link the Brute force rule to it.
Remove also HTTP Constraint in order to avoid detection in this setting.
To facilitate our packet captures in the next exercises, we need to disable HTTP
health check – otherwise we would have some difficulties to separate them from
the client traffic. To do so, go to Server Load Balance > Real Server Pool and edit
the WebPool-DMZ1. Keep only ICMP:
Go to FAD1 command line through SSH and run the following capture:
Then open the website from Router-Bastion again and see the captured packets.
Source IP is always from the FAD itself:
To change that, go to Server Load Balance > Application Resources and create a
new HTTP profile with the Source Address option enabled:
Another option to make the real client IP reach the server is by adding some
information in the header as X-Forwarded-For.
Access the website from Router-Bastion again, stop the capture and download it
to your laptop.
If you don’t have Wireshark or any other equivalent tool, trust the picture below or
check with other students:
Then go to FortiADC SSH console and run the following command to get all TCP
SYN packets:
Notice that for each SYN packet received in port2 (DMZ1) there’s also a SYN
packet in port2 (SRV1) to the server.
Still from CLI, set this connection pool in the VS-Web-DMZ1 virtual server:
Stop the script running at Router-Bastion, then run the capture from FAD SSH
console again, then start the Router-Bastion script again.
Tip: FortiADC is reusing the same TCP connection to the webserver for multiple
client connections.