Purpose
Scope
All FortiGates or VDOMs in NAT mode.
Diagram
Note :
Expectations, Requirements
- uranium-mvm08 requests HTTP traffic on the Internet using TCP port 80 (browser is not configured to use a proxy)
- FGT3600 intercepts the traffic with a WCCP policy and redirects traffic to uranium-mvm03 squid transparent proxy through a GRE tunnel
- uranium-mvm03 squid gets the content from the Internet if not already in the cache via FortiGate port1
- uranium-mvm03 squid returns the content towards the FortiGate for uranium-mvm08 using the GRE tunnel
- FGT3600 receives the content from GRE and hooks it back to uranium-mvm08 using the WCCP policy
WCCP stands for "Web Cache Coordinator Protocol". The idea is to transparently redirect user traffic to a cache (that is: no explicit web proxy configured on client web browser).
- WCCP is defined as an RFC draft
- It has built-in load-balancing and fault tolerance
- WCCP protocol uses UDP port 2048 to communicate between FortiGate and Caches
- WCCP has 2 types of services (well-known service id=0 for http and dynamic services (from id 51 to 255)
- WCCP allows 2 types of tunneling mechanisms ( GRE and L2 Forwarding)
Configuration
(only the relevant configuration is shown)
config system interface edit "port1" set vdom "root" set ip 10.120.0.225 255.255.254.0 set allowaccess ping https ssh http telnet set type physical set wccp enable (#1) next edit "internal" set vdom "root" set ip 10.100.0.225 255.255.254.0 set allowaccess ping https ssh http telnet set type physical next edit "external" set vdom "root" set ip 192.168.182.225 255.255.254.0 set allowaccess ping https ssh http telnet set type physical next end config firewall address edit "all" next edit "squid-proxy" set associated-interface "port1" set subnet 10.102.0.83 255.255.255.255 next edit "client-subnet" set associated-interface "internal" set subnet 10.100.0.0 255.255.255.0 next end config firewall policy edit 3 set srcintf "internal" set dstintf "external" set srcaddr "client-subnet" set dstaddr "all" set action accept set schedule "always" set service "HTTP" set wccp enable (#2) set comments "HTTP TRAFFIC TO INTERCEPT" set nat enable next edit 1 set srcintf "internal" set dstintf "external" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "DNS" "PING" set comments "CLIENT NON HTTP TRAFFIC DIRECT" set nat enable next edit 2 set srcintf "port1" set dstintf "external" set srcaddr "squid-proxy" set dstaddr "all" set action accept set schedule "always" set service "DNS" "HTTP" "PING" set comments "PROXY TRAFFIC" set nat enable next end config router static edit 1 set device "external" set gateway 192.168.183.254 next edit 2 set device "port1" set dst 10.102.0.0 255.255.254.0 set gateway 10.120.0.76 next end config system wccp edit "0" (#3) set router-id 10.120.0.225 (#4) set server-list 10.102.0.83 255.255.255.255 (#5) set authentication enable (#6) set password ENC /pSXIHLNBkcXgQD5XOAhnq0dfgOcHsFwIAp3yDVWa6zWMZTM+y1dolT5yxO3GZgKAQsOluZ21HNzi+qxxOJ0hUfrwDhEJwFFbuVzAXEP9XtZPdBh (#7) next end |
Keys of the configuration:
(only the relevant configuration is shown)
In the first place we focus on the networking settings for the Linux server, then we highlight the relevant parts of the squid configuration.
# ip addresses and default route : ifconfig eth0 10.102.0.83 netmask 255.255.254.0 route add default gw 10.102.0.76 # GRE Tunnel : modprobe ip_gre ip tunnel add wccp0 mode gre remote 10.120.0.225 local 10.102.0.83 dev eth0 ip addr add 10.102.0.83/32 dev wccp0 ip link set wccp0 up # Route to send the content back to the GRE tunnel route add -net 192.168.182.225/32 dev wccp0 # Disabling reverse path filtering and enable routing in the kernel echo 0 > /proc/sys/net/ipv4/conf/wccp0/rp_filter echo 1 > /proc/sys/net/ipv4/ip_forward # Setup the redirection of traffic from the GRE tunnel to squid port 3128 iptables -t nat -F iptables -t nat -A PREROUTING -i wccp0 -m tcp -p tcp -j REDIRECT --to-ports 3128 |
/etc/squid/squid.conf # setup transparent squid on port 3128 http_port 3128 transparent # Allow clients to request contents http_access allow all # FortiGate interface of wccp wccp2_router 10.120.0.225 # wccp version 2 configuration for standard service HTTP on tcp port 80 (service 0) with authentication password 'fortinet' wccp2_service standard 0 password=fortinet # tunneling method GRE for forward traffic wccp2_forwarding_method 1 # tunneling method GRE for return traffic wccp2_return_method 1 # Assignemment method (default), only relevant if multiple caches used wccp2_assignment_method 1 # wccp weight (default) ,only relevant if multiple caches used wccp2_weight 10000 # which interface to use for WCCP (0.0.0.0 determines the interface from routing) wccp2_address 0.0.0.0 |
Verification
FG3600-4 # diagnose test application wccpd 1 vdoms=1 pkts=0 |
FG3600-4 # diagnose test application wccpd 2 vdom-root: working NAT first_phy_id=2 interface list: intf=port1, gid=2 phy_id=2 service list: service: 0, router_id=10.120.0.225, group=0.0.0.0, auth(fortinet) access:10.102.0.83/255.255.255.255 forward=1 return=1, assign=1. erouter_id=10.120.0.225 |
FG3600-4 # diagnose test application wccpd 3 service-0 in vdom-root: num=1, usable=1 cache server ID: len=44, addr=10.102.0.83, weight=4135, status=0 rcv_id=51, usable=1, fm=1, nq=0, dev=2(k2), to=10.120.0.225 ch_no=0, num_router=1: 10.120.0.225 |
FG3600-4 # diagnose test application wccpd 4 service-0 in vdom-root: total_servers=1, usable_servers=1, assign_m=1, rtun_m=1, wcid_len=48, rcv_id=54, ch_no=2 ID=0, type=0, pri=0, pro=0 f=00000000 Port: 0 0 0 0 0 0 0 0 num-routers=1: 10.120.0.225 |
FG3600-4 # diagnose test application wccpd 5 service-0 in vdom-root: key: ip=10.102.0.83, change-number=1 cache_list: 1 0. 10.102.0.83 primary assignment: key=10.102.0.83 change-number=1 num_routers=1 router element[0]: router_id=10.120.0.225, receive_id=4, ch_no=2 cache-server-num=1: 10.102.0.83 buckets: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
session info: proto=6 proto_state=01 expire=3599 timeout=3600 flags=00000000 sockflag=00000000 sockport=0 av_idx=0 use=4 origin-shaper= reply-shaper= ha_id=0 hakey=53608 policy_dir=0 tunnel=/ state=wccp may_dirty nlb rem statistic(bytes/packets/allow_err): org=598/4/1 reply=1967/4/1 tuples=2 orgin->sink: org pre->post, reply pre->post dev=3->4/4->3 gwy=192.168.183.254/10.100.0.88 hook=post dir=org act=snat 10.100.0.88:1752->4.71.209.16:80(192.168.182.225:50780) hook=pre dir=reply act=dnat 4.71.209.16:80->192.168.182.225:50780(10.100.0.88:1752) pos/(before,after) 0/(0,0), 0/(0,0) misc=0 policy_id=3 auth_info=0 chk_client_info=0 vd=0 serial=000091f5 tos=ff/ff app=0 dd_type=0 dd_rule_id=0 wccp: server=10.102.0.83, rid=10.120.0.225, dev=2, pri=180, alt=0 GRE-F L2-R std |
Activity of the proxy is traceable from the squid logs
/var/log/squid/access.log 1242672135.232 1 10.100.0.88 TCP_MEM_HIT/200 3548 GET http://search.cpan.org/author/ - NONE/- text/html 1242672135.388 39 10.100.0.88 TCP_MEM_HIT/200 1998 GET http://st.pimg.net/tucs/style.css - NONE/- text/css 1242672135.401 12 10.100.0.88 TCP_MEM_HIT/200 627 GET http://st.pimg.net/tucs/print.css - NONE/- text/css 1242672135.401 12 10.100.0.88 TCP_MEM_HIT/200 2362 GET http://st.pimg.net/tucs/img/DC-LOGO-S.gif - NONE/- image/gif 1242672135.402 13 10.100.0.88 TCP_MEM_HIT/200 5610 GET http://st.pimg.net/tucs/img/cpan_banner.png - NONE/- image/png 1242672135.575 1 10.100.0.88 TCP_HIT/200 9617 GET http://www.google-analytics.com/ga.js - NONE/- text/javascript 1242672135.782 13 10.100.0.88 TCP_MEM_HIT/200 772 GET http://search.cpan.org/favicon.ico - NONE/- image/x-icon 1242672487.062 144 10.100.0.88 TCP_MISS/404 2927 GET http://search.cpan.org/search?query=&mode=author - DIRECT/84.45.68.23 text/html |
Troubleshooting
debug flow
Output example of 'diag debug flow' showing in this example how client traffic is processed by the FortiGate
id=20085 trace_id=100222 func=resolve_ip_tuple_fast line=3196 msg="vd-root received a packet(proto=6, 10.100.0.88:1658->84.45.68.23:80) from internal."
Related articles: WCCP CLI reference.
WCCP configuration between 2 FortiGates using GRE tunnel (Router/Server and Client): |
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.