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

[TLSInterception] Renew generated certificates on expiration #731

Open abhinavsingh opened 2 years ago

abhinavsingh commented 2 years ago

Describe the bug On long running instances, generate certificates for upstream will expire after sometime. Core must delete/renew such certificates.

To Reproduce See https://github.com/abhinavsingh/proxy.py/issues/371#issuecomment-882101159 for background

Expected behavior Proxy must delete/renew certificate for interception.

wizzfizz94 commented 2 years ago

Hello. I was having the same issue in #371 where i was getting a KEY_VALUES_MISMATCH error. This was because i deleted my first self signed key and cert pair and made new ones. I followed the solution in #371 (comment) but now I'm getting a TLSV1_ALERT_UNKNOWN_CA error. I think maybe firefox has cached the old certificate and is rejecting the new one as a result. I want to clear the old cert from the cache but im no sure where it resides on the fs? Below is my proxy init code and my error log. Thanks.

    # set up proxy to redirect all requests from the browser through the client
    with proxy.start(
            ['--host', '127.0.0.1',
             '--port', str(proxy_port),
             '--ca-cert-file', '/home/kiosk/Kiosk/kiosk-ca.pem',
             '--ca-key-file', '/home/kiosk/Kiosk/kiosk-ca.key',
             '--ca-signing-key-file', '/home/kiosk/Kiosk/kiosk-signing.key'],
            plugins=
            [b'header_modifier.BasicAuthorizationPlugin',
             header_modifier.BasicAuthorizationPlugin]):
        selenium_proxy.proxyType = ProxyType.MANUAL
        selenium_proxy.httpProxy = '127.0.0.1:' + str(proxy_port)
        selenium_proxy.sslProxy = '127.0.0.1:' + str(proxy_port)
        print('Proxy address: ' + selenium_proxy.httpProxy)
Dec 21 07:43:06 raspberrypi python3[12587]: 2021-12-21 07:43:06,634 - pid:12592 [E] intercept:540 - OSError when wrapping client
Dec 21 07:43:06 raspberrypi python3[12587]: Traceback (most recent call last):
Dec 21 07:43:06 raspberrypi python3[12587]:   File "/usr/local/lib/python3.7/dist-packages/proxy/http/proxy/server.py", line 529, in intercept
Dec 21 07:43:06 raspberrypi python3[12587]:     self.wrap_client()
Dec 21 07:43:06 raspberrypi python3[12587]:   File "/usr/local/lib/python3.7/dist-packages/proxy/http/proxy/server.py", line 559, in wrap_client
Dec 21 07:43:06 raspberrypi python3[12587]:     self.client.wrap(self.flags.ca_signing_key_file, generated_cert)
Dec 21 07:43:06 raspberrypi python3[12587]:   File "/usr/local/lib/python3.7/dist-packages/proxy/core/connection/client.py", line 43, in wrap
Dec 21 07:43:06 raspberrypi python3[12587]:     ssl_version=ssl.PROTOCOL_TLS)
Dec 21 07:43:06 raspberrypi python3[12587]:   File "/usr/lib/python3.7/ssl.py", line 1222, in wrap_socket
Dec 21 07:43:06 raspberrypi python3[12587]:     suppress_ragged_eofs=suppress_ragged_eofs
Dec 21 07:43:06 raspberrypi python3[12587]:   File "/usr/lib/python3.7/ssl.py", line 412, in wrap_socket
Dec 21 07:43:06 raspberrypi python3[12587]:     session=session
Dec 21 07:43:06 raspberrypi python3[12587]:   File "/usr/lib/python3.7/ssl.py", line 853, in _create
Dec 21 07:43:06 raspberrypi python3[12587]:     self.do_handshake()
Dec 21 07:43:06 raspberrypi python3[12587]:   File "/usr/lib/python3.7/ssl.py", line 1117, in do_handshake
Dec 21 07:43:06 raspberrypi python3[12587]:     self._sslobj.do_handshake()
Dec 21 07:43:06 raspberrypi python3[12587]: ssl.SSLError: [SSL: TLSV1_ALERT_UNKNOWN_CA] tlsv1 alert unknown ca (_ssl.c:1056)
abhinavsingh commented 2 years ago

All data is stored under --ca-cert-dir flag. When missing, following value is used as default:

https://github.com/abhinavsingh/proxy.py/blob/develop/proxy/http/proxy/server.py#L86-L92

flags.add_argument(
    '--ca-cert-dir',
    type=str,
    default=DEFAULT_CA_CERT_DIR,
    help='Default: ~/.proxy/certificates. Directory to store dynamically generated certificates. '
    'Also see --ca-key-file, --ca-cert-file and --ca-signing-key-file',
)
wizzfizz94 commented 2 years ago

@abhinavsingh as you can see in the init script above I'm not specifying --ca-cert-dir but I'm specifying --ca-cert-file so i believe proxy should be able to locate the cert file? I tried the following commands to get it to work but i get the same error as in my last comment.

sudo su -
cd /home/kiosk/Kiosk

# wipe proxy config
rm -rf /home/kiosk/.proxy/

# remove old keys and certs
rm kiosk-*

# Generate new cert & private keys for self signed cert
openssl genrsa -out kiosk-ca.key 2048
openssl req -x509 -new -nodes -key kiosk-ca.key -sha256 -days 1825 -out kiosk-ca.pem
openssl genrsa -out kiosk-signing.key 2048

# reboot to restart the service running the proxy
reboot

I also tried copying the certs and keys to the default cert directory thinking that was the problem using the commands below and also get the same error.

sudo su -
cp -p /home/kiosk/Kiosk/kiosk-* /home/kiosk/.proxy/certificates/
reboot
abhinavsingh commented 2 years ago

TLSV1_ALERT_UNKNOWN_CA is caused when client is unable to verify the authenticity of the certificate. Most likely, you also trusted old ca-cert.pem on your system, but now it has expired. You must remove and re-trust the ca-cert.pem and make sure it's valid and hasn't expired itself :)

wizzfizz94 commented 8 months ago

Thanks @abhinavsingh but how do I do that? I can't find a file called ca-cert.pem anywhere on my system.

find / -type f -name "ca-cert.pem"
find: ‘/proc/605/task/605/net’: Invalid argument
find: ‘/proc/605/net’: Invalid argument
find: ‘/run/user/1001/gvfs’: Permission denied

I'm trying the following to added my certificate to the trust store and deal with any caching issues but still get the TLSV1_ALERT_UNKNOWN_CA error

rm -rf /home/kiosk/.proxy

pip3 uninstall proxy.py

cp kiosk-ca.pem /usr/local/share/ca-certificates/kiosk-ca.crt

update-ca-certificates
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.

# installs proxy.py again
pip3 install -r requirements.txt --system

# restart and follow service log
systemctl restart kiosk.service && journalctl -fu kiosk.service