มาจัดการกับ OpenSSH กันเถอะ 

         

     ไม่ได้เขียนบทความซะนานเลย  วันนี้พอมีเวลาบ้าง ก็เลยขอเขียนเรื่องนี้ซะเลย ท้าวความกันก่อน เนื่องจากมีสหายท่านหนึ่งได้โทรมาปรึกษา ว่าจะรู้ได้อย่างไรว่า server โดน hack แล้ว ผมก็เลยตอบไปว่า “เอาจริงๆนะ – ไม่รู้อ่ะ” แต่ว่า… มันก็มีวิธีการตรวจสอบเบื้องต้นอยู่ได้บ้างนะ ผมก็เลยลองซักถามเหตุการณ์ที่เกิดขึ้นก่อน ซึ่งสหายท่านนี้ได้พบว่า วันนี้เค้า ssh เข้าไปที่ server linux แล้ว มันดันถามเพื่อให้ save public key ใหม่ ซึ่งมันไม่น่าจะเกิดขึ้นเลย เพราะเมื่อวานยังเข้าได้ปกติ แปลก!!  ผมจึงแนะนำไปว่า ลองตรวจสอบเบื้องต้นอย่างง่ายๆ ก่อน เช่น

  • ตรวจสอบ file /etc/passwd ว่ามีการเพิ่มเติมหรือเปลี่ยนแปลงหรือไม่ 
  • ตรวจสอบ log system ว่ามี file ใดถูกเปลี่ยนแปลงแก้ไขหรือไม่(กรณีนี้อาจจะต้อง software ช่วย monitor อย่าง tripwire หรือ zapbix ต้องลงไว้ก่อนที่จะถูก hack นะ)

ซึ่งเมื่อตรวจสอบดูแล้ว เฮ้ย!! มี user ใหม่ถูกเพิ่มเข้ามาใน passwd จริงๆด้วย แล้ว file มันก็ถูกแก้ไขไปเมื่อตอนบ่ายวันนี้เอง เอาแล้วไง งั้นลองดูว่า user นั้นยังอยู่ในระบบหรือไม่

  • ใช้คำสั่ง who เพื่อดูว่า user นั่นยัง login อยู่  
  •  ลอง ps -ef |  grep ชื่อuser ดูว่าได้ทำการรัน process อะไรไว้ 
  •  ลองที่ /var/log/auth.log ไฟล์นี้จะเก็บการ authen ทุกครั้งที่มีการ login เข้า Linux  


ผลปรากฎว่า มี user ดังกล่าวพยายาม login ผ่าน port 22 หลายครั้ง ซึ่งก็สอดคล้องกับเหตุการณ์ที่มีการถามถึง Public key ใหม่ จึงเป็นไปได้ว่า น่าจะถูกยิง port 22 ที่เป็น ssh service

     OpenSSH เป็น open source ตัวหนึ่งที่ใช้ protocol SSH (secure shell) ในการติดต่อสื่อสารกันระหว่างหลายๆ application ไม่ว่าจะเป็น การใช้ remote file transfer อย่าง sftp, remote terminal ซึ่งการสื่อสารแบบนี้มีความปลอดภัยและเป็นส่วนตัวมากกว่าแบบธรรมดา โดยหลักการ SSH server จะใช้การตรวจสอบสิทธิแบบหนึ่งผ่าน Key pairing จะประกอบไปด้วย Public key ซึ่งเป็นตัวเข้ารหัส และ Private key ที่เป็นตัวเข้าถอดรหัส โดยกระบวนการจะเริ่มจาก Client จะร้องขอช่องทางการติดต่อไปยัง SSH server จากนั้น Server ก็จะทดสอบ Client ด้วยการส่งข้อความสุ่มที่เข้ารหัสโดย Public key มาให้ Client ทำการถอดรหัสด้วย Private key และจึงส่งข้อความที่ถอดรหัสแล้วไปให้ Server ตรวจสอบ ถ้าตรงกันก็จะอนุญาตให้ login ได้
     ** อย่างไรก็ตาม OpenSSH นั้นก็มีช่องโหว่ที่ถูกค้นพบจากฟีเจอร์ Roaming ที่เป็นการ resume connection ทำให้ hacker สามารถขโมย private key จากเครื่อง Client ได้ ช่องโหว่ถูกพบใน OpenSSH เวอร์ชั่น 5.4 - 7.1 **

     ซึ่งวันนี้เรามี 21 วิธีเพิ่มความปลอดภัยให้กับ OpenSSH มากขึ้น เริ่มจากมารู้จัก Default Config File และ SSH Port กันก่อน

  • /etc/ssh/sshd_config — Server configuration file
  • /etc/ssh/ssh_config — Client configuration file
  • ~/.ssh/ — Users SSH configuration file
  • ~/.ssh/authorized_keys — Public keys list(RSA หรือ DSA)
  • /etc/nologin — ถ้ามี file นี้อยู่ sushi จะไม่อนุญาตให้ใคร loing ยกเว้น root
  • /etc/hosts.allow และ /etc/hosts.deny เป็น Access controls list
  • SSH default port : 22

     ~มาเริ่มกันเลย~

1. ปิด SSHD — ถ้าเครื่องของคุณเป็นแค่ workstation หรือ laptop ก็ไม่มีความจำเป็นต้องเปิด OpenSSH server หรือไม่ต้องการให้ใคร remote เข้ามา งั้นก็ขอให้ปิดมันไปเลย โดย CentOS/ RHEL / Fedora Linux ใช้คำสั่ง Yum ในการ remove SSHD ออกจากเครื่องได้เลย

Command:

# chkconfig sshd off
# yum erase openssh-server

Dabian / Ubuntu Linux ใช้คำสั่ง

Command:

# apt-get remove openssh-server

2. ใช้ SSH Protocol version 2 — ใน version 1 นั้นมีปัญหาเรื่องการโจมตีแบบ man-in-the-middle และช่องโหว่เรื่อง security , เปิด file sshd_config แล้วดูให้แน่ใจว่าที่เป็น Protocol 2

3. จำกัดการเข้าใช้งาน SSH — โดยปกติแล้ว ทุก user account ที่มีอยู่ในระบบสามารถ login ผ่าน SSH ได้โดยใช้ password หรือ public key เมื่อเราสร้าง user บนระบบเพื่อจะใช้แค่ email หรือ ftp มันก็สามารถนำมาใช้ login ผ่าน ssh ได้เหมือนกัน ดังนั้นเราจึงต้องกำหนดเฉพาะ user ที่อนุญาตให้เข้าผ่าน ssh ได้ โดยไปที่ sshd_config ไฟล์แล้ว เพิ่มเฉพาะ user ที่ต้องการหลัง AllowUsers เช่น

AllowUsers root admin crazy

จะมีเฉพาะ root admin และ crazy เท่านั้นที่สามารถ login ssh ได้ หรืออีกวิธีคือ สามารถให้ทุก user เข้าได้ยกเว้นบาง user โดยใส่ user ที่ไม่ต้องการไว้หลัง DenyUsers เช่น

DenyUsers bumbu april fool

bumbu april และ fool จะ login ssh ไม่ได้ นอกนั้นได้หมด

4. Configure Idle Log Out Timeout interval — หลังจากที่ user ssh เข้ามาแล้ว session นั้นจะคงอยู่ตลอดไปจนกว่าจะ log out ออกไปหรือถูก terminate ออก เพื่อหลีกเลี่ยง seesion ที่ค้างอยู่หลังจากเลิกใช้งานแล้ว เราสามารถ config เวลาได้โดยไปที่ sshd_config ไฟล์แล้วตั้งค่าเวลา(วินาที) ที่ ClientAliveInterval 300 ในที่นี้หมายถึง ถ้า session ไม่ถูกใช้งานภายใน 300 วินาที session นี้จะถูกเตะออกจากระบบทันที

5. Disable .rhosts Files — rsh เป็นการใช้งานที่ไม่ปลอดภัย เพื่อไม่ให้มีการอ่าน ~/.rhosts และ ~/.shosts ให้เข้าไปแก้ไข sshd_config โดยแก้เป็น IgnoreRhosts yes

6. Disable Host-Based Authentication — เข้าไปที่ sshd_config แล้วแก้ HostbasedAuthentication no

7. Disable root Login ผ่าน SSH — ไม่มีความจำเป็นที่จะใช้ root ในการ login ข้าม network ซึ่งแค่เพียง user ธรรมดาก็สามารถใช้ sudo หรือ su ในการได้สิทธิของ root มา และมันทำให้รู้ด้วยว่า “ใคร” เข้ามาใช้งานหรือเข้ามารันอะไรผ่าน sudo ป้องกันการ login ด้วย root โดยไปที่ sshd_config แล้วแก้ PermitRootLogin no

8. เปิดใช้ Warning Banner — เข้าไปแก้ไข sshd_config แล้วแก้เป็น Banner /etc/issue

9. Firewall SSH Port 22 —อัพเดท iptables หรือ firewall configuration เพื่อให้ OpenSSH server อนุญาตเฉพาะ ip ที่กำหนดเท่านั้น ตัวอย่าง ใช้ Netfilter (Iptables) Configuration แก้ไข /etc/sysconfig/iptables ใน RedHat เพื่ออนุญาตการเชื่อมต่อระหว่าง 192.168.1.0/24 และ 202.54.1.5/29

-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -s 202.54.1.5/29 -m state --state NEW -p tcp --dport 22 -j ACCEPT

10. เปลี่ยน SSH port และ Limit IP binding — โดยปกติ SSH จะรับทุก interface และ IP ที่อยู่บนระบบ ทำการกำหนด port ในการเชื่อมต่อใหม่ (การโจมตีโดยใช้ script มักจะยิงไปที่ port 22) อย่างเช่น กำหนดให้ Listen ผ่าน 192.168.1.5 และ 202.54.1.5 ผ่าน port 300 ทำได้ดังนี้

Port 300
ListenAddress 192.168.1.5
ListenAddress 202.54.1.5

11. ใช้ Password และ Passphrase ที่ยากต่อการเดา — การโจมตีแบบ Brute force ใช้ได้ผลดีกับ password ที่มีคำอยู่ใน dictionary นี่เป็น script ที่ใช่ในการ random password เอาไปใช้ได้เลย

genpasswd() {
local l=$1
[ "$l" == "" ] && l=20
tr -dc A-Za-z0-9_ < /dev/urandom | head -c ${l} | xargs
}

Run:
genpasswd 16

Output:
uw8CnDVMwC6vOKgW

12. ใช้ Public key base Authentication — ใช้ public/private key ที่ถูกสร้างด้วยวิธีการ RSA หรือ DSA และมี passphrase ป้องกัน private key หากถูกขโมย ดูการ Configure RSA/DSA ได้ที่นี่

13. ใช้ Keychain Based Authentication — Keychain เป็นเทคนิคที่ใช้ script ในการเก็บ private key ที่สามารถมี passphrase ได้และยังสามารถใช้แบบ passphrase-free ได้โดยที่ยังความปลอดภัยให้กับ SSH อยู่ ดูวิธีการ Configure Keychain ได้ที่นี่

14. Chroot SSHD — จำกัดขอบเขตการเข้าถึง Directory ต่างๆของ User ไว้เฉพาะ Home Directory เท่านั้น ซึ่งโดยปกติ user ที่ ssh เข้ามาจะสามารถเข้าถึง directory ต่างๆได้เช่น /etc/ ,/bin/ ซึ่ง chroot จะไปสร้าง environment จำลองระบบ Linux ให้ user อยู่แค่เฉพาะใน home เท่านั้น

15. ใช้ TCP Wrappers — TCP Wrapper เป็น host-based Networking ACL ที่ใช้ทำ filter network address ซึ่ง OpenSSH สามาถใช้งาน TCP Wrapper ได้โดยใส่ ip ที่อนุญาตให้เข้า ssh ได้ที่ไฟล์ /etc/hosts.allow จากตัวอย่างต้องการให้เฉพาะ 192.168.1.2 และ 172.16.23.12 เข้า ssh ได้

sshd : 192.168.1.2 172.16.23.12

16. ยกเลิกการใช้ Empty Passwords — ไม่ควรอนุญาตให้ account ที่ไม่มี password เข้าใช้งาน ssh โดยสามารถไป configure ที่ sshd_config แล้วแก้เป็น PermitEmptyPasswords no

17. ป้องกัน SSH Cracker (โจมตีแบบ Brute Force) — การโจมตีแบบ Brute force เป็นการพยายามถอดรหัสโดยใช้ทุกรูปแบบที่เป็นไปได้จำนวนมากๆจาก computer เครื่องเดียว หรือเป็นกลุ่ม computer แบบเครือข่ายขนาดใหญ่ เราสามารถป้องกันการโจมตีแบบนี้ได้โดยใช้ software เหล่านี้

  • DenyHosts เป็น security tool ที่เขียนจาก Python สำหรับ SSH server ที่ทำขึ้นมาเพื่อป้องกันการโจมตีแบบ Brute force โดยเฉพาะ โดย tool นี้จะคอย monitor การพยายาม login ที่ไม่สำเร็จบ่อยๆ และจะทำการ block ip ที่พยายาม login เข้ามา
  • Fail2ban, sshguard-pf, sshguard-ipfw, sshguard-ipfilter, sshblock, sshit, BlockHosts, Blacklist, Brute Force Detection, IPQ BDB filter tool เหล่านี้มีไว้เพื่อป้องกัน Brute Force เช่นกัน


18. จำกัดจำนวนครั้งของ Connection Incoming Port 22 — ทั้ง netfilter และ pf สามารถจำกัดจำนวนครั้งในการพยายามติดต่อเข้ามาผ่าน port 22 ได้ จากตัวอย่างของ Iptables จำทการ drop incoming connection ที่มีการพยายาม 5 ครั้ง ใน 1 นาที
#!/bin/bash
inet_if=eth1
ssh_port=22
$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent --set
$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent --update --seconds 60 --hitcount 5 -j DROP

19. ใช้ Port knocking — Port knocking เป็นวิธีการเปิด port firewall โดยใช้การกำหนดลำดับการพยายาม connect ถ้าลำดับการ connect ตาม port ถูกต้อง firewall จะทำการ Allow host ที่ติดต่อเข้ามาลงใน iptable ให้สามารถ connect ผ่าน port 22 ได้ ตัวอย่างการใช้ Port Knocking

-N stage1
$IPT -A stage1 -m recent --remove --name knock
$IPT -A stage1 -p tcp --dport 3456 -m recent --set --name knock2

$IPT -N stage2
$IPT -A stage2 -m recent --remove --name knock2
$IPT -A stage2 -p tcp --dport 2345 -m recent --set --name heaven

$IPT -N door
$IPT -A door -m recent --rcheck --seconds 5 --name knock2 -j stage2
$IPT -A door -m recent --rcheck --seconds 5 --name knock -j stage1
$IPT -A door -p tcp --dport 1234 -m recent --set --name knock

$IPT -A INPUT -m --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 5 --name heaven -j ACCEPT
$IPT -A INPUT -p tcp --syn -j door

20. ใช้ Log Analyzer — ใช้ logwatch หรือ logcheck ในการอ่าน log ซึ่งจะทำให้ง่ายต่อการอ่าน log มากขึ้น อย่าลืม LogLevel ใน sshd_config เป็น INFO หรือ DEBUG

21. Patch OpenSSH หรือ OS — พยายาม update OpenSSH ให้เป็นเวอร์ชั่นล่าสุด หรืออัพเดท OS ให้ใหม่เสมอ เพราะเวอร์ชั่นใหม่ๆมักจะแก้ไขช่องโหว่ด้านความปลอดภัยให้ดีขึ้นแล้ว

ที่มา -- nixCraft

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

SSL VPN Windows 2008 server R2

การติดตั้ง OpenERP 7.0 อย่างง่าย บน Ubuntu Server 12.10