Description
This article describes how to configure automation stitches to update DNS records hosted in Cloudflare upon DHCP lease renewal or PPPoE (re)connection, effectively creating a dynamic DNS (DDNS) setup.
Scope
This guide applies to FortiGate devices that obtain public IP addresses from DHCP or PPPoE and to DNS zones hosted in Cloudflare. For other DDNS providers, refer to the built-in DDNS feature documentation:
DDNS
Solution
At a high level, this automation stitch consists of the following steps:
- Detect a DHCP/PPPoE.
- Update the DNS record via Cloudflare API with the new IP address.
Cloudflare Preparation:
Create an API token following the official guide at https://developers.cloudflare.com/fundamentals/api/get-started/create-token/
Select the following options during creation:
- Use the 'Edit zone DNS' template.
- Confirm that Permissions is set to Zone / DNS / Edit.
- Confirm that Zone Resources shows Include / Specific zone / <your dns zone>.
- Select the desired validity for the token in the TTL section.
Save the newly generated token.
In the Overview screen of the DNS zone in the dashboard, make a note of the zone ID.
Cloudflare - DNZ zone ID
(Optional) Create the DNS record for the DDNS hostname if it does not exist yet. Ensure the status is 'DNS only'. (The record will not resolve to the FortiGate's public IP if the record is set to proxy mode).
Obtain the record ID of the hostname via Cloudflare API:
$ curl "https://api.cloudflare.com/client/v4/zones/<ZONE-ID>/dns_records?name=lab-test-ddns.<domain.com>" -H "Authorization: Bearer XXXXXXXXXX"
Example response:
{"result":[{"id":"aeXXXXXXXXXXXXXXXXXXXXXXXX5a","zone_id":"XXXXXXXXXXXXXXXXXXXX","zone_name": [...]
Note down the first 'id' value. This is the record ID. This API call can also be used to verify that the API token is valid.
At this stage the following should be ready for use in the automation stitch: API token, zone ID, and record ID.
FortiGate Configuration:
Two versions of the automation stitch are provided below: For DHCP and PPPoE.
The DHCP stitch requires an intermediate action to retrieve the current IP with a FortiOS REST API call as the IP cannot be retrieved from the triggering message. The PPPoE stitch does not require this step.
DHCP Version:
Create an API admin to retrieve the current IP:
- Create a new admin profile in System -> Admin Profiles.
- The minimum required permission is Network -> Configuration set to read, everything else can be set to none.
- Switch 'Permit usage of CLI diagnostic commands' to off.
- Create a new rest API admin in System -> Administrators -> Create New -> Rest API Admin.
- Select the newly created admin profile.
- Disable 'PKI Group'.
- (Optional) Set trusted hosts to the FortiGate IP which will be used for the API call.
Note down the API key generated after selecting 'OK'.
Create the automation trigger:
- Security Fabric -> Automation -> Trigger -> Create New.
- Type: FortiOS Event Log.
- Event: DHCP client lease granted (ID 26004).
Create the FortiOS webhook to retrieve the IP:
- Security Fabric -> Automation -> Action -> Create New.
- Type: Webhook.
- Protocol: HTTPS.
- URL: <FGT-ADDR>/api/v2/monitor/system/interface?interface_name=<INTF-NAME>
- <FGT-ADDR>: Replace with an IP or FQDN of the FortiGate interface with HTTPS admin access enabled, ideally some internal or loopback interface.
- <INTF-NAME>: Replace with the name of the interface that is monitored for IP changes.
- If the WAN interface is a VLAN interface make sure to add &include_vlan=true in the URL ending.(e.g : <FGT-ADDR>/api/v2/monitor/system/interface?interface_name=<INTF-NAME>&include_vlan=true )
- (Optional) Set a custom port of the FortiGate GUI that does not use the default port 443.
- Method: GET.
- HTTP body: Leave empty.
- HTTP header: Add header 'Authorization' with value 'Bearer <API-KEY>'. (without quotes).
- <API-KEY>: Replace with the FortiOS REST API admin key generated earlier.
- Verify Remote host: disable if the current GUI certificate is not valid for the IP/FQDN used, otherwise leave it enabled.
FortiOS Action Webhook - Retrieve IP
Create the Cloudflare API webhook:
- Security Fabric -> Automation -> Action -> Create New.
- Type: Webhook.
- Protocol: HTTPS.
- URL: https://api.cloudflare.com/client/v4/zones/<ZONE-ID>/dns_records/<RECORD-ID>
- <ZONE-ID>: Replace with the DNS zone ID from the Cloudflare preparation section.
- <RECORD-ID>: Replace with the DNS hostname record ID from the Cloudflare preparation section.
- Method: PATCH.
- HTTP body: {"content":"%%results.results.<INTF-NAME>.ip%%"}
- <INTF-NAME>: Replace with the name of the interface that is monitored for IP changes.
- HTTP header: Add header "Authorization" with value "Bearer <CF-API-TOKEN>". (without quotes).
- <CF-API-TOKEN>: Replace with the Cloudflare API token from the Cloudflare preparation section.
FortiOS Action Webhook - Update Cloudflare
Create the automation stitch:
- Security Fabric -> Automation -> Stitch > Create New.
- Action Execution: Sequential (default).
- Stitch: DHCP client lease event trigger created above.
- Action 1: FortiOS IP retrieval webhook created above.
- Action 2: Cloudflare webhook.
A full CLI configuration snippet is attached at the end of the article.
PPPoE Version:
Create the automation trigger:
- Security Fabric -> Automation -> Trigger > Create New.
- Type: FortiOS Event Log.
- Event: PPPoE status report (ID 29010).
Create the Cloudflare API webhook:
- Security Fabric -> Automation -> Action -> Create New.
- Type: Webhook.
- Protocol: HTTPS.
- URL: https://api.cloudflare.com/client/v4/zones/<ZONE-ID>/dns_records/<RECORD-ID>
- <ZONE-ID>: Replace with the DNS zone ID from the Cloudflare preparation section.
- <RECORD-ID>: Replace with the DNS hostname record ID from the Cloudflare preparation section.
- Method: PATCH.
- HTTP body: {"content":"%%log.assigned%%"}
- HTTP header: Add header 'Authorization' with value 'Bearer <CF-API-TOKEN>'. (without quotes).
- <CF-API-TOKEN>: Replace with the Cloudflare API token from the Cloudflare preparation section.
FortiOS Automation Webhook - Update Cloudflare IP
Note:
The PPPoE event does not announce for which interface it is generated. As a consequence, this stitch can be used when only one PPPoE interface is in use.
Create the automation stitch:
- Security Fabric -> Automation -> Stitch > Create New.
- Action Execution: Sequential (default).
- Trigger: PPPoE Status event trigger created above.
- Action: Cloudflare webhook.
- Delay: Select 'Add delay' and add a short delay, for example 10 seconds, to allow some additional time for connectivity to start working.
A full CLI configuration snippet is attached at the end of the article.
Verification:
To verify the automation stitch either wait for the next natural renewal or trigger the renewal manually:
- GUI: Edit the DHCP/PPPoE interface, and select 'Renew' next to the Obtained IP field.
- CLI:
execute interface dhcpclient-renew <interface-name>
execute interface pppoe-reconnect <interface-name>
Note: Short network disruption is expected during the renegotiation.
Troubleshooting:
Enable the debug commands:
diagnose test app autod 1 <----- This command is an on/off toggle, make sure the output says 'log packet dump enabled'.
diagnose debug app autod -1
diagnose debug enable
Trigger renewal as described in the Verification section above. In the resulting outputs, look for potential errors. If any curl errors are shown in the output, review the webhook automation actions, especially the URLs and variables (API keys, zone/record ID) for possible misspellings.
Example debug output for successful DHCP and PPPoE stitches:
Working DHCP Stitch 1/2
Working DHCP Stitch 2/2
Working PPPoE Stitch