mTLS verify client and server certificate to establish the connections. For example we’ll using urllib3 in Python. In real world example, many corporate put their API behind Akamai/CloudFlare and set the mTLS to secure it. For developer it seem more complicated to utilize the API, but once we pass the mTLS connection everything is same.
Requirements:
– Root CA, Client Certificate and Private Key
Client certificate must be sign by the same Root CA or Intermediate CA that use in server.
Install urllib3 library
pip install urllib3
Without mTLS / TLS Only
There are a lot of website that we can use to verify connection without mTLS. Any website will do it, for my favorite is httpbin.org
using GET
import urllib3 response = http.request("GET", "https://httpbin.org/get") print(response.data)
using POST
import urllib3 response = http.request("POST", "https://httpbin.org/post") print(response.data)
accessing website behind mTLS will gives some errors, the error messages depend on the server, by default nginx will show these messages
<html> <head><title>400 No required SSL certificate was sent</title></head> <body> <center><h1>400 Bad Request</h1></center> <center>No required SSL certificate was sent</center> <hr><center>nginx/1.28.0</center> </body> </html>
With mTLS
The only differences we have here is we use PoolManager to define the certificate, Root CA and private key. The private key password is optional, remove if not required
import urllib3 client_cert_file = "/home/atetux/staging/certs/client.crt" client_key_file = "/home/atetux/staging/certs/client.key" ca_file = "/home/atetux/staging/certs/ca.crt" # mTLS setting http = urllib3.PoolManager( cert_file=client_cert_file, key_file=client_key_file, key_password="PRIVATE_KEY_PASSWORD", ca_certs=ca_file, cert_reqs='REQUIRED' ) response = http.request('GET', 'https://mTLS.DOMAIN.com') print(response.data.decode())