← All guides

How to Set Up a FortiAP at a Remote Site Over the Internet (FortiGate Remote AP Guide)

A FortiAP doesn't have to sit on the same network as its FortiGate. This guide covers how to put one at a remote site, tunnel it home over the internet, and broadcast an SSID whose clients land on your main network. It includes requirements, firmware notes, limitations, a step-by-step build, verification, and rollback.

by Markdown
  • fortinet
  • fortiap
  • fortigate
  • wireless
  • capwap
  • guide
  • homelab

I built this in my homelab and tested the core build on live hardware. Where something comes from Fortinet’s documentation rather than my own testing, I say so.

A wall-plate FortiAP at a remote site broadcasts Wi-Fi and sends an encrypted CAPWAP-in-IPsec tunnel across the internet to a FortiGate at the main site, while other internet traffic leaves locally.
Illustration of a FortiAP 23JK, not a product photo. Traffic for your network rides the encrypted tunnel home, and everything else leaves from the remote site.

What it is

A FortiAP is a thin access point. It has no configuration of its own worth speaking of: a FortiGate acting as its wireless controller tells it what to broadcast, over a protocol called CAPWAP. CAPWAP is ordinary routed traffic, so nothing requires the AP to be on the same LAN as its controller.

That means you can plug a FortiAP into any internet connection (a house, a small office, a hotel desk), have it find your FortiGate across the internet, and broadcast an SSID whose clients get addresses from, and land on, your main network. Fortinet calls this Remote AP. Many people who run FortiGates have never heard of it.

What you get:

  • Devices at the remote site join a normal Wi-Fi network and are simply on your main network, with no VPN client on any of them.
  • The FortiGate’s security policy, logging, and DNS filtering all apply to them.
  • By default all of a remote AP’s traffic tunnels home, so the FortiGate inspects everything. With split tunneling, only traffic for your main network goes home, and everything else uses the remote site’s own internet.

When to use it, and when not to

A good fit:

  • A small remote site, home office, or second home that needs a few devices on the main network.
  • Devices that can’t run a VPN client: printers, smart TVs, IoT, consoles.
  • Places where you can’t or don’t want to install a firewall.

Not a good fit:

  • A site that must keep working when the main site’s internet is down. A tunnel-mode SSID disappears when the AP can’t reach its controller. If that’s a dealbreaker, put a firewall at the remote site and build a site-to-site VPN.
  • A remote network where outbound UDP 5246–5247 is blocked. Guest networks and hotels often block it.
  • Reusing an existing bridge-mode SSID at the remote site. A tunnel-mode SSID can be broadcast by on-site and remote APs alike, but a bridge-mode one can’t be (see Limitations).

What you need

Requirement Why
A FortiGate with a publicly reachable address The AP has to reach the controller. CGNAT on the controller’s connection breaks this. CGNAT at the remote site is fine, because the AP connects outbound.
A stable address, or a plan for discovery The AP’s static controller setting accepts only an IP address. See Decisions below.
A free managed-AP slot Remote APs count against the FortiGate model’s managed-AP limit. Check the datasheet.
A FortiAP model your FortiOS release manages Recommended: a current, in-support model on up-to-date firmware. It gets security fixes, and the remote AP is the hardest one to reach for an update.
Outbound UDP 5246 and 5247 at the remote site CAPWAP control and data
PoE, either a switch or an injector Most FortiAPs have no separate power brick
Physical access to stage the AP With the staged approach, discovery settings are applied and checked while the AP is still on your LAN. Zero-touch provisioning is the alternative (see Decisions).

Firmware and version notes

  • capwap is not an allowaccess value on current FortiOS. Fortinet’s own remote-AP page says to enable “CAPWAP” on FortiOS 6.2.2 and earlier, and Security Fabric Connection on FortiOS 6.2.3 and later. The CLI value is fabric. Nearly every forum post and blog says capwap, and on a modern FortiGate that token doesn’t exist.
  • “Set wtp-mode to remote” is dead advice. That setting is gone from modern FortiOS. The wtp-mode: normal you’ll see in diagnostic output is read-only.
  • ipsec-sn-vpn, an IPsec data channel that also carries the AP’s serial number in the IKE exchange, was added in FortiOS 7.4.0. Fortinet’s documents spell it both ipsec-vpn-sn and ipsec-sn-vpn, sometimes on the same page, so check with set dtls-policy ? on your own device.
  • Virtual patching on local-in policies (see Security best practices) is available on recent releases and needs a FortiGuard firmware virtual-patch license.
  • apcfg-profile pushes discovery settings to the AP from the FortiGate, so you don’t need the AP’s own CLI.
  • Check which FortiOS releases manage your AP model. Major releases can drop older models: FortiOS 8.0 stops managing several E-series units. An in-support model on current firmware is the recommended choice, because it keeps getting fixes.
  • I tested this build on the FortiOS 7.6 branch. Before you script anything, settle field names against your own build’s live schema: GET /api/v2/cmdb/wireless-controller/vap?action=schema.

Limitations

  • Tunnel down means SSID down. No internet at the main site means no Wi-Fi at the remote one.
  • Bridge-mode SSIDs don’t travel. An SSID object’s mode and VLAN apply everywhere it’s deployed. If your existing SSID is tunnel mode, the remote AP can broadcast it too, and Fortinet’s deployment guide does exactly that. If it’s bridge mode, as most on-site SSIDs are, it won’t work remotely. FortiOS also won’t let a second SSID object broadcast the same name (node_check_object fail! / -651), so the remote AP needs its own, distinctly named tunnel-mode SSID.
  • Discovery is fragile with a dynamic WAN address. Covered next.
  • Overhead. CAPWAP inside IPsec adds encapsulation. If the remote link is already tunneled (PPPoE, a carrier tunnel), you may need to tune the tunnel MTU (tun-mtu-uplink / tun-mtu-downlink on the AP profile). I didn’t hit this, so treat it as a lead from Fortinet’s documentation rather than something I tested.

Decisions to make before you build

Tunnel mode, not bridge mode

This is the most expensive thing to get wrong. I got it wrong twice, once in each direction, before testing it:

SSID on the remote AP Where the client lands
Bridge, untagged The remote site’s own network. Its router hands out the address, and the FortiGate issues no lease.
Bridge, VLAN-tagged Nowhere. Nothing at the remote site serves that VLAN, so the client ends up with a 169.254 address.
Tunnel Your main network. The FortiGate hands out the address across the tunnel.

A bridged AP tags frames onto whatever it’s plugged into. At home that’s a switch trunk that honors the tag. At a remote site it’s a router that has never heard of your VLAN.

Fortinet does recommend bridge mode for APs managed across a WAN. That advice is for branch offices whose users should stay on their local network and internet. To put remote clients on your main network, the SSID must be tunnel mode.

How the AP will find the controller

The AP looks for its controller in this order: static IP, DHCP, DNS, Fortinet’s cloud service, multicast, broadcast. Across the internet only the first three matter.

  • Static (AC_IPADDR_1) accepts only an IP address, never a hostname. If the main site’s public address changes, the AP is stranded. This is what happened to mine.
  • DNS (AC_HOSTNAME_1) takes only a short name. The AP appends the domain suffix that the remote site’s DHCP server hands out (option 15). You can’t type a full hostname on the AP, and many consumer routers can’t set option 15. Confirm the remote router can before the AP ships.
  • Best option with a dynamic address: build a site-to-site VPN from the remote router to a dynamic-DNS name, and point the AP at the FortiGate’s private address. That address never changes, and you no longer need a CAPWAP listener open to the internet at all.

Full tunnel or split tunnel

Fortinet’s default is to tunnel all remote-AP traffic home. Fortinet calls this the most secure option, because the FortiGate inspects everything. Split tunneling sends only chosen traffic home, which saves your main site’s bandwidth, but internet traffic from the remote clients is then not inspected. Split tunneling has two modes (split-tunneling-acl-path):

Mode Default for unlisted traffic What you list
tunnel Stays local The networks that go home. If you list none, nothing is tunneled.
local Goes home The networks that stay local. Fortinet says to enable Include Local Subnet “in almost all situations”, so devices like a local printer still work.

Either way, decide which networks should go home and which destinations and services the remote clients may reach, and write it down. It becomes the split-tunnel list and the firewall policy. This guide uses tunnel mode.

Staged on your LAN, or zero-touch

  • Staged: authorize the AP and push its discovery settings while it’s on your LAN, then ship it. That’s what this guide does.
  • Zero-touch: with FortiDeploy (through FortiLAN Cloud in Fortinet’s deployment guide), you add the AP to cloud inventory using its FortiCloud key and point it at your FortiGate’s external IP or hostname. The AP can then ship straight to the remote site, unstaged, and find its controller once it’s online. This needs the AP’s FortiCloud key, or a FortiDeploy key ordered with the hardware. I haven’t tested it, including whether a hostname survives an address change.

Step-by-step build

Placeholders: <wan> is the FortiGate’s internet interface, <ssid> is the new SSID name, <model> is the AP model, <serial> is the AP’s serial number.

1. Build the fence before you open the door

Create a service for CAPWAP, then local-in policies that allow it only from where you expect the AP to be, and deny everything else. This comes first so the listener is never open to the whole internet, even briefly.

config firewall service custom
    edit "CAPWAP"
        set udp-portrange 5246-5247
    next
end
config firewall local-in-policy
    edit 0
        set intf "<wan>"
        set srcaddr "<allowed-region-or-addresses>"
        set dstaddr "all"
        set action accept
        set service "CAPWAP"
        set schedule "always"
    next
    edit 0
        set intf "<wan>"
        set srcaddr "all"
        set dstaddr "all"
        set service "CAPWAP"
        set schedule "always"
    next
end
  • edit 0 appends, so create the allow before the deny. An allow that lands below a deny for the same service silently does nothing.
  • A deny rule shows no set action line. Confirm it by the absence of set action accept.
  • If the WAN is in an SD-WAN zone, intf takes the zone name.
  • Virtual patching can be enabled on the allow rule. See Security best practices.
  • This is defense in depth. The AP is still authorized by serial number.

2. Open the listener

config system interface
    edit "<wan>"
        set allowaccess ping fabric
    next
end

set allowaccess replaces the whole list. Run show system interface <wan> first and restate every existing value plus fabric, or you’ll lose WAN-side access you meant to keep.

3. Create the tunnel-mode SSID, its interface, and DHCP

config wireless-controller vap
    edit "<ssid>"
        set ssid "<ssid>"
        set security wpa3-sae
        set sae-password <temporary>
        set split-tunneling enable
    next
end
  • Leave local-bridging unset. Its default, disable, is tunnel mode.
  • Create the SSID with a throwaway password, then set the real one in the GUI before the SSID is assigned to any radio, so the throwaway is never broadcast and the real one never sits in your shell history.
  • wpa3-sae is WPA3-Personal, which requires Protected Management Frames. Use wpa3-sae-transition if some devices only support WPA2, or an 802.1X mode if you have RADIUS. With 802.1X, the RADIUS conversation happens between the FortiGate and the RADIUS server, so the remote AP never needs to reach it. See Security best practices.

Creating the SSID auto-creates an interface with the same name. Give it an address and a DHCP server, and set dns-service specify with both DNS servers if you want clients to use your own resolvers. Both default to 0.0.0.0.

4. Firewall policy

Create a policy from <ssid> to your internal network. A new policy defaults to deny, so set action accept is required.

  • Enumerate destinations and services. The remote AP sits on a network you don’t control and holds a trusted tunnel into yours. Policy scope is your biggest lever if it’s ever compromised.
  • Internet access depends on your tunnel choice. With split tunneling in tunnel mode, internet traffic leaves at the remote site and needs no policy. With a full tunnel, add an internet policy for the remote SSID, with the security profiles you use elsewhere.
  • Leave NAT off so logs show real client addresses.

5. The remote AP profile

config wireless-controller wtp-profile
    edit "<model>-Remote"
        config platform
            set type <model>
        end
        set dtls-policy ipsec-vpn
        set split-tunneling-acl-path tunnel
        config split-tunneling-acl
            edit 1
                set dest-ip <main-network> <mask>
            next
        end
        config radio-1
            set vap-all manual
            set vaps "<ssid>"
        end
        config radio-2
            set vap-all manual
            set vaps "<ssid>"
        end
    next
end
  • dtls-policy defaults to clear-text. On a LAN that’s fine. Across the internet it means every client frame crosses the public network unencrypted. This is the most important line in the profile. IPsec is also faster than DTLS: FortiGates with NP6 chips can offload IPsec in hardware, and DTLS can’t be offloaded at all.
  • split-tunneling-acl-path tunnel means the list says what goes home. With local the meaning flips, and getting it backwards silently tunnels everything or nothing.
  • Always use vap-all manual. A radio set to tunnel or bridge automatically adopts every new SSID of that mode the moment it’s created. A freshly adopted AP on a stock profile once broadcast my open guest network and none of the real ones.
  • Profiles are tied to a platform, so each AP model needs its own. If one model serves both on-site and remote roles, it needs two profiles.
  • Fortinet’s deployment guide recommends enabling radio resource provisioning on remote profiles (set darrp enable under each radio), so the AP picks channels for its own surroundings.
  • Split-tunneling options are hidden in the GUI by default. config system settings / set gui-fortiap-split-tunneling enable shows them.
  • Decide on the AP hardening options in Security best practices before the AP ships, while it’s still easy to change.
  • If you script this, assign SSIDs to radios with the CLI, not a REST PUT to a radio sub-object. A partial PUT wipes the channel list.

6. Stage the AP on your LAN

Authorize the AP, assign the remote profile, and push its discovery settings from the FortiGate with an apcfg-profile:

config wireless-controller apcfg-profile
    edit "Remote-AP-Discovery"
        set ac-type specify
        set ac-ip <controller-address>
        set ac-timer 10
        config command-list
            edit 1
                set name "AC_IPADDR_1"
                set value "<controller-address>"
            next
        end
    next
end
config wireless-controller wtp
    edit "<serial>"
        set apcfg-profile "Remote-AP-Discovery"
    next
end

ac-type specify with ac-timer is a safety net: if the AP can’t rejoin within the timer after applying the settings, it rolls them back.

Then confirm it applied with diagnose wireless-controller wlac -c wtp. Both cfg-apcfg-prof and oper-apcfg-pro should name your profile, with a completed status. If they don’t, stop and fix it now. This is the last moment you can reach the AP.

Verify it works

Do these in order. Each one gates the next.

  1. Optional dry run. Fortinet suggests temporarily broadcasting the remote SSID from an on-site AP first. That validates the SSID, DHCP, and firewall policy before the remote AP is in the picture.

  2. The AP connects from outside. Take it off your LAN and plug it into a genuinely separate internet connection. A FortiAP’s uplink is wired, so it can’t join a phone hotspot by itself. I used a spare router on its own, separate internet connection, so the AP sat behind a different public address and its own NAT, just like a real remote site. A travel router that uses a phone as its internet and gives the AP an Ethernet port works too. diagnose wireless-controller wlac -c wtp should show Connected with the remote site’s public address as the peer. An internal address means you’re still testing the LAN. Allow up to five minutes while it cycles through discovery methods.

  3. The data channel is encrypted. show wireless-controller wtp-profile <model>-Remote should show ipsec-vpn (or ipsec-sn-vpn). If it says clear-text, stop.

  4. A client gets an address from the FortiGate. execute dhcp lease-list should show the client in the remote SSID’s range. That’s the whole point of the feature.

  5. That client reaches an allowed internal service.

  6. The tunnel behaves as you chose. With split tunneling, from the client, run a traceroute to any internet address. The first hop should be the remote site’s router. If it’s your FortiGate, all of the remote site’s traffic is hairpinning through your main site, and everything will still look fine. That’s the defect you’re least likely to notice, which is why it gets its own check. With a full tunnel, the first hop should be your FortiGate.

Use diagnose output as proof of what’s running, not show output, which is only configuration.

Troubleshooting and gotchas

  • The AP never shows up in the controller. Check the switch port before the wireless config. Mine was on a port labeled “AP” that was still running NAC and parking it on an onboarding VLAN.
  • A long CLI line fails with value parse error / -173. If you’re automating over SSH, the client may be wrapping long lines. Keep lines short and read the config back. Don’t trust the echo.
  • The AP was working and went dark. Check whether the main site’s public address changed. With a static AC_IPADDR_1 there’s no remote fix. This is why the discovery decision matters.
  • A delete is refused. FortiOS won’t delete an object that’s still referenced. Work in reverse creation order.

Rollback

Reverse the build order:

  1. Move the AP to a default profile, or set admin disable on it.
  2. Delete the remote AP profile.
  3. Delete the firewall policy, then any objects it used.
  4. Delete the DHCP server, then the SSID.
  5. Remove fabric from the WAN’s allowaccess. This closes the listener.
  6. Delete both local-in policies, then the CAPWAP service.

Close the listener (step 5) before removing its fence (step 6), never the other way round.

If the AP is already remote and unreachable, don’t start by closing the listener, or you lose your last way to reconfigure it. Revoke it explicitly with set admin disable, and change the SSID passphrase, since the AP still holds it.

Security best practices

Security decisions for any network belong to the network administrator, who knows its risks, requirements, and constraints. This section lays out the recommended best practices for a remote AP and names the industry standard or vendor guidance behind each one, so you can weigh them against your own environment.

The standards referenced are the CIS FortiGate Benchmark, NIST SP 800-153 (Guidelines for Securing Wireless Local Area Networks), the Wi-Fi Alliance’s WPA3 certification, and Fortinet’s own documentation and PSIRT advisories.

A remote AP is worth this attention because of where it sits. On-site APs sit behind the firewall, on a switch you control. A remote AP sits on a network you don’t control, holds an encrypted tunnel into yours, and stores your Wi-Fi credentials.

Minimize the FortiGate’s exposure

The CAPWAP listener is real attack surface. CVE-2024-35279 (FG-IR-24-160) was a stack buffer overflow in FortiOS’s CAPWAP handling, reachable without authentication on any interface with fabric enabled. Fortinet’s published workarounds line up with the first three practices below.

Recommended practice Why Basis
Prefer a design with no internet-facing listener. Use a site-to-site VPN, and point the AP at the FortiGate’s private address. Removes the exposure entirely. It needs a remote router that can build a VPN. Fortinet PSIRT workaround (remove fabric)
Restrict CAPWAP with local-in policy. Allow UDP 5246 only from expected sources, and deny everything else. The narrowest source is the remote site’s static public address. A geography object is a broader fallback. CIS 2.4.6 Apply Local-in Policies. Fortinet PSIRT workaround.
Enable virtual patching (set virtual-patch enable) on the local-in allow rule The FortiGate’s IPS engine drops local-in traffic that matches known FortiOS exploits, covering the window between an advisory and your upgrade. It needs the FortiGuard firmware virtual-patch license. Fortinet notes it breaks agentless VPN and ZTNA connections that use client certificates. CIS 2.4.8 Virtual patching on the local-in management interface. Fortinet PSIRT workaround.
Pre-authorize APs by serial number and disable discovery on the WAN (set ap-discover disable) Only APs you added by hand can register, and unknown APs never appear. Fortinet Discovery and authorization of APs. Fortinet’s deployment guide calls auto-authorizing on the WAN “very poor security practice”, and FortiOS doesn’t offer it on WAN interfaces.
Keep management services off the WAN, and restrict admins to trusted hosts A remote AP needs only fabric, so HTTPS, SSH, and SNMP can stay internal. CIS 2.4.2 trusted hosts for all login accounts
Patch FortiOS promptly, and subscribe to Fortinet PSIRT advisories Listener bugs like the one above get fixed in firmware. NIST SP 800-153: vulnerability monitoring for WLAN components at least as often as for wired systems

Encrypt the data channel

The CAPWAP control channel is always DTLS. The data channel, meaning every client frame, defaults to clear-text, which is appropriate on a LAN but not across the internet.

Recommended: dtls-policy ipsec-vpn, or ipsec-sn-vpn where your release supports it. The second option also checks the AP’s serial number in the IKE exchange. Check the token with set dtls-policy ?.

IPsec can be hardware-offloaded on FortiGates with NP6 chips. dtls-enabled also encrypts the data channel, but it can’t be offloaded, so throughput is lower. The basis is Fortinet’s Data channel security guidance.

Harden the AP

Recommended practice Why Basis
Use a current, in-support model on up-to-date firmware, pushed from the FortiGate It keeps receiving security fixes. A remote AP is also the hardest one to reach for an update, so plan for that. NIST SP 800-153: vulnerability monitoring and patching
Set a unique AP admin password (login-passwd-change yes + login-passwd) The default, no, leaves the factory password in place. NIST SP 800-153: standardized security configurations
Disable management access on the AP (empty allowaccess) The AP then doesn’t answer HTTPS, SSH, or SNMP on the remote network. If you need SSH for staging, it’s common to open it only on your LAN and close it before the AP ships. NIST SP 800-153: standardized security configurations
Disable the console port (console-login disable) where the AP is physically accessible Blocks local login through the serial port, which is on by default. Changing this reboots every AP on the profile. Fortinet Disabling FortiAP port access
Disable the USB port (usb-port disable) if it isn’t used Removes an unused interface. It requires full PoE power. Fortinet Disabling FortiAP port access

Secure the LAN ports

APs like the 23JK have extra Ethernet ports, which are a big part of their appeal at a remote site: a printer, a desk phone, a TV. Each port’s behavior is set with port-mode (in config lan, or port1-mode, port2-mode and so on, depending on the model):

Mode What a plugged-in device gets
offline Nothing. The port is disabled.
bridge-to-ssid Joins an SSID’s network and tunnels home with it. Fortinet’s docs note that such a host “will be taken as authenticated”.
bridge-to-wan The remote site’s own network. It never touches the tunnel.
nat-to-wan Local network access, NATed behind the AP. It never touches the tunnel.

Recommended:

  • Disable ports that aren’t in use. That’s NIST SP 800-153’s guidance on disabling unauthorized interfaces and bridging.
  • Keep wired devices that only need the internet local with bridge-to-wan or nat-to-wan.
  • Give wired devices that need to reach home their own SSID. Create a separate SSID for wired devices, with its own subnet and a tightly scoped policy, rather than bridging ports into the network your wireless clients use. That follows NIST’s guidance to separate networks with different security profiles.

Secure the wireless side

Recommended practice Why Basis
WPA3-Enterprise (802.1X) where a RADIUS server is available Per-user or per-device credentials are checked on your side of the tunnel, so the AP holds no shared passphrase. Wi-Fi Alliance WPA3
Otherwise, WPA3-Personal (SAE) with a long, unique passphrase SAE resists offline password guessing, and WPA3 requires Protected Management Frames. Use transition mode only while devices that can’t do WPA3 remain. Wi-Fi Alliance WPA3
Client isolation (intra-vap-privacy) where clients don’t need to reach each other Limits how far one compromised device can reach. It breaks casting and printing between clients. NIST SP 800-153: limit access to what’s necessary

Contain the remote clients

Recommended practice Why Basis
Give remote clients their own subnet and zone Treats them as semi-trusted rather than as part of the main LAN. NIST SP 800-153: separate WLANs with different security profiles
Allow only the destinations and services they need Limits what a compromised remote device can reach. NIST SP 800-153: limit wired-network access to necessary hosts and protocols
Scope the policy’s source by an address object, not only by interface The policy keeps its meaning if the interface is later grouped into a zone. I learned this one in my own lab: a policy that relied only on the interface silently widened when I added it to a zone with other networks. Least privilege
Apply security profiles (IPS, antivirus, DNS filtering, application control) Inspects remote traffic the same way as any other segment. NIST SP 800-153: monitor for wired-network attacks too
Log all traffic, with NAT off The logs show the real client address. NIST SP 800-153: continuous monitoring

Monitor, assess, and plan for loss

  • Monitor continuously. Alert when the remote AP disconnects and when an unknown AP tries to join. Watch for denied local-in traffic to UDP 5246, which shows who’s probing the listener. FortiOS’s wireless intrusion detection (WIDS) profiles add rogue-AP detection. (NIST SP 800-153: continuous monitoring and WIDPS)
  • Assess regularly. NIST recommends a WLAN security assessment at least annually, and more often where continuous monitoring doesn’t already cover it.
  • Have a revocation plan. set admin disable on a lost AP’s entry cuts it off immediately. Rotating the SSID passphrase completes the job, because the AP still holds it. The serial number is what the AP is pre-authorized with, so treat it as sensitive.
  • Retire it completely. When a remote AP is no longer needed, close the listener and its fence (see Rollback), don’t just unplug it. I eventually removed mine: an address change had stranded it, and an AP that can’t connect isn’t worth an open port.

References

Everything this guide relies on, grouped so you can find the official documentation without hunting for it. Fortinet’s document library is versioned: open a link, then use the version selector to switch to your FortiOS or FortiAP release.

Fortinet deployment guides

FortiAP configuration guide topics

FortiOS CLI reference

Hardware, compatibility, and lifecycle

Security advisories and hardening

Industry standards