บทความก่อนหน้านี้ได้แนะนำ การติดตั้ง Let’s Encrypt ร่วมกับ Apache บน CentOS 7 ไปแล้ว สำหรับบทความในนี้จะขอแนะนำการติดตั้ง Let’s Encrypt ร่วมกับ Nginx บน CentOS 7

หลังจากที่ดำเนินการติดตั้ง CentOS รวมทั้งดำเนินการ update package manager ต่างๆ ให้เรียบร้อยแล้ว จึงมาเริ่มดำเนินการติดตั้งตามขั้นตอนดังนี้

ขั้นตอนที่ 1 – ติดตั้ง Nginx

ในกรณีที่ยังไม่ได้ทำการติดตั้ง Nginx สามารถติดตั้ง Nginx จาก Epel repositories

# yum install epel-release
# yum install nginx

ขั้นตอนที่ 2 – ติดตั้งแพคเกจที่ต้องใช้สำหรับ Let’s Encrypt

สำหรับการติดตั้งแพคเกจจำเป็นสำหรับ Let’s Encrypt client บนระบบ Linux ที่รวดเร็วแนะนำให้ติดตั้งจาก github repositories

# yum install git
# cd /opt
# git clone https://github.com/letsencrypt/letsencrypt

ขั้นตอนที่ 3 – การสร้าง SSL Certificate สำหรับ Nginx

การติดตั้งฟรี SSL Certificate สำหรับ Nginx ด้วยตัวเอง โดยใช้ Standalone plugin

ตรวจสอบ port 80 ว่าใช้งานอยู่หรือไม่

# ss -tln

หากพบว่ามีการทำงานอยู่ให้ทำการ stop service

# systemctl stop nginx
# ss -tln

***การสร้าง free SSL Certificate โดยในที่นี้ให้เปลี่ยนข้อมูลโดเมนเป็นข้อมูลจริงของท่าน แทนค่า letsencrypt.thaivs.com (โดเมนตัวอย่างของบทความ)

# cd /opt/letsencrypt/
# ./letsencrypt-auto certonly --standalone -d letsencrypt.thaivs.com -d www.letsencrypt.thaivs.com

กรอกอีเมล์ของท่านที่ใช้ในกรณีติดต่อและจากนั้นให้ยอมรับเงื่อนไข

ติดตั้งเรียบร้อย จะพบข้อความแสดงอายุของ Certificate (มีอายุ 90 วัน นับจากวันที่ติดตั้ง)

ขั้นตอนที่ 4 – การติดตั้ง SSL Certificate สำหรับ Nginx

ไฟล์ของ SSL Certificate จะวางอยู่ที่ /etc/letsencrypt/live/

# ls /etc/letsencrypt/live/
# ls -al /etc/letsencrypt/live/letsencrypt.thaivs.com

การติดตั้ง SSL Certificate สำหรับ Nginx ให้ทำการเปิดไฟล์ /etc/nginx/nginx.conf

# vi /etc/nginx/nginx.conf

และวางข้อความดังนี้ภายในไฟล์

# SSL configuration
listen 443 ssl default_server;
ssl_certificate /etc/letsencrypt/live/letsencrypt.thaivs.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/letsencrypt.thaivs.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

ทำการ restart Nginx

# systemctl restart nginx

เมื่อติดตั้งเรียบร้อยแล้ว เรามาตรวจสอบ SSL Certificate ที่เราได้ติดตั้งกัน โดยตรวจสอบได้ที่ (ทำการทดสอบแบบมีและไม่มี www)

https://www.ssllabs.com/ssltest/analyze.html

ในกรณีที่ตรวจสอบพบเกรดเท่าหรือต่ำกว่า B สามารถทำการ generate ค่า Diffie-Hellman ใหม่

Diffie–Hellman (DH) เป็นกระบวนการสร้าง “ความลับ” ระหว่างกันโดยไม่ต้องส่งความลับนั้นถึงกันจริงๆ โดยทั่วไปแล้วความลับที่ว่าคือการแลก “กุญแจ” สำหรับการเข้ารหัสแบบกุญแจสมมาตรเพื่อส่งข้อมูลถึงกันต่อไป

# mkdir /etc/nginx/ssl
# cd /etc/nginx/ssl
# openssl dhparam -out dhparams.pem 4096

หลังจาก generate ค่า Diffie-Hellman เรียบร้อยแล้ว ให้ทำการเปิดไฟล์ /etc/nginx/nginx.conf และวางข้อความดังนี้ภายในไฟล์ เพิ่มเติมจากข้อความเดิมก่อนหน้า

ssl_dhparam /etc/nginx/ssl/dhparams.pem;
ssl_session_timeout 30m;
ssl_session_cache shared:SSL:10m;
ssl_buffer_size 8k;
add_header Strict-Transport-Security max-age=31536000;

และ restart Nginx

# systemctl restart nginx

เรามาตรวจสอบ SSL Certificate กันอีกครั้ง ให้ทำการกด Clear cache และทดสอบแบบมีและไม่มี www

ขั้นตอนที่ 5 – การตั้งค่าต่ออายุ Let’s Encrypt

Let’s Encrypt แบบ free SSL certificates จะมีอายุ 90 วัน ในที่นี้เราจะใช้ webroot plugin ในการต่ออายุ

# cd /opt/letsencrypt/
# ./letsencrypt-auto certonly -a webroot --agree-tos --renew-by-default --webroot-path=
/usr/share/nginx/html/ -d letsencrypt.thaivs.com -d www.letsencrypt.thaivs.com
# systemctl reload nginx

เพื่อให้การต่ออายุ SSL certificates ได้แบบอัตโนมัติ ให้ทำการสร้าง script ไว้ที่ /usr/local/bin/

# vi /usr/local/bin/cert-renew

และวางข้อความดังนี้ภายในไฟล์ (ตรวจสอบค่าตัวแปร $webpath ให้ถูกต้อง ตาม path ที่ท่านใช้งาน)

#!/bin/bash
webpath='/usr/share/nginx/html/'
domain=$1
le_path='/opt/letsencrypt'
le_conf='/etc/letsencrypt'
exp_limit=30;
get_domain_list(){
  certdomain=$1
  config_file="$le_conf/renewal/$certdomain.conf"
  if [ ! -f $config_file ] ; then
    echo "[ERROR] The config file for the certificate $certdomain was not found."
    exit 1;
  fi
  domains=$(grep --only-matching --perl-regex "(?<=domains \= ).*" "${config_file}")
  last_char=$(echo "${domains}" | awk '{print substr($0,length,1)}')
  if [ "${last_char}" = "," ]; then
    domains=$(echo "${domains}" |awk '{print substr($0, 1, length-1)}')
  fi
  echo $domains;
}
if [ -z "$domain" ] ; then
  echo "[ERROR] you must provide the domain name for the certificate renewal."
  exit 1;
fi
cert_file="/etc/letsencrypt/live/$domain/fullchain.pem"
if [ ! -f $cert_file ]; then
  echo "[ERROR] certificate file not found for domain $domain."
  exit 1;
fi
exp=$(date -d "`openssl x509 -in $cert_file -text -noout|grep "Not After"|cut -c 25-`" +%s)
datenow=$(date -d "now" +%s)
days_exp=$(echo \( $exp - $datenow \) / 86400 |bc)
echo "Checking expiration date for $domain..."
if [ "$days_exp" -gt "$exp_limit" ] ; then
  echo "The certificate is up to date, no need for renewal ($days_exp days left)."
  exit 0;
else
  echo "The certificate for $domain is about to expire soon. Starting renewal request..."
  domain_list=$( get_domain_list $domain )
  "$le_path"/letsencrypt-auto certonly -a webroot --agree-tos --renew-by-default --webroot
-path=”$webpath” --domains "${domain_list}"
  echo "Reloading Nginx..."
  sudo systemctl reload nginx
  echo "Renewal process finished for domain $domain"
  exit 0;
fi

เมื่อดำเนินการวาง script เรียบร้อยแล้ว ให้ทำการตั้งค่า executable และติดตั้ง bc

# chmod +x /usr/local/bin/cert-renew
# yum install bc

และทดสอบ script

# /usr/local/bin/cert-renew letsencrypt.thaivs.com

ในที่สุดเราก็ตั้งค่าการต่ออายุ SSL certificates อัตโนมัติไว้พร้อมแล้ว เรามาตั้ง cron เพื่อให้ run script ทุกๆ อาทิตย์ เพื่อให้ตรวจสอบและต่ออายุก่อน 30 วัน

# crontab -e

และวางข้อความดังนี้ภายในไฟล์

0 0 * * 0 /usr/local/bin/cert-renew letsencrypt.thaivs.com >> /var/log/letsencrypt.thaivs.com
-renew.log 2>&1