Skip to main content
  1. Posts/

Fortigate - Transactions and Automatic Config Revert

Introduction #

In its default setting a Fortigate firewall will apply and save all configuration changes permanently once you leave a configuration block with either next or end. Depending on the use case this behavior can cause problems. For example assume you are working on a remote firewall and need to change the IP address of the interface you connect to as well as adjust a related route to avoid loosing connection. It also doesn’t allow for easy reverts if a faulty configuration change makes a device inaccessible. Of course using a serial console connection can help to avoid such problems, but they are not always available.

Thankfully the Fortigate offers two methods that can help to avoid problems of this kind: Transactions and an Automatic Configuration Revert. In this article I shortly document these two possibilities and how they can be used.

Transactions #

The first method that I’m showing are transactions or the workspace mode as Fortinet calls it. Similar to their function in databases, transactions allow us to group one or more configuration changes into a unit of work that has to be explicitly committed before its changes become active.

To start a new transaction on a Fortigate firewall use the following command:

Starting a new transaction
FortiGate-VM # execute config-transaction start
config transaction (id=1) started

Once a transaction is started we can change the configuration normally. For the sake of a small example assume that we configure an additional interface and add a static route. By using the command diagnose sys config-transaction show txn-cli-commands during a transaction it’s possible to review the changes that would be applied to the system if we were to commit them.

Show transaction changes
FortiGate-VM # diagnose sys config-transaction show txn-cli-commands
  config system interface
      edit "port2"
          set status up
          set mode static
          set ip 10.10.10.10/24
      end
  config router static
      edit 1
          set dst 17.0.0.0/8
          set device "port2"
      end

Once all necessary changes to the configuration have been made, and we are ready to apply them we can commit the transaction and save the changes with the following command:

Committing a transaction and saving changes
FortiGate-VM # execute config-transaction commit
config transaction (id=1) committed

If we decide that we want to discard the changes instead, we can abort the transaction with the following command:

Aborting a transaction and discarding changes
FortiGate-VM # execute config-transaction abort
config transaction (id=1) aborted

It’s important to keep in mind that changes made inside a transaction don’t become active until the transaction is committed. To further illustrate this let’s look at a small example. Assume our Fortigate has the following routing table with a default route via port1 and a single static route that routes 17.0.0.0/8 via port2:

FortiGate-VM # get router info routing-table details
[...]

Routing table for VRF=0
S*      0.0.0.0/0 [5/0] via 192.168.5.2, port1, [1/0]
C       10.10.10.0/24 is directly connected, port2
S       17.0.0.0/8 [10/0] is directly connected, port2, [1/0]
C       192.168.5.0/24 is directly connected, port1

We now start a new transaction and delete the static route:

FortiGate-VM # execute config-transaction start
config transaction (id=2) started

FortiGate-VM # config router static
FortiGate-VM (static) # delete 1
FortiGate-VM (static) # end

While the transaction is still active, we have another look at the routing table:

FortiGate-VM # get router info routing-table details
[...]

Routing table for VRF=0
S*      0.0.0.0/0 [5/0] via 192.168.5.2, port1, [1/0]
C       10.10.10.0/24 is directly connected, port2
S       17.0.0.0/8 [10/0] is directly connected, port2, [1/0]
C       192.168.5.0/24 is directly connected, port1

As one can see it hasn’t changed yet and the route for 17.0.0.0/8 is still present, even though we deleted the corresponding configuration. The route will only be removed from the active routing table once we commit the transaction.

Automatic Configuration Revert #

Another way to handle risky configuration changes is to change the setting that controls how the configuration is saved. Instead of the default behavior mentioned in the introduction the firewall also offers a method where changes are applied directly but need to be saved manually within a specifiable timeframe for them to become permanent.

To switch to this mode we need to change the cfg-save option from automatic to revert and specify a cfg-revert-timeout timeout in seconds:

cfg-save options
FortiGate-VM # config system global

FortiGate-VM (global) # set cfg-save ?
automatic    Automatically save config.
manual       Manually save config.
revert       Manually save config and revert the config when timeout.

FortiGate-VM (global) # set cfg-save revert
FortiGate-VM (global) # set cfg-revert-timeout 300

FortiGate-VM (global) # end

As mentioned above and in contrast to transactions, changes made to the configuration are applied immediately. To pick up the example from the last section: When deleting a static route from the configuration the corresponding entry in the routing table will also be immediately removed.

However, for the changes to become permanent and survive a reboot we need to explicitly save them. This can be done with the following command:

Saving changes in revert mode
FortiGate-VM # execute cfg save
..config saved.

If the changes aren’t saved, the firewall will revert them and restore its previous state after the timeframe defined in the cfg-revert-timeout setting.

To restore the save behavior to its original setting we need to set the cfg-save option to automatic again:

Revert cfg-save option to default behavior
FortiGate-VM # config system global
FortiGate-VM (global) # set cfg-save automatic
FortiGate-VM (global) # end

I hope this blog post was helpful to you. Thanks for reading and until next time 👋.