Allow running sniproxy as a gateway
root@dev4-20-tunapi:/usr/local/bin# ./sniproxy --dns-redirect-ipv4-to=127.0.0.1 --tls-port=3133 --http-port=3134 --forward-proxy=http://192.168.118.21:3128
2023/10/10 11:04:19 [info] cmd: run sniproxy with the following configuration:
{
"DNSListenAddress": "0.0.0.0",
"DNSPort": 53,
"DNSUpstream": "8.8.8.8",
"DNSRedirectIPV4To": "127.0.0.1",
"DNSRedirectIPV6To": "",
"DNSRedirectRules": [
"*"
],
"DNSDropRules": null,
"HTTPListenAddress": "0.0.0.0",
"HTTPPort": 3134,
"TLSListenAddress": "0.0.0.0",
"TLSPort": 3133,
"BandwidthRate": 0,
"BandwidthRules": {},
"ForwardProxy": "http://192.168.118.21:3128",
"ForwardRules": null,
"BlockRules": null,
"DropRules": null,
"Verbose": false,
"LogOutput": ""
}
grk@dev4-20-tunapi:~$ curl -Iv https://193.109.212.15 -k
- Trying 193.109.212.15:443...
- Connected to 193.109.212.15 (193.109.212.15) port 443 (#0)
- ALPN, offering h2
- ALPN, offering http/1.1
- successfully set certificate verify locations:
- CAfile: /etc/ssl/certs/ca-certificates.crt
- CApath: /etc/ssl/certs
- TLSv1.3 (OUT), TLS handshake, Client hello (1):
- OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to 193.109.212.15:443
- Closing connection 0 curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to 193.109.212.15:443
in sniproxy terminal output ... 2023/10/10 11:07:41 [info] sniproxy: [4] start tunneling to :443 2023/10/10 11:08:05 [info] sniproxy: [5] start tunneling to mail.google.com:443 ...
in upstream squid access.log ... 1696928862.134 1 192.168.118.11 NONE/400 3861 CONNECT :443 - HIER_NONE/- text/html 1696928899.311 240197 192.168.118.11 TCP_TUNNEL/200 2748 CONNECT mail.google.com:443 - HIER_DIRECT/216.58.215.69 - ...
looks like fallback to TCP destination IP doesn't work properly, when in https connection there is no SNI field when SNI field is present (https://mail.google.com) sniproxy works properly
Yeah but that's natural for a SNI proxy, the only place where it can learn about the target endpoint is the SNI field.
I know it's rather corner case. URL like https://193.109.212.15/ is stupid but legit. I met such case in the wild. I hope you decide to implement such feature - fallback to TCP dest IP if no SNI field is found. It could make sniproxy to cover almost 100% cases met in https traffic.
The problem is that there's no other signal in a TLS connection apart from SNI that can be used to discover the target address.
hm... even from IP header in raw TCP? Maybe from client handshake before TLS connection. I'm sure there is some way, but.... this is your code and you're most oriented what can be done and what can't. I don't want be too smart here because I'm not ;)
I think I found "the way" in other project. I hope it could be an inspiration for sniproxy to resolve this issue. https://github.com/cybozu-go/transocks/blob/master/original_dst_linux.go Looks like this code works in linux only, regarding to NAT redirect.
@grzech0 this is a case when you redirect connections locally using iptables. Alternative way would be to parse manually /proc/net/tcp for connections that were redirected using iptables -t nat redirect.
The thing is that this is a bit different from how sniproxy is supposed to be used. For instance, you won't be able to do this trick on a mobile device (originally, I made it for debugging mobile apps).
A more sophisticated way would be to allow using sniproxy as a gateway (basically, replacing the router), this approach is much more complicated, but on the other hand it does not limit it to a single device and does not require root access on the devices which traffic you want to inspect.
You're absolutely right. I fact, I try to use sniproxy on linux gateway for containers. My goal is to transparently redirect all https/http traffic to upstream squid, to have ACLs working without getting into squids bump/splice.
Squid is configured as explicit proxy and is placed in same network segment but not on the default route path.
I'll look into the gateway approach when I have free time, it is indeed may be very useful.
Thank you in advance