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

TLS cert Hostname validation fails when connecting over a forwarding proxy #26

Open
amarinderca opened this issue Jun 17, 2024 · 3 comments

Comments

@amarinderca
Copy link

amarinderca commented Jun 17, 2024

Description

When connecting to the auth api via a forwarding proxy, TLS cert hostname validation fails.

Expected Behavior

  • TLS cert hostname validation works when connecting to the duo auth api servers over a simple forwarding proxy

Actual Behavior

  • TLS cert hostname validation does not work over proxy

Steps to Reproduce

  1. Setup a http simple forwarding proxy (no ssl splicing) proxy like squid
  2. Add that proxy to the script as shown in the readme
  3. Setup openvpn as usual with duo 2fa
  4. Try logging in to the vpn
  5. Connection to the duo auth api fails

Logs

2024-06-06T23:31:52.000000+00:00 <user.info> openvpn2test.x.com openvpnas[50848]: Duo OpenVPN_AS: pre-authentication for amarinder

2024-06-06T23:31:52.000000+00:00 <user.info> openvpn2test.x.com openvpnas[50848]: Duo OpenVPN_AS: Traceback (most recent call last): File "<string>", line 719, in post_auth_cr File "<string>", line 596, in preauth File "<string>", line 363, in json_api_call File "<string>", line 582, in api_call File "<string>", line 350, in api_call File "/usr/lib64/python3.9/http/client.py", line 1285, in request self._send_request(method, url, body, headers, encode_chunked) File "/usr/lib64/python3.9/http/client.py", line 1331, in _send_request self.endheaders(body, encode_chunked=encode_chunked) File "/usr/lib64/python3.9/http/client.py", line 1280, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) File "/usr/lib64/python3.9/http/client.py", line 1040, in _send_output self.send(msg) File "/usr/lib64/python3.9/http/client.py", line 980, in send self.connect() File "<string>", line 523, in connect File "/usr/lib64/python3.9/ssl.py", line 501, in wrap_socket return self.sslsocket_class._create( File "/usr/lib64/python3.9/ssl.py", line 1074, in _create self.do_handshake() File "/usr/lib64/python3.9/ssl.py", line 1343, in do_handshake self._sslobj.do_handshake() ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch, certificate is not valid for 'egress1.hc.x.com'. (_ssl.c:1129)

2024-06-06T23:31:52.000000+00:00 <user.info> openvpn2test.x.com openvpnas[50848]: Duo OpenVPN_AS: Traceback (most recent call last): File "<string>", line 719, in post_auth_cr File "<string>", line 596, in preauth File "<string>", line 363, in json_api_call File "<string>", line 582, in api_call File "<string>", line 350, in api_call File "/usr/lib64/python3.9/http/client.py", line 1285, in request self._send_request(method, url, body, headers, encode_chunked) File "/usr/lib64/python3.9/http/client.py", line 1331, in _send_request self.endheaders(body, encode_chunked=encode_chunked) File "/usr/lib64/python3.9/http/client.py", line 1280, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) File "/usr/lib64/python3.9/http/client.py", line 1040, in _send_output self.send(msg) File "/usr/lib64/python3.9/http/client.py", line 980, in send self.connect() File "<string>", line 523, in connect File "/usr/lib64/python3.9/ssl.py", line 501, in wrap_socket return self.sslsocket_class._create( File "/usr/lib64/python3.9/ssl.py", line 1074, in _create self.do_handshake() File "/usr/lib64/python3.9/ssl.py", line 1343, in do_handshake self._sslobj.do_handshake() ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch, certificate is not valid for 'egress1.hc.x.com'. (_ssl.c:1129) 

Workarounds

  • Diff with a fix
  • We need to not use self.host when calling self.sock = context.wrap_socket(self.sock, server_hostname=self.host) if connecting VIA a forwarding proxy, instead we need to use self._tunnel_host here.
--- duo_openvpn_as.py   2024-06-06 21:10:53.706861401 -0700
+++ duo_openvpn_as(1).py        2024-06-12 12:50:50.993250093 -0700
@@ -505,30 +505,31 @@

  def connect(self):
    "Connect to a host on a given (SSL) port."
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((self.host, self.port))
    self.sock = sock
-    if self._tunnel_host:
+    if getattr(self, '_tunnel_host', None):
      self._tunnel()

    context = ssl.create_default_context()
    context.load_verify_locations(cafile=self.ca_certs)

    if self.cert_file:
        context.load_cert_chain(self.cert_file, keyfile=self.key_file)

    ssl_version_blacklist = ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3
    context.options = self.cert_reqs | ssl_version_blacklist

-    self.sock = context.wrap_socket(self.sock, server_hostname=self.host)
+    api_host = self._tunnel_host or self.host
+    hostname = api_host.split(':', 0)[0]
+
+    self.sock = context.wrap_socket(self.sock, server_hostname=hostname)

    if self.cert_reqs & ssl.CERT_REQUIRED:
      cert = self.sock.getpeercert()
-      cert_validation_host = self._tunnel_host or self.host
-      hostname = cert_validation_host.split(':', 0)[0]
      if not self._ValidateCertificateHostname(cert, hostname):
        raise InvalidCertificateException(hostname, cert, 'hostname mismatch')

### duo_openvpn_as.py integration code:

__version__ = '2.6'
@amarinderca amarinderca changed the title TLS cert Hostname validation fails when over a forwarding proxy TLS cert Hostname validation fails when connecting over a forwarding proxy Jun 17, 2024
@DuoKristina
Copy link
Contributor

@amarinderca Did you mean to create a pull request with the proposed change?

amarinderca added a commit to amarinderca/duo_openvpn_as that referenced this issue Jun 17, 2024
@amarinderca
Copy link
Author

@DuoKristina I hope you had a good weekend. Yes, that thought did occur to me a bit too late (after I submitted this ticket). 😅 Here is the PR: #27

Thanks!

@DuoKristina
Copy link
Contributor

Thank you!

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