Tutorial

5 วิธีการทำให้ SSH ของคุณ "แข็ง(แกร่ง) อึด ทน"

By Arnon Puitrakul - 18 ตุลาคม 2024

5 วิธีการทำให้ SSH ของคุณ "แข็ง(แกร่ง) อึด ทน"

SSH น่าจะเป็น Protocol ที่หลาย ๆ คนใช้ในการเข้าถึง Shell ของเครื่องปลายทาง สำหรับควบคุมการทำงานของเครื่องคอมพิวเตอร์ต่าง ๆ แต่มันไม่น่าจะดีเท่าไหร่ หาก SSH Server ไม่แข็งแกร่งมากเพียงพอ วันนี้เราจะมาแนะนำ 5 วิธีการที่จะช่วยลด Attack Surface ของ SSH Server ในเครื่องของเรากัน

1. Disable Root Login

Root เรียกว่าเป็น Daddy ของ User ทั้งปวง มาพร้อมกับพลังอำนาจมหาศาล แต่มันก็มาพร้อมกับความรับผิดชอบอันใหญ่ยิ่งด้วยเช่นกัน เราคงไม่อยากให้พลังอำนาจขนาดนี้ไปตกอยู่ในมือของคนที่ไม่ควรจะมีใช่มะ เพื่อป้องกันไม่ให้มันเกิดขึ้น เราจำเป็นที่จะต้องปิด ไม่ให้ใครก็ตาม SSH เข้ามาด้วย Root User ได้

sudo vim /etc/ssh/sshd_config

เราสามารถเข้าไปแก้ไข Config File ที่อยู่ด้านบนนี้ได้เลย

PermitRootLogin no

ให้เรามองหาบรรทัดที่เขียนว่า PermitRootLogin จากเดิมมันจะเป็น yes ให้เราเปลี่ยนเป็น no ซะ เท่านี้ เราก็จะไม่สามารถ Login ผ่าน Root User ได้แล้ว

หากเราต้องการทำงานที่ต้องใช้ Superuser เราก็แค่ใช้ Sudo เท่านั้น หรือถ้าเราต้องการเข้าถึง Root จริง ๆ เราก็แค่ใช้ User พร้อม Sudo เข้าไปแก้ SSH Config อนุญาติให้ Login ผ่าน Root ได้อีกครั้งก็จบ หรือ ถ้าเราสามารถเข้าถึง Physical Machine ได้ก็เข้าได้อยู่แล้ว

2. Limit Maximum Number of Authentication Attempts

Brute Force เป็นอีกหนึ่งการโจมตีที่สามารถใช้เล่นได้ ดังนั้น เพื่อป้องกันไม่ให้ Brute Force Flood เข้ามารัว ๆ และสามารถเข้าถึงเครื่องของเราได้ เราสามารถกำหนด จำนวนครั้งที่สามารถยืนยันตัวตนได้ เช่น เซ็ตไว้ 3 ครั้งคือ ผู้ใช้นั้นสามารถใส่ Credential ผิดได้ 3 ครั้งก่อนมันจะล๊อคผู้ใช้นั้นไปเลย

MaxAuthTries 6

เราสามารถเข้าไปที่ Config File ก่อนหน้านี้ และใส่ MaxAuthTries เข้าไปตามด้วยจำนวนครั้งที่อนุญาติให้ยืนยันตัวตนได้ โดยพื้นฐานจะใช้ประมาณ 6 ครั้ง แต่เราสามารถปรับขึ้นลงตามความเสี่ยงที่เราประเมินได้ หากเราประเมินว่ามันมีการยิงเข้ามาเยอะมาก เราอาจจะปรับจำนวนครั้งลงไปหน่อย เหลือสัก 3 เพื่อให้มันเริ่ม Block เร็วขึ้นได้

PermitEmptyPasswords no

อันนี้เราขอเติมมาหน่อย เผื่อเครื่องใครใช้งานหลายคนแล้วมีไอ้งั่งไปสร้าง User ที่ไม่มี Password เราจะต้องปิดไม่อนุญาติให้ Authenticate โดยไม่มี Password ซะเลย ไม่งั้นหาก Brute Force เจอ ก็คือเกมส์เลยนะ

3. Reduce Login Grace Period

นอกจากการที่เราจะป้องกันไม่ให้ Brute Force ยิงเข้ามา มันจะมีช่วงเวลาที่เราเริ่ม Login แต่เราอาจจะยังไม่ใส่ Password หรือให้ Credential ผิดอะไรก็ตาม ตัว SSH Server มันควรที่จะมีเวลา Timeout ว่า หากเรายังไม่สามารถใส่ Credential ที่ถูกต้องในเวลาที่กำหนด

เพราะว่า ถ้าเราไม่เซ็ตเวลาตรงนี้ไว้ แล้วเราปล่อยให้คนที่ยังแม้แต่จะให้ Credential ที่ไม่ถูกต้องเชื่อมต่อกับ Server ของเราคาไว้นาน ๆ ย่อมเพิ่มโอกาสที่เขาอาจจะใช้วิธีการเช่น Script-Upload เพื่อเข้าถึง Server ของเราได้ ดังนั้น การจำกัดเวลานี้ให้น้อยที่สุดก็จะช่วยลดโอกาสที่จะทำได้ทัน

LoginGraceTime 2m

การตั้งค่านี้จะอยู่ในตัวเลือกที่ชื่อว่า LoginGraceTime โดยค่าพื้นฐานมันจะเซ็ตไว้ให้เรา 2 นาทีด้วยกัน โดยเราสามารถใส่ให้มันเร็วกว่านี้ได้ เช่น เราเองเราจะใส่ 30 เฉย ๆ หมายถึง 30 วินาที เผลอ ๆ หากเราใช้ Key-Based Authentication เราสามารถใส่ให้มันสั้นกว่านี้ได้อีกเยอะเลยละ ลดโอกาสที่จะโดน Side Script ยิงเข้ามามหาศาล

4. Use Key-Based Authentication

อีกวิธีการที่ทำได้คือ แทนที่เราจะใช้ Password Authentication ที่สามารถโดนยิง Brute Force ได้ง่าย เราทำให้ชีวิตพวกมันยากขึ้นด้วยการเปลี่ยนมาใช้ Key-Based Authentication ดีกว่า เราแค่จัดการ Generate Key ไว้ในเครื่องเราและโยน Key ลงไปใน SSH Server เรา เวลาเราจะ Authenticate เข้าใช้งาน เราแค่ Authenticate ด้วย Key ที่เรามีในเครื่อง ทำให้การที่จะโดนยิง Brute Force เพื่อหวังเจอ Password สำหรับเข้าเครื่องมันก็จะยากกว่าเดิมมาก ๆ

PasswordAuthentication no

และเพื่อป้องกันไม่ให้เราโดนยิง Brute Force สำหรับการเดา Password ได้ ไหน ๆ เราไม่ได้ใช้งาน Password Authentication แล้ว ก็ปิดมันไปซะสิ ไม่ใช้ก็ปิด ลด Attack Surface ได้มหาศาล

5. Restricting non-shell User

สำหรับบางเครื่อง อาจจะมีการสร้าง User สำหรับให้ App บางตัวใช้ สำหรับการกำหนดสิทธิ์การเข้าถึงบางอย่าง ซึ่งแน่นอนว่า User พวกนี้ เราไม่ได้สร้างมาเพื่อให้มัน SSH เข้ามาแน่นอน ดังนั้น เหมือนเดิมคือ ไม่ใช้ เราก็ปิดมันซะเลย

sudo usermod --shell /usr/sbin/nologin docker

เราสามารถใช้ Usermod โยน User นั้น ๆ เข้าไปใน Group nologin เท่านี้ก็เรียบร้อยแล้ว ถึงจะรู้ Username แต่ยังไง ก็เข้าไม่ได้ เพราะเราปิดไม่ให้ Login นั่นเอง ถึงจะอยู่หน้าเครื่องก็ไม่ได้เช่นกัน

ทำไมเราไม่เปลี่ยน Port SSH ละ ?

หลาย ๆ คนที่เคยผ่านประสบการณ์มา อ่านถึงตอนนี้แล้วอาจจะเอ๊ะว่า ทำไมใน 5 วิธีการที่เราเล่ามานั้นมันไม่มีวิธีการที่ง่ายที่สุดอย่างการเปลี่ยน Port สำหรับ SSH Service ละ เพราะมันน่าจะทำให้ปลอดภัยขึ้นได้

เราเรียกการซ่อน Port ลักษณะนี้ว่า Security through obscurity (STO) หรือก็คือการที่เราซ่อนข้อมูลบางอย่างเพื่อเพิ่มความปลอดภัย หรือถ้าพูดเป็นสำนวนภาษาอังกฤษคือ Hiding in the plain sight ด้วยวิธีการนี้ มันทำให้คนที่เขาต้องการเข้ามาหาอะไรบางอย่างจากเรา หาเจ้าสิ่งนั้นได้ยาก เช่นถ้าเราจะซ่อนเงิน(เมีย) หากเราเอาไปซ่อนในตู้เซฟ โจรเข้า มันก็เดาได้ว่า เงินหรือทรัพย์สินมันต้องอยู่ในเซฟแน่ ๆ มันก็จะเอาเซฟไป แต่ถ้าเราใช้หลักการนี้คือ เราก็เอาเงินไปแบ่งซ่อนตามหนังสือหน้าต่าง ๆ โอกาสที่โจรจะคิดไปหาในหนังสือมันย่อมน้อยกว่าการหาในเซฟแน่นอน (แกดูน้าค่อมเป็นตัวอย่างดิ ไอดอลเลยคนนี้) นี่แหละคือหลักการที่เราใช้สำหรับการซ่อนพวก Service Port ต่าง ๆ โดยการเปลี่ยนจาก Default Port เป็น Port อะไรสักอย่าง เพื่อซ่อนตัวจากผู้ที่ต้องการเข้าหา Service นั้น ๆ

แต่เชื่อมั้ยว่า สุดท้าย Port ที่เราเปลี่ยนเพื่อซ่อนนี้ มันสามารถหาเจอได้ง่าย ๆ เลยแหละ มันทำได้โดยการ Scan Port ของ Address ของเราอย่างละเอียด ก็ใช้เวลาต่อ Host ไม่นานเท่าไหร่หรอก ทำให้ส่วนตัวเรา ไม่แนะนำวิธีการนี้สักเท่าไหร่ เราคิดว่า มันช่วยได้เมื่อเครื่องของเราอยู่ในพวก Cloud ทั้งหลายแล้ว Expose ออกผ่าน Public IP ของ Cloud Provider ซึ่งมันจะมีคนที่เอา IP Range มาแล้วยิง Port Scan รัว ๆ หากเจอมันก็จะเริ่ม Brute Force ทันที อย่างน้อยที่สุด แมร่งกิน CPU Time และ Network Traffic ของเครื่องเราแน่นอน เสียเงินกันชิบหาย

นอกจากนั้น หากเรามีเครื่องหลายเครื่อง เราจะเปลี่ยนแยกกันคนละ Port หมดเลยมั้ยอะ ถ้าเราทำหมดนั่น มันเพิ่มความซับซ้อนในการใช้งานอีกมหาศาล เราต้องมานั่งจำอีกเหรอว่า เครื่องนี้ เราทำ SSH ไว้ที่ Port ไหนกันนะ มันดูจะเป็นเรื่องตลกเกินไปหน่อย

ดังนั้นสุดท้ายแล้ว ถึงเราจะซ่อนไปเท่าไหร่ มันก็หาเจอได้ไม่ยากขนาดนั้น และสร้างความยุ่งยากในการทำงานเข้าไปอีก เราเลยไม่ค่อยอย่างแนะนำวิธีการนี้เท่าไหร่

ทั้งหมดนี้เป็นเพียงเบื้องต้นเท่านั้น ยังมีอีกหลายวิธีที่ทำได้

ทั้งหมดที่เราเล่ามา เป็นเพียงแค่การตั้งค่าภายใน SSH Service ของเราเท่านั้น แต่จริง ๆ แล้วการ Harden Security ของ SSH Service เราสามารถทำได้มากกว่านี้อีก ตั้งแต่การใช้ Firewall เข้ามาดัก Connection ที่ไม่สมควรจะเข้าถึง SSH ได้แต่แรก หรือกระทั่งการการใช้ 2-Factor Authentication แต่สุดท้าย ไม่ว่าจะเป็นวิธีการใด ๆ ก็ตาม หลักการมันเหมือนเดิมคือ เราพยายามลด Attack Surface ของมันให้ได้มากที่สุด โดยการไม่ใช้อะไรก็ปิด เปิดแค่ที่ต้องใช้พอแล้วแค่นี้เลย

ไว้วันหลังจะมาเล่าวิธีการใช้ fail2ban ในการงัดกับพวก Brute Force Attack อีกทีเด้อ ใส่ไว้นี้เลย มันยาวเกิ้น (จริง ๆ ไม่มี Content จะเขียนแหละ แยกแมร่ง!)

Read Next...

จัดการเรื่องแต่ละมื้อ แต่ละเดย์ด้วย Obsidian

จัดการเรื่องแต่ละมื้อ แต่ละเดย์ด้วย Obsidian

Obsidian เป็นโปรแกรมสำหรับการจด Note ที่เรียกว่า สารพัดประโยชน์มาก ๆ เราสามารถเอามาทำอะไรได้เยอะมาก ๆ หนึ่งในสิ่งที่เราเอามาทำคือ นำมาใช้เป็นระบบสำหรับการจัดการ Todo List ในแต่ละวันของเรา ทำอะไรบ้าง วันนี้เราจะมาเล่าให้อ่านกันว่า เราจัดการะบบอย่างไร...

Loop แท้ไม่มีอยู่จริง มีแต่ความจริงซึ่งคนโง่ยอมรับไม่ได้

Loop แท้ไม่มีอยู่จริง มีแต่ความจริงซึ่งคนโง่ยอมรับไม่ได้

อะ อะจ๊ะเอ๋ตัวเอง เป็นยังไงบ้างละ เมื่อหลายเดือนก่อน เราไปเล่าเรื่องกันขำ ๆ ว่า ๆ จริง ๆ แล้วพวก Loop ที่เราใช้เขียนโปรแกรมกันอยู่ มันไม่มีอยู่จริง สิ่งที่เราใช้งานกันมันพยายาม Abstract บางอย่างออกไป วันนี้เราจะมาถอดการทำงานของ Loop จริง ๆ กันว่า มันทำงานอย่างไรกันแน่ ผ่านภาษา Assembly...

Monitor การทำงาน MySQL ด้วย Prometheus และ Grafana

Monitor การทำงาน MySQL ด้วย Prometheus และ Grafana

นอกจากการทำให้ Application รันได้แล้ว อีกเรื่องที่สำคัญไม่แพ้กันคือการวางระบบ Monitoring ที่ดี วันนี้เราจะมาแนะนำวิธีการ Monitor การทำงานของ MySQL ผ่านการสร้าง Dashboard บน Grafana กัน...

เสริมความ"แข็งแกร่ง" ให้ SSH ด้วย fail2ban

เสริมความ"แข็งแกร่ง" ให้ SSH ด้วย fail2ban

จากตอนที่แล้ว เราเล่าในเรื่องของการ Harden Security ของ SSH Service ของเราด้วยการปรับการตั้งค่าบางอย่างเพื่อลด Attack Surface ที่อาจจะเกิดขึ้นได้ หากใครยังไม่ได้อ่านก็ย้อนกลับไปอ่านกันก่อนเด้อ วันนี้เรามาเล่าวิธีการที่มัน Advance มากขึ้น อย่างการใช้ fail2ban...