เอา ssh notification script ไปไว้ใน pam.d

Bank Eakasit
2 min readJun 25, 2019

--

เห็น tutorial login notification ส่วนมากจะเอา script ไปใส่ไว้ใน bash_profile ซะหมด ซึ่งมันขัดๆความรู้สึกยังไงก็ไม่รู้ คือมีกี่ user ก็ต้องเอา script นี้ไปใส่ bash_profile ของทุก user ที่ขัดที่สุดคือ bash_profile นี่มันก็โดน user คนนั้นแก้หรือลบทิ้งได้ ถูกไหมครับ ก็เลยจะมาเสนออีกวิธีที่(อาจจะ)ดีกว่า

ที่จริงผมเขียนขึ้นมาเพื่อจดบันทึกส่วนตัวด้วยแหละ ทำไว้หลายปีแล้ว ตอนนั้นเสียเวลาอ่านไปพอสมควร หลงๆลืมๆไปบ้างละ ถ้าไม่บันทึกอันนี้ไว้ เกิด server ล่ม disk พังขึ้นมา ต้องมาเริ่มใหม่หมดอีก ._.

ใน linux มันมี service อันหนึ่งครับ ที่เอาไว้ควบคุม authentication, session, login ต่างๆ คือ pam.d ซึ่งค่อนข้าง low level พอสมควร และการ config ผิด อาจจะทำให้เราไม่สามารถ login เข้า server เราได้ (พูดจริงนะ 555) ถ้าไม่แม่น linux command, config, permission ก็กดปิดหน้านี้ได้เลยครับ

ซึ่งรายละเอียดต่างๆ ผมคงไม่จำเป็นต้องแปลมาอีกรอบมั้ง

ส่วน pam.d ครอบคลุมอะไรบ้าง ก็ลองดูในเครื่องตัวเองเลยก็ได้ครับ

ls /etc/pam.d/

รูปนี้ของผมเป็น CentOS ส่วนของ Ubuntu รู้สึกจะมีน้อยกว่า เขาบอกว่าอะไรไม่มี ให้ยัดลง /etc/pam.conf แทนครับ

เป้าหมายของผม login noti ซึ่งก็คือ sshd นั่นเอง

ซึ่งมันก็มี config อะไรหลายๆอย่างอยู่แล้ว อย่าไปแตะมันนะครับ ส่วนของผมก็เพิ่มบรรทัดสุดท้ายเข้าไป (กรอบสีแดง)โดยให้เป็น

session — เพราะ script ของผมจะรันเมื่อ login เสร็จเท่านั้น ไม่ได้เกี่ยวกับขึ้นตอน authentication ใดๆoptional — เพราะถ้า script ของผมพัง หรือ return false ก็ให้ ignore ไปเลย. หากไปตั้ง required หรืออื่นๆ อาจจะมีปัญหาได้ หาก network ระหว่าง server-discord/line พัง อาจจะทำให้เรา login server ไม่ได้ซะงั้น ถ้า discord ล่มก็ไม่ได้ noti สิ ? ใช่ครับ เป็น tradeoff ไปpam_exec.so <my_script> — สำหรับบอกว่า config อันนี้คือ รัน script ของเราครับ ซึ่งของผมก็เป็น loginChecker.sh ที่ผมตั้ง permission ว่าเฉพาะ root ที่เข้าถึงได้เท่านั้น

ส่วนตัว script ของผมก็ไม่ได้ซับซ้อนอะไรครับ ที่จริงจะเป็นอะไรก็ได้เลย

#!/bin/bash

[ "$PAM_TYPE" = "open_session" ] || exit 0
# Your Line/Discord Noti script here
/usr/bin/curl -H "Content-Type: application/json" -H "Authorization: Bearer <token>" -X POST -d "{\"message\":\"Detected $PAM_USER login from $PAM_RHOST\"}" https://Your=Chat=Server.com &
exit 0

ก่อนอื่น ตัว session ของ pam.d มันคือทั้งตอน เข้า session และตอนออก session แต่เราไม่ได้ต้องการให้ script เรามันรันหลายรอบถูกไหมครับ ก็เลยเช็คด้วย $PAM_TYPE ว่าเป็น open_session แล้วค่อยทำ script ที่เหลือ

ซึ่ง env มีอะไรบ้าง ผมก็ลอง env > /tmp/envใส่เข้าไปไหน script แล้ว login ดูเท่านั้นเอง (printf, echo เฉยๆ ไม่ได้นะครับ)

XDG_SESSION_ID=xxxxx
PAM_SERVICE=sshd
PAM_RHOST=184.82.xxx.xxx
LC_ALL=en_US.UTF-8
PAM_USER=bankde
PWD=/
LANG=en_US.UTF-8
SHLVL=1
PAM_TYPE=open_session
PAM_TTY=ssh
XDG_RUNTIME_DIR=/run/user/xxxx
_=/usr/bin/env

ก็ได้ env มาประมาณนี้ จะเห็นว่ามีแม้กระทั่ง USER และ RHOST ด้วย

ผมก็เลยใส่เข้าไปใน message ด้วยเท่านั้นเอง

"message":"Detected $PAM_USER login from $PAM_RHOST"

ข้อควรระวังคือ ตัว script นี้มันรันก่อนเปิด session นะครับ ถึงแม้จะเป็น optional แล้ว (ต่อให้ fail ก็ยังได้ session) มันรัน script แบบ synchronous !! แปลว่าถ้า curl ผมค้าง ผมอาจจะต้องรอถึง 2 นาที (curl timeout) จนกว่าจะ login ได้ ผมจึงใส่ & ให้มันรันเป็น background ไปด้วยครับ

pam.d ไม่ได้มีแค่ config sshd เท่านั้น ยังมี config อื่นๆให้เล่นอีกมากเลย su, sudo, login, etc ถ้าอยากเล่นอะไรสุดขอบที่เกี่ยวกับพวก authentication ก็มาทางนี้ได้ครับ แต่ย้ำอีกรอบนะครับ ถ้าทำผิด อาจจะเข้า server ไม่ได้นะ XD

- Jun 25, 2019 -

--

--

Bank Eakasit
Bank Eakasit

No responses yet