When analyzing OpenVPN connections, we often need the actual certificate chain rather than just verification results. While openssl s_client
works perfectly for TCP-based TLS, OpenVPN primarily uses UDP with a custom TLS implementation. This requires a different approach to certificate extraction.
The most reliable method is to use OpenVPN's built-in debugging capabilities. Here's how to configure your client:
# Save this as cert-dump.ovpn
client
dev tun
proto udp
remote your.vpn.server 1194
resolv-retry infinite
nobind
persist-key
persist-tun
verb 4
tls-export-cert /path/to/save/certs
For cases where you can't modify client config, use packet capture with certificate extraction:
# Capture OpenVPN handshake
sudo tcpdump -i any -w openvpn.pcap 'udp port 1194'
# Extract certificates using Wireshark CLI
tshark -r openvpn.pcap -Y "ssl.handshake.certificate" -Tfields -e x509sat.uTF8String > certs.txt
For automation, here's a Python script using Scapy:
from scapy.all import *
from scapy_ssl_tls.ssl_tls import *
def extract_openvpn_certs(pcap_file):
packets = rdpcap(pcap_file)
certs = []
for pkt in packets:
if TLSHandshake in pkt:
for h in pkt[TLSHandshake]:
if isinstance(h, TLSCertificate):
certs.extend(h.certificates)
return certs
certs = extract_openvpn_certs("openvpn.pcap")
for i, cert in enumerate(certs):
with open(f"cert_{i}.der", "wb") as f:
f.write(cert.data)
Once extracted, examine certificates with OpenSSL:
openssl x509 -inform der -in cert_0.der -text -noout
When analyzing OpenVPN server certificates, traditional tools like openssl s_client
fall short because OpenVPN primarily uses UDP with custom TLS encapsulation. The protocol implements TLS over UDP through its own security layer rather than standard DTLS.
The most reliable approach is using OpenVPN's native logging capabilities:
openvpn --client --dev tun --proto udp --remote vpn.example.com 1194 \
--verb 4 --tls-export-cert /path/to/certs \
--config client.ovpn
This command will:
- Set verbosity level 4 to show TLS handshake details
- Export certificates to specified directory using
--tls-export-cert
- Maintain standard UDP transport
For situations where you can't modify OpenVPN commands:
# Capture initial handshake
tcpdump -i eth0 -s0 -w openvpn.pcap 'udp port 1194'
# Analyze with Wireshark:
# 1. Set protocol preference for OpenVPN
# 2. Add pre-shared keys if available
# 3. Follow TLS stream to extract certificates
For programmatic access, create a MITM proxy:
from scapy.all import *
import dpkt
def packet_handler(pkt):
if UDP in pkt and pkt[UDP].dport == 1194:
# Parse OpenVPN protocol
if pkt.load.startswith(b'\x38\x01\x00\x00'):
# Extract TLS handshake portion
tls_data = pkt.load[16:]
# Process as TLS records
records = dpkt.ssl.TLSRecord(tls_data)
for record in records:
if isinstance(record, dpkt.ssl.TLSCertificate):
for cert in record.certificates:
open(f'cert_{len(cert)}.der', 'wb').write(cert)
sniff(filter="udp port 1194", prn=packet_handler)
Be aware that:
- OpenVPN may use static key mode without certificates
- Some implementations use abbreviated handshakes
- Perfect Forward Secrecy configurations may prevent full chain extraction
Once extracted, examine certificates with:
openssl x509 -in certificate.crt -text -noout
For DER format certificates:
openssl x509 -inform der -in certificate.der -text -noout