Extend Kubernetes to Fortinet firewall devices
The Fortinet integration is deprecated and will be removed in a future release. If you want to use Calico Enterprise with Fortinet or any other firewall, we recommend instead using an egress gateway.
Big picture​
Use Calico Enterprise network policy to control traffic from Kubernetes clusters in your FortiGate firewalls.
Value​
As platform and security engineers, you want your apps to securely communicate with the external world. But you also want to secure the network traffic from the Kubernetes clusters using your Fortigate firewalls. Using the Fortinet/Calico Enterprise integration, security teams can retain firewall responsibility, secure traffic using Calico Enterprise network policy, which frees up time for ITOps.
Concepts​
Integration at a glance​
This Calico Enterprise/Fortinet integration workflow lets you control egress traffic leaving the Kubernetes cluster. You create perimeter firewall policies in FortiManager and FortiGate that reference Kubernetes workloads. Calico Enterprise acts as a conduit, using the tigera-firewall-controller and global network policies to pass Kubernetes workload information to FortiManager and Fortigate devices where policies are applied and enforced.
The basic workflow is:
- Determine the Kubernetes pods that are allowed access outside the perimeter firewall.
- Create Calico Enterprise global network policies with selectors that match those pods. Each global network policy maps to an address group in the FortiGate firewall.
- Deploy the tigera firewall controllerin the Kubernetes cluster.
- Create a ConfigMap with Fortinet firewall information.
 Thetigera firewall controllerreads the ConfigMap, gets the FortiGate firewall IP address, API token, and source IP address selection withnodeorpod. In your Kubernetes cluster, the controller populates pod IPs or Kubernetes node IPs of selector matching pods in Fortigate address group objects.
Before you begin​
Supported versions
- FortiGate v6.2
- FortiManager v6.4
Required
- Pull secret that you used during Calico Enterprise installation
- IPv4 CIDR’s or IP addresses of all Kubernetes nodes; this is required for FortiManager to treat Kubernetes nodes as trusted hosts.
Recommended
- Experience creating and administering FortiGate/FortiManager firewall policies
- Experience using Calico Enterprise tiers and Global network policy
How to​
- Create tier and global network policy
- Configure FortiGate firewall to communicate with firewall controller
- Configure FortiManager to communicate with firewall controller
- Create a config map for address selection in firewall controller
- Create a config map with FortiGate and FortiManager information
- Install FortiGate ApiKey and FortiManager password as secrets
- Deploy firewall controller in the Kubernetes cluster
Create tier and global network policy​
- 
Create a tier for organizing global network policies. Create a new Tier to organize all Fortigate firewall global network policies in a single location. 
- 
Note the tier name to use in a later step for the FortiGate firewall information config map. 
- 
Create a GlobalNetworkPolicy for address group mappings. For example, a GlobalNetworkPolicy can select a set of pods that require egress access to external workloads. In the following GlobalNetworkPolicy, the firewall controller creates an address group named, default.production-microservice1in the Fortigate firewall. The members ofdefault.production-microservice1address group include IP addresses of nodes. Each node can host one or more pods whose label selector match withenv == 'prod' && role == 'microservice1'. Each GlobalNetworkPolicy maps to an address group in FortiGate firewall.apiVersion: projectcalico.org/v3
 kind: GlobalNetworkPolicy
 metadata:
 name: default.production-microservice1
 spec:
 selector: "env == 'prod' && role == 'microservice1'"
 types:
 - Egress
 egress:
 - action: Allow
Configure FortiGate firewall to communicate with firewall controller​
- Determine and note the CIDR's or IP addresses of all Kubernetes nodes that can run the tigera-firewall-controller. Required to explicitly allow thetigera-firewall-controllerto access the FortiGate API.
- Create an Admin profile with read-write access to Address and Address Group Objects.
For example: tigera_api_user_profile
- Create a REST API Administrator, associate this user with the tigera_api_user_profileprofile, and add the CIDR or IP address of your Kubernetes cluster nodes as trusted hosts. For example:calico_enterprise_api_user
- Note the API key.
Configure FortiManager to communicate with firewall controller​
- Determine and note the CIDR's or IP addresses of all Kubernetes nodes that can run the tigera-firewall-controller. Required to explicitly allow the tigera-firewall-controller to access the FortiManager API.
- From system settings, create an Admin profile with Read-Write access for Policy & Objects. For example:tigera_api_user_profile
- Create a JSON API administrator, associate this user with the tigera_api_user_profileprofile, and add the CIDR or IP address of your Kubernetes cluster nodes asTrusted Hosts.
- Note the username and password.
Create a config map for address selection in firewall controller​
- 
Create a namespace for tigera-firewall-controller. kubectl create namespace tigera-firewall-controller
- 
Create a config map with FortiGate firewall information. For example: kubectl -n tigera-firewall-controller create configmap tigera-firewall-controller \
 --from-literal=tigera.firewall.policy.selector="projectcalico.org/tier == 'default'" \
 --from-literal=tigera.firewall.addressSelection="node"ConfigMap values Field Enter values... tigera.firewall.policy.selector The tier name with the global network policies with the Fortigate address group mappings. 
 For example, this selects the global network policies in thedefaulttier:
 `tigera.firewall.policy.selector: "projectcalico.org/tier == 'default'"tigera.firewall.addressSelection The addressSelection for outbound traffic leaving the cluster. 
 For example, if outgoingNat is enabled in cluster and compute Node IP address is used "tigera.firewall.addressSelection ==nodeor
 If pod IP address used then "tigera.firewall.addressSelection ==pod"
Create a config map with FortiGate and FortiManager information​
- 
In the Fortigate ConfigMap manifest, add your FortiGate firewall information in the data section, tigera.firewall.fortigate.Where: Field Description name FortiGate device name ip FortiGate Management Ip address apikey Secret in tigera-firewall-controller namespace, to store FortiGate's APIKey apikey.secretKeyRef.name Name of the secret to store APIKey apikey.secretKeyRef.key Key name in the secret, which stores APIKey vdom FortiGate VDOM name For example: - name: prod-eastcoast-1
 ip: 1.2.3.1
 apikey:
 secretKeyRef:
 name: fortigate-east1
 key: apikey-fortigate-east1
 vdom: fortigate-vdom1
 - name: prod-eastcoast-2
 ip: 1.2.3.2
 apikey:
 secretKeyRef:
 name: fortigate-east2
 key: apikey-fortigate-east2
 vdom: fortigate-vdom2
- 
In the FortiManager ConfigMap manifest, add your FortiManager information in the data section, tigera.firewall.fortimgr.Where: Field Description name FortiManager device name ip FortiManager Management Ip address adom FortiManager ADOM name to manage kubernetes cluster. username JSON api access account name to Read/Write FortiManager address objects. password Secret in tigera-firewall-controller namespace, to store FortiManager password password.secretKeyRef.name Name of the secret to store password. password.secretKeyRef.key Key name in the secret, which stores password. For example: - name: prod-east1
 ip: 1.2.4.1
 username: api_user
 adom: root
 password:
 secretKeyRef:
 name: fortimgr-east1
 key: pwd-fortimgr-east1
If you are not using FortiManager in the integration, include only the following field in the ConfigMap data section. tigera.firewall.fortimgr: |
- 
Apply the manifest. kubectl apply -f https://downloads.tigera.io/ee/v3.21.2/manifests/fortinet-device-configmap.yaml
Install FortiGate ApiKey and FortiManager password as secrets​
- 
Store each FortiGate API key as a secret in the tigera-firewall-controllernamespace. For example, the FortiGate device,prod-east1, store its ApiKey as a secret name asfortigate-east1, with key asapikey-fortigate-east1.kubectl create secret generic fortigate-east1 \
 -n tigera-firewall-controller \
 --from-literal=apikey-fortigate-east1=<fortigate-api-secret>
- 
Store each FortiManager password as secret in the tigera-firewall-controllernamespace. For example, for FortiMgrprod-east1, store its password as a secret name asfortimgr-east1, with key aspwd-fortimgr-east1.kubectl create secret generic fortimgr-east1 \
 -n tigera-firewall-controller \
 --from-literal=pwd-fortimgr-east1=<fortimgr-password>
Deploy firewall controller in the Kubernetes cluster​
- 
Install your pull secret. kubectl create secret generic tigera-pull-secret \
 --from-file=.dockerconfigjson=<path/to/pull/secret> \
 --type=kubernetes.io/dockerconfigjson -n tigera-firewall-controller
- 
Apply the manifest. kubectl apply -f https://downloads.tigera.io/ee/v3.21.2/manifests/fortinet.yaml
Verify the integration​
- Log in to the FortiGate firewall user interface.
- Under Policy & Objects, click Addresses.
- Verify that your Kubernetes-related address objects and address group objects are created with the following comments "Managed by Tigera Calico Enterprise".
Fof all FortiManagers that are configured to work with firewall-controller, log in to each FortiManager UI with the correct ADOM.
- Click Policy & Objects, Object Configuration, **Addresses.
- Verify that your Kubernetes-related address objects and address group objects are created with the following comments "Managed by Tigera Calico Enterprise".