Creating FortiGate Config with Terraform

For this lab I have created a small topology with a FortiGate which will be configured with Terraform. There are two networks INSIDE 192.168.10.0/24 and DMZ 192.168.20.0/24. The other interface is for OUTSIDE this is connected into my home lab network and has an IP of 10.10.30.215.

Terraform is used to configure the FortiGate firewall, only the DHCP address from the home lab network for the OUTSIDE interface of 10.10.30.215 is not Terraform. There are two DHCP servers running on the Fortigate for each network segment INSIDE and DMZ. I have enabled internet access for the INSIDE segment and a 1 to 1 NAT to allow traffic from the OUTSIDE to reach the server in the DMZ interface using IP 10.10.30.222. Finally, there is a firewall rule to permit traffic from the INSIDE segment to the DMZ segment.

For this lab I have used FortiGate version 7.2.4, this does have limitations with firewall rules, only allowing three rules. If a fourth is added, Terrform fails. This is just trial licence issues and wouldn’t be a problem if you were to buy a licence.

Full documentation for the FortiGate provider can be found here. And the Terraform script can be found in my GitHub.

Terraform Configuration Elements

  • DHCP
  • DNS
  • Two physical interface IPs
  • Create static route to internet
  • PAT(NAT overload) for INSIDE
  • DMZ 1:1 NAT 10.10.30.222
  • Firewall rule INSIDE to DMZ

Terraform Setup

The Terraform Setup for the FortiGate appliance is very simple.
– Create API admin in FortiGate
– Use API Token and initialise Terraform

Create FortiGate API Admin

This is the user that Terraform will use to issue all configuration commands. The following steps should get the API admin user setup.

The administrative profile must be created, I have manually created full_access, to add a new profile just press select.

I have disabled the PKI, as I don’t require any certificates to be correct for my lab.

After clicking ok, the API key will be displayed. This is to be copied as it will be used inside the Terraform script.

Fortios Terraform Setup

This is the basics for setting up Terraform to use with the FortiGate appliances. Required is; IP, API token (from the username in previous step) and setting insecure for certificate checking.
Terraform will connect over HTTPS, but the certificates are self-signed so setting to insecure will ignore this.

I have created a file called main.tf in the directory C:\Users\Stef\Documents\Terraform\FortiGate>

Once this is done, open a terminal and navigate to the directory C:\Users\Stef\Documents\Terraform\FortiGate>, from here run terraform init

Terraform is now ready to go. Next is configuration of the FortiGate appliance.

Terraform Configuration

For the configuration, I have pulled these from the examples in the documentation. There are a lot of parameters that I have not used, and are left as defaults.

The examples can be found in the Terraform Fortios provider documentation. Here, you just search for what you want. Below, I have searched for interface to configure a physical interface. There are multiple matching results, but the one that is required is fortios_system_interface.

All configuration uses only single resource. Only the NAT for the DMZ server is another resource referenced. More on this below.

In the FortiGate configuration, a Virtual IP (VIP) is created that maps the OUTSIDE IP to the DMZ IP. This VIP is referenced by the firewall policy to perform the NAT. In the below config the VIP name is DMZ_NAT_IN, this is referenced in the firewall policy under dstaddr (second code block).

The full terraform script is below

Deploying the Configuration

To deploy the configuration, I have used terraform plan to first show the changes that will be made. Any line with a + is a new configuration that will be added. Any line with a - is a line that will be removed. As this is a new FortiGate there won’t be any config to be removed.
I have included a partial output below. The entire things is quite long.

Now I am happy with the configuration I will use terraform apply -auto-approve, this will apply the configuration. As this is a lab, I do not require any interaction to confirm the application of the config.

Testing the Configuration

There is quite a lot to test, DHCP, DNS, NAT, PAT and the firewall rules. I’m going to test; the NAT for the DMZ server, the PAT for the INSIDE server and the firewall rules from the INSIDE server to the DMZ server.

The server named MetasploitableVM-1 is pingable as the IP 10.10.30.222

The Kali Linux server is also able to reach the internet and is NATed to the IP of the OUTSIDE interface, port 1 of 10.10.30.215.

The last test is for the connectivity between the two segments, INSIDE and DMZ. For this, I will simply run an Nmap port scan. The firewall rule from INSIDE to DMZ is a permit IP any any type policy.

Leave a Comment

Your email address will not be published. Required fields are marked *