Day: November 19, 2020

  • วิธีติดตั้ง HTTPS ด้วย Certificate ของ Let’s Encrypt แบบ wildcard สำหรับ Intranet ที่ไม่สามารถเข้าถึงได้จาก Internet

    ความเดิมตอนที่แล้ว

    ต่อจาก วิธีติดตั้ง HTTPS ด้วย Certificate ของ Let’s Encrypt ซึ่ง เครื่องที่จะขอใช้ Certificate นั้น ต้องสามารถ “เข้าถึงได้” จาก Internet เพราะ จะต้องสร้าง File ไปวางในตำแหน่งที่ Let’s Encrypt CA สามารถเข้ามาตรวจสอบได้ว่าเป็น ผู้ที่มีสิทธิ์ในการจัดการ Domain Name นั้นจริง

    ปัญหาคือ

    • ในองค์กร ถ้าจะให้มีเซิร์ฟเวอร์ ที่สามารถเข้าถึงได้ จาก Internet ต้องเปิด Firewall ขององค์กร ซึ่ง ซับซ้อน และ มีความเสี่ยง
    • แล้ว ถ้ามีเครื่องภายใต้โดเมนเดียวกันอีกหลายเครื่อง ต้องทำทุกเครื่อง ซึ่งไม่สะดวกเลย

    ต้องเข้าใจก่อน

    Let’s encrypt มีวิธีการตรวจสอบความเป็นเจ้าของ Domain Name หรือที่เรียกว่า “Challenge” หลายวิธี ได้แก่

    1. HTTP-01 Challenge
    2. DNS-01 Challenge
    3. TLS-SNI-01 Challenge
    4. TLS-ALPN-01 Challenge

    วิธีที่ง่าย และทำกันทั่วไป คือ HTTP-01 คือ เมื่อ certbot client รับคำสั่งขอ certificate สำหรับโดเมนที่ต้องการแล้ว จะต้องเอาไฟล์ ไปวางที่

    http://<YOUR_DOMAIN>/.well-known/acme-challenge/<TOKEN>

    ซึ่ง ชื่อต้องตรงกับที่กำหนด และในไฟล์ จะเป็น Token และ Thumbprint ของ account key

    (ในทางเทคนิค อาจจะให้มีสักเครื่องในองค์กรที่เปิดให้เข้าถึงจาก Internet ได้ ทำหน้าที่ร้องขอ Certificate ได้ แล้วทำ HTTP-01 Challenge ให้ผ่าน ก็จะสามารถขอ Certificate ให้กับ Subdomain อื่น ๆ ได้)

    แต่มีอีกวิธีหนึ่ง คือ DNS-01 Challenge ซึ่ง ไม่จำเป็นต้องมีเครื่องที่เข้าถึงได้จาก Internet (แต่สามารถ ออก Internet ได้) แต่อาศัยการสร้าง TXT Record ตามที่กำหนดแทน ประมาณนี้

    _acme-challenge.<YOUR_DOMAIN> 300 IN TXT "<TOKEN>"

    วิธีการมีดังนี้

    0. เราจะขอ wildcard certificate โดเมนของ abc.ijk.xyz.psu.ac.th โดยการติดตั้ง Let’s Encrypts certbot client บน Ubuntu 20.04 ซึ่งเครื่องนี้ สามารถต่อ Internet ได้ แต่ไม่สามารถเข้าถึงได้จาก Internet

    1.ติดตั้ง Let’s Encrypts certbot client (ยุ่งยากหน่อย แต่จะได้ certbot version 1.19)

    sudo apt update
    sudo snap install core; sudo snap refresh core
    sudo apt-get remove certbot
    sudo snap install --classic certbot
    sudo ln -s /snap/bin/certbot /usr/bin/certbot

    หรือสั้นๆ ทำอย่างนี้ก็ได้ (ไม่ต้องใช้ snap แต่จะได้ certbot version 0.40)

    sudo apt update
    sudo apt install certbot

    2. สั่ง certbot ให้ไปขอเฉพาะ certificate จากนั้นบอกว่าจะติดตั้งเอง (manual) และ ขอใช้ DNS-01 Challenge

    sudo certbot certonly --manual --preferred-challenges dns

    3. กรอกข้อมูล โดเมนเนม ที่ต้องการ ในที่นี้ จะขอใช้ wildcard คือ *.abc.ijk.xyz.psu.ac.th

    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Plugins selected: Authenticator manual, Installer None
    Please enter in your domain name(s) (comma and/or space separated) (Enter 'c' to cancel): *.abc.ijk.xyz.psu.ac.th
    Obtaining a new certificate
    Performing the following challenges:
    dns-01 challenge for *.abc.ijk.xyz.psu.ac.th

    NOTE: The IP of this machine will be publicly logged as having requested this
    certificate. If you're running certbot in manual mode on a machine that is not
    your server, please ensure you're okay with that.
    Are you OK with your IP being logged?

    (Y)es/(N)o: y

    Please deploy a DNS TXT record under the name
    _acme-challenge.abc.ijk.xyz.medicine.psu.ac.th with the following value:
    xjid...4u1znkFXut0Y...n3ck89gGaUl75K4fI
    Before continuing, verify the record is deployed.

    Press Enter to Continue

    **** ตรงนี้ อย่าเพิ่งเคาะ Enter เด็ดขาด จนกว่า DNS admin จะดำเนินการเสร็จ *****

    4. แจ้งผู้ดูแล DNS ขององค์กร ว่า ให้เพิ่ม TXT Record ส่งข้อความตามนี้ไปให้เค้าก็น่าจะได้

    Please deploy a DNS TXT record under the name
    _acme-challenge.abc.ijk.xyz.medicine.psu.ac.th with the following value:
    xjid...4u1znkFXut0Y...n3ck89gGaUl75K4fI

    หรือจะให้ดี แจ้งไปตรง ๆ ว่า จะเอาแบบนี้

    _acme-challenge.abc.ijk.xyz.medicine.psu.ac.th 300 IN TXT 
    "xjid...4u1znkFXut0Y...n3ck89gGaUl75K4fI"

    5. รอ รอ รอ จนกว่า DNS Admin บอกว่า เสร็จแล้ว (แนะนำว่า ควรทำในเวลาที่สามารถประสานงานกับ DNS Admin ได้ เพราะ ในขั้นตอนข้อ 3. นั้น จะเคาะผ่านไม่ได้ หากแจ้ง DNS admin ไปแล้ว แต่เค้ายังไม่ทันทำให้ แล้วเราดันไปเคาะ Enter ผ่านไปก่อน TOKEN ที่แจ้งไป ก็จะใช้ไม่ได้)

    ตรวจสอบด้วย Google Admin Toolbox ก็ได้ ว่าได้ TXT ตรงตามที่กำหนดมาแล้ว ที่

    https://toolbox.googleapps.com/apps/dig/#TXT/

    สิ่งที่ควรได้ น่าจะมีหน้าตาประมาณนี้

    เมื่อมั่นใจว่า TXT Record ตรงกันแล้ว ค่อยกลับไปที่หน้าต่างในข้อ 3. แล้วกด Enter

    Let’s Encrypt certbot client จะแจ้งไปยัง CA server ให้ตรวจสอบ ถ้าผ่านก็จะได้ข้อคาวมประมาณนี้

    Waiting for verification…
    Cleaning up challenges
    Subscribe to the EFF mailing list (email: kanakorn.h@g.psu.ac.th).
    IMPORTANT NOTES:
    Congratulations! Your certificate and chain have been saved at:
    /etc/letsencrypt/live/abc.ijk.xyz.psu.ac.th/fullchain.pem
    Your key file has been saved at:
    /etc/letsencrypt/live/abc.ijk.xyz.psu.ac.th/privkey.pem
    Your cert will expire on 2021-02-17. To obtain a new or tweaked
    version of this certificate in the future, simply run certbot
    again. To non-interactively renew all of your certificates, run
    "certbot renew"
    If you like Certbot, please consider supporting our work by:
    Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
    Donating to EFF: https://eff.org/donate-le

    ตรวจสอบ Certification ด้วยคำสั่ง

    sudo certbot certificates

    จะได้รายละเอียดว่า Certificate ที่ได้มา เป็นของ domain อะไรบ้าง

    Found the following certs:
    Certificate Name: abc.ijk.xyz.psu.ac.th
    Serial Number: 3808642657a...........bbeacd6df8bacc
    Domains: *.abc.ijk.xyz.psu.ac.th
    Expiry Date: 2021-02-17 02:59:43+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/abc.ijk.xyz.psu.ac.th/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/abc.ijk.xyz.psu.ac.th/privkey.pem

    สุดท้าย เอา fullchain.pem และ privkey.pem ไปไว้ในเครื่อง web server ที่จะต้องการใช้ https เป็น subdomain ของ abc.ijk.xyz.psu.ac.th

    จากนั้น ตั้งค่าใน Web Server เช่น Apache2 ให้ใช้ Certificate ประมาณนี้

    <VirtualHost *:443>
    # ...
       SSLEngine on
       SSLCertificateFile /etc/ssl/letsencrypt/fullchain.pem
       SSLCertificateKeyFile /etc/ssl/letsencrypt/privkey.pem
    </VirtualHost>

    แล้วก็ restart เป็นอันเรียบร้อย

    ตรวจสอบการใช้งานจริง โดยการใช้ https://server1.abc.ijk.xyz.psu.ac.th/ จะได้แบบนี้

    หวังว่าจะเป็นประโยชน์ครับ