Address objects, without the click-fatigue

Firewall policies reference address objects, not raw IPs. Building them one at a time in the GUI is slow and error-prone when you have a whole subnet list to onboard. This tool turns a plain list of <ip>/<cidr> into ready-to-paste FortiGate CLI blocks. It is dual stack: IPv4 lines land in a config firewall address block and IPv6 lines in a config firewall address6 block, so a mixed list produces both at once.

address object = name (h-/n- + ip_cidr) + subnet (network + mask)

Naming convention

A consistent, self-describing name is what makes a large object list searchable. Each object is named after what it contains: an h- prefix for a single host (/32 or /128) and an n- prefix for a network, followed by the address and prefix length.

input:   10.0.10.0/24
         192.168.1.5/32
         172.16.4.10
         2001:db8:aced::/48
         2001:db8:aced:1::10/128

script:  config firewall address
             edit "n-10.0.10.0_24"
                 set subnet 10.0.10.0 255.255.255.0
             next
             edit "h-192.168.1.5"
                 set subnet 192.168.1.5 255.255.255.255
             next
             edit "h-172.16.4.10"
                 set subnet 172.16.4.10 255.255.255.255
             next
         end

         config firewall address6
             edit "n-2001:db8:aced::_48"
                 set ip6 2001:db8:aced::/48
             next
             edit "h-2001:db8:aced:1::10"
                 set ip6 2001:db8:aced:1::10/128
             next
         end

A line with no prefix is treated as a single host (/32 for IPv4, /128 for IPv6), so 172.16.4.10 becomes h-172.16.4.10. IPv6 addresses are normalised and compressed per RFC 5952.

Attach to an existing policy

Creating the objects is only half the job — they still have to be referenced somewhere. Tick attach to an existing policy, enter the Policy ID, and pick source or destination. The tool then adds a policy block that appends each object to that policy. append is deliberately non-destructive: it adds members to the current list instead of overwriting it, so you won't wipe out addresses already on the policy.

config firewall policy
    edit 42
        append srcaddr "n-10.0.10.0_24"
        append srcaddr "h-192.168.1.5"
        append srcaddr6 "n-2001:db8:aced::_48"
    next
end

IPv4 objects go to srcaddr/dstaddr and IPv6 objects to srcaddr6/dstaddr6, matching how a dual-stack FortiGate policy keeps the two families in separate fields. Two more switches let you edit the policy's identity at the same time — set the policy name (set name) and set the policy comment (set comments) — each written into the same edit block.

config firewall policy
    edit 42
        set name "LAN_to_WAN"
        set comments "Web servers onboarded 2026-09-25"
        append srcaddr "n-10.0.10.0_24"
    next
end

Wrap them in an address group

Referencing a dozen objects on every policy is noise. Tick wrap all objects in an address group and name it — the objects are collected into a config firewall addrgrp block (and addrgrp6 for IPv6). Point your policy at the one group instead. If you also enabled the policy option, the tool attaches the group rather than each object.

group = config firewall addrgrp + set member(objects)

config firewall addrgrp
    edit "web_servers"
        set member "n-10.0.10.0_24" "h-192.168.1.5"
    next
end

Choose the name case

The Name case switch sets the case of every generated name — the object names and the group name — in one move. The h-/n- prefix is always left lowercase; only the rest of the name is cased. Minimize writes everything lowercase (web, n-2001:db8:aced::_48), maximize uppercases the body (WEB, n-2001:DB8:ACED::_48), capitalize each word uppercases the first letter of every word — words split on _, -, ., : (Web_Servers, n-2001:Db8:Aced::_48), and off leaves every name exactly as entered. It is purely a naming-convention choice; the address values (set subnet, set ip6) always stay canonical, and every reference — group members and policy entries — is cased to match so the script stays consistent.

Related