SSD Nodes Learn 🎉 VPS $5.50/महिन्यापासून
मार्गदर्शक Matt Connorद्वारे Matt Connor

सर्व्हरवर वापरकर्त्यांच्या कमांड्सचे ऑडिट कसे करावे

Shell history सुरक्षित नसते. sudo logging, session recording, bash hooks आणि auditd execve नियमांची तुलना करा. सर्व्हरवरील लॉग्स सुरक्षित ठेवण्यासाठी योग्य पद्धती जाणून घ्या.

तुमच्या सर्व्हरवर वापरकर्त्यांनी चालवलेल्या कमांड्सची नोंद नक्की कोण ठेवते

तुमच्या सर्व्हरवर वापरकर्त्यांनी कोणत्या कमांड्स चालवल्या याचे ऑडिट करण्यासाठी, तुम्हाला अशा नोंदीची आवश्यकता आहे जी वापरकर्ता बदलू शकणार नाही. Shell history ही अशी नोंद नाही. ती केवळ सोयीसाठी असलेली फाईल आहे, जिच्या मालकी हक्क संबंधित अकाउंटकडे असतात. ज्याला त्या शेलमध्ये टाईप करता येते, तो ती बंद करू शकतो किंवा हटवू शकतो.

चार स्तर खऱ्या अर्थाने नोंदी ठेवतात आणि प्रत्येकाची काही किंमत मोजावी लागते. sudo प्रत्येक कमांडची एक ओळ syslog मध्ये लिहिते. sudo I/O logging एका अकाउंटसाठी संपूर्ण सेशन कॅप्चर करते. PROMPT_COMMAND सारखा शेल हुक, इंटरअॅक्टिव्ह bash वापरकर्ता काय टाईप करतो याची नोंद ठेवतो. कर्नल ऑडिट सबसिस्टम स्वतः execve syscall ची नोंद करते, म्हणूनच हा एकमेव स्तर आहे जो प्रत्येक प्रोसेस पाहू शकतो. हे मार्गदर्शक या पायऱ्या चढत जाते, प्रत्येक स्तर कुठे थांबतो हे सांगते आणि शेवटी अशा भागावर संपते जो ठरवतो की यातील कशाचीही काही किंमत आहे का: ज्या व्यक्तीचे तुम्ही ऑडिट करत आहात, ती व्यक्ती नोंदींपर्यंत पोहोचण्याआधी त्या मशीनवरून बाहेर काढणे.

सुरू करण्यापूर्वी एक चेतावणी. ऑडिट सबसिस्टम हे कर्नलचे काम आहे, त्यामुळे होस्ट कर्नल शेअर करणाऱ्या कंटेनरमध्ये यातील कशाचीही चाचणी घेता येणार नाही. या कमांड्स अशा KVM VPS वर चालवा जिथे कर्नल तुमचे स्वतःचे आहे.

शेल हिस्ट्री (shell history) ऑडिट ट्रेल का नसते

~/.bash_history चार सामान्य कारणांमुळे पुराव्यासाठी अपयशी ठरते आणि यासाठी कोणत्याही हुशार अटॅकरची गरज नसते.

ही वापरकर्त्याच्या मालकीची असते. फाईलचा मोड 600 असतो आणि ती संबंधित अकाउंटच्या मालकीची असते, त्यामुळे rm ~/.bash_history साठी कोणत्याही विशेष अधिकारांची (privilege) गरज नसते. तसेच, ती फाईल एडिटरमध्ये उघडून महत्त्वाच्या वीस ओळी काढून टाकणेही सहज शक्य असते.

ही शेल बंद झाल्यावर लिहिली जाते. जर एखादे सेशन kill -9 $$ ने किंवा कनेक्शन तुटल्यामुळे बंद झाले, तर काहीही लिहिले जात नाही. exit च्या आधी history -c केल्यास त्याचाही तोच परिणाम होतो आणि काहीही घडले नसल्याचे दिसते.

हे एका शब्दाने बंद करता येते. unset HISTFILE मुळे त्या सेशनसाठी फाईलमध्ये माहिती लिहिणे थांबते. set +o history मुळे रेकॉर्डिंग त्वरित थांबते. HISTCONTROL=ignorespace मुळे सुरुवातीला स्पेस देऊन टाईप केलेली प्रत्येक कमांड लपवली जाते. हे सर्व man bash मध्ये उपलब्ध आहे, कारण हे वापरकर्त्याच्या नियंत्रणात असण्यासाठीच बनवले आहे.

हे काय टाईप केले ते रेकॉर्ड करते, काय रन झाले ते नाही. एखादे alias किंवा शेल फंक्शन वापरल्यास, फाईलमध्ये दिसणारा मजकूर हा कर्नलने एक्झिक्युट केलेल्या प्रोग्रामसारखा नसतो.

यात टाइमस्टॅम्प्स (timestamps) देखील नसतात, जोपर्यंत एंट्री लिहिली जात असताना HISTTIMEFORMAT सेट केलेले नसेल, कारण bash त्याचे #1755043200 मार्कर फक्त तेव्हाच लिहिते जेव्हा तो व्हेरिएबल सेट असतो.

सामायिक लॉगिनवर (shared login) हे कोण होते हे देखील सांगू शकत नाही. तीन लोक एकच deploy अकाउंट वापरत असल्यास, एकाच uid अंतर्गत एकच इंटरलीव्ह्ड फाईल तयार होते. जेव्हा दोन व्यक्ती एकच uid वापरतात, तेव्हा कोणतीही लॉगिंग लेयर एखाद्या कृतीला विशिष्ट व्यक्तीशी जोडू शकत नाही. म्हणूनच सामायिक लॉगिनऐवजी प्रत्येक व्यक्तीसाठी एक स्वतंत्र अनप्रिव्हिलेज्ड अकाउंट असणे हा व्यावहारिक युक्तिवाद आहे.

शेल हिस्ट्री तिच्या मूळ कामासाठी चांगली आहे, म्हणजेच कालची कमांड पुन्हा टाईप करण्यासाठी मदत करणे. तिचा वापर केवळ एक संकेत म्हणून करा. तिला कधीही पुरावा म्हणून सादर करू नका.

sudo काय लॉग करते आणि ते कुठे थांबते

sudo चालवल्या जाणाऱ्या प्रत्येक कमांडची एक ओळ authpriv syslog सुविधेला पाठवते.

sudo grep 'sudo:' /var/log/auth.log | tail -5
journalctl -t sudo -n 5

प्रत्येक ओळीत वापरकर्ता, टर्मिनल, वर्किंग डिरेक्टरी, लक्ष्य वापरकर्ता आणि कमांडचे नाव असते:

sudo:    alice : TTY=pts/0 ; PWD=/home/alice ; USER=root ; COMMAND=/usr/bin/apt update

जर /var/log/auth.log अस्तित्वात नसेल, तर त्या इमेजवर rsyslog इंस्टॉल केलेले नाही आणि सर्व नोंदी फक्त journal मध्येच असतात. त्यावर अवलंबून राहण्यापूर्वी journal अस्थिर (volatile) नाही याची खात्री करा:

journalctl --list-boots

केवळ सध्याचे बूट सूचीबद्ध असणे म्हणजे /var/log/journal अस्तित्वात नाही, त्यामुळे journal /run मध्ये राहते आणि प्रत्येक ओळ पुढच्या रीबूटला नष्ट होते. ते कायमस्वरूपी (persistent) करा:

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald

आता मर्यादा समजून घ्या. sudo फक्त त्याला चालवण्यास सांगितलेली कमांड लॉग करते. ती कमांड त्यानंतर काय करते, हे sudo लॉग करत नाही. त्यामुळे एक ओळ मागोवा संपवते:

sudo -i

लॉगमध्ये शेलसाठी फक्त एकच नोंद मिळते. त्या root शेलमध्ये टाईप केलेली प्रत्येक कमांड sudo ला दिसत नाही, कारण sudo आता पाथमध्ये नसते. sudo su -, sudo bash, आणि sudo vim /etc/shadow त्यानंतर :!bash या सर्वांचे स्वरूप सारखेच असते. शेल एस्केप (shell escape) असलेली कोणतीही प्रोग्राम चालवण्याची परवानगी देणारा sudoers नियम, जसे की vim किंवा find, हा नियम प्रत्यक्षात अनलॉग (unlogged) root प्रवेश देतो. एखाद्या खात्याच्या लॉग ओळींवर विश्वास ठेवण्यापूर्वी ते खाते प्रत्यक्षात कशापर्यंत पोहोचू शकते, हे तपासा:

sudo -l -U alice

एका खात्यासाठी संपूर्ण सत्र रेकॉर्ड करणे

प्रथम तुमच्याकडे कोणता sudo आहे ते तपासा, कारण Rust rewrite मध्ये हे वैशिष्ट्य उपलब्ध नाही:

sudo --version | head -1

जर आउटपुटमध्ये sudo-rs दिसत असेल, तर हा विभाग वगळा आणि audit subsystem वापरा. Ubuntu च्या 25.10 आणि 26.04 releases च्या अधिकृत दस्तऐवजीकरणानुसार I/O logging आणि sudoreplay समर्थित नाहीत, आणि ऑगस्ट 2026 पर्यंत ही स्थिती कायम होती. हे महत्त्वाचे आहे कारण त्या releases वर sudo-rs हा डीफॉल्ट sudo असतो, त्यामुळे अपग्रेड केल्यास तुमच्या नियंत्रणाखाली असलेली एखादी सुविधा काढून टाकली जाऊ शकते. sudo-आधारित लॉगिंगचे नियोजन करण्यापूर्वी sudo-rs मधील बदलांची संपूर्ण यादी वाचणे फायदेशीर ठरेल.

मूळ sudo सह, जो Ubuntu 24.04 LTS मध्ये उपलब्ध आहे, एका खात्यासाठी I/O logging सुरू करा:

sudo visudo -f /etc/sudoers.d/iolog
Defaults:deploy log_output
Defaults!/usr/bin/sudoreplay !log_output

एडिटर वापरण्याऐवजी visudo वापरा, कारण ज्या फाईलचे पार्सिंग होत नाही ती फाईल सेव्ह करण्यास तो नकार देतो. सदोष sudoers फाईलमुळे कोणालाही sudo वापरता येणार नाही. त्यानंतर सत्र पुन्हा प्ले (replay) करा:

sudo sudoreplay -l user=deploy
sudo sudoreplay 000001

sudoreplay -l सत्रांची यादी त्यांच्या ID सह दाखवतो आणि जर त्या वापरकर्त्यावर log_output कधीही लागू केले नसेल तर काहीही प्रिंट करत नाही. याची किंमत: टर्मिनलवरून जाणारा प्रत्येक बाइट /var/log/sudo-io अंतर्गत साठवला जातो, त्यामुळे सविस्तर सत्र मोठी फाईल तयार करते. दुसरी sudoers ओळ रिप्लेला स्वतःला रेकॉर्ड करण्यापासून थांबवते. खरी अडचण गोपनीयतेची आहे, कारण I/O log मध्ये टाईप केलेले आणि प्रिंट झालेले सर्व काही साठवले जाते, ज्यामध्ये सत्रादरम्यान प्रॉम्प्टमध्ये टाईप केलेला पासवर्ड देखील समाविष्ट असतो, त्यामुळे याला पासवर्ड स्टोअर इतकीच सुरक्षा आवश्यक असते. याचे कव्हरेज देखील मर्यादित आहे. हे फक्त sudo द्वारे चालवलेले कमांड्स पाहते. जो कोणी लॉग इन करून पूर्णपणे स्वतःच्या खात्यातून काम करतो, त्याचे रेकॉर्डिंग होत नाही.

शेल हुक्स आणि ते बायपास कसे केले जातात

"प्रत्येक कमांड लॉग करा" यासाठी फिरणारी रेसिपी म्हणजे PROMPT_COMMAND हुक, जो /etc/profile.d/ मध्ये टाकला जातो:

# /etc/profile.d/00-cmdlog.sh
PROMPT_COMMAND='logger -p local6.info -t cmdlog "$(whoami) $$ $(history 1 | sed "s/^ *[0-9]* *//")"'

bash प्रत्येक प्रॉम्प्ट दाखवण्यापूर्वी PROMPT_COMMAND चालवते, त्यामुळे कमांड टाईप केल्यावर ती लगेच syslog मध्ये पोहोचते, एक्झिट होण्याची वाट पाहिली जात नाही. तसेच logger सिस्टिम लॉग डेमनद्वारे लिहिते, त्यामुळे वापरकर्त्याच्या स्वतःच्या फाईल परवानग्यांचा यात अडथळा येत नाही. नवीन लॉगिन शेल उघडा आणि sudo tail -f /var/log/syslog ने तपासा, किंवा rsyslog नसलेल्या इमेजवर journalctl -t cmdlog -f वापरा.

परंतु, हे पाच प्रकारे काम करणे थांबवते, जे तुम्ही एका मिनिटात सिद्ध करू शकता.

  • नॉन-इंटरअॅक्टिव्ह शेल कधीही प्रॉम्प्ट दाखवत नाहीत. ssh you@server 'id' कमांड चालवते आणि परत येते, काहीही लॉग होत नाही, कारण PROMPT_COMMAND कधीही इव्हॅल्युएट झाले नाही.
  • हे एक व्हेरिएबल आहे. unset PROMPT_COMMAND ते उर्वरित सत्रासाठी बंद करते आणि यासाठी कोणत्याही विशेषाधिकाराची (privilege) गरज नसते.
  • ही फाईल लॉगिन शेलद्वारे वाचली जाते. bash --noprofile --norc कधीही /etc/profile.d/ सोर्स करत नाही.
  • हे फक्त bash साठी आहे. vim मधील zsh, sh, python3 -c 'import os; os.system("id")' आणि :!id हे सर्व असे प्रोग्राम्स चालवतात जे bash प्रॉम्प्ट हुकला कधीही दिसणार नाहीत.
  • हे टाईप केल्याप्रमाणे ओळ लॉग करते, त्यामुळे एखादे alias किंवा function प्रत्यक्षात चाललेली कमांड लपवू शकते.

शेल हुकचा वापर सोयीसाठी करा. हे सहकार्य करणाऱ्या वापरकर्त्यांसाठी "मी गेल्या मंगळवारी काय चालवले होते" या प्रश्नाचे उत्तर देते. चेकलिस्टमध्ये याला नियंत्रण (control) मानण्याची चूक करू नका.

कर्नेल ऑडिट सबसिस्टम प्रत्येक execve पाहते

Linux ऑडिट सबसिस्टम, जी auditd डेमनद्वारे चालविली जाते, हा यातील एकमेव स्तर आहे ज्याला वापरकर्ता टाळू शकत नाही, कारण syscall रन होत असताना रेकॉर्ड थेट कर्नेलमध्ये तयार केला जातो. जर एखादी प्रक्रिया प्रोग्राम कार्यान्वित (execute) करत असेल, तर एक इव्हेंट तयार होतो. शेल, प्रोग्रामिंग लँग्वेज आणि टर्मिनलची उपस्थिती यामुळे काहीही फरक पडत नाही.

sudo apt update && sudo apt install -y auditd audispd-plugins
sudo systemctl enable --now auditd
sudo auditctl -s

auditctl -s डेमनची स्थिती दर्शवते. enabled 1 सोबत शून्य नसलेला pid याचा अर्थ असा की तो चालू आहे, आणि lost 0 चा अर्थ असा की आतापर्यंत एकही रेकॉर्ड गमावलेला नाही. तो lost काउंटर लक्षात ठेवा, तो नंतर पुन्हा येईल.

auid हे ते फील्ड आहे ज्यामुळे ऑडिट उपयुक्त ठरते. जेव्हा एखादे सत्र सुरू होते तेव्हा PAM एक लॉगिन uid सेट करते आणि त्यानंतर कर्नेल प्रत्येक चाइल्ड प्रोसेसवर ते कायम ठेवते. तुमचा uid तपासा:

cat /proc/self/loginuid

एक इंटरअॅक्टिव्ह SSH सत्र तुमचा uid प्रिंट करते, कारण /etc/pam.d/sshd मध्ये pam_loginuid.so समाविष्ट असते. 4294967295 मूल्याचा अर्थ असा की लॉगिन-uid कधीही सेट केले गेले नव्हते, जे बूट वेळी सिस्टम डेमनद्वारे सुरू केलेल्या प्रक्रियेसाठी सामान्य आहे. महत्त्वाचा भाग असा की sudo -i ते बदलत नाही: alice द्वारे उघडलेल्या root शेलमध्ये अजूनही auid 1000 असतो, त्यामुळे त्यातील प्रत्येक कमांड alice ला जबाबदार धरता येते. sudo मुळे नेमकी हीच त्रुटी राहते. एकदा सेट केलेले लॉगिन-uid बदलण्यासाठी CAP_AUDIT_CONTROL ची आवश्यकता असते, जे सामान्य वापरकर्त्यांकडे नसते, आणि sudo auditctl --loginuid-immutable पुढील रीबूटपर्यंत root साठी देखील ते बंद करते.

/etc/pam.d/sshd, /etc/pam.d/login आणि /etc/pam.d/cron या प्रत्येकामध्ये pam_loginuid.so समाविष्ट असल्याची खात्री करा, अन्यथा इव्हेंट्स कोणाशीही न जोडता येतील. ही तीच फाईल लिस्ट आहे जी तुम्ही VPS वर SSH ॲक्सेस हार्डनिंग करताना वापरता, त्यामुळे ही दोन्ही कामे एकत्र करा.

auditd साठी सुरुवातीचा नियम संच

नियम /etc/audit/rules.d/*.rules मध्ये असतात. augenrules त्यांना फाईलच्या नावानुसार क्रमाने एका यादीत एकत्रित करतो. नियमांचा क्रम महत्त्वाचा असतो, कारण कर्नल पहिल्या जुळणाऱ्या नियमावर प्रक्रिया थांबवते. काहीही जोडण्यापूर्वी तिथे आधीच काय आहे ते वाचा, कारण नंतरच्या फाईलमधील -D आधी लोड केलेले सर्व नियम पुसून टाकते.

ls /etc/audit/rules.d/
cat /etc/audit/rules.d/audit.rules

त्यानंतर /etc/audit/rules.d/50-exec.rules लिहा:

## Suppressions first: the kernel takes the first matching rule.
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-deb
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-query
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-split
-a never,exit -F arch=b64 -S execve -F exe=/usr/bin/dpkg-trigger

## Every program started by a logged-in human.
-a always,exit -F arch=b64 -S execve,execveat -F auid>=1000 -F auid!=unset -k exec
-a always,exit -F arch=b32 -S execve,execveat -F auid>=1000 -F auid!=unset -k exec

## Changes to who may become root.
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity

## Changes to the audit configuration itself.
-w /etc/audit/ -p wa -k auditconfig

ते लोड करा आणि खात्री करा:

sudo augenrules --load
sudo auditctl -l

auditctl -l ने तुमचे नियम पुन्हा प्रिंट होणे म्हणजे ते कार्यान्वित आहेत. No rules चा अर्थ लोड अयशस्वी झाला असा होतो आणि journalctl -u auditd -n 20 त्या फाईलचे नाव आणि ओळ दर्शवते जी पार्सरने नाकारली आहे. जुन्या audit userspace ला unset कीवर्ड समजत नाही. जर लोडरने त्या फील्डबद्दल तक्रार केली, तर त्याऐवजी -F auid!=4294967295 लिहा, जे समान मूल्य दर्शवते.

आता इव्हेंट्स वाचा:

sudo ausearch -k exec -ts recent -i | tail -40
sudo ausearch -ul 1000 -ts today -i
sudo aureport -k --summary -i

-i ने uid आणि syscall नंबर्स नावांमध्ये रूपांतरित होतात, आणि व्यवहारात हे अनिवार्य आहे. -ts recent मागील दहा मिनिटांचा कालावधी कव्हर करते. प्रत्येक एक्झिक्यूशन रेकॉर्डच्या गटाच्या स्वरूपात येते: uid, auid, exit status आणि key असलेले SYSCALL रेकॉर्ड, पूर्ण आर्गुमेंट लिस्ट असलेले EXECVE रेकॉर्ड, आणि संदर्भासाठी CWDPATH रेकॉर्ड्स.

एक महत्त्वाची मर्यादा, कारण यामुळे अनेकदा गोंधळ होतो. audit syscalls रेकॉर्ड करते, आणि shell builtin स्वतःचा कोणताही syscall करत नाही. cd /root कोणताही प्रोग्राम चालवत नाही. bash प्रॉम्प्टवर टाईप केलेले echo evil >> /etc/passwd देखील कोणताही प्रोग्राम चालवत नाही, कारण echo आणि रिडायरेक्शन दोन्ही आधीच चालू असलेल्या शेल प्रोसेसमध्येच घडतात. त्यामुळे execve नियम प्रोग्राम्स पाहतात आणि -w नियम राईट्स (writes) पाहतात. यापैकी एकही नियम स्वतंत्रपणे पुरेसा नाही.

शेवटी, कॉन्फिगरेशन लॉक करा:

## /etc/audit/rules.d/99-finalize.rules
-e 2

-e 2 पुढच्या रीबूटपर्यंत नियम संच अपरिवर्तनीय (immutable) बनवते. ते लोड झाल्यानंतर, auditctl -s हे enabled 2 रिपोर्ट करते आणि root युजरसह कोणताही नियम जोडण्याचा किंवा हटवण्याचा प्रयत्न Operation not permitted मुळे अयशस्वी होतो. ही फाईल सर्वात शेवटी जोडा आणि जेव्हा तुम्हाला नियम बदलायचे असतील तेव्हा रीबूटची अपेक्षा ठेवा. हाच यामागचा उद्देश आहे: जो नियम संच कोणीही गुपचूप बंद करू शकते, तो पुरावा मानला जाऊ शकत नाही.

ज्या ऑडिट लॉगकडे कोणीही पाहत नाही, तो केवळ एक अनुपालन दस्तऐवज असतो

auditd चे अपयश हे नाही की ते काही गोष्टी नोंदवत नाही. त्याचे अपयश हे आहे की ते इतकी जास्त माहिती नोंदवते की कोणीही ती पाहत नाही, आणि मग तो लॉग केवळ चेकलिस्ट पूर्ण करण्यासाठी अस्तित्वात राहतो, कोणत्याही प्रश्नाचे उत्तर देण्यासाठी नाही.

काहीही ट्यून करण्यापूर्वी तुमच्या स्वतःच्या सर्व्हरवर गणित करून पहा:

sudo aureport -k --summary -i
sudo du -sh /var/log/audit

एकच sudo apt upgrade हजारो अल्पायुषी प्रक्रिया चालवते आणि त्यातील प्रत्येकाकडे तुमचा auid असतो, त्यामुळे एका पॅकेज अपडेटमुळे मानवी टायपिंगच्या आठवडाभराच्या कामापेक्षा जास्त डेटा तयार होऊ शकतो. म्हणूनच वरील सप्रेशनमध्ये dpkg आणि त्याच्या सहाय्यक प्रोग्राम्सची नावे दिली आहेत. सप्रेशन नेहमी एक्झिक्युटेबलनुसार करा, युजरनुसार कधीही करू नका: /usr/bin/dpkg साठी दिलेली सवलत ही एक अशी त्रुटी आहे जी तुम्ही एका वाक्यात स्पष्ट करू शकता, तर एखाद्या अकाउंटसाठी दिलेली सवलत ही तुम्ही ज्या गोष्टीला पकडण्याचा प्रयत्न करत होतात, तशाच आकाराची एक मोठी त्रुटी असते.

प्रत्येक नियमावरील -k की (key) मुळेच एक महिन्यानंतरही लॉग शोधणे शक्य होते. ausearch -k sudoers हा एक प्रश्न आहे ज्याला उत्तर असते. फिल्टर नसलेला ausearch म्हणजे मजकुराची एक भिंत आहे, जी तुम्हाला वाचणे बंद करण्यास प्रवृत्त करते. जर तुमच्या कलेक्टरला नेटिव्ह फॉरमॅटऐवजी JSON हवे असेल, तर laurel हे एक auditd प्लगइन आहे जे प्रत्येक इव्हेंटला डिकोड केलेल्या आर्ग्युमेंट्ससह एका JSON ऑब्जेक्टमध्ये रूपांतरित करते. ते इतर कोणत्याही प्लगइनप्रमाणे /etc/audit/plugins.d/ मध्ये रजिस्टर होते आणि auditd प्लगइनमधील बदल sudo pkill -HUP auditd वर स्वीकारते.

auditd चा खर्च किती असतो, प्रामाणिकपणे

प्रत्येक जुळणारा syscall एका रेकॉर्डमध्ये रूपांतरित होतो, जो कर्नल फॉरमॅट करून userspace कडे पाठवते. याचा खर्च दोन ठिकाणी होतो आणि तो दुसऱ्याच्या आकड्यांवरून अंदाज लावण्यापेक्षा तुमच्या स्वतःच्या वर्कलोडवर मोजता येतो.

  • CPU आणि लेटन्सी. सतत fork होणारे मशीन, जसे की build host किंवा CI runner, प्रत्येक exec साठी एक रेकॉर्ड तयार करते. जेव्हा कर्नलचा backlog भरतो, तेव्हा --backlog_wait_time मुळे कर्नल इव्हेंट तयार करणाऱ्या प्रोसेसला जागा मिळेपर्यंत थांबवते. त्यामुळे audit चा परिणाम CPU टक्केवारीपेक्षा संथ builds म्हणून दिसून येतो. प्रत्यक्ष लोड असताना sudo auditctl -s मध्ये backlog आणि lost तपासा. वाढता lost म्हणजे रेकॉर्ड्स गहाळ झाले आहेत, आणि ज्या लॉगमध्ये माहितीचे भाग गहाळ आहेत तो लॉग नसणे अधिक चांगले, कारण तुम्ही त्यावर विश्वास ठेवू शकता.
  • डिस्क. /etc/audit/auditd.conf वाचा आणि डिस्क भरल्यावर काय करायचे याचा विचारपूर्वक निर्णय घ्या, कारण डीफॉल्ट व्हॅल्यूज या केवळ मते आहेत. max_log_file, num_logs आणि max_log_file_action रोटेशन नियंत्रित करतात. space_left_action, admin_space_left_action आणि disk_full_action आपत्कालीन स्थिती नियंत्रित करतात, आणि काही उपलब्ध कृती, ज्यामध्ये halt आणि single समाविष्ट आहेत, रेकॉर्ड गहाळ होण्यापेक्षा मशीन बंद करणे पसंत करतात.

/etc/audit/rules.d/audit.rules मधील -f ओळ कर्नल स्तरावर हाच निर्णय घेते: -f 1 ऑडिट फेल्युअरचा रिपोर्ट syslog ला पाठवते, आणि -f 2 कर्नलला पॅनिक मोडमध्ये नेते. 2 तेव्हाच निवडा जेव्हा तुम्हाला रेकॉर्ड गहाळ होण्यापेक्षा सर्व्हर गहाळ होणे खरोखर मान्य असेल. ज्या VPS वर लोक अवलंबून आहेत, तिथे रोटेशन वापरा आणि स्टोरेजची समस्या सर्व्हरच्या बाहेर हलवा.

लॉग्स सर्व्हरच्या बाहेर रिअल-टाइममध्ये पाठवा

इन्सिडेंट रिपोर्टमध्ये हे वारंवार सिद्ध झाले आहे. जर लॉग्स कॉम्प्रमाइज्ड (breached) सर्व्हरवरच राहिले, तर ते कोणीही बदलू शकते. root युजर /var/log/auth.log पुन्हा लिहू शकतो, /var/log/audit/audit.log डिलीट करू शकतो आणि डेमन थांबवू शकतो. -e 2 मुळे नियम अनलोड होण्यापासून वाचतात, पण ते rm बद्दल काहीही करू शकत नाही. जोपर्यंत लॉगची एक प्रत मशीनच्या बाहेर जात नाही, तोपर्यंत वरील कोणताही स्तर पुरावा देऊ शकत नाही.

ऑडिटचे स्वतःचे ट्रान्सपोर्ट म्हणजे audispd-plugins मधील audisp-remote प्लगइन आहे. ते /etc/audit/plugins.d/au-remote.conf मध्ये सुरू करा:

active = yes
direction = out
path = /usr/sbin/audisp-remote
type = always
format = string

रीलोड करण्यापूर्वी path ची तुलना command -v audisp-remote शी करा, कारण चुकीच्या पाथमुळे जर्नलमध्ये फक्त एक ओळ दिसते आणि इतर काहीही होत नाही. /etc/audit/audisp-remote.conf मध्ये remote_server आणि port सेट करा आणि कलेक्टरवर त्याच्या स्वतःच्या auditd.conf मध्ये tcp_listen_port = 60 सेट करा. sudo pkill -HUP auditd वापरून रीलोड करा. अनेक इमेजेसवर systemctl restart auditd नाकारले जाते, कारण युनिट फाईलमध्ये RefuseManualStop=yes सेट केलेले असते, त्यामुळे सिग्नल पाठवणे हाच खात्रीशीर मार्ग आहे.

दुसरा पर्याय म्हणजे ऑडिटला तुम्ही आधीच फॉरवर्ड करत असलेल्या syslog स्ट्रीममध्ये समाविष्ट करणे. active = no सोबत /etc/audit/plugins.d/syslog.conf येते. ते yes वर सेट करा, रीलोड करा आणि ऑडिट इव्हेंट्स sudo च्या ओळींसोबत आणि इतर सर्व डेटासोबत जोडले जातील. त्यानंतर rsyslog द्वारे TLS (transport layer security) वापरून सर्व डेटा फॉरवर्ड करा, ज्यासाठी rsyslog-gnutls पॅकेजची आवश्यकता असते:

# /etc/rsyslog.d/60-forward.conf
*.* action(type="omfwd"
    target="logs.example.net" port="6514" protocol="tcp"
    StreamDriver="gtls" StreamDriverMode="1"
    StreamDriverAuthMode="x509/name"
    StreamDriverPermittedPeers="logs.example.net"
    action.resumeRetryCount="-1"
    queue.type="linkedList" queue.filename="fwd" queue.saveOnShutdown="on")

क्यू (queue) सेटिंग्ज हा महत्त्वाचा भाग आहे. action.resumeRetryCount="-1" कायमस्वरूपी प्रयत्न (retry) करत राहते आणि queue.saveOnShutdown="on" सह डिस्क-असिस्टेड क्यू कलेक्टर उपलब्ध नसल्यास रेकॉर्ड्स साठवून ठेवते आणि तो पुन्हा ऑनलाइन आल्यावर ते पाठवते. या दोन गोष्टींशिवाय, कलेक्टर रीबूट झाल्यास तुमच्या पुराव्यांमध्ये त्रुटी (hole) निर्माण होईल आणि ती त्रुटी निर्माण झाल्याचे तुम्हाला समजणारही नाही. sudo systemctl restart rsyslog सह लागू करा आणि त्यावर विश्वास ठेवण्यापूर्वी रेकॉर्ड्स खरोखर कलेक्टरवर पोहोचत आहेत का याची खात्री करा.

एक शेवटची गोष्ट: कलेक्टर असे मशीन असावे ज्यावर ऑडिट होणारे लोक लॉग-इन करू शकणार नाहीत. जर लॉग सर्व्हरवरही त्याच ॲडमिन ग्रुपकडे root ॲक्सेस असेल, तर तुम्ही फाईल फक्त कॉपी केली आहे, सुरक्षित केलेली नाही. यासाठी वेगळी क्रेडेन्शियल्स, वेगळ्या कीज आणि शक्य असल्यास वेगळे प्रोव्हायडर अकाउंट वापरा. याच कारणामुळे अनेक Linux सर्व्हर्स व्यवस्थापित करण्याचा मध्यवर्ती मार्ग तयार करणे गरजेचे असते, आणि जेव्हा तुम्ही कॉम्प्रमाइज्ड VPS हाताळत असता, तेव्हा हेच उपयुक्त आणि निरुपयोगी पहिल्या तासातील फरक ठरते.

सामान्य वापरकर्ता रेकॉर्ड पुन्हा लिहू शकत नाही याची खात्री करा

गृहीत धरण्याऐवजी दाव्याची चाचणी करा. कोणत्याही sudo अधिकाराशिवाय, एका सामान्य खात्यावरून:

echo test >> /var/log/auth.log
cat /var/log/audit/audit.log
auditctl -D
id -nG

क्रमाने खालील गोष्टींची अपेक्षा करा: Permission denied, कारण auth.log ची मालकी syslog कडे आहे, त्याचा गट adm आहे आणि मोड 640 आहे; पुन्हा Permission denied, कारण ऑडिट लॉगचा मोड 600 आहे आणि तो root च्या मालकीचा आहे; चालवण्यास नकार देणारी त्रुटी, कारण ऑडिट नियम बदलण्यासाठी CAP_AUDIT_CONTROL आवश्यक आहे; आणि अशा गटांची यादी ज्यामध्ये adm किंवा systemd-journal यापैकी कोणीही नाही.

ती शेवटची तपासणी अशी आहे जिथे लोक चुकतात. adm चे सदस्यत्व /var/log/auth.log साठी वाचन प्रवेश (read access) देते आणि systemd-journal चे सदस्यत्व संपूर्ण जर्नलसाठी वाचन प्रवेश देते. यापैकी कशामुळेही लेखन प्रवेश (write access) मिळत नाही, त्यामुळे कशामुळेही फेरफार करता येत नाही. दोन्हीमुळे एखादी व्यक्ती सर्व्हरवरील प्रत्येक प्रमाणीकरण ओळ वाचू शकते, हा निर्णय एखाद्या फोरमच्या उत्तरातून usermod -aG ओळ कॉपी करण्याऐवजी जाणीवपूर्वक घेणे आवश्यक आहे.

शेवटी, रीबूटनंतर टिकून राहणाऱ्या दोन गोष्टींची पुष्टी करा:

sudo auditctl -s
systemctl is-enabled auditd

enabled 2 चा अर्थ असा आहे की नियम संच पुढील बूटपर्यंत लॉक केला आहे. दुसऱ्या कमांडमधील enabled चा अर्थ असा आहे की त्या बूटनंतर auditd पुन्हा सुरू होईल. जो नियम संच फक्त पुढील कर्नल अपडेटपर्यंत टिकतो, तो ऑडिट ट्रेल असू शकत नाही.

FAQ

विशिष्ट वापरकर्त्याने चालवलेली सर्व कमांड्स मी कशी पाहू शकतो?

त्यांचा uid शोधण्यासाठी id -u alice वापरा आणि त्यानंतर login uid नुसार audit log शोधण्यासाठी sudo ausearch -ul 1000 -ts today -i वापरा. execve नियमापुरते मर्यादित ठेवण्यासाठी -k exec जोडा. login uid हे लॉगइनच्या वेळी सेट केले जाते आणि ते susudo -i नंतरही कायम राहते, त्यामुळे त्या खात्याने उघडलेल्या root shell मध्ये चालवलेली कमांड्स यात पकडली जातात. हे फक्त नियम लोड केल्यानंतर चालवलेल्या कमांड्ससाठीच काम करते, कारण ज्या घटना रेकॉर्ड करण्यासाठी कॉन्फिगर केल्या नव्हत्या, त्यांचा इतिहास audit ठेवत नाही. जर तुम्हाला डेटाचे स्वरूप आधी पाहायचे असेल, तर sudo aureport -k --summary -i तुम्हाला प्रति-नियम (per-rule) संख्या देईल.

एखादा वापरकर्ता त्याने काय चालवले हे लपवण्यासाठी त्याचा bash इतिहास हटवू शकतो का?

हो, आणि यासाठी कोणत्याही विशेषाधिकाराची (privilege) गरज नाही. ~/.bash_history ची मालकी त्या वापरकर्त्याकडे असते आणि त्याचा मोड 600 असतो, त्यामुळे तो ती फाईल एडिट करू शकतो, ट्रंकेट करू शकतो किंवा काढून टाकू शकतो. तसेच, unset HISTFILE वापरून ते लिहिणे थांबवू शकतो, set +o history वापरून सेशन दरम्यान रेकॉर्डिंग थांबवू शकतो, किंवा HISTCONTROL=ignorespace सेट असताना कमांडच्या सुरुवातीला स्पेस देऊन ती कमांड लपवू शकतो. शेल बंद झाल्यावर bash फाईल लिहितो, त्यामुळे kill -9 $$ ने बंद केलेले सेशन काहीही रेकॉर्ड करत नाही. शेल इतिहासाकडे फक्त एक संकेत म्हणून पहा, पुरावा म्हणून कधीही नाही.

sudo हे sudo -i च्या आत काय घडते ते लॉग करते का?

नाही. sudo फक्त त्याला चालवायला सांगितलेली कमांड लॉग करते, त्यामुळे sudo -i शेलसाठी एक ओळ तयार करते आणि त्यानंतर काहीही नाही. त्या root shell मध्ये टाईप केलेली प्रत्येक कमांड sudo ला दिसत नाही, कारण sudo चा त्यात सहभाग नसतो. sudo su -, sudo bash आणि शेल एस्केप (shell escape) असलेले कोणतेही परवानगीप्राप्त प्रोग्राम अशाच प्रकारे वागतात. दोन गोष्टी ही उणीव भरून काढतात: execve वरील audit नियम, जे मूळ login uid सह प्रत्येक प्रोग्राम रेकॉर्ड करतात, आणि sudoers नियम जे सुरुवातीलाच शेल देत नाहीत.

auditd मुळे माझा सर्व्हर धीमा होईल का?

हे पूर्णपणे तुमच्या वर्कलोडमध्ये किती प्रोसेस सुरू होतात यावर अवलंबून आहे, त्यामुळे आकड्यांवर विश्वास ठेवण्यापेक्षा त्याचे मोजमाप करा. जो सर्व्हर प्रामुख्याने विनंत्यांना प्रतिसाद देतो, तिथे exec चे प्रमाण कमी असते आणि तिथे फरक जाणवणार नाही. मात्र, build host किंवा CI runner वर सतत exec होत असते आणि तिथे मोठा फरक जाणवू शकतो, कारण जेव्हा कर्नल audit बॅकलॉग भरतो, तेव्हा जागा मिळेपर्यंत ती घटना निर्माण करणारी प्रोसेस थांबवली जाते. प्रत्यक्ष लोड असताना sudo auditctl -s चालवा आणि backloglost वर लक्ष ठेवा. lost शून्य पेक्षा जास्त असणे म्हणजे रेकॉर्ड्स गहाळ झाले आहेत, जो सर्वात वाईट परिणाम आहे, कारण लॉगमध्ये आता अदृश्य पोकळ्या निर्माण झाल्या आहेत.

audit logs कुठे साठवले पाहिजेत?

दुसऱ्या मशीनवर, जिथे काही सेकंदांचा विलंब असेल. ज्या सर्व्हरचे ऑडिट केले जात आहे, तिथे root ॲक्सेस मिळवणारी कोणतीही व्यक्ती /var/log/audit/audit.log हटवू शकते आणि /var/log/auth.log पुन्हा लिहू शकते, त्यामुळे स्थानिक प्रती फक्त अशा घटनांबद्दल माहिती देतात ज्या लपवण्याचा कोणीही प्रयत्न केला नाही. audisp-remote प्लगइन वापरून मध्यवर्ती auditd कडे फॉरवर्ड करा, किंवा audit syslog प्लगइन सक्षम करा आणि rsyslog द्वारे TLS वर संपूर्ण syslog स्ट्रीम फॉरवर्ड करा. कलेक्टरला स्वतःची क्रेडेन्शियल्स द्या आणि ज्या खात्यांचे ऑडिट केले जात आहे, त्यांना त्याचा ॲक्सेस नाही याची खात्री करा.