Description |
This article describes an expected behavior where DNS traffic can successfully bypass captive-portal authentication on the FortiGate. |
Scope | FortiOS. |
Solution |
When a firewall policy requires user authentication (for example, when captive-portal is enabled on the interface), any traffic originating from an IP address that does not belong to an authenticated firewall user entry will be dropped by default. To check the firewall user list, use the command diagnose firewall auth list.
However, DNS traffic is an exception to this rule. By design, DNS queries are allowed to pass through firewall polices without authentication. This ensures that users can resolve domain names even before authenticating, which is necessary in most cases to trigger the captive portal. As a result, DNS is the only protocol permitted without prior user authentication, while all other unauthenticated traffic is denied. Consider the following example Firewall Policy for port3, which has captive-portal enabled on the interface settings as well as a Firewall Policy with the 'LocalGroup' User Group specified:
config firewall policy edit 1 set name "LAN WAN" next end
Currently, there are no authenticated user entries on the FortiGate. This can be verified with the following command:
FortiGate # diagnose firewall auth list
----- 0 listed, 0 filtered ------
Other network protocols are dropped as expected when a client tries to send them through the FortiGate. The following is an example of debug flow output for ICMP traffic:
id=65308 trace_id=1 func=print_pkt_detail line=6005 msg="vd-root:0 received a packet(proto=1, 192.168.10.2:1->1.1.1.1:2048) tun_id=0.0.0.0 from port3. type=8, code=0, id=1, seq=1." id=65308 trace_id=1 func=init_ip_session_common line=6204 msg="allocate a new session-0000553c" id=65308 trace_id=1 func=__vf_ip_route_input_rcu line=1989 msg="find a route: flag=00000000 gw-192.168.1.1 via port1" id=65308 trace_id=1 func=__iprope_tree_check line=524 msg="gnum-100004, use int hash, slot=43, len=2" id=65308 trace_id=1 func=get_new_addr line=1274 msg="find SNAT: IP-192.168.1.120(from IPPOOL), port-60418" id=65308 trace_id=1 func=fw_forward_handler line=839 msg="Denied by forward policy check (policy 0)"
However, DNS traffic is allowed even though the client is not authenticated via the captive-portal:
id=65308 trace_id=2 func=print_pkt_detail line=6005 msg="vd-root:0 received a packet(proto=17, 192.168.10.2:52708->96.45.45.45:53) tun_id=0.0.0.0 from port3." id=65308 trace_id=2 func=init_ip_session_common line=6204 msg="allocate a new session-000055bc" id=65308 trace_id=2 func=__vf_ip_route_input_rcu line=1989 msg="find a route: flag=00000000 gw-192.168.1.1 via port1" id=65308 trace_id=2 func=__iprope_tree_check line=524 msg="gnum-100004, use int hash, slot=43, len=2" id=65308 trace_id=2 func=get_new_addr line=1274 msg="find SNAT: IP-192.168.1.120(from IPPOOL), port-52708" id=65308 trace_id=2 func=fw_forward_handler line=1002 msg="Allowed by Policy-1: SNAT" id=65308 trace_id=2 func=ip_session_confirm_final line=3179 msg="npu_state=0x100, hook=4" id=65308 trace_id=2 func=__ip_session_run_tuple line=3512 msg="SNAT 192.168.10.2->192.168.1.120:52708" id=65308 trace_id=2 func=__ip_session_run_tuple line=3566 msg="run helper-dns-udp(dir=original)" id=65308 trace_id=3 func=print_pkt_detail line=6005 msg="vd-root:0 received a packet(proto=17, 96.45.45.45:53->192.168.1.120:52708) tun_id=0.0.0.0 from port1."
If this behavior is not wanted, then an explicit Firewall Policy needs to be created and placed at the top of the list (above other Firewall Policies with authentication) to only allow DNS traffic access for specific DNS servers. For example, the following policy blocks all DNS traffic except traffic towards Google DNS (8.8.8.8): config firewall policy edit 5 set name "Block_unwanted DNS traffic" next end |
The Fortinet Security Fabric brings together the concepts of convergence and consolidation to provide comprehensive cybersecurity protection for all users, devices, and applications and across all network edges.
Copyright 2025 Fortinet, Inc. All Rights Reserved.