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())

Leave a comment

Your email address will not be published. Required fields are marked *