Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about transparent SSL/TLS proxying without decryption #35

Open
djosip opened this issue Nov 1, 2021 · 3 comments
Open

Question about transparent SSL/TLS proxying without decryption #35

djosip opened this issue Nov 1, 2021 · 3 comments

Comments

@djosip
Copy link

djosip commented Nov 1, 2021

Hello!

First, thank you for the effort and time invested in SSLproxy project.

I went through the available documentation and did some testing but I am unable to conclude if it's possible to achieve transparent SSL/TLS proxying with SSLproxy without content decryption (and without forging of SSL certificates).
I have spent some time playing with the options such as -o Divert=no and -o Passthrough=yes as I assumed that if the diverting is turned off and passing through is turned on, the traffic would be "simply" transparently forwarded to the target server running https service.

I have setup something like this using SSLproxy 0.9 on the Centos Linux 7.9 x86_64 with kernel 3.10.0-1160.42.2.el7.x86_64:

,----------,     ,----------,     ,----------,
|          |     |          |     |          |
|  Client  | --> |  Proxy   | --> |  Server  |
|          |     |          |     |          |
'----------'     '----------'     '----------'
 172.16.1.1       192.168.1.1       8.8.8.8

This is the command I used (as root) on the Proxy server:
sslproxy -D4 -c /etc/sslproxy/certs/ca.crt -k /etc/sslproxy/certs/ca.key -C /etc/pki/tls/cert.pem -o Divert=no -o Passthrough=yes -o VerifyPeer=no -P https 192.168.1.1 443

For testing purposes on the Client server I used curl and the /etc/hosts file had a line 192.168.1.1 dns.google
The curl command looked like: curl -v https://dns.google:443
The Proxy server is able to properly resolve domain names and to connect to https services on the Internet.
Note that for the purpose of explaining the issue I used different IP addresses and URL but it doesn't really matter.
I didn't use any specific iptables rules as I wanted the SSLproxy to listen on 192.168.1.1:443

Upon execution of the curl command on the Client server, the above setup would result with SSLproxy momentarily opening all remaining ~1024 file descriptors and the client would get the error stating that the connection was reset.

What am I missing?
My goal was to pass the https traffic from Client to the Server via SSLproxy and use its filtering feature without decrypting the actual content (I assume that SNI makes this possible).

Kind regards!

@sonertari
Copy link
Owner

Please see the filtering rules in SSLproxy 0.9.0 (and structured filtering rules on the develop branch to be released soon with v0.9.1). Note that the Passthrough mode is for fail-open configuration for SSL/TLS errors, that's all (if there is no SSL/TLS error, it does not pass the connection through).

So, first, I suggest you use a config file, instead of command line. And in the config file add a rule like the following:

Pass from 172.16.1.1 to *

which should engage the Passthrough mode for all connections originating from 172.16.1.1 (fail-open or not).

I'll see if I need to clarify the documentation for the Passthrough mode.

@djosip
Copy link
Author

djosip commented Nov 3, 2021

Initially I used config file but I thought it would be easier to test it if I provide command line arguments.
I tested it with different Pass filters including Pass * and Pass from ip 172.16.1.1 to *

No matter what I try, I get almost thousand lines like this:

SNI peek: [dns.google] [complete], fd=1008
Connecting to [192.168.1.1]:443

followed by a single line:

Out of file descriptors

and after that, almost thousand lines like this:

Closing on ssl error without filter match: 192.168.1.1:50002, 192.168.1.1:443, -, -, dns.google, -
Client-side BEV_EVENT_ERROR
Error from bufferevent: 104:Connection reset by peer 0:0:-:0:-:0:-
Closing on ssl error without filter match: 172.16.1.1:44742, 192.168.1.1:443, -, -, dns.google, -

Config file looks like this:

PidFile /var/run/sslproxy.pid
Daemon no
Debug yes
DebugLevel 4
ConnectLog /var/log/sslproxy/connect.log
LogStats yes
StatsPeriod 1
ConnIdleTimeout 120
ExpiredConnCheckPeriod 10
UserDBPath users.db

ProxySpec {
        Proto https
        Addr 192.168.1.1
        Port 443
        Divert no
        Passthrough yes
        VerifyPeer no
        CACert /etc/pki/tls/certs/localhostca.crt
        CAKey /etc/pki/tls/private/localhost.key
        CAChain /etc/pki/tls/cert.pem
        #Pass from ip 172.16.1.1 to sni dns.google port 443
        Pass from ip 172.16.1.1 to *
}

And this is the command line I am using:
sslproxy -f /etc/sslproxy/sslproxy.conf -D4 -c /etc/sslproxy/certs/ca.crt -k /etc/sslproxy/certs/ca.key -C /etc/pki/tls/cert.pem

I decided to post the question here because I wasn't sure whether I am doing something wrong or SSLproxy doesn't support passthrough without certificate forging.

On the client side I get this:

# curl -k -v https://dns.google:443
* Expire in 0 ms for 6 (transfer 0x55a03f1a5fb0)
* Expire in 1 ms for 1 (transfer 0x55a03f1a5fb0)
* Expire in 1 ms for 1 (transfer 0x55a03f1a5fb0)
* Expire in 2 ms for 1 (transfer 0x55a03f1a5fb0)
*   Trying 192.168.1.1...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x55a03f1a5fb0)
* Connected to dns.google (192.168.1.1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to dns.google:443
* Closing connection 0
* curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to dns.google:443

@sonertari
Copy link
Owner

I don't see any problem with your sslproxy configuration (at least as far as I can see). But if you get the Out of file descriptors error, it reminds me of a possible network configuration issue. I saw such errors if there is a loop, and sslproxy was receiving the traffic passing through it indirectly redirected to itself. Can you post how you redirect traffic to sslproxy?

Also, can you test with a target address/port proxyspec like https 192.168.1.1 443 8.8.8.8 443, just to see if it works? I wonder if target spec can detect a loop (8.8.8.8:443 is the server in your first post).

And also, perhaps you can first test with plain HTTP, instead of HTTPS, to rule out ssl cert issues.

(I have tried Passthrough yes and Divert no options based on your report, and I don't use them often, but they seem to not cause any issues in my test setup.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants