alexdlaird / pyngrok

A Python wrapper for ngrok
https://pyngrok.readthedocs.io
MIT License
421 stars 59 forks source link

SSL problem when connecting to ngrok #93

Closed Xam-Mlr closed 2 years ago

Xam-Mlr commented 2 years ago

Describe the Bug Hi, i would like to create a bridge for my socket so i copy paste the code on your website about socket and i get this error:

Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 1342, in do_open h.request(req.get_method(), req.selector, req.data, headers, File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 1255, in request self._send_request(method, url, body, headers, encode_chunked) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 1301, in _send_request self.endheaders(body, encode_chunked=encode_chunked) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 1250, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 1010, in _send_output self.send(msg) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 950, in send self.connect() File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 1424, in connect self.sock = self._context.wrap_socket(self.sock, File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 500, in wrap_socket return self.sslsocket_class._create( File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 1040, in _create self.do_handshake() File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 1309, in do_handshake self._sslobj.do_handshake() ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/Users/XXX/Library/Python/3.9/lib/python/site-packages/pyngrok/installer.py", line 94, in install_ngrok download_path = _download_file(url, kwargs) File "/Users/XXX/Library/Python/3.9/lib/python/site-packages/pyngrok/installer.py", line 215, in _download_file response = urlopen(url, kwargs) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 214, in urlopen return opener.open(url, data, timeout) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 517, in open response = self._open(req, data) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 534, in _open result = self._call_chain(self.handle_open, protocol, protocol + File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 494, in _call_chain result = func(*args) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 1385, in https_open return self.do_open(http.client.HTTPSConnection, req, File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 1345, in do_open raise URLError(err) urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)>

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/Users/XXX/Documents/MacBookPro/python/net_project/hack/test2.py", line 18, in public_url = ngrok.connect(port, "tcp", remote_addr="{}:{}".format(host, port)).public_url File "/Users/XXX/Library/Python/3.9/lib/python/site-packages/pyngrok/ngrok.py", line 251, in connect api_url = get_ngrok_process(pyngrok_config).api_url File "/Users/XXX/Library/Python/3.9/lib/python/site-packages/pyngrok/ngrok.py", line 160, in get_ngrok_process install_ngrok(pyngrok_config) File "/Users/XXX/Library/Python/3.9/lib/python/site-packages/pyngrok/ngrok.py", line 98, in install_ngrok installer.install_ngrok(pyngrok_config.ngrok_path) File "/Users/XXX/Library/Python/3.9/lib/python/site-packages/pyngrok/installer.py", line 98, in install_ngrok raise PyngrokNgrokInstallError("An error occurred while downloading ngrok from {}: {}".format(url, e)) pyngrok.exception.PyngrokNgrokInstallError: An error occurred while downloading ngrok from https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-darwin-amd64.zip: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)>

Steps to Reproduce `

import os
import socket

from pyngrok import ngrok

host = os.environ.get("HOST")
port = int(os.environ.get("PORT"))

# Create a TCP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Bind a local socket to the port
server_address = ("", port)
sock.bind(server_address)
sock.listen(1)

# Open a ngrok tunnel to the socket
public_url = ngrok.connect(port, "tcp", remote_addr="{}:{}".format(host, port)).public_url
print("ngrok tunnel \"{}\" -> \"tcp://127.0.0.1:{}\"".format(public_url, port))

while True:
    connection = None
    try:
        # Wait for a connection
        print("\nWaiting for a connection ...")
        connection, client_address = sock.accept()

        print("... connection established from {}".format(client_address))

        # Receive the message, send a response
        while True:
            data = connection.recv(1024)
            if data:
                print("Received: {}".format(data.decode("utf-8")))

                message = "pong"
                print("Sending: {}".format(message))
                connection.sendall(message.encode("utf-8"))
            else:
                break
    except KeyboardInterrupt:
        print(" Shutting down server.")

        if connection:
            connection.close()
        break

sock.close()

Environment

rikuru-to865 commented 2 years ago

https://github.com/alexdlaird/pyngrok/blob/main/pyngrok/installer.py You should change ` import zipfile from http import HTTPStatus from urllib.request import urlopen

import yaml to import zipfile from http import HTTPStatus from urllib.request import urlopen import ssl ssl._create_default_https_context = ssl._create_unverified_context

import yaml `

maybe it works.A I sent a pull request but it wasn't merged.

alexdlaird commented 2 years ago

This can present itself in Python when you're behind certain proxies or VPNs. Allowing for unverified SSL contexts within a library like pyngrok would introduce a security vulnerability, so we would not want to merge that. However, you can easily workaround this, because install_ngrok() takes kwargs that are passed down to urlopen, as documented here.

There are a myriad of ways to resolve this, since it's not specific to any one Python package, but if bypassing SSL verification is an acceptable security risk to your application, here's one example for doing this in pyngrok:

import ssl
from pyngrok import ngrok, conf, installer

pyngrok_config = conf.get_default()

if not os.path.exists(pyngrok_config.ngrok_path):
    myssl = ssl.create_default_context();
    myssl.check_hostname=False
    myssl.verify_mode=ssl.CERT_NONE
    installer.install_ngrok(pyngrok_config.ngrok_path, context=context)

ngrok.connect()

For visibility, tagging: