การทำ  Mutual authentication พูดง่ายๆคือ คนที่จะเรียกใช้เว็บ หรือ API ได้ ต้องมีกุญแจ หรือ key ที่ถูกต้อง ถึงจะใช้งานได้

Mutual authentication หรือเรียกสั้นๆ mTLS (Mutual TLS authentication)

รัน NGINX ปกติด้วย Docker ง่ายๆ ด้วย Docker Compose

version: '3.7'
services:
  nginx:
    image: nginx:alpine
    container_name: nginx
    ports:
    - 80:80

ได้ NGINX ง่ายๆแล้ว เพิ่ม HTTPS ให้กับ NGINX โดยใช้ mkcert ในการสร้าง SSL สมมติว่า ชื่อโดเมน bank.api

mkdir -p certs
cd certs
mkcert bank.api

จะได้

Using the local CA at "/Users/USERNAME/Library/Application Support/mkcert" ✨

Created a new certificate valid for the following names 📜
 - "bank.api"

The certificate is at "./bank.api.pem" and the key at "./bank.api-key.pem" ✅

แก้ไฟล์ docker-compose.yml เพื่อตั้งค่า HTTPS

version: '3.7'
services:
  nginx:
    image: nginx:alpine
    container_name: nginx
    volumes:
    - ./certs:/etc/nginx/certs
    - ./conf.d:/etc/nginx/conf.d
    ports:
    - 80:80
    - 443:443

เพิ่มไฟล์ conf.d/bank.api.conf


server {
    listen       443 ssl http2;
    server_name  bank.api;

    ssl_certificate     /etc/nginx/certs/bank.api.pem;
    ssl_certificate_key /etc/nginx/certs/bank.api-key.pem;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

จากนั้น รัน docker-compose up -d ใหม่อีกรอบ แล้วแก้ไฟล์ /etc/hosts เพิ่ม 127.0.0.1 bank.api

# /etc/hosts
127.0.0.1 bank.api

เสร็จแล้วลองเรียกหน้าเว็บด้วย HTTPS https://bank.api

https

จะได้หน้าเว็บที่เป็น HTTPS ถ้าใครใช้ mkcert ครั้งแรก แล้วไม่ได้ติดตั้ง Root CA ตอนสร้าง Cert ให้รันคำสั่งนี้

cd certs
mkcert -install

สร้าง Client Certificate สำหรับทำ mTLS

mkcert -client bank.api
Using the local CA at "/Users/USERNAME/Library/Application Support/mkcert" ✨

Created a new certificate valid for the following names 📜
 - "bank.api"

The certificate is at "./bank.api-client.pem" and the key at "./bank.api-client-key.pem" ✅

จากนั้นคัดลอก rootCA.pem มาที่ certs/rootCA.pem

จะได้ไฟล์

.
├── bank.api-client-key.pem
├── bank.api-client.pem
├── bank.api-key.pem
├── bank.api.pem
└── rootCA.pem

แล้วแก้ไฟล์ conf.d/bank.api.conf เพื่อทำการเช็ค client certificate


server {
    listen       443 ssl http2;
    server_name  bank.api;

    ssl_certificate     /etc/nginx/certs/bank.api.pem;
    ssl_certificate_key /etc/nginx/certs/bank.api-key.pem;

    ssl_verify_client on;
    ssl_client_certificate /etc/nginx/certs/rootCA.pem;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

หลังจากนั้น reload nginx เมื่อเข้าผ่านหน้าเว็บ จะได้ error

มัน error เพราะไม่ได้ส่ง client certificate ไปด้วย ขี้เกียจติดตั้ง client certificate จะโกงด้วยการใช้ curl

cd  certs
curl -v \
    --key bank.api-client-key.pem \
    --cert bank.api-client.pem \
    --cacert bank.api.pem \
    https://bank.api

จะได้ผลลัพธ์เป็น 200 OK

จบ