Tags:
Node Thumbnail

ทุกวันนี้การเชื่อมต่อเว็บต่างๆ แทบทั้งหมดกลายเป็นการเชื่อมต่อแบบเข้ารหัส หลังจาก Let's Encrypt เปิดให้บริการเมื่อปี 2015 ตั้งแต่ปี 2018 เป็นต้นมาอัตราการเชื่อมต่อเว็บด้วย HTTPS ขึ้นไปถึง 94-95% และคงที่อยู่ที่เดิมเสมอมา เว็บสาธารณะที่เราใช้งานแทบทั้งหมดแม้อาจจะมีหลายเว็บยังให้บริการแบบ HTTP อยู่แต่ก็มักจะรองรับ HTTPS ไปพร้อมกัน อย่างไรก็ดียังมีเว็บกลุ่มหนึ่งที่เราใช้ HTTP เสมอ นั่นคือเว็บของอุปกรณ์ในบ้านหรือภายในองค์กร ไม่ว่าจะเป็นเราท์เตอร์หรือสตอเรจ ตลอดจนอุปกรณ์อื่นๆ

การขอใบรับรองเข้ารหัสจาก Let's Encrypt นั้นโดยปกติแล้วเรามักอาศัยกระบวนการยืนยันเจ้าของโดเมนแบบ HTTP-01 ที่ต้องการเว็บเซิร์ฟเวอร์ที่เข้าถึงจากอินเทอร์เน็ตได้เพราะทาง Let's Encrypt จะเข้ามาดาวน์โหลดข้อมูลยืนยันเจ้าของโดเมนจากเว็บ กระบวนการ HTTP-01 ไม่เหมาะกับการยืนยันตัวตนเซิร์ฟเวอร์ภายในและเราท์เตอร์ เนื่องจากอุปกรณ์เหล่านี้มันมีเฉพาะไอพีภายในเช่น 10.0.0.0/8 หรือ 192.168.1.0/24 เป็นต้น ทำให้หากเรากำหนดชื่อโดเมนให้กับอุปกรณ์เหล่านี้ เครื่องเหล่านี้ก็เข้าถึงจากอินเทอร์เน็ตไม่ได้อยู่ดี ทำให้เซิร์ฟเวอร์ Let's Encrypt ไม่สามารถเข้ามาตรวจสอบเพื่อออกใบรับรองผ่านกระบวนการ HTTP-01 ได้

No Description

Let's Encrypt ยังรองรับกระบวนการยืนยันเจ้าของโดเมนแบบ DNS-01 ที่อาศัยการตรวจสอบฟิลด์ TXT แทนที่จะเป็นการเชื่อมต่อไปยังเซิร์ฟเวอร์โดยตรง กระบวนการ DNS-01 กำหนดให้เจ้าของโดเมนต้องตั้งค่าฟิลด์ TXT ให้กับโดเมน _acme_challenge.[ชื่อโดเมน] ตามที่กำหนด

ปัญหาของ DNS-01 คือกระบวนการปรับแก้ข้อมูลใน DNS นั้นไม่สะดวกนัก โดยปกติแล้วผู้ดูแลเว็บเซิร์ฟเวอร์ไม่มีสิทธิ์ในการปรับแก้ข้อมูลด้วยตัวเอง หรือกระบวนการปรับแก้สะดวกนัก เช่น ต้องล็อกอินเข้าเว็บเพื่อปรับแก้ไขค่าเป็นครั้งๆ แต่ทุกวันนี้เรามีบริการ Dynamic DNS ที่หลายคนนิยม ในกรณีนี้ผมเลือกบริการ Dynamic DNS ของ Hurricane Electric เพราะเป็นบริการฟรีที่รองรับฟิลด์หลากหลาย ทั้ง IPv4, IPv6, และฟิลด์ TXT รวมถึงมีบริการ Dynamic TXT สามารถกำหนดค่าฟิลด์ TXT ได้โดยไม่ต้องล็อกอินเว็บโดยตรง (ตอนนี้โปรแกรมขอใบรับรอง Let's Encypt ยังไม่มีตัวใดรองรับฟีเจอร์นี้) และสามารถกำหนดหมายเลขไอพีได้เองจากไคลเอนต์ Dynamic DNS ทำให้ใช้งานกับเน็ตเวิร์คภายในได้ง่าย เราสามารถตั้งสริปต์ให้แก้ไขค่า DNS จากภายในตัวอุปกรณ์ได้อัตโนมัติเมื่อมีการแก้ไขหมายเลขไอพี

ในบทความนี้ผมใช้เราท์เตอร์ของ MikroTik เป็นตัวอย่าง เราท์เตอร์ตามบ้านที่เรามักได้รับจากผู้ให้บริการอินเทอร์เน็ตส่วนมากรองรับการให้บริการผ่าน HTTPS และสามารถติดตั้งใบรับรองได้เช่นกัน อย่างไรก็ดีผู้ให้บริการอินเทอร์เน็ตในไทยหลายรายมักแก้ไขรอมเป็นของตัวเองและตัดฟีเจอร์ HTTPS ออก

การขอใบรับรองแบบ DNS-01

กระบวนการขอใบรับรองจาก Let's Encrypt นั้นเริ่มจากการโอนโดเมนเราไปอยู่กับ Hurricane Electric ก่อน ด้วยการตั้งค่า name server ไปเป็น ns1.he.net, ns2.he.net, ns3.he.net, ns4.he.net, และ ns5.he.net จากนั้นสร้างบัญชีบนเว็บ dns.he.net และเพิ่มโดเมนของเราเข้าไป เราจะสามารถตั้งค่า DNS ได้เอง

จากนั้นเราต้องหาลินุกซ์สักเครื่องเพื่อรันไคลเอนต์ของ Let's Encrypt ในกรณีของผมใช้โปรแกรม acme.sh สามารถติดตั้งได้ด้วยคำสั่ง curl https://get.acme.sh | sh - ในกรณีของผมต้องติดตั้งแพ็กเกจ curl และ openssl ลงในลินุกซ์เพิ่มเติม

ก่อนจะรัน acme.sh เราจำเป็นต้องกำหนดตัวแปรเพื่อให้โปรแกรมรู้รหัสผ่าน Hurricane Electric ของเราก่อน เป็นค่า HE_Username และ HE_Password หากในอนาคต acme.sh รองรับฟีเจอร์ใหม่ของ Hurricane Electric ก็น่าจะสามารถใส่โทเค็นเฉพาะโดเมนเพื่อตั้งค่า Dynamic TXT แทนที่จะใส่รหัสผ่านไปทั้งหมดเช่นนี้ ค่าเริ่มต้นนั้น acme.sh จะติดตั้งอยู่ใน ~/.acme.sh ให้เข้าไปในโฟลเดอร์นี้ หลังจากนั้นรันคำสั่ง

./acme.sh --issue --dns dns_he -d [domain name]

กระบวนการขอรับรองจะใช้เวลา 2-5 นาทีเนื่องจากต้องแน่ใจว่าค่าฟิลด์ TXT อัพเดตใน DNS เรียบร้อยแล้ว เมื่อตรวจสอบจนเสร็จสิ้นแล้วทาง Let's Encrypt จะออกใบรับรองมาให้ อยู่ใน ~/.acme.sh/[domain name]/

การติดตั้งใบรับรองเข้าเราท์เตอร์

กระบวนการติดตั้งใบรับรองเข้าเราท์เตอร์เป็นอีกส่วนหนึ่ง เราอาจจะดาวน์โหลดไฟล์ไปติดตั้งในหน้าเว็บของ Mikrotik ได้โดยตรง แต่ควรระวังว่าใบรับรองของ Let's Encrypt นั้นมีอายุเพียง 3 เดือน ควรหาทางเขียนสคริปต์เพื่ออัพเดตอัตโนมัติให้เรียบร้อย เริ่มจากสร้างกุญแจ SSH เพื่อให้สามารถเขียนสคริปต์ติดตังใบรับรองได้ โดยใช้คำสั่ง ssh-keygen หากใช้ค่าเริ่มต้นจะได้รับกุญแจแบบ RSA (ผมลองกุญแจแบบอื่นๆ แต่ใช้งานกับ MikroTik ไม่สำเร็จ) ในไฟล์ ~/.ssh/id_rsa และกุญแจสาธารณะ ~/.ssh/id_rsa.pub นำกุญแจสาธารณะเข้าไปผูกกับบัญชี โดยต้องอัพโหลดกุญแจสาธารณะเข้าไปยังไฟล์ก่อน แล้วผูกกับบัญชีผู้ดูแลระบบทางเมนู System > Users > SSH Keys > Import SSH Key เมื่อผูกบัญชีสำเร็จ เราสามารถล็อกอินผ่านทาง SSH ด้วยคำสั่ง ssh admin@[router IP] ได้ทันที โดยไม่ถูกถามรหัสผ่านอีกต่อไป

เมื่อล็อกอินผ่าน SSH ได้แล้วให้เริ่มอิมพอร์ตใบรับรองโดเมนเข้าไปยัง MikroTik

cd ~/.acme.sh/[domain name]/
export router="ssh admin@[router IP]"
scp fullchain.cer admin@[router IP]:fullchain.cer
scp [domain name].key admin@[router IP]:private.key
$router /certificate import file-name=fullchain.cer passphrase=\"\"
$router /certificate import file-name=private.key passphrase=\"\"

ถึงขั้นตอนนี้หากเราเข้าไปดูเว็บ MikroTik ในเมนู System > Certificates ก็จะเห็นใบรับรองตามโดเมนที่เราจดทะเบียนมาแล้ว เช่น

No Description

กระบวนการหลังจากนี้จะเป็นการตั้งค่าใบรับรองเข้าไปยัง บริการของ MikroTik โดยบริการหลักคือหน้าเว็บ แต่เราสามารถใช้กับบริการอื่น เช่น API ด้วยเช่นกัน คำสั่งตั้งค่าเว็บให้เป็น HTTPS เป็น

$router /ip service set www-ssl certificate=fullchain.cer_0

ตัวบริการ www-ssl นี้ค่าเริ่มต้นบน MikroTik ไม่ได้เปิดใช้งานไว้ อาจจะต้องไปเปิดใช้งานเองก่อน

No Description

หากเราตั้งฟิลด์ A ของโดเมนไว้ตรงกับไอพีของเราท์เตอร์เราแล้ว เราจะพบว่าเราสามารถใช้งานเราท์เตอร์ผ่านทาง HTTPS ได้แล้ว

การขอใบรับรองจาก Let's Encrypt นั้นหลังจากขอครั้งแรกแล้ว acme.sh จะตั้ง cron สำหรับขอต่ออายุใบรับรองโดยอัตโนมัติ เราควรนำคำสั่งสำหรับติดตั้งใบรับรองเข้าไปยัง MikroTik ไปเขียนเป็นสคริปต์รันใน cron ล้อไปพร้อมกันเพื่อให้เราท์เตอร์มีใบรับรองใหม่เสมอเช่นกัน

ส่งท้าย

บทความนี้แสดงให้เห็นว่าเราสามารถทำให้การเชื่อมต่อกับบริการต่างๆ ภายในเน็ตเวิร์คของเราเองเป็น HTTPS ได้แล้วในยุคนี้ แม้การใช้งานตามบ้านอาจจะเกินความจำเป็นไปบ้างเนื่องจากความเสี่ยงที่จะถูกดักฟังหรือถูกคั่นกลางการเชื่อมต่อ (man-in-the-middle) นั้นค่อนข้างต่ำ แต่ในเน็ตเวิร์คที่มีขนาดใหญ่ขึ้นเช่นเน็ตเวิร์คระดับองค์กร ความเสี่ยงเหล่านี้เพิ่มขึ้นเป็นเงาตามตัว และการทำให้บริการทั้งหมดเป็น HTTPS ก็ช่วยให้ผู้ใช้ในองค์กรไม่ชินกับการเข้าเว็บไม่เข้ารหัส หรือเว็บที่ใช้ใบรับรองไม่ถูกต้องได้

บริการ DNS เช่น Hurricane Electric นั้นช่วยลดความยุ่งยากในการตั้งเซิร์ฟเวอร์ DNS ด้วยตัวเอง และหากในอนาคตไคลเอนต์ของ Let's Encrypt รองรับฟีเจอร์เต็มรูปแบบแล้ว องค์กรอาจจะสามารถกระจายความรับผิดชอบให้ผู้ดูแลเซิร์ฟเวอร์แต่ละตัวสามารถตั้งค่าไอพีด้วยตัวเองและขอใบรับรองเข้ารหัสด้วยตัวเอง โดยใช้โทเค็นสำหรับ Dynamic DNS ทำให้ไม่ต้องแชร์รหัสผ่านกันแต่อย่างใด

Get latest news from Blognone

Comments

By: hisoft
ContributorWindows PhoneWindows
on 11 May 2021 - 04:31 #1208604
hisoft's picture

ตอนนี้มี remote เข้าบ้านแค่ Home Assistant โชคดีที่มันทำ DuckDNS + Let's Encrypt บน IPv6 อัตโนมัติได้เลย

ส่วน THDDNS ของ AIS เองทำใบรับรอง Let's Encrypt ไม่ผ่าน 😩

By: lew
FounderJusci's WriterMEconomicsAndroid
on 11 May 2021 - 11:29 #1208619 Reply to:1208604
lew's picture

สคริปต์น่าจะคล้ายๆ กันนี่ล่ะครับ

แอบเซ็งๆ อยู่ที่ MikroTik ไม่รองรับในตัวแบบนี้


lewcpe.com, @wasonliw

By: big50000
AndroidSUSEUbuntu
on 12 May 2021 - 15:16 #1208805 Reply to:1208604
big50000's picture

ของผมทำแบบบรรลัยโลกว่า ยิง DuckDNS ไป GCP แล้วขอ cert จากทางนั้น แล้วดาวน์โหลดกลับมาเก็บไว้ที่บ้านแล้วโยง DuckDNS กลับมาที่บ้านเหมือนเดิม 55555

By: hisoft
ContributorWindows PhoneWindows
on 12 May 2021 - 15:58 #1208811 Reply to:1208805
hisoft's picture

มีข้อดียังไงบ้างครับ ขายบ้างๆ

By: big50000
AndroidSUSEUbuntu
on 13 May 2021 - 16:32 #1208909 Reply to:1208811
big50000's picture

จริง ๆ วิธีนี้ค่อนข้างยุ่งยากนะ แต่เป็นเพราะ 3BB ปิดพอร์ต 80 และ 443 (ซึ่งก็รู้ ๆ กันว่าเพราะอะไร) มันเป็นวิธีเดียวที่ผมจะขอ cert ได้ ตอนนี้ผมกำลังนึกหาวิธี automate อยู่ แต่ต้องศึกษา API ของ DuckDNS ถึงจะเริ่มทำได้ ตอนนี้ก็ setup แบบ manual ไปก่อน

ข้อดีอย่างเดียวเลยคือ มันหลบพอร์ต 3BB ได้ 555555 (ผมใช้แค่ไว้เปิด API กับ WebSocket)

By: hisoft
ContributorWindows PhoneWindows
on 13 May 2021 - 17:37 #1208916 Reply to:1208909
hisoft's picture

ขอบคุณครับ

By: lew
FounderJusci's WriterMEconomicsAndroid
on 13 May 2021 - 11:43 #1208884 Reply to:1208805
lew's picture

ผมภายในก็แบบนี้นะครับ มีตัวขอ cert ทุกชื่อที่เดียว แล้วค่อยกระจายข้างใน


lewcpe.com, @wasonliw

By: phoenix298 on 11 May 2021 - 08:35 #1208610

Microtik -> Mikrotik

By: Ford AntiTrust
ContributorAndroidBlackberryUbuntu
on 11 May 2021 - 11:03 #1208617
Ford AntiTrust's picture

ผมลดความยุ่งยากด้วยการซื้อ certificate ตัวถูก ๆ ที่ใช้การ validate ผ่านอีเมล หรือ DNS แล้วมีอายุ 1 ปีแทน 😅

By: lew
FounderJusci's WriterMEconomicsAndroid
on 11 May 2021 - 11:38 #1208620 Reply to:1208617
lew's picture

ปีละรอบก็ไม่ไหวแฮะ ใช้ไม่บ่อยแล้วมันลืม ยุ่งยาก


lewcpe.com, @wasonliw

By: SilentHeal
AndroidUbuntuWindowsIn Love
on 11 May 2021 - 17:20 #1208681 Reply to:1208617
SilentHeal's picture

ใช้ของ cloudflare เลยได้รึเปล่าครับ มันให้มาตั้ง 15 ปี

By: Ford AntiTrust
ContributorAndroidBlackberryUbuntu
on 13 May 2021 - 09:08 #1208864 Reply to:1208681
Ford AntiTrust's picture

ตอนนี้ certificate ขอทีใช้ได้แค่ 1 ปีนิดๆ ครับ ยังไงก็ต้องเปลี่ยนทุกปีอยู่แล้ว

By: btoy
ContributorAndroidWindows
on 11 May 2021 - 12:55 #1208641
btoy's picture

thanks for a great article krub :)


..: เรื่อยไป

By: teenigma
AndroidRed HatWindows
on 11 May 2021 - 19:26 #1208698

DNS A record ผมใช้ script ในเว็บ Mikrotik เลยครับ
แล้วตั้ง Scheduler ไว้ให้ทำงานทุกๆ 10 นาที

Dynamic DNS Update Script for Hurricane Electric DNS

By: lew
FounderJusci's WriterMEconomicsAndroid
on 12 May 2021 - 00:38 #1208714 Reply to:1208698
lew's picture

เสียดายตัวสคริปต์ของ MikroTik มันจำกัดมาก ไม่งั้นใส่ acme.sh ลงไปให้มันขอ cert ในตัวเลยจะเนียนกว่านี้มาก


lewcpe.com, @wasonliw