DEV Community

Cover image for Rotate certificate in NGINX Open Source without restart
terngr
terngr

Posted on

Rotate certificate in NGINX Open Source without restart

ตอนนี้ทีมทยอยย้ายเข้า Office ใหม่ตึก OASIS ในรูปเป็นห้องร้อง Karaoke เอ๊ยห้องประชุมขนาดย่อม ไว้ร้อง Karaoke ได้เต็มที่ 8 คน เอ๊ยนั่งทำงานได้เต็มที่ 4 คนครับ

ท่านที่ใช้งาน NGINX คงจะคุ้นเคยกับการใส่ Certificate บน NGINX เพื่อที่เวลา Client request จะได้สามารถเปิด Connection แบบเข้ารหัสได้ ผลคือทำให้ Client สามารถเชื่อได้ว่าเป็นเว็บไซต์ เช่นเว็บผู้ให้บริการนี้ตัวจริง และยังช่วยเข้ารหัสข้อความที่ส่งไปมาระหว่างกัน

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ...
}
Enter fullscreen mode Exit fullscreen mode

โดยปกติ Certificate จะถูกอ่านจากไฟล์(Disk) แล้วนำไปเก็บใน Memory ตอนที่ start NGINX ฉะนั้นการ Establish connection ก็จะเรียกใช้ key pairs ได้อย่างรวดเร็วผ่าน memory ถ้าเว็บมี server_name เดียว และไม่ได้เปลี่ยนคีย์บ่อยๆ หรือเปลี่ยนแบบมี Downtime ได้ การใช้งานแบบปกติก็ยังเพียงพอ

แต่ถ้าเป็นการที่มี Dynamic name เช่นมีหลายชื่อ มีชื่อเพิ่มเข้าออกบ่อย, หรือกรณีต้องการเปลี่ยน Certificate เป็นตัวใหม่ โดยไม่ให้เกิด Downtime กรณีนี้ เดิมทำได้ทั้งบน NGINX Plus และ NGINX OSS อยู่แล้ว ต่างกันที่วิธีการและ Performance

  • โดย NGINX Plus ใช้ key-value store ในการเก็บ ซึ่งอยู่บน memory และ load ค่าใหม่จาก Disk เข้า Memory ได้หากต้องการ
  • NGINX Open Source ใช้วิธีให้อ่านใหม่ทุกครั้ง ซึ่งมีผลกระทบคือเป็นการอ่านจาก Disk ทำให้กระทบกับ Performance กรณีที่ต้อง Establish connection บ่อยๆ

ที่จะเล่าวันนี้มาจาก SSL/TLS Certificate Rotation Without Restarts in NGINX Open Source โดยเป็นการใช้ความสามารถของ NGINX JavaScript Module มาทดแทน key-value store บน NGINX Plus

เริ่มจาก ให้ njs เป็นคนเก็บค่า certificate ไว้ใน Memory

     # Sets an njs function for the variable. Returns a value of cert/key
      js_set $dynamic_ssl_cert main.js_cert;
      js_set $dynamic_ssl_key main.js_key;   
Enter fullscreen mode Exit fullscreen mode

จากนั้น NGINX นำค่านี้ไปใช้ตามปกติ ก็จะเป็นค่าอ่านค่า Certificate จาก Memory ซึ่งไม่กระทบกับ Performance แล้วนั่นเอง

      # use variable's data
      ssl_certificate data:$dynamic_ssl_cert;
      ssl_certificate_key data:$dynamic_ssl_key;
Enter fullscreen mode Exit fullscreen mode

เมื่อต้องการเปลี่ยนไปใช้ Certificate ใหม่ สามารถใช้ njs ให้ยกเลิกค่าใน Memory และไปอ่านค่าจากไฟล์ใหม่ได้ทันที, เมื่อ NGINX เรียกใช้ ก็จะเรียกใช้งานจาก Memory ได้ต่อเนื่อง

เบื้องหลังการยกเลิกการใช้งาน Certificate เดิมที่อยู่ใน Memory ให้ไป Load Certificate ใหม่จาก Disk

   location = /clear {
      js_content main.clear_cache;
      # allow 127.0.0.1;
      # deny all;
    }
Enter fullscreen mode Exit fullscreen mode

โดยสรุป เราสามารถที่จะใช้ NJS หรือ NGINX JavaScript Module ซึ่งใช้งานได้ง่ายด้วยภาษา JavaScript และคนทำเว็บคุ้นเคยอยู่แล้ว มาช่วยเพิ่มความสามารถอื่นๆ ให้ NGINX ได้ครับ ในทีนี้คือทำ Function Serve certificate จาก Cache พร้อมความสามารถในการ Reload Certificate ใหม่จาก Disk ลง Cache ได้ด้วยครับ __

Top comments (0)