By Arnon Puitrakul - 17 พฤษภาคม 2023
สำหรับหลาย ๆ คนที่ทำงานในคอมพิวเตอร์เยอะ ๆ น่าจะต้องผ่านการใช้งานพวก Secure Shell มาไม่มากก็น้อย เอาว่าบางคนยังไม่รู้เลยว่า SSH และ Secure Shell คือเรื่องเดียวกัน พีคนะ เป็นของที่ Common มาก ๆ แต่คนเข้าใจมันน้อยมาก ๆ วันนี้เราจะมาเล่าเรื่องของ SSH กันดีกว่ากว่า มันทำงานยังไง
ก่อนเราจะไปเข้าใจตัว SSH เรามาทำให้เห็นความสำคัญกันก่อนว่า ถ้าวันนี้เราไม่มี SSH เราจะเกิดอะไรขึ้นกับวงการคอมพิวเตอร์บ้าง
ถ้าเราไม่มี SSH เลย แต่เราก็ยังคงจำเป็นต้องควบคุมเครื่องคอมพิวเตอร์ระยะไกล เข้าถึง Shell ของเครื่องอยู่ เราก็จะต้องเข้าถึง Shell ของเครื่องตรง ๆ เลยคือ ไม่มีการเข้ารหัสอะไรทั้งนั้น หลักการมันจะง่ายมาก ๆ คือ เราก็ส่งคำสั่งไปที่ปลายทางตรง ๆ เมื่อได้รับ มันก็แค่ทำตาม แล้วส่งผลกลับไปให้ต้นทางเท่านั้นเอง เห้ยดูเป็นอะไรที่ง่ายตรง ๆ เนอะ
แต่ถ้าเราคิดดี ๆ มีผู้ไม่หวังดีมาเสียบตรงกลางเกิด MITM ขึ้นมา อย่างแรกคือ เราสามารถที่จะอ่านได้หมดเลยนะว่า คำสั่งที่เราสั่งไปคืออะไร และ ผลลัพธ์ที่ได้คืออะไร ทำให้เขาพอจะเดา หรือหาช่องโหว่ได้สบาย ๆ เลยนะ หนักกว่านั้นสามารถทำ Session Hijacking เข้ามาปลอมเป็นเรา แล้วสั่งเครื่องได้อีก เราว่า ไม่น่าจะเป็นเรื่องสนุกสำหรับทุก ๆ คนเลยเนอะ
หรือถ้าเราบอกว่า โอเค ถ้าเราไม่มี SSH แล้ว การส่งข้อมูลแบบไม่ปลอดภัยมันก็ไม่ดี งั้นเราก็ไม่เข้าถึงเครื่องระยะไกลเลย เราเอาหน้าจอเสียบ เอา Keyboard เสียบแล้วทำงานเลย ถามว่าได้มั้ย มันก็ได้แหละ มีเครื่องเยอะแยะที่ไม่ได้เปิด SSH เอาไว้ แต่สำหรับบางเคส เช่น Server Farm ใหญ่ ๆ มีเครื่องสักแสนเครื่อง ถ้าจะให้เอาจอ กับ Keyboard ไปจิ้มทีละเครื่องที่เราต้องการ Config ที เราว่า ไม่น่าจะสนุกนะ Deploy Config ทีไม่ใช้เวลาหลายสิบชั่วโมง กับคนหลักร้อยคนเลยเหรอ
ดังนั้นการเกิดขึ้นของ SSH เป็นเรื่องที่มี Impact มาก ๆ กับการใช้งานคอมพิวเตอร์ในปัจุบันมาก ๆ นอกจากที่จะทำให้เราสามารถเข้าถึง Shell ของเครื่องปลายทางได้อย่างปลอดภัยแล้ว มันทำให้เราสามารถที่จะจัดการเครื่องได้ง่ายขึ้นอย่างไม่น่าเชื่อเลยละ ทุกวันนี้ เราก็ใช้งานกันเยอะมาก ๆ เช่น เราเปิด Instance บน Cloud ขึ้นมาสักตัว เราก็คงไม่ต้องนั่งเครื่องบินไป Singapore เพื่อเอาจอและ Keyboard ต่อแน่ ๆ เราก็ SSH เข้าไป ไม่ก็ KVM เอา
เมื่อปัญหาเกิดจากการที่มันสามารถที่จะโดน Sniff ว่า เราส่งคำสั่งอะไรไป และ เครื่องปลายทางส่งอะไรกลับมา งั้นเราก็เข้ารหัสมันเลยมั้ย ใช่แล้ว นี่แหละ คือเบื้องหลังของ SSH เลย
OpenSSH_9.0p1, LibreSSL 3.3.6
debug1: Reading configuration data /Users/arnonpuitrakul/.ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 21: include /etc/ssh/ssh_config.d/* matched no files
debug1: /etc/ssh/ssh_config line 54: Applying options for *
debug1: Authenticator provider $SSH_SK_PROVIDER did not resolve; disabling
debug1: Connecting to 192.168.88.196 [192.168.88.196] port 22.
debug1: Connection established.
ถ้าเราลอง Verbose Mode ให้มันพ่น Log ออกมาเลย อันนี้เป็น Log จากฝั่ง Client ที่เราเรียก SSH ไปที่ Server จะเห็นว่า ในช่วงแรก เครื่องมันพยายามที่จะอ่านก่อนว่า เรามี Config อะไรที่มันจะต้องทำตามก่อนที่จะเชื่อมต่อมั้ย และ 2 บรรทัดสุดท้าย มันก็จะพยายามเชื่อมต่อไปที่ปลายทาง และ สุดท้าย มันก็จะบอกว่า การเชื่อมต่อสำเร็จละ
ถ้าเราลอง Package Sniffing ผ่าน Wireshark ออกมาดู เรา Filter เฉพาะ SSH Protocol เท่านั้น เราจะเห็นว่า ใน 2 Packet แรก คือ เราทัก Server ไปบอกว่า เห้ยนาย ๆ เราใช้ SSH Protocol ตัวนี้นะ และ Server ก็ตอบกลับใน Packet ที่ 2 ว่า โอเคนาย ๆ ส่วนเราใช้ SSH Protocol ตัวนี้ ๆ นะ
debug1: Local version string SSH-2.0-OpenSSH_9.0
debug1: Remote protocol version 2.0, remote software version OpenSSH_8.9p1 Ubuntu-3ubuntu0.1
debug1: compat_banner: match: OpenSSH_8.9p1 Ubuntu-3ubuntu0.1 pat OpenSSH* compat 0x04000000
ซึ่งมันก็คือ Log ตรงนี้แหละ สุดท้าย เครื่องเราก็จะเช็คว่า เรา และ Server เข้ากันได้มั้ย ผ่านสิ่งที่เรียกว่า compat_banner ถ้าเราเข้ากันได้ เราก็จะดำเนินการต่อได้เลย
debug1: Authenticating to 192.168.88.196:22 as 'arnonpuitrakul'
เมื่อเราเชื่อมต่อกันได้ และ เราเข้ากันได้ คุยภาษาเดียวกันแล้ว ถัดไปคือ เราพยายามที่จะ Authenticate ละ แต่ถ้าเราพยายามจะทำแบบนั้นเลย แล้วมีการส่ง Private Key กันไปมา หรือ ส่ง Password ข้ามกัน มันจะไม่รอดแน่ ๆ
ดังนั้น เราจะต้อง Secure Connection ก่อน มันจะต้องมีวิธีการในการแลก Key กันใน Hostile Environment อย่างปลอดภัยใช่มะ สำหรับคนเรียน CS มา ก็เดาได้ไม่ยาก ก็คือใช้ Diffie-Hellman Key Exchange Method วิธีการจริง ๆ มันพื้นฐานมาก ไปทบทวนที่เรียนกันมาเนอะ ควรจะรู้ไว้ก็ดี มันใช้เยอะมาก ๆ สุดท้ายแล้ว เครื่องทั้งสองฝั่งก็จะได้ Common Key ตัวนึง เป็น Shared Secret Key อันนี้ไปอ่านเพิ่มเองเนอะ โต ๆ กันแล้ว
debug1: Authentications that can continue: publickey,password
debug1: Trying private key: /Users/arnonpuitrakul/.ssh/id_ed25519_sk
debug1: Trying private key: /Users/arnonpuitrakul/.ssh/id_xmss
debug1: Trying private key: /Users/arnonpuitrakul/.ssh/id_dsa
debug1: Next authentication method: password
[email protected]'s password:
Authenticated to 192.168.88.196 ([192.168.88.196]:22) using "password".
จากนั้น เราก็สามารถทำการ Authenticate ผ่าน Secured Connection ได้ละ มันก็จะเริ่มจากวิธีการแรกที่ง่ายสุดๆ คือ เราใช้ Private/Public Key ในการ Authenticate ก่อน เป็นวิธีที่เราแนะนำมาก ๆ แต่ในที่นี้เป็น Server ที่เราสร้างขึ้นมาเพื่อสาธิตให้ดูเลย เลือกเป็นวิธีต่อไปคือการใช้ Password มันก็จะ Prompt ให้เรากรอก Password เข้าไป เมื่อเรากรอกแล้ว มันก็จะส่ง Password ไปที่ Server ถ้าถูก Server ก็จะยืนยันกลับมาว่า Authenticated ก็ทำให้เราสามารถเข้าใช้ SSH ของ Server ปลายทางได้นั่นเอง
หลังจากที่เราทำการ Authenticate อะไรเรียบร้อย เข้าใช้งานแล้ว มันก็จะเป็นการคุยไปมา ระหว่างเครื่องเรา กับ Server ละ ความหวานเจี๊ยบ ถ้าเราลองดู Packet ที่มันคุยกัน ดึง Application Layer ออกมา เราจะเห็นว่า เราจะอ่านสิ่งที่มันคุยกันไม่รู้เรื่องเลย เพราะมันมีการเข้ารหัสไว้ จากขั้นตอนก่อนหน้านั่นเอง
ถามว่า แล้ว Packet ของมันจริง ๆ แล้วมันประกอบด้วยอะไรบ้างละ อันนี้เราเข้าไปอ่านในพวก Standard ได้นะ ตัวมัน จะมี Packet Length หรือความยาวของ Packet ตัวเอง, Padding Amount, Payload, Padding และ Message Authentication Code
ตัวแรก Pecket Length มันตรงตัวง่าย ๆ เลย คือ เป็นการบอกไปเลยว่า ความยาวของ Packet ที่จะใช้คุยกัน ทั้งหมดกี่ Byte เพื่อให้โปรแกรมสามารถดึงออกมาได้ตรง ๆ เลย จากนั้น มันจะมีของอยู่อีก 2 อย่างคือ Payload และ Message Authentication Code ซึ่งมันจะอยู่แยกกัน เพราะไม่งั้น เวลาอ่านมันจะยากมาก ๆ แล้วถ้าติดกัน อ่านยากเนอะ ต้องมานั่งไล่ว่า อันไหนคืออะไร เขาเลย มีตัวแยก เราเรียกว่า Padding ที่อยู่คั่น โดยที่ขนาดของ Padding ก็จะกำหนดโดย Padding Amount ที่คุยกันไว้ตอนแรกนั่นเอง
ซึ่งตรง Padding จริง ๆ มันจะเป็นอะไรก็ได้นะ จะสุ่ม ๆ ก็ได้เหมือนกัน เพื่อให้เวลาเราเข้ารหัสแล้ว มันจะออกมาดูยุ่งยากกว่าเดิม ทำให้ยากต่อการเดามากกว่าเดิมก็ทำได้เหมือนกัน หรือกระทั่ง การทำ Compression เพื่อให้ส่งข้อมูลได้เร็วมากขึ้น ก็สามารถทำได้ ขึ้นกับ Server และ เครื่องของเราตกลง Protocol กันในช่วงแรกมากกว่า
ส่วน Message Authentication Code จริง ๆ เป็นเหมือนตัว Checksum เพื่อยืนยันกันทั้งสองฝั่งว่า ไม่มีใครมาเปลี่ยนแปลงข้อมูลที่ส่งไปกลับกัน ไม่งั้น ถ้ามีคนกลางมาทำ MITM แล้วเปลี่ยนสมมุติว่า สถานะการใช้งานอะไรสักอย่างเป็นอีกอย่าง มันก็น่าจะยุ่งพอสมควรเลย ดังนั้น การใช้ กลไกนี้ก็เป็นการป้องกันทางหนึ่งเหมือนกัน
arnonpuitrakul@ssh-demo-server:~$ logout
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: client_input_channel_req: channel 0 rtype [email protected] reply 0
debug1: channel 0: free: client-session, nchannels 1
Connection to 192.168.88.196 closed.
Transferred: sent 3624, received 5156 bytes, in 4.6 seconds
Bytes per second: sent 779.9, received 1109.6
debug1: Exit status 0
สุดท้าย เมื่อเราสั่ง Logout ออกจาก Shell มันก็ต้องทำการ Teardown Connection ออกไปเนอะ เพราะระหว่างที่เราทำการเชื่อมต่อผ่าน SSH อยู่ มันจะต้องเปิด Connection ทิ้งไว้ พอเราใช้เสร็จเราก็ปิดแค่นั้นเอง (ถ้าอยากรู้ว่ามันเปิด Connection ไว้จริงมั้ยก็ใช้ netstat เช็คเอาได้)
Secure Shell (SSH) เป็น Protocol ที่ทำให้เราสามารถเชื่อมต่อ Shell ของเครื่องคอมพิวเตอร์ปลายทางอย่างปลอดภัยได้ ผ่านการเข้ารหัส ทำให้คนที่เข้ามาอยู่ตรงกลางเพื่อ Sniff ข้อมูลก็จะอ่านสิ่งที่ เราและ Server โต้ตอบกันได้ยากมาก ๆ (ไม่ได้บอกว่าทำไม่ได้นะ แค่ยากมาก ๆ) นั่นทำให้ SSH เลยถูกใช้อย่างกว้างขวางมาก ๆ ในวงการคอมพิวเตอร์ ถ้าไม่มีมัน นี่เราก็คิดไม่ออกเลยนะว่า เราจะใช้คอมพิวเตอร์ขนาดใหญ่ ๆ กันยังไง เสียบจอกับ Keyboard ก็ไม่ไหวนะ ฮ่า ๆ
เคยสงสัยกันมั้ยว่า Filter ที่เราใช้เบลอภาพ ไม่ว่าจะเพื่อความสวยงาม หรืออะไรก็ตาม แท้จริงแล้ว มันทำงานอย่างไร วันนี้เราจะพาไปดูคณิตศาสตร์และเทคนิคเบื้องหลังกันว่า กว่าที่รูปภาพจะถูกเบลอได้ มันเกิดจากอะไร...
หลังจากดูงาน Google I/O 2024 ที่ผ่านมา เรามาสะดุดเรื่องของการใส่ Watermark ลงไปใน Content ที่ Generate จาก AI วันนี้เราจะมาเล่าให้อ่านกันว่า วิธีการทำ Watermark ใน Content ทำอย่างไร...
ก่อนหน้านี้เราทำ Content เล่าความแตกต่างระหว่าง CPU, GPU และ NPU ทำให้เราเกิดคำถามขึ้นมาว่า เอาเข้าจริง เราจำเป็นต้องมี NPU อยู่ในตลาดจริง ๆ รึเปล่า หรือมันอาจจะเป็นแค่ Hardware ตัวนึงที่เข้ามาแล้วก็จากไปเท่านั้น วันนี้เราจะมาเล่าให้อ่านกัน...
บทความนี้ เราเขียนสำหรับมือใหม่ หรือคนที่ไม่ได้เรียนด้านนี้แต่อยากรู้ละกัน สำหรับวันนี้เรามาพูดถึงคำที่ถ้าเราทำงานกับพวก Developer เขาคุยกันบ่อย ๆ ใช้งานกันเยอะ ๆ อย่าง Database กันว่า มันคืออะไร ทำไมเราต้องใช้ และ เราจะมีตัวเลือกอะไรในการใช้งานบ้าง...