ตัวอย่าง NGINX mutual authentication

Nginx Sep 08, 2019

การทำ  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

จบ

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.