Fortinet white logo
Fortinet white logo

New Features

DNS filtering in proxy policies

DNS filtering in proxy policies

Note

This information is also available in the FortiOS 7.6 Administration Guide:

DNS filtering can be applied to proxy policies, providing an extra layer of protection for users that are behind a proxy. This is particularly useful when client applications use DoH and DoT protocols and require the added security of DNS filtering.

To configure and test a proxy policy with a DNS filter:
  1. Configure a DNS filter. See DNS filter.

  2. Go to Policy & Objects > Proxy Policy, create or edit an explicit or transparent web proxy policy, and apply the DNS filter.

    config firewall proxy-policy
        edit 1 
            set proxy {explicit-web | transparent-web}
            set dnsfilter-profile "dnsfilter_fgd"
        next
    end
  3. Test the filter from a client that is configured to use the proxy:

  • DoH client request through an explicit proxy policy with the action set to block:

    curl -H 'accept: application/dns-message' -x 10.1.100.1:8080  -v -k 'https://1.1.1.1/dns-query?dns=q80BAAABAAAAAAAAA3d3dwN1YmMCY2EAAAEAAQ' | hexdump
    
    *   Trying 10.1.100.1:8080...
    * TCP_NODELAY set
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
      0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 10.1.100.1 (10.1.100.1) port 8080 (#0)
    * allocate connect buffer!
    * Establish HTTP proxy tunnel to 1.1.1.1:443
    > CONNECT 1.1.1.1:443 HTTP/1.1
    > Host: 1.1.1.1:443
    > User-Agent: curl/7.68.0
    > Proxy-Connection: Keep-Alive
    >
    < HTTP/1.1 200 Connection established
    < Proxy-Agent: Fortinet-Proxy/1.0
    <
    * Proxy replied 200 to CONNECT request
    * CONNECT phase completed!
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    } [5 bytes data]
    * Using Stream ID: 1 (easy handle 0x555786e4bdb0)
    } [5 bytes data]
    > GET /dns-query?dns=q80BAAABAAAAAAAAA3d3dwN1YmMCY2EAAAEAAQ HTTP/2
    > Host: 1.1.1.1
    > user-agent: curl/7.68.0
    > accept: application/dns-message
    } [5 bytes data]
    < HTTP/2 200
    < content-type: application/dns-message
    < content-length: 28
    <
    { [28 bytes data]
    100    28  100    28    0     0    430      0 --:--:-- --:--:-- --:--:--   430
    * Connection #0 to host 10.1.100.1 left intact
    0000000 cdab 0381 0100 0000 0000 0000 7703 7777
    0000010 7503 6362 6302 0061 0100 0100
    000001c
    connect svr orig 10.1.100.11:33270->10.1.100.1:8080 out 10.1.100.11:33270->1.1.1.1:8080
    [I][p:386][s:1746142837][r:50331664] wad_http_upd_ses_ctx_by_req       :1046  wad http session 0x7f3842990b80  forward (nil) fwd_srv_ip=
    [V][p:386][s:1746142837][r:50331664] wad_http_connect_srv              :791   [0x7f384377a8e8] Connect to server: 1.1.1.1:443/1.1.1.1:443
    
    HTTP/1.1 200 Connection established
    Proxy-Agent: Fortinet-Proxy/1.0
    
    HTTP/1.1 200
    server: cloudflare
    
    [V][p:386][s:1746142837] wad_http_doh_proc_payload         :274   msg(0x7f384378ace8) proc doh payload from 10.1.100.11 -> 1.1.1.1.
    [V][p:386][s:1746142837] wad_http_doh_proc_payload         :289   dnsproxy_local_id=0xabcd.
    [I][p:386][s:1746142837] wad_dns_req_msg_send_hdr          :172   send unreq to dnsproxy.
    msg_len=135, type=wad_srv_res, dnxproxy_local_id=0xabcd,  session_id=157, flags=0, vfid=1, vrf=0, ifindex=7, policy_id=1, proto=6, src_addr=10.1.100.11, dst_addr=1.1.1.1
    
    [worker 0] dns_profile_do_url_rating()-2036: vfid=1 profile=dnsfilter_fgd category=30 domain=www.ubc.ca
    [worker 0] dns_profile_do_url_rating()-2128: response filter result for www.ubc.ca (type=7 action=10)
    [worker 0] dns_secure_apply_action()-2270: action=10 category=30 log=1 error_allow=0 profile=dnsfilter_fgd
    [worker 0] dns_send_error_response()-1809: id: 0xabcd domain: www.ubc.ca qtype: 1 err: 3
    [worker 0] dns_send_response()-1626: domain=www.ubc.ca reslen=28
    [worker 0] dns_secure_log_response()-1254: id:0xcdab domain=www.ubc.ca profile=dnsfilter_fgd action=10 log=1
    [worker 0] dns_secure_log_response()-1276: cannot find IPv4 session
    [worker 0] dns_unix_stream_packet_write()-287: vfid=1 real_vfid=1 vrf=0 id=0xabcd domain=www.ubc.ca req_type=2 req=0
    [worker 0] dns_unix_stream_packet_write()-309: type=7 len=31 session_id=147 flags=1
    [worker 0] dns_query_delete()-560: orig id:0xabcd local id:0xabcd domain=www.ubc.ca use=5 active
  • DoT client request to a Cloudfare server at 1.1.1.1 through an explicit proxy policy with the action set to redirect:

    kdig www.ubc.ca +tls @127.0.0.1:853
    ;; TLS session (TLS1.3)-(ECDHE-X25519)-(ECDSA-SECP256R1-SHA256)-(AES-256-GCM)
    ;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 64291
    ;; Flags: qr rd; QUERY: 1; ANSWER: 1; AUTHORITY: 0; ADDITIONAL: 0
    
    ;; QUESTION SECTION:
    ;; www.ubc.ca.                  IN      A
    
    ;; ANSWER SECTION:
    www.ubc.ca.             60      IN      A       208.91.112.55
    
    ;; Received 44 B
    ;; Time 2024-07-02 22:18:51 UTC
    ;; From 127.0.0.1@853(TCP) in 54.8 ms
    [worker 0] dns_secure_forward_response()-1660: category=30 profile=dnsfilter_fgd
    [worker 0] dns_visibility_log_hostname()-371: vd=1 pktlen=468
    [worker 0] wildcard_fqdn_response_cb()-951: vd=1 pktlen=468
    [worker 0] hostname_entry_insert()-292: af=2 domain=www.ubc.ca
    [worker 0] hostname_entry_insert()-292: af=2 domain=www.ubc.ca
    [worker 0] hostname_entry_insert()-292: af=2 domain=www.ubc.ca
    [worker 0] hostname_entry_insert()-292: af=2 domain=www.ubc.ca
    [worker 0] dns_profile_do_url_rating()-2036: vfid=1 profile=dnsfilter_fgd category=30 domain=www.ubc.ca
    [worker 0] dns_profile_do_url_rating()-2128: response filter result for www.ubc.ca (type=7 action=10)
    [worker 0] dns_secure_apply_action()-2270: action=10 category=30 log=1 error_allow=0 profile=dnsfilter_fgd
    [worker 0] dns_secure_answer_redir()-1605
    [worker 0] dns_send_response()-1626: domain=www.ubc.ca reslen=44
    [worker 0] dns_secure_log_response()-1254: id:0x23fb domain=www.ubc.ca profile=dnsfilter_fgd action=10 log=1
  • DoH client request through a transparent proxy policy with the action set to redirect:

    curl -H 'accept: application/dns-message'  -v -k 'https://1.1.1.1/dns-query?dns=q80BAAABAAAAAAAAA3d3dwN1YmMCY2EAAAEAAQ' | hexdump
    
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    } [5 bytes data]
    * Using Stream ID: 1 (easy handle 0x562b7267bdb0)
    } [5 bytes data]
    > GET /dns-query?dns=q80BAAABAAAAAAAAA3d3dwN1YmMCY2EAAAEAAQ HTTP/2
    > Host: 1.1.1.1
    > user-agent: curl/7.68.0
    > accept: application/dns-message
    < HTTP/2 200
    < content-type: application/dns-message
    < content-length: 28
    <
    { [28 bytes data]
    100    28  100    28    0     0     27      0  0:00:01  0:00:01 --:--:--    27
    * Connection #0 to host 1.1.1.1 left intact
    0000000 cdab 0381 0100 0000 0000 0000 7703 7777
    0000010 7503 6362 6302 0061 0100 0100
    000001c
    [worker 0] dns_profile_do_url_rating()-2036: vfid=1 profile=dnsfilter_fgd category=30 domain=www.ubc.ca
    [worker 0] dns_profile_do_url_rating()-2128: response filter result for www.ubc.ca (type=7 action=10)
    [worker 0] dns_secure_apply_action()-2270: action=10 category=30 log=1 error_allow=0 profile=dnsfilter_fgd
    [worker 0] dns_send_error_response()-1809: id: 0xabcd domain: www.ubc.ca qtype: 1 err: 3
    [worker 0] dns_send_response()-1626: domain=www.ubc.ca reslen=28
    [worker 0] dns_secure_log_response()-1254: id:0xcdab domain=www.ubc.ca profile=dnsfilter_fgd action=10 log=1
    [worker 0] dns_policy_find_by_idx()-2990: vfid=1 idx=1 policy_type=1
    [worker 0] dns_secure_log_response()-1504: write to log: logid=54803 qname=www.ubc.ca
    [worker 0] dns_unix_stream_packet_write()-287: vfid=1 real_vfid=1 vrf=0 id=0xabcd domain=www.ubc.ca req_type=2 req=0
    [worker 0] dns_unix_stream_packet_write()-309: type=7 len=31 session_id=259 flags=1
    [worker 0] dns_query_delete()-560: orig id:0xabcd local id:0xabcd domain=www.ubc.ca use=5 active
    

DNS filtering in proxy policies

DNS filtering in proxy policies

Note

This information is also available in the FortiOS 7.6 Administration Guide:

DNS filtering can be applied to proxy policies, providing an extra layer of protection for users that are behind a proxy. This is particularly useful when client applications use DoH and DoT protocols and require the added security of DNS filtering.

To configure and test a proxy policy with a DNS filter:
  1. Configure a DNS filter. See DNS filter.

  2. Go to Policy & Objects > Proxy Policy, create or edit an explicit or transparent web proxy policy, and apply the DNS filter.

    config firewall proxy-policy
        edit 1 
            set proxy {explicit-web | transparent-web}
            set dnsfilter-profile "dnsfilter_fgd"
        next
    end
  3. Test the filter from a client that is configured to use the proxy:

  • DoH client request through an explicit proxy policy with the action set to block:

    curl -H 'accept: application/dns-message' -x 10.1.100.1:8080  -v -k 'https://1.1.1.1/dns-query?dns=q80BAAABAAAAAAAAA3d3dwN1YmMCY2EAAAEAAQ' | hexdump
    
    *   Trying 10.1.100.1:8080...
    * TCP_NODELAY set
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
      0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 10.1.100.1 (10.1.100.1) port 8080 (#0)
    * allocate connect buffer!
    * Establish HTTP proxy tunnel to 1.1.1.1:443
    > CONNECT 1.1.1.1:443 HTTP/1.1
    > Host: 1.1.1.1:443
    > User-Agent: curl/7.68.0
    > Proxy-Connection: Keep-Alive
    >
    < HTTP/1.1 200 Connection established
    < Proxy-Agent: Fortinet-Proxy/1.0
    <
    * Proxy replied 200 to CONNECT request
    * CONNECT phase completed!
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    } [5 bytes data]
    * Using Stream ID: 1 (easy handle 0x555786e4bdb0)
    } [5 bytes data]
    > GET /dns-query?dns=q80BAAABAAAAAAAAA3d3dwN1YmMCY2EAAAEAAQ HTTP/2
    > Host: 1.1.1.1
    > user-agent: curl/7.68.0
    > accept: application/dns-message
    } [5 bytes data]
    < HTTP/2 200
    < content-type: application/dns-message
    < content-length: 28
    <
    { [28 bytes data]
    100    28  100    28    0     0    430      0 --:--:-- --:--:-- --:--:--   430
    * Connection #0 to host 10.1.100.1 left intact
    0000000 cdab 0381 0100 0000 0000 0000 7703 7777
    0000010 7503 6362 6302 0061 0100 0100
    000001c
    connect svr orig 10.1.100.11:33270->10.1.100.1:8080 out 10.1.100.11:33270->1.1.1.1:8080
    [I][p:386][s:1746142837][r:50331664] wad_http_upd_ses_ctx_by_req       :1046  wad http session 0x7f3842990b80  forward (nil) fwd_srv_ip=
    [V][p:386][s:1746142837][r:50331664] wad_http_connect_srv              :791   [0x7f384377a8e8] Connect to server: 1.1.1.1:443/1.1.1.1:443
    
    HTTP/1.1 200 Connection established
    Proxy-Agent: Fortinet-Proxy/1.0
    
    HTTP/1.1 200
    server: cloudflare
    
    [V][p:386][s:1746142837] wad_http_doh_proc_payload         :274   msg(0x7f384378ace8) proc doh payload from 10.1.100.11 -> 1.1.1.1.
    [V][p:386][s:1746142837] wad_http_doh_proc_payload         :289   dnsproxy_local_id=0xabcd.
    [I][p:386][s:1746142837] wad_dns_req_msg_send_hdr          :172   send unreq to dnsproxy.
    msg_len=135, type=wad_srv_res, dnxproxy_local_id=0xabcd,  session_id=157, flags=0, vfid=1, vrf=0, ifindex=7, policy_id=1, proto=6, src_addr=10.1.100.11, dst_addr=1.1.1.1
    
    [worker 0] dns_profile_do_url_rating()-2036: vfid=1 profile=dnsfilter_fgd category=30 domain=www.ubc.ca
    [worker 0] dns_profile_do_url_rating()-2128: response filter result for www.ubc.ca (type=7 action=10)
    [worker 0] dns_secure_apply_action()-2270: action=10 category=30 log=1 error_allow=0 profile=dnsfilter_fgd
    [worker 0] dns_send_error_response()-1809: id: 0xabcd domain: www.ubc.ca qtype: 1 err: 3
    [worker 0] dns_send_response()-1626: domain=www.ubc.ca reslen=28
    [worker 0] dns_secure_log_response()-1254: id:0xcdab domain=www.ubc.ca profile=dnsfilter_fgd action=10 log=1
    [worker 0] dns_secure_log_response()-1276: cannot find IPv4 session
    [worker 0] dns_unix_stream_packet_write()-287: vfid=1 real_vfid=1 vrf=0 id=0xabcd domain=www.ubc.ca req_type=2 req=0
    [worker 0] dns_unix_stream_packet_write()-309: type=7 len=31 session_id=147 flags=1
    [worker 0] dns_query_delete()-560: orig id:0xabcd local id:0xabcd domain=www.ubc.ca use=5 active
  • DoT client request to a Cloudfare server at 1.1.1.1 through an explicit proxy policy with the action set to redirect:

    kdig www.ubc.ca +tls @127.0.0.1:853
    ;; TLS session (TLS1.3)-(ECDHE-X25519)-(ECDSA-SECP256R1-SHA256)-(AES-256-GCM)
    ;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 64291
    ;; Flags: qr rd; QUERY: 1; ANSWER: 1; AUTHORITY: 0; ADDITIONAL: 0
    
    ;; QUESTION SECTION:
    ;; www.ubc.ca.                  IN      A
    
    ;; ANSWER SECTION:
    www.ubc.ca.             60      IN      A       208.91.112.55
    
    ;; Received 44 B
    ;; Time 2024-07-02 22:18:51 UTC
    ;; From 127.0.0.1@853(TCP) in 54.8 ms
    [worker 0] dns_secure_forward_response()-1660: category=30 profile=dnsfilter_fgd
    [worker 0] dns_visibility_log_hostname()-371: vd=1 pktlen=468
    [worker 0] wildcard_fqdn_response_cb()-951: vd=1 pktlen=468
    [worker 0] hostname_entry_insert()-292: af=2 domain=www.ubc.ca
    [worker 0] hostname_entry_insert()-292: af=2 domain=www.ubc.ca
    [worker 0] hostname_entry_insert()-292: af=2 domain=www.ubc.ca
    [worker 0] hostname_entry_insert()-292: af=2 domain=www.ubc.ca
    [worker 0] dns_profile_do_url_rating()-2036: vfid=1 profile=dnsfilter_fgd category=30 domain=www.ubc.ca
    [worker 0] dns_profile_do_url_rating()-2128: response filter result for www.ubc.ca (type=7 action=10)
    [worker 0] dns_secure_apply_action()-2270: action=10 category=30 log=1 error_allow=0 profile=dnsfilter_fgd
    [worker 0] dns_secure_answer_redir()-1605
    [worker 0] dns_send_response()-1626: domain=www.ubc.ca reslen=44
    [worker 0] dns_secure_log_response()-1254: id:0x23fb domain=www.ubc.ca profile=dnsfilter_fgd action=10 log=1
  • DoH client request through a transparent proxy policy with the action set to redirect:

    curl -H 'accept: application/dns-message'  -v -k 'https://1.1.1.1/dns-query?dns=q80BAAABAAAAAAAAA3d3dwN1YmMCY2EAAAEAAQ' | hexdump
    
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    } [5 bytes data]
    * Using Stream ID: 1 (easy handle 0x562b7267bdb0)
    } [5 bytes data]
    > GET /dns-query?dns=q80BAAABAAAAAAAAA3d3dwN1YmMCY2EAAAEAAQ HTTP/2
    > Host: 1.1.1.1
    > user-agent: curl/7.68.0
    > accept: application/dns-message
    < HTTP/2 200
    < content-type: application/dns-message
    < content-length: 28
    <
    { [28 bytes data]
    100    28  100    28    0     0     27      0  0:00:01  0:00:01 --:--:--    27
    * Connection #0 to host 1.1.1.1 left intact
    0000000 cdab 0381 0100 0000 0000 0000 7703 7777
    0000010 7503 6362 6302 0061 0100 0100
    000001c
    [worker 0] dns_profile_do_url_rating()-2036: vfid=1 profile=dnsfilter_fgd category=30 domain=www.ubc.ca
    [worker 0] dns_profile_do_url_rating()-2128: response filter result for www.ubc.ca (type=7 action=10)
    [worker 0] dns_secure_apply_action()-2270: action=10 category=30 log=1 error_allow=0 profile=dnsfilter_fgd
    [worker 0] dns_send_error_response()-1809: id: 0xabcd domain: www.ubc.ca qtype: 1 err: 3
    [worker 0] dns_send_response()-1626: domain=www.ubc.ca reslen=28
    [worker 0] dns_secure_log_response()-1254: id:0xcdab domain=www.ubc.ca profile=dnsfilter_fgd action=10 log=1
    [worker 0] dns_policy_find_by_idx()-2990: vfid=1 idx=1 policy_type=1
    [worker 0] dns_secure_log_response()-1504: write to log: logid=54803 qname=www.ubc.ca
    [worker 0] dns_unix_stream_packet_write()-287: vfid=1 real_vfid=1 vrf=0 id=0xabcd domain=www.ubc.ca req_type=2 req=0
    [worker 0] dns_unix_stream_packet_write()-309: type=7 len=31 session_id=259 flags=1
    [worker 0] dns_query_delete()-560: orig id:0xabcd local id:0xabcd domain=www.ubc.ca use=5 active