duosecurity / duo_openvpn_as Goto Github PK
View Code? Open in Web Editor NEWLicense: Other
License: Other
I want to automate launching OpenVPN using Docker. In my Dockerfile, I'm now pulling in the python file, and then I have to manually replace the credentials.
I want to build the Docker image e.g. on a CI/CD pipeline, where I want to have my duo credentials stored. Passing them in now requires me to do some dark magic, like e.g.
RUN sed -i "s/<DUO[[:space:]]INTEGRATION[[:space:]]KEY[[:space:]]HERE>/"${DUO_INTEGRATION_KEY}"/g" duosecurity/duo_openvpn_as.py && \
sed -i "s/<DUO[[:space:]]INTEGRATION[[:space:]]SECRET[[:space:]]KEY[[:space:]]HERE>/"${DUO_INTEGRATION_SECRET}"" duosecurity/duo_openvpn_as.py && \
sed -i "s/<DUO[[:space:]]API[[:space:]]HOSTNAME[[:space:]]HERE>/"${DUO_API_HOSTNAME}"" duosecurity/duo_openvpn_as.py
to replace the credentials. This is brittle and not really nice. Also if you change the strings, my setup will break. Also, sed
has encoding and escaping issues.
Allow duo_openvpn_as.py
to read the credentials from environment variables. I.e. instead of
IKEY = '<DUO INTEGRATION KEY HERE>'
we would have sth. like
IKEY = os.environ.get('DUO_INTEGRATION_KEY')
by default.
When connecting to the auth api via a forwarding proxy, TLS cert hostname validation fails.
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)
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'
We are using Duo with OpenVPN Access Server and have found that the source IP (access device in the log) is not always recorded correctly.
Sometimes the "access device" IP shows up correctly, but other times it shows up as 127.0.0.1.
Hello
I have been using this script for several years but i updated from AS 2.0.17 to 2.0.25 today and it stopped working. The internet access from our openvpn server is via a squid v3.3. proxy. The connection to the duo server fails with an InvalidCertificateException "returned an invalid certificate (hostname mismatch)". I wonder if it is to do with a change in the bundled python version. It looks like it is validating the proxy hostname against the duosecurity certificate
Thanks
I am using the latest duo_openvpn_as.py script with OpenVPN AS 2.11.0 and find that script needs to be updated with new function call syntax. 2.11.0 is running on python3 and python3 replaced httplib with http.client. Function names remain the same, but many variables are being converted from byte-type to strings and vice versa. Main thing I'm having to look at it hash digest generation and ca-certs parsing. Attempts to auto-fix duo_openvpn_as.py by 2to3(-3 and -6) fail.
When you log in, the prompt text that appears seems kind of confusing to me:
duo_openvpn_as/duo_openvpn_as.py
Line 606 in 4f8f5a6
It's not immediately apparent to me that I could/should type "push" in the box. The prompt that my org uses is "Enter 'push', 'sms', 'phone', or a Duo app passcode".
I think moving the prompt variable to the top of the file along with the rest of the config vars would make it clearer that admins can edit it. Even if we rephrase the prompt to mention all those commands, maybe some orgs have "sms" disabled and would want to remove that part of it. Or maybe admins would want to include a link to internal docs or a helpdesk link.
Users can manually edit line 606 of the script.
I followed the guide to connect OpenVPN AS with Duo.
When trying to login via web ui I get:Unknown error communicating with Duo service
The logs show:
2018-03-06 02:53:11+0000 [-] WEB OUT: "2018-03-06 02:53:11+0000 [UDSProxyQueryProtocol,client] Web login authentication failed: {'status': 1, 'client_reason': 'Unknown error communicating with Duo service', 'reason': 'Exception caught in pre-auth: Received 401 Invalid signature in request credentials', 'user': 'felixvpn', 'proplist': {'prop_deny': 'false', 'prop_autogenerate': 'true'}}"
2018-03-06 02:53:11+0000 [-] WEB OUT: '2018-03-06 02:53:11+0000 [UDSProxyQueryProtocol,client] Web login failed (twisted.cred.error.UnauthorizedLogin)'
2018-03-06 02:53:11+0000 [-] WEB OUT: "2018-03-06 02:53:11+0000 [UDSProxyQueryProtocol,client] CPage WebException in CLogin/auth: 'Unknown error communicating with Duo service' (None)"
I also tried to reset the secret key but no success.
OpenVPN AS version: 2.5
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.