FortiGate Next Generation Firewall utilizes purpose-built security processors and threat intelligence security services from FortiGuard labs to deliver top-rated protection and high performance, including encrypted traffic.


This article describes the operations that need to be performed on an ARM platform with KVM virtualization support for deploying a FortiGate.



Consider this material as a proof of concept that only focuses on the steps involved in the configuration of the ARM device and, in the guest VM deployment. The ARM technology is largely adopted by industrial vendors that offer rugged appliances aiming to be installed close to the field devices for running control applications.



Raspberry Pi 4 Model B Rev 1.2 is used as the ARM platform. An interim build of FortiGate VM 7.2.x for ARM will be utilized.


Operating System Installation on the ARM device


The Raspberry Pi Imager v1.7.2 is used to format and dump Raspberry Pi OS (64-bit) on a 16GB Micro SD drive.




Once installed the commandlscpu gives some information about the ARM host.


root# lscpu

Architecture: aarch64

CPU op-mode(s): 32-bit, 64-bit


CPU(s): 4


Vendor ID: ARM


Model name: Cortex-A72


KVM Installation

root# apt install qemu-system libvirt-clients libvirt-daemon-system virtinst cpu-checker


Package cpu-checkerprovides the toolkvm-ok which is used to verify proper support for KVM virtualization.


root# kvm-ok

INFO: /dev/kvm exists

KVM acceleration can be used


Also, verify into the hypervisor domain capabilities that the aarch64 architecture supports thekvmvirtualization type.


root# virsh domcapabilities --arch aarch64 | grep kvm



The tag kvm must be present. Not having it will result in a very slow guest virtual machine.


FortiGate VM Image Extraction


The guest VM is a  disk image in qcow2 format. It is named fortios.cqow2. It is embedded into a ZIP archive with a flat hierarchy. The name of the image for ARM and KVM has the following form: where xxxx is the build the number.


root# zipinfo


Zip file size: 71129678 bytes, number of entries: 1

-rw-r--r-- 3.0 unx 82313216 bx defN 22-May-05 04:11 fortios.qcow2

1 file, 82313216 bytes uncompressed, 71129502 bytes compressed: 13.6%


The disk image is extracted from the ZIP archive:


root# unzip


inflating: fortios.qcow2

root@raspberrypi:/home/pi# qemu-img info fortios.qcow2

image: fortios.qcow2

file format: qcow2

virtual size: 2 GiB (2147483648 bytes)

disk size: 78.5

MiB cluster_size: 65536

Format specific information:

compat: 1.1

compression type: zlib

lazy refcounts: false

refcount bits: 16

corrupt: false

extended l2: false



Virtual machine definition


The following command, using the tool virt-install, is executed for defining the guest virtual machine. 


root# virt-install --noautoconsole --name fgvm --memory 2048 --vcpus 4 --virt-type kvm --import --disk fortios.qcow2 --disk fgvm-logs.qcow2,size=1 --network type=direct,source=eth0,source_mode=bridge,model=virtio

Starting install...

Allocating 'fgvm-logs.qcow2'

1.0 GB 00:00:00

Domain creation completed.


root# virsh list

Id Name State


1 fgvm running



The guest VM is defined with 4 virtual CPUs and 2GB of RAM. It has an additional virtual hard disk (1GB only because the device doesn't have so much storage space) which FortiOS will use for logging purposes.


Because in a proof of concept, give the guest VM  a single virtual network interface of type macvtap . It is defined on top of the physical network interface eth0.


root# virsh domiflist fgvm
Interface Type Source Model MAC
macvtap1 direct eth0 virtio 52:54:00:97:12:cb


# ip link show type macvtap
4: macvtap0@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 500
link/ether 52:54:00:97:12:cb brd ff:ff:ff:ff:ff:ff


The boot process of the guest VM can be monitored.



root# virsh console fgvm

Connected to domain 'fgvm'

Escape character is ^] (Ctrl + ])

BdsDxe: loading Boot0002 "UEFI Misc Device 2" from PciRoot(0x0)/Pci(0x1,0x3)/Pci(0x0,0x0) BdsDxe: starting Boot0002 "UEFI Misc Device 2" from PciRoot(0x0)/Pci(0x1,0x3)/Pci(0x0,0x0) Welcome to GRUB!

Booting `FOS'


EFI stub: Booting Linux Kernel...

EFI stub: Using DTB from configuration table

EFI stub: Exiting boot services and installing virtual address map...


System is starting...

Formatting shared data partition ... done!

Starting system maintenance...

Active CPU number will be decreased after reboot.

The config file may contain errors.

Please see details by the command 'diagnose debug config-error-log read'.

Serial number is FGVMEVDVUEAQO67E


Disk usage changed, please wait for reboot...


Formatting the disk...

- unmounting /data2 : ok

Partitioning and formatting /dev/vdb label LOGUSEDX6B90CEAB ... done


The system is going down NOW !!


Please stand by while rebooting the system.

[ 101.219174] reboot: Restarting system


System is starting...

The config file may contain errors.

Please see details by the command 'diagnose debug config-error-log read'.

Serial number is FGVMEVDVUEAQO67E


FortiGate-ARM64-KVM login:


Verifying access to the FortiGate VM


The current network setup is as follows.


fortigate-vm-arm-kvm-on-raspberry4.drawio (1).svg



An initial network configuration can be performed through the console of the guest VM.



root# virsh console fgvm

Connected to domain 'fgvm'

Escape character is ^] (Ctrl + ])

FortiGate-ARM64-KVM login: admin




FortiGate-ARM64-KVM # config system interface

FortiGate-ARM64-KVM (interface) # edit port1

FortiGate-ARM64-KVM (port1) # set ip

FortiGate-ARM64-KVM (port1) # end



Communication originating from the guest VM can be tested. In the example below, from the FortiGate VM's console, initiate a PING  to an external device.



FortiGate-ARM64-KVM # execute ping

PING ( 56 data bytes

64 bytes from icmp_seq=0 ttl=64 time=6.1 ms


--- ping statistics ---

1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 6.1/6.1/6.1 ms



The remote device can also reach the FortiGate VM administration console.