abhinavsingh / proxy.py

💫 Ngrok FRP Alternative • ⚡ Fast • 🪶 Lightweight • 0️⃣ Dependency • 🔌 Pluggable • 😈 TLS interception • 🔒 DNS-over-HTTPS • 🔥 Poor Man's VPN • ⏪ Reverse & ⏩ Forward • 👮🏿 "Proxy Server" framework • 🌐 "Web Server" framework • ➵ ➶ ➷ ➠ "PubSub" framework • 👷 "Work" acceptor & executor framework
https://abhinavsingh.com/proxy-py-a-lightweight-single-file-http-proxy-server-in-python/
BSD 3-Clause "New" or "Revised" License
2.91k stars 568 forks source link

`FileNotFoundError` while using TLS Interception #1096

Open guiqiqi opened 2 years ago

guiqiqi commented 2 years ago

Describe the bug Got this error when using TLS interception:

handler.handle_readables:234 - Exception when receiving from client connection#24 with reason FileNotFoundError(2, 'No such file or directory')

To Reproduce With ca files generated by make ca-certificates and signed by make sign-https-certificates, I got three files:

then using nested python code to start proxy.py:

main(
    hostname=hostname, 
    ca_cert_file="/Users/doge/desktop/https-cert.pem", 
    ca_key_file="/Users/doge/desktop/https-key.pem", 
    ca_signing_key_file="/Users/doge/desktop/https-csr.pem",
    plugins=[ModifyLBXLocationPlugin], 
    local_executor=False,
)

I'm pretty sure these CA files are exists, but got the exception above and no connection could pass proxy. Using relative path not helps.

Version information

Additional context Thanks for your working :)!

abhinavsingh commented 2 years ago

Hi @guiqiqi , Looks like I missed this one somehow. This error shows up when proxy.py is unable to generate certificates. Can you double check if they exists under the ~/.proxy folder. Thank you

topnessman commented 2 years ago

I'm having the exact same issue. Tried absolute path, relative path, none of them worked and the certs exist 100% on the right path. Also tried manually specifying ca-cert-dir but no luck. Please help!

topnessman commented 2 years ago

Sample log:

pi@raspberrypi:~/Downloads/proxy.py $ proxy --hostname 0.0.0.0 --plugins proxy.plugin.CacheResponsesPlugin --ca-key-file /home/pi/Downloads/proxy.py/ca-key.pem --ca-cert-file /home/pi/Downloads/proxy.py/ca-cert.pem --ca-signing-key-file /home/pi/Downloads/proxy.py/ca-signing-key.pem --log-level DEBUG --ca-cert-dir ~/Downloads/
2022-03-12 10:51:23,634 - pid:29553 [I] plugins.load:85 - Loaded plugin proxy.http.proxy.HttpProxyPlugin
2022-03-12 10:51:23,634 - pid:29553 [I] plugins.load:85 - Loaded plugin proxy.plugin.CacheResponsesPlugin
2022-03-12 10:51:23,636 - pid:29553 [I] tcp.listen:82 - Listening on 0.0.0.0:8899
2022-03-12 10:51:23,644 - pid:29553 [D] pool._start:151 - Started acceptor#0 process 29556
2022-03-12 10:51:23,652 - pid:29553 [D] pool._start:151 - Started acceptor#1 process 29557
2022-03-12 10:51:23,661 - pid:29553 [D] pool._start:151 - Started acceptor#2 process 29558
2022-03-12 10:51:23,670 - pid:29553 [D] pool._start:151 - Started acceptor#3 process 29559
2022-03-12 10:51:23,672 - pid:29553 [I] pool.setup:108 - Started 4 acceptors in threaded mode
2022-03-12 10:51:38,785 - pid:29556 [D] acceptor.accept:116 - Accepting new work#5
2022-03-12 10:51:38,788 - pid:29556 [D] tcp_server.__init__:122 - Work#5 accepted from 192.168.0.153:57099
2022-03-12 10:51:38,793 - pid:29556 [D] selector_events.__init__:53 - Using selector: EpollSelector
2022-03-12 10:51:38,795 - pid:29556 [D] acceptor._work:254 - Started work#5.0.0 in thread#1974621280
2022-03-12 10:51:38,797 - pid:29556 [D] tcp_server.initialize:131 - Handling connection 192.168.0.153:57099
2022-03-12 10:51:38,800 - pid:29556 [D] handler.handle_readables:216 - Client is read ready, receiving...
2022-03-12 10:51:38,801 - pid:29556 [D] connection.recv:64 - received 221 bytes from client
2022-03-12 10:51:38,804 - pid:29556 [D] server.connect_upstream:569 - Connecting to upstream stackoverflow.com:443
2022-03-12 10:51:38,868 - pid:29556 [D] server.connect_upstream:604 - Connected to upstream stackoverflow.com:443
2022-03-12 10:51:38,875 - pid:29556 [W] handler.handle_readables:236 - Exception when receiving from client connection#5 with reason FileNotFoundError(2, 'No such file or directory')
2022-03-12 10:51:38,877 - pid:29556 [D] handler._flush:383 - Flushing pending data
2022-03-12 10:51:38,877 - pid:29556 [D] handler._flush:390 - Waiting for client read ready
2022-03-12 10:51:38,878 - pid:29556 [D] connection.flush:97 - flushed 39 bytes to client
2022-03-12 10:51:38,879 - pid:29556 [I] server.access_log:384 - 192.168.0.153:57099 - CONNECT stackoverflow.com:443 - 0 bytes - 75.92ms
2022-03-12 10:51:38,879 - pid:29556 [D] disk.close:67 - Cached response at /home/pi/.proxy/cache/responses/stackoverflow.com-dbbd970c86594e7bb9c1a06d57af798e.txt
2022-03-12 10:51:38,880 - pid:29556 [D] server.on_client_connection_close:377 - Closed server connection, has buffer False
2022-03-12 10:51:38,880 - pid:29556 [D] handler.shutdown:89 - Closing client connection 192.168.0.153:57099 has buffer False
2022-03-12 10:51:38,881 - pid:29556 [D] handler.shutdown:97 - Client connection shutdown successful
2022-03-12 10:51:38,881 - pid:29556 [D] handler.shutdown:111 - Client connection closed
abhinavsingh commented 2 years ago

2022-03-12 10:51:38,875 - pid:29556 [W] handler.handle_readables:236 - Exception when receiving from client connection#5 with reason FileNotFoundError(2, 'No such file or directory')

This error message can get printed when: 1) Server is unable to generate intermediate certificates for your client, this can happen when underlying openssl command fails 2) A common reason for openssl command to fail is, CA certificates were re-generated but there are older intermediate certificates (generated using older CA certs) under ~/.proxy/certificates folder.

In general, we have integration tests for interception on Ubuntu/Mac/Windows. Hence, I feel this is more of a local config issue, which proxy.py probably must handle/alert about in future.

Irrespective, I'll retry at my end and update if I see it broken. At your end, please try to delete the old generated certificates and try again. Thank you for reporting this.

topnessman commented 2 years ago

I somehow worked around this issue by explicitly passing in --ca-file /etc/ssl/certs/ca-certificates.crt. Seems like the default path doesn't exist and causes an error. I'm running the proxy.py on raspberry pi os (buster) btw.

abhinavsingh commented 2 years ago

@topnessman Thanks for letting us know about this. Ideally, --ca-file defaults to .venv/lib/python3.10/site-packages/certifi/cacert.pem. This should already be under your virtual environment. Can you double check on this file. May be for some reason this file is missing on RPi?

guiqiqi commented 2 years ago

@abhinavsingh Sorry for late replying, I tried push my CA files inside default path and with given parameter with it, but problem still persist.

Thanks for your developing again.

bugfest commented 2 years ago

Hi @abhinavsingh, @guiqiqi

I was facing the same issues until realized from @abhinavsingh's comment that certifi wasn't installed in my virtualenv (I'm running Python 3.9.12). Installed with:

$ mkvirtualenv proxy.py --python python3.9

$ pip install proxy.py --pre --upgrade
Collecting proxy.py
  Using cached proxy.py-2.4.1-py3-none-any.whl (204 kB)
Installing collected packages: proxy.py
Successfully installed proxy.py-2.4.1

$ pip freeze
proxy.py==2.4.1

After installing certifi I got it working without explicitly setting --ca-file parameter.

$ pip install certifi
changbowen commented 1 year ago

Same issue here: When I do curl -v --cacert ca-cert.pem -x 127.0.0.1:8899 https://httpbin.org/get, first I see Proxy CONNECT aborted. I did pip install certifi in the container, the error changed to OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to httpbin.org:443. In the container log there are exceptions that says FileNotFoundError: [Errno 2] No such file or directory: 'openssl'. Then I find openssl doesn't seem to be installed at all in the container: sh: openssl: not found. According to the doc it looks like the abhinavsingh/proxy.py:latest should come with openssl... And I don't know how to install it without apt in the container... Did I miss something?

dliebner commented 5 months ago

I'm getting this FileNotFoundError while following these directions: https://github.com/abhinavsingh/proxy.py#tls-interception-with-docker