infrasdoc
Fortinet · FortiGate · CLI

Block a list of domains with an FQDN address group and a deny policy

A repeatable CLI recipe: create a wildcard and a root FQDN address object for each domain, bundle them into one address group, verify the group, and apply it as the destination of a deny policy. Shown with 16 passkey/MFA-lookalike phishing domains, giving 32 objects in one group.

16 domains 32 FQDN objects 1 address group deny policy · CLI idempotent append member
00

What this builds

What it does

Turns a list of domains into a single reusable address group that any policy can reference, so blocking or unblocking is a one-line change to the group instead of a policy edit.

Why two objects per domain

A wildcard *.example.com does not match example.com itself in FortiGate wildcard FQDN matching. Adding the root domain as its own object gives complete coverage.

The domains used in this example:

assignpasskey.commfaregister.comoskeysetup.compasskey-mfa.com registermymfa.comoskey.comoskeyconnect.comsetpasskey.com secure-passkey.cominstallmykey.comnowsso.comoursso.com passkeydeploy.comaddssopasskey.comcreatessopasskey.compasskeyhelpdesk.com
1

Create the FQDN address objects

What it does

Creates one wildcard (FQDN_WC_…) and one root (FQDN_…) object per domain — 32 in total.

Naming

The FQDN_WC_ prefix marks the wildcard object so the pair stays easy to spot and sort in the object list.

config firewall address
config firewall address
    edit "FQDN_WC_assignpasskey.com"
        set type fqdn
        set fqdn "*.assignpasskey.com"
    next
    edit "FQDN_assignpasskey.com"
        set type fqdn
        set fqdn "assignpasskey.com"
    next
    edit "FQDN_WC_mfaregister.com"
        set type fqdn
        set fqdn "*.mfaregister.com"
    next
    edit "FQDN_mfaregister.com"
        set type fqdn
        set fqdn "mfaregister.com"
    next
    edit "FQDN_WC_oskeysetup.com"
        set type fqdn
        set fqdn "*.oskeysetup.com"
    next
    edit "FQDN_oskeysetup.com"
        set type fqdn
        set fqdn "oskeysetup.com"
    next
    edit "FQDN_WC_passkey-mfa.com"
        set type fqdn
        set fqdn "*.passkey-mfa.com"
    next
    edit "FQDN_passkey-mfa.com"
        set type fqdn
        set fqdn "passkey-mfa.com"
    next
    edit "FQDN_WC_registermymfa.com"
        set type fqdn
        set fqdn "*.registermymfa.com"
    next
    edit "FQDN_registermymfa.com"
        set type fqdn
        set fqdn "registermymfa.com"
    next
    edit "FQDN_WC_oskey.com"
        set type fqdn
        set fqdn "*.oskey.com"
    next
    edit "FQDN_oskey.com"
        set type fqdn
        set fqdn "oskey.com"
    next
    edit "FQDN_WC_oskeyconnect.com"
        set type fqdn
        set fqdn "*.oskeyconnect.com"
    next
    edit "FQDN_oskeyconnect.com"
        set type fqdn
        set fqdn "oskeyconnect.com"
    next
    edit "FQDN_WC_setpasskey.com"
        set type fqdn
        set fqdn "*.setpasskey.com"
    next
    edit "FQDN_setpasskey.com"
        set type fqdn
        set fqdn "setpasskey.com"
    next
    edit "FQDN_WC_secure-passkey.com"
        set type fqdn
        set fqdn "*.secure-passkey.com"
    next
    edit "FQDN_secure-passkey.com"
        set type fqdn
        set fqdn "secure-passkey.com"
    next
    edit "FQDN_WC_installmykey.com"
        set type fqdn
        set fqdn "*.installmykey.com"
    next
    edit "FQDN_installmykey.com"
        set type fqdn
        set fqdn "installmykey.com"
    next
    edit "FQDN_WC_nowsso.com"
        set type fqdn
        set fqdn "*.nowsso.com"
    next
    edit "FQDN_nowsso.com"
        set type fqdn
        set fqdn "nowsso.com"
    next
    edit "FQDN_WC_oursso.com"
        set type fqdn
        set fqdn "*.oursso.com"
    next
    edit "FQDN_oursso.com"
        set type fqdn
        set fqdn "oursso.com"
    next
    edit "FQDN_WC_passkeydeploy.com"
        set type fqdn
        set fqdn "*.passkeydeploy.com"
    next
    edit "FQDN_passkeydeploy.com"
        set type fqdn
        set fqdn "passkeydeploy.com"
    next
    edit "FQDN_WC_addssopasskey.com"
        set type fqdn
        set fqdn "*.addssopasskey.com"
    next
    edit "FQDN_addssopasskey.com"
        set type fqdn
        set fqdn "addssopasskey.com"
    next
    edit "FQDN_WC_createssopasskey.com"
        set type fqdn
        set fqdn "*.createssopasskey.com"
    next
    edit "FQDN_createssopasskey.com"
        set type fqdn
        set fqdn "createssopasskey.com"
    next
    edit "FQDN_WC_passkeyhelpdesk.com"
        set type fqdn
        set fqdn "*.passkeyhelpdesk.com"
    next
    edit "FQDN_passkeyhelpdesk.com"
        set type fqdn
        set fqdn "passkeyhelpdesk.com"
    next
end
2

Build the address group

What it does

Collects all 32 objects into Blocked-Passkey-Domains.

Why append member

append member preserves any members already in the group, so the script is safe to re-run or extend later.

config firewall addrgrp
config firewall addrgrp
    edit "Blocked-Passkey-Domains"
        append member "FQDN_WC_assignpasskey.com"
        append member "FQDN_assignpasskey.com"
        append member "FQDN_WC_mfaregister.com"
        append member "FQDN_mfaregister.com"
        append member "FQDN_WC_oskeysetup.com"
        append member "FQDN_oskeysetup.com"
        append member "FQDN_WC_passkey-mfa.com"
        append member "FQDN_passkey-mfa.com"
        append member "FQDN_WC_registermymfa.com"
        append member "FQDN_registermymfa.com"
        append member "FQDN_WC_oskey.com"
        append member "FQDN_oskey.com"
        append member "FQDN_WC_oskeyconnect.com"
        append member "FQDN_oskeyconnect.com"
        append member "FQDN_WC_setpasskey.com"
        append member "FQDN_setpasskey.com"
        append member "FQDN_WC_secure-passkey.com"
        append member "FQDN_secure-passkey.com"
        append member "FQDN_WC_installmykey.com"
        append member "FQDN_installmykey.com"
        append member "FQDN_WC_nowsso.com"
        append member "FQDN_nowsso.com"
        append member "FQDN_WC_oursso.com"
        append member "FQDN_oursso.com"
        append member "FQDN_WC_passkeydeploy.com"
        append member "FQDN_passkeydeploy.com"
        append member "FQDN_WC_addssopasskey.com"
        append member "FQDN_addssopasskey.com"
        append member "FQDN_WC_createssopasskey.com"
        append member "FQDN_createssopasskey.com"
        append member "FQDN_WC_passkeyhelpdesk.com"
        append member "FQDN_passkeyhelpdesk.com"
    next
end
3

Verify the import

Confirm the group exists and holds every object:

exec
show firewall addrgrp "Blocked-Passkey-Domains"
Expect

All 32 FQDN objects listed as members — 16 FQDN_WC_… wildcards and 16 root entries.

4

Apply it in a deny policy

What it does

References the group as the destination of a deny policy so traffic to any listed domain is dropped and logged.

Why it's needed

Creating the objects alone does not block anything — traffic is only blocked once a policy uses the group.

config firewall policy · example
config firewall policy
    edit 0                                    # 0 = next free policy ID
        set name "Block-Passkey-Domains"
        set srcintf "lan"                     # your internal interface or zone
        set dstintf "wan1"                    # your internet-facing interface or zone
        set srcaddr "all"
        set dstaddr "Blocked-Passkey-Domains"
        set action deny
        set schedule "always"
        set service "ALL"
        set logtraffic all
    next
end
Adjust

Replace lan / wan1 with the interfaces or zones that carry your outbound traffic, and add one policy per egress path if traffic leaves by more than one.

5

Order the policy above the allow rules

What it does

Moves the deny policy ahead of the internet allow policies.

Why it's needed

FortiGate evaluates policies top-down and stops at the first match, so a deny placed below a broad allow never gets hit.

config firewall policy
show firewall policy | grep -f "Block-Passkey-Domains"

config firewall policy
    move <deny-policy-id> before <first-internet-allow-policy-id>
end

Confirm with a hit count after a test lookup:

exec
diagnose firewall iprope lookup <src-ip> 0 6 <dst-ip> 443 <src-interface>
6

Limits & hardening

Know the limits

FQDN-based matching depends on the firewall observing DNS responses, so it can miss traffic from devices using DNS-over-HTTPS. IP-based matching can also be imprecise for domains hosted on shared IP addresses.

For security-relevant blocking, back the address group with a DNS Filter (or Web Filter) containing the same domains. Add both the wildcard and root form of each entry, since the wildcard alone does not cover the bare domain.

config dnsfilter · optional hardening (illustrative — repeat for all 16 domains)
config dnsfilter domain-filter
    edit 1
        set name "Blocked-Passkey-Domains"
        config entries
            edit 1
                set domain "*.assignpasskey.com"
                set type wildcard
                set action block
            next
            edit 2
                set domain "assignpasskey.com"
                set type simple
                set action block
            next
            # ... repeat for the remaining domains ...
        end
    next
end

config dnsfilter profile
    edit "dns-block-passkey"
        config domain-filter
            set domain-filter-table 1
        end
    next
end

config firewall policy
    edit <deny-or-allow-policy-id>
        set dnsfilter-profile "dns-block-passkey"
    next
end
Note

DNS filter attaches to policies that use a security-profile (UTM) inspection mode, so apply the profile on your outbound allow policy as well as the deny policy above. Validate syntax against your FortiOS release before running in production.