Transparent squid not working (pf, nat, openvpn subnet)

I have set up openvpn server on subnet 10.8.0.0/24 and pf NAT to the internal network 192.168.1.0/24, I had some problems but I solved them and the whole thing is working fine. For the sake of anonymizing the web surfing I am having squid set in another fib, where another instance of openvpn is running, as a client. Squid (version 3.5.11 and compiled with --enable-pf-transparent) is configured for SSL bumping (MITM), and has two ports opened, one as a normal http(s) proxy, and another one as a transparent proxy, the normal web proxy port works fine. Squid has acls set for whole 192.168.1.0/24.

The ruleset for transparent proxying is killing me, I can't make it to work, the nat is proxying the 10.8.0.0/24 network just fine over alias 192.168.1.203 and the rdr pass should catch that address on the other side to reach the squid. But it is like calling the dead... no answer.

Code:
ext_if = "re0"                                                                    
ext_ip = "192.168.1.203"                                                          
vpn_if = "tun2"                                                                    
vpn_net = "10.8.0.0/24"                                                            
nat on ! $vpn_if from $vpn_net to any -> $ext_ip                                  
rdr pass inet proto tcp from $ext_ip to any port 80 -> 127.0.0.1 port 3129        
rdr pass inet proto tcp from $ext_ip to any port 443 -> 127.0.0.1 port 3129

I just can't figure out what I am doing wrong? :confused: The phone (openvpn client) is reaching the internet so the whole set up works fine, but not over the squid.
 
Last edited by a moderator:
,,, Squid (version 3.5.11 and compiled with --enable-pf-transparent) is configured for SSL bumping (MITM), and has two ports opened, one as a normal http(s) proxy, and another one as a transparent proxy, the normal web proxy port works fine. ...
Code:
...        
rdr pass inet proto tcp from $ext_ip to any port 80 -> 127.0.0.1 port 3129
rdr pass inet proto tcp from $ext_ip to any port 443 -> 127.0.0.1 port 3129

I assume, with "... the normal web proxy port works fine.", you mean Squid does listen on the internal IP on port 3127 and is able to receive traffic from the internal clients and pass that forth and back to/from the internet.

For the transparent proxy you need to divide the traffic on 80 and on 443 to two different ports. In my installation I use 3128 as the transparent proxy port for the real port 80 and 3129 as the tp port for the real port 443. So, I suggest, to switch the port 80 rdr of your firewall rule to 3128.

With that my /usr/local/etc/squid/squid.conf looks as follows:
Code:
shutdown_lifetime       0 seconds

acl localnet            src 10.0.0.0/24
acl safari5             src 10.0.0.2 10.0.0.8 10.0.0.13
acl http_port           port 80
acl https_port          port 443
acl proxy_ports         port 80 443
acl CONNECT             method CONNECT

http_access             deny !proxy_ports
http_access             deny CONNECT !https_port
http_access             deny to_localhost
http_access             allow localhost manager
http_access             deny manager
http_access             allow localnet
http_access             deny all

http_port               10.0.0.1:3127
http_port               127.0.0.1:3128 intercept
https_port              127.0.0.1:3129 intercept ssl-bump generate-host-certificates=on cert=/usr/local/etc/squid/proxy-ca.pem options=NO_SSLv2

acl step1               at_step SslBump1
ssl_bump                peek step1
ssl_bump                bump https_port

sslproxy_options        NO_SSLv2
sslproxy_cafile         /etc/ssl/cert.pem
sslcrtd_program         /usr/local/libexec/squid/ssl_crtd -s /usr/local/etc/squid/dyn-certs -M 4MB
sslcrtd_children        8 startup=3 idle=1

cache_mem               512 MB
cache_dir               aufs /var/squid/cache 10000 16 256
coredump_dir            /var/squid/cache

refresh_pattern         -i (/cgi-bin/|\?)  0    0%    0
refresh_pattern         .                  0   20% 4320

request_header_access   User-Agent deny safari5
request_header_add      User-Agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/600.8.9 (KHTML, like Gecko) Version/8.0.8 Safari/600.8.9" safari5
Notes:
  1. For a working transparent ssl-proxy, you need to place your own CA certificate chain, consisting of a root CA certificate, a signing certificate and its private key (all joined together in one .pem file) into a place where squid can read it, in my configuration above the file is /usr/local/etc/squid/proxy-ca.pem.

  2. For Squid being able to validate TLS traffic on behalf of its clients, you need to indicate to it a store of publicly trusted CA certificates. In my configuration file above this is /etc/ssl/cert.pem, which is actually a dynamic link of security/ca_root_nss.

  3. Finally, you need to make the directory where Squid can place the dynamically created and signed intermediate certificates, in my configuration file this is: /usr/local/etc/squid/dyn-certs.

  4. The request_header_access directives are of my special purpose. I left it in there, so you can see where to put your customization.
I showed my whole configuration file because I figured, that by using a working example, you could better find your way through the obstacles. If some detail is unclear, please ask.
 
Thank you for your post, this is going to be highly useful for someone, but the problem is, that my squid is working, including the ssl bumping. I think the problem is in the PF rules, when I check the IP over the browser, my external IP is not the one as would be if the traffic would pass the squid. This means that the PF is not redirecting packets to squid.
 
Nothing works, iI can’t get packets with dst port 80/443 from tun to either re0 127.0.0.1 3128/9 or after the NAT has translated it, getting it from NAT external IP (still LAN, but not within VPN subnet) to re0 127.0.0.1 3128/9.

rdr rules just don’t do anything :(

Code:
#rdr pass on $vpn_if inet proto tcp from $vpn_net to any port 80 -> 127.0.0.1 port 3129
#rdr pass on $vpn_if inet proto tcp from $vpn_net to any port 443 -> 127.0.0.1 port 3129
#rdr pass inet proto tcp from $ext_ip to any port 80 -> 127.0.0.1 port 3128
#rdr pass inet proto tcp from $ext_ip to any port 443 -> 127.0.0.1 port 3129

# rdr on $vpn_if proto tcp from any to any port 80 -> 127.0.0.1 port 3128
# rdr on $vpn_if proto tcp from any to port 443 -> 127.0.0.1 port 3129
nat on ! $vpn_if from $vpn_net to any -> $ext_ip

#rdr pass on $ext_if inet proto tcp from 192.168.1.203 to ($ext_if:0) port 80 -> 127.0.0.1 port 3128
#rdr pass on $ext_if inet proto tcp from 192.168.1.203 to ($ext_if:0) port 443 -> 127.0.0.1 port 3129
#rdr pass inet proto tcp from $ext_ip to any port 80 -> 127.0.0.1 port 3128
#rdr pass inet proto tcp from $ext_ip to any port 443 -> 127.0.0.1 port 3129

iI have tryied all those nothing works... :(
 
Back
Top