sniproxy icon indicating copy to clipboard operation
sniproxy copied to clipboard

Allow running sniproxy as a gateway

Open grzech0 opened this issue 2 years ago • 9 comments

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

grzech0 avatar Oct 10 '23 09:10 grzech0

Yeah but that's natural for a SNI proxy, the only place where it can learn about the target endpoint is the SNI field.

ameshkov avatar Oct 10 '23 09:10 ameshkov

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.

grzech0 avatar Oct 10 '23 10:10 grzech0

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.

ameshkov avatar Oct 10 '23 12:10 ameshkov

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 ;)

grzech0 avatar Oct 10 '23 13:10 grzech0

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 avatar Oct 16 '23 07:10 grzech0

@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.

ameshkov avatar Oct 16 '23 07:10 ameshkov

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.

grzech0 avatar Oct 16 '23 07:10 grzech0

I'll look into the gateway approach when I have free time, it is indeed may be very useful.

ameshkov avatar Oct 16 '23 07:10 ameshkov

Thank you in advance

grzech0 avatar Oct 16 '23 08:10 grzech0