Linux server-ல் பயனர் கட்டளைகளை தணிக்கை செய்வது எப்படி
Shell history நம்பகமானதல்ல. Sudo logging, session recording, shell hooks மற்றும் auditd execve விதிகளை ஒப்பிட்டு, பதிவுகளை server-லிருந்து பாதுகாப்பாக வெளியேற்றுவது எப்படி என
உங்கள் server-ல் பயனர்கள் இயக்கிய கட்டளைகளை உண்மையில் பதிவு செய்வது எது
உங்கள் server-ல் பயனர்கள் இயக்கிய கட்டளைகளைத் தணிக்கை (audit) செய்ய, பயனரால் திருத்த முடியாத ஒரு பதிவு உங்களுக்குத் தேவை. Shell history என்பது அத்தகைய பதிவு அல்ல. அது ஒரு வசதிக்காகப் பயன்படுத்தப்படும் கோப்பு; அதை உருவாக்கிய கணக்கின் உரிமையிலேயே அது இருக்கும். அந்த shell-ல் தட்டச்சு செய்யும் எவரும் அதை அணைக்கவோ அல்லது நீக்கவோ முடியும்.
நான்கு அடுக்குகள் உண்மையான பதிவை வைத்திருக்கின்றன, ஒவ்வொன்றிற்கும் ஒரு விலை உண்டு. sudo ஒவ்வொரு கட்டளைக்கும் ஒரு வரியை syslog-ல் எழுதுகிறது. sudo I/O logging ஒரு கணக்கிற்கான முழு அமர்வையும் (session) படம்பிடிக்கிறது. PROMPT_COMMAND போன்ற shell hook, ஒரு interactive bash பயனர் தட்டச்சு செய்ததைப் பதிவு செய்கிறது. Kernel audit subsystem ஆனது execve syscall-ஐயே பதிவு செய்கிறது; இதனால்தான் ஒவ்வொரு process-ஐயும் காணக்கூடிய ஒரே அடுக்கு இதுவாகும். இந்த வழிகாட்டி அந்தப் படிகளில் ஏறிச் செல்கிறது, ஒவ்வொரு அடுக்கின் வரம்புகளையும் விளக்குகிறது, மேலும் எதற்கும் மதிப்பு இருக்கிறதா என்பதைத் தீர்மானிக்கும் பகுதியுடன் முடிகிறது: நீங்கள் தணிக்கை செய்யும் நபர் அந்தப் பதிவுகளை அணுகுவதற்கு முன்பே அவற்றை machine-லிருந்து வெளியேற்றுவது.
தொடங்குவதற்கு முன் ஒரு எச்சரிக்கை. Audit subsystem என்பது kernel சார்ந்த வேலை, எனவே host kernel-ஐப் பகிரும் container-க்குள் எதையும் சோதிக்க முடியாது. இந்த கட்டளைகளை உங்கள் சொந்த kernel-ஐக் கொண்ட KVM VPS-ல் இயக்கவும்.
Shell history ஏன் ஒரு தணிக்கை தடயமாக (audit trail) இருக்க முடியாது
~/.bash_history நான்கு சாதாரண காரணங்களுக்காக ஆதாரமாகத் தோல்வியடைகிறது, இதற்குத் தாக்குதல் நடத்துபவர் புத்திசாலியாக இருக்க வேண்டிய அவசியமில்லை.
இது பயனருக்குச் சொந்தமானது. இந்த கோப்பு mode 600-ல் உள்ளது மற்றும் அந்த கணக்கின் உரிமையாளருக்குச் சொந்தமானது, எனவே rm ~/.bash_history-க்கு எந்தவிதமான சலுகையும் தேவையில்லை. ஒரு எடிட்டரில் அதைத் திறந்து, முக்கியமான இருபது வரிகளை நீக்குவதற்கும் எந்தத் தடையும் இல்லை.
இது shell வெளியேறும்போது எழுதப்படுகிறது. kill -9 $$ மூலம் முடிவடையும் அல்லது இணைப்பு துண்டிக்கப்படும் ஒரு session எதையும் பதிவு செய்யாது. exit-க்கு முன் history -c-ஐப் பயன்படுத்துவதும் அதே விளைவைத் தரும், மேலும் எதுவும் நடக்காதது போலத் தோன்றும்.
ஒரே ஒரு வார்த்தையில் இதை நிறுத்தலாம். unset HISTFILE அந்த session-க்கான கோப்பு எழுதப்படுவதைத் தடுக்கிறது. set +o history பதிவை உடனடியாக நிறுத்துகிறது. HISTCONTROL=ignorespace ஒரு இடைவெளியுடன் (leading space) தட்டச்சு செய்யப்படும் அனைத்து கட்டளைகளையும் மறைக்கிறது. இவை அனைத்தும் man bash-ல் உள்ளன, ஏனெனில் இது பயனரின் கட்டுப்பாட்டில் இருக்க வேண்டும் என்ற நோக்கத்துடன் வடிவமைக்கப்பட்டுள்ளது.
இது தட்டச்சு செய்யப்பட்டதை மட்டுமே பதிவு செய்கிறது, இயக்கப்பட்டதை அல்ல. ஒரு alias அல்லது shell function இருந்தால், கோப்பில் உள்ள உரை kernel இயக்கிய நிரல் அல்ல.
இதில் நேர முத்திரைகளும் (timestamps) இல்லை. HISTTIMEFORMAT அமைக்கப்பட்டிருந்தால் மட்டுமே நேர முத்திரைகள் இருக்கும், ஏனெனில் bash அதன் #1755043200 குறிப்பான்களை அந்த variable அமைக்கப்பட்டிருக்கும்போது மட்டுமே எழுதும்.
பகிரப்பட்ட login-ல், இது யார் செய்தார்கள் என்பதையும் சொல்ல முடியாது. ஒரே deploy கணக்கைப் பயன்படுத்தும் மூன்று நபர்கள், ஒரே uid-ன் கீழ் ஒரு கோப்பை உருவாக்குகிறார்கள். இரண்டு நபர்கள் ஒரே uid-ஐப் பகிரும்போது, எந்த logging layer-ஆலும் ஒரு செயலை ஒரு குறிப்பிட்ட நபருடன் இணைக்க முடியாது. இதனால்தான் பகிரப்பட்ட login-க்கு பதிலாக ஒவ்வொரு நபருக்கும் ஒரு தனிப்பட்ட unprivileged கணக்கு இருக்க வேண்டும் என்பது நடைமுறை வாதமாக உள்ளது.
Shell history அதன் உண்மையான வேலைக்குச் சிறந்தது, அதாவது நேற்று நீங்கள் தட்டச்சு செய்த கட்டளையை மீண்டும் தட்டச்சு செய்ய உதவுவது. இதை ஒரு குறிப்பிற்காக மட்டும் பயன்படுத்தவும். ஒருபோதும் இதை ஆதாரமாக முன்வைக்காதீர்கள்.
sudo எதை பதிவு செய்கிறது மற்றும் அது எங்கே நின்றுவிடுகிறது
sudo தான் இயக்கும் ஒவ்வொரு கட்டளைக்கும் ஒரு வரியை authpriv syslog வசதிக்கு அனுப்புகிறது.
sudo grep 'sudo:' /var/log/auth.log | tail -5
journalctl -t sudo -n 5ஒவ்வொரு வரியும் பயனர், terminal, working directory, இலக்கு பயனர் மற்றும் கட்டளை ஆகியவற்றைக் குறிப்பிடுகிறது:
sudo: alice : TTY=pts/0 ; PWD=/home/alice ; USER=root ; COMMAND=/usr/bin/apt update/var/log/auth.log இல்லை என்றால், அந்த image-ல் rsyslog நிறுவப்படவில்லை என்று அர்த்தம், மேலும் அதே பதிவுகள் journal-ல் மட்டுமே இருக்கும். நீங்கள் அதை நம்புவதற்கு முன்பு, journal நிலையற்றதாக (volatile) இல்லை என்பதை உறுதிப்படுத்தவும்:
journalctl --list-bootsதற்போதைய boot மட்டுமே பட்டியலிடப்பட்டிருந்தால், /var/log/journal இல்லை என்று அர்த்தம், எனவே journal /run-ல் உள்ளது மற்றும் ஒவ்வொரு வரியும் அடுத்த reboot-ல் அழிந்துவிடும். அதை நிரந்தரமாக்குங்கள்:
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journaldஇப்போது வரம்பு. sudo தான் இயக்கக் கோரப்பட்ட கட்டளையை மட்டுமே பதிவு செய்கிறது. அந்த கட்டளை அதற்குப் பிறகு என்ன செய்கிறது என்பதை அது பதிவு செய்வதில்லை. எனவே ஒரு வரி தடத்தை முடித்துவிடுகிறது:
sudo -ilog-ல் shell-க்கான ஒரே ஒரு பதிவு மட்டுமே கிடைக்கும். அந்த root shell-க்குள் தட்டச்சு செய்யப்படும் ஒவ்வொரு கட்டளையும் sudo-க்குத் தெரியாது, ஏனெனில் sudo இனி அந்த path-ல் இல்லை. sudo su -, sudo bash, மற்றும் sudo vim /etc/shadow ஆகியவற்றைத் தொடர்ந்து வரும் :!bash அனைத்தும் ஒரே மாதிரியானவை. vim அல்லது find போன்ற shell escape வசதி கொண்ட எந்தவொரு நிரலையும் அனுமதிக்கும் sudoers விதி, பதிவு செய்யப்படாத root அனுமதியை வழங்கும் விதியாகும். ஒரு கணக்கின் log வரிகளை நம்புவதற்கு முன்பு, அந்த கணக்கு உண்மையில் எதை அணுக முடியும் என்பதைப் படியுங்கள்:
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 என்பதால் இது முக்கியமானது; எனவே, நீங்கள் வைத்திருப்பதாக நினைக்கும் ஒரு கட்டுப்பாட்டை upgrade நீக்கிவிடக்கூடும். sudo-rs செயல்பாட்டு மாற்றங்களின் முழுப் பட்டியல்-ஐ sudo-அடிப்படையிலான logging-ஐத் திட்டமிடுவதற்கு முன் படிப்பது நல்லது.
Ubuntu 24.04 LTS-ல் உள்ள அசல் sudo-வைப் பயன்படுத்தி, ஒரு கணக்கிற்கு I/O logging-ஐ இயக்கவும்:
sudo visudo -f /etc/sudoers.d/iologDefaults:deploy log_output
Defaults!/usr/bin/sudoreplay !log_outputஎடிட்டருக்குப் பதிலாக visudo-ஐப் பயன்படுத்தவும், ஏனெனில் பிழையான syntax கொண்ட கோப்பை அது சேமிக்க அனுமதிக்காது. சிதைந்த sudoers கோப்பு அனைவரையும் sudo-விலிருந்து வெளியேற்றிவிடும். பின்னர் ஒரு அமர்வை மீண்டும் இயக்கவும் (replay):
sudo sudoreplay -l user=deploy
sudo sudoreplay 000001sudoreplay -l அமர்வுகளை அவற்றின் ID-களுடன் பட்டியலிடும்; அந்த பயனருக்கு log_output ஒருபோதும் பயன்படுத்தப்படவில்லை என்றால் அது எதையும் காட்டாது. இதன் விளைவு: terminal வழியாகச் செல்லும் ஒவ்வொரு byte-ம் /var/log/sudo-io-ன் கீழ் சேமிக்கப்படும், எனவே விரிவான அமர்வுகள் அதிக இடத்தைப் பிடிக்கும். இரண்டாவது sudoers வரி, ஒரு replay-ஐ மீண்டும் பதிவு செய்வதைத் தடுக்கிறது. இதன் உண்மையான ஆபத்து ரகசியத் தகவல்கள் ஆகும்; ஏனெனில் I/O log தட்டச்சு செய்யப்பட்ட மற்றும் திரையில் காட்டப்பட்ட அனைத்தையும் சேமிக்கும், இதில் அமர்வுக்குள் கேட்கப்படும் password-களும் அடங்கும். எனவே, இதை ஒரு password store-க்கு இணையான பாதுகாப்போடு வைத்திருக்க வேண்டும். இதன் வரம்பும் குறுகியது. இது sudo வழியாக இயக்கப்படும் கட்டளைகளை மட்டுமே கவனிக்கும். ஒருவர் உள்நுழைந்து முழுமையாகத் தனது சொந்த கணக்கில் செயல்பட்டால், அது பதிவு செய்யப்படாது.
Shell hooks மற்றும் அவை எவ்வாறு தவிர்க்கப்படுகின்றன
"ஒவ்வொரு கட்டளையையும் பதிவு செய்" என்பதற்காகப் பரப்பப்படும் முறை, PROMPT_COMMAND hook-ஐ /etc/profile.d/-ல் சேர்ப்பதாகும்:
# /etc/profile.d/00-cmdlog.sh
PROMPT_COMMAND='logger -p local6.info -t cmdlog "$(whoami) $$ $(history 1 | sed "s/^ *[0-9]* *//")"'ஒவ்வொரு prompt-ஐயும் காண்பிப்பதற்கு முன்பு bash PROMPT_COMMAND-ஐ இயக்குகிறது. எனவே, கட்டளை முடிந்த பிறகு பதிவு செய்யப்படுவதற்குப் பதிலாக, தட்டச்சு செய்யப்படும்போதே அது syslog-க்குச் செல்கிறது. மேலும், logger system log daemon வழியாக எழுதுவதால், பயனரின் சொந்த file permissions இதில் எந்தத் தாக்கத்தையும் ஏற்படுத்தாது. ஒரு புதிய login shell-ஐத் திறந்து sudo tail -f /var/log/syslog மூலமாகவோ, அல்லது rsyslog இல்லாத image-ல் journalctl -t cmdlog -f மூலமாகவோ இதைச் சரிபார்க்கவும்.
ஆனால், பின்வரும் ஐந்து வழிகளில் இது வேலை செய்யாமல் போகும்; இவற்றை நீங்கள் ஒரு நிமிடத்தில் சோதித்துப் பார்க்கலாம்.
- Non-interactive shells ஒருபோதும் prompt-ஐக் காண்பிப்பதில்லை.
ssh you@server 'id'கட்டளையை இயக்கிவிட்டுத் திரும்பிவிடும், எதையும் பதிவு செய்யாது. ஏனெனில்PROMPT_COMMANDஒருபோதும் செயல்படுத்தப்படுவதில்லை. - இது ஒரு variable ஆகும்.
unset PROMPT_COMMANDஅந்த session-ன் மீதமுள்ள பகுதிக்கு இதை முடக்கிவிடும், இதற்கு எந்தவிதமான privilege-ம் தேவையில்லை. - இந்த file login shells-ஆல் மட்டுமே வாசிக்கப்படுகிறது.
bash --noprofile --norcஒருபோதும்/etc/profile.d/-ஐ source செய்வதில்லை. - இது bash-க்கு மட்டுமே உரியது.
zsh,sh,python3 -c 'import os; os.system("id")'மற்றும்:!idஆகிய அனைத்தும்vim-க்குள் இயங்கும். இவை எந்த bash prompt hook-க்கும் தெரிவதில்லை. - இது தட்டச்சு செய்தபடியே பதிவு செய்வதால், ஒரு alias அல்லது function உண்மையில் இயங்கிய கட்டளையை மறைத்துவிடும்.
Shell hook-ஐ ஒரு வசதிக்காக மட்டும் பயன்படுத்தவும். ஒத்துழைக்கும் பயனர்களுக்கு "கடந்த செவ்வாய்க்கிழமை நான் என்ன கட்டளையை இயக்கினேன்" என்ற கேள்விக்கு இது விடையளிக்கும். ஒரு checklist-ல் இதைக் கட்டுப்பாட்டு முறையாக (control) குறிப்பிட வேண்டாம்.
Kernel audit subsystem ஒவ்வொரு execve-ஐயும் கவனிக்கிறது
Linux audit subsystem, auditd daemon-ஆல் இயக்கப்படுகிறது. இதுவே பயனர் தவிர்க்க முடியாத ஒரே அடுக்கு ஆகும், ஏனெனில் syscall இயங்கும் தருணத்தில் kernel-க்குள்ளேயே பதிவு செய்யப்படுகிறது. ஒரு process நிரலை இயக்கினால், அங்கு ஒரு event உருவாகிறது. shell, programming language அல்லது terminal-ன் இருப்பு இதில் எந்த மாற்றத்தையும் ஏற்படுத்தாது.
sudo apt update && sudo apt install -y auditd audispd-plugins
sudo systemctl enable --now auditd
sudo auditctl -sauditctl -s daemon-ன் நிலையை அச்சிடும். enabled 1 கட்டளையுடன் பூஜ்ஜியமற்ற pid மதிப்பு இருந்தால், அது இயங்கிக்கொண்டிருக்கிறது என்று பொருள். lost 0 என்பது இதுவரை எந்தப் பதிவுகளும் இழக்கப்படவில்லை என்பதைக் குறிக்கிறது. அந்த lost counter-ஐ நினைவில் கொள்ளுங்கள், அது பிறகு தேவைப்படும்.
auid என்பது audit-ஐ பயனுள்ளதாக்கும் field ஆகும். ஒரு session தொடங்கும் போது PAM ஒரு login uid-ஐ அமைக்கும், அதன் பிறகு வரும் அனைத்து child process-களுக்கும் kernel அதைத் தொடரும். உங்களுடையதைச் சரிபார்க்கவும்:
cat /proc/self/loginuidஒரு interactive SSH session உங்கள் uid-ஐ அச்சிடும், ஏனெனில் /etc/pam.d/sshd-ல் pam_loginuid.so அடங்கும். 4294967295 மதிப்பு என்பது loginuid அமைக்கப்படவில்லை என்று பொருள்; boot-ன் போது system daemon-ஆல் தொடங்கப்படும் process-களுக்கு இது இயல்பானது. முக்கியமான விஷயம் என்னவென்றால், sudo -i இதை மாற்றாது: alice-ஆல் திறக்கப்பட்ட root shell-லும் auid 1000-ஆகவே இருக்கும், எனவே அதற்குள் இயங்கும் ஒவ்வொரு கட்டளையும் alice-க்கு உரியதாகவே கருதப்படும். இதுவே sudo விட்டுச்செல்லும் இடைவெளி. ஒருமுறை அமைக்கப்பட்ட loginuid-ஐ மாற்ற CAP_AUDIT_CONTROL தேவை, இது சாதாரண பயனர்களுக்கு இருக்காது. மேலும், sudo auditctl --loginuid-immutable அடுத்த reboot வரை root-க்கும் இதை மூடிவிடும்.
/etc/pam.d/sshd, /etc/pam.d/login மற்றும் /etc/pam.d/cron ஒவ்வொன்றிலும் pam_loginuid.so உள்ளதா என்பதைச் சரிபார்க்கவும், இல்லையெனில் எந்தப் பயனரும் இணைக்கப்படாத நிகழ்வுகள் வந்து சேரும். VPS-ல் SSH access-ஐ பலப்படுத்துதல் என்ற பகுதியில் நீங்கள் கையாளும் அதே கோப்புப் பட்டியல் இதுதான், எனவே அந்த இரண்டு பணிகளையும் ஒன்றாகச் செய்யவும்.
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 -lauditctl -l உங்கள் விதிகளைத் திரும்பக் காட்டினால், அவை செயல்பாட்டில் உள்ளன என்று அர்த்தம். No rules என்றால் ஏற்றுதல் தோல்வியடைந்தது என்று பொருள், மேலும் journalctl -u auditd -n 20 அந்தப் பிழையான கோப்பு மற்றும் வரியைக் குறிப்பிடும். பழைய audit userspace-க்கு unset keyword புரியாது. loader அந்தப் புலத்தைப் பற்றி புகார் அளித்தால், அதற்குப் பதிலாக -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 பதிவு, முழுமையான argument பட்டியலைக் கொண்ட EXECVE பதிவு, மற்றும் சூழலுக்கான CWD மற்றும் PATH பதிவுகள்.
ஒரு முக்கியமான வரம்பு: audit என்பது syscall-களை மட்டுமே பதிவு செய்யும், shell builtin-கள் சொந்தமாக எந்த syscall-ஐயும் உருவாக்குவதில்லை. cd /root எந்த நிரலையும் இயக்குவதில்லை. bash prompt-ல் தட்டச்சு செய்யப்படும் echo evil >> /etc/passwd-ம் எந்த நிரலையும் இயக்குவதில்லை, ஏனெனில் echo மற்றும் redirect ஆகிய இரண்டும் ஏற்கனவே இயங்கிக்கொண்டிருக்கும் shell process-க்குள்ளேயே நடக்கின்றன. எனவே, execve விதிகள் நிரல்களைப் பார்க்கின்றன, -w விதிகள் எழுதும் செயல்களைப் பார்க்கின்றன. இவை இரண்டில் ஒன்று மட்டும் போதாது.
இறுதியாக, configuration-ஐப் பூட்டவும்:
## /etc/audit/rules.d/99-finalize.rules
-e 2-e 2 அடுத்த reboot வரை விதித் தொகுப்பை மாற்ற முடியாததாக (immutable) மாற்றுகிறது. இது ஏற்றப்பட்ட பிறகு, auditctl -s என்பது enabled 2 என்று காட்டும், மேலும் root பயனராக இருந்தாலும் விதியைச் சேர்க்கவோ நீக்கவோ முயற்சித்தால் Operation not permitted பிழை ஏற்படும். இந்தக் கோப்பை இறுதியாகச் சேர்க்கவும், விதியை மாற்ற விரும்பும் போதெல்லாம் reboot செய்யத் தயாராக இருக்கவும். இந்த வரம்புதான் இதன் நோக்கம்: யாராலும் எளிதாக அணைக்கக்கூடிய விதித் தொகுப்பு ஆதாரமாக இருக்க முடியாது.
யாரும் வாசிக்காத audit log என்பது ஒரு compliance ஆவணம் மட்டுமே
auditd-ன் தோல்விக்குக் காரணம் அது தகவல்களைத் தவறவிடுவது அல்ல. அது மிக அதிகப்படியான தகவல்களைப் பதிவு செய்வதால், யாரும் அதைப் பார்ப்பதில்லை. ஒரு கேள்விக் குப் பதில் தேடுவதற்குப் பதிலாக, ஒரு சரிபார்ப்புப் பட்டியலை (checklist) நிறைவு செய்வதற்காக மட்டுமே அந்த log கோப்பு அங்கு இருக்கிறது.
எந்தவொரு மாற்றத்தையும் செய்வதற்கு முன், உங்கள் server-ல் கணக்கீட்டைச் செய்து பாருங்கள்:
sudo aureport -k --summary -i
sudo du -sh /var/log/auditஒரே ஒரு sudo apt upgrade ஆயிரக்கணக்கான குறுகிய கால process-களை இயக்குகிறது. ஒவ்வொன்றும் உங்கள் auid-ஐக் கொண்டிருப்பதால், ஒரு package update-ஆனது ஒரு வார கால மனித செயல்பாட்டை விட அதிக log-களை உருவாக்கிவிடும். இதனால்தான் மேலே உள்ள suppressions-ல் dpkg மற்றும் அதன் உதவியாளர்களைக் குறிப்பிட்டுள்ளோம். Executable மூலம் suppress செய்யுங்கள், ஒருபோதும் user மூலம் செய்யாதீர்கள்: /usr/bin/dpkg-க்கான விலக்கு என்பது ஒரு வரியில் விவரிக்கக்கூடிய ஒரு பாதுகாப்பு ஓட்டை; ஆனால் ஒரு account-க்கான விலக்கு என்பது நீங்கள் எதைக் கண்டுபிடிக்க முயன்றீர்களோ, அதே வடிவில் இருக்கும் ஒரு பாதுகாப்பு ஓட்டை.
ஒவ்வொரு விதியிலும் உள்ள -k key-தான், ஒரு மாதம் கழித்து log-ஐத் தேடக்கூடியதாக மாற்றுகிறது. ausearch -k sudoers என்பது ஒரு கேள்விக்கான பதில். வடிகட்டி (filter) இல்லாத ausearch என்பது வாசிப்பதையே தவிர்க்கத் தூண்டும் ஒரு நீண்ட உரைச் சுவர். உங்கள் collector-க்கு native format-க்கு பதிலாக JSON தேவைப்பட்டால், laurel என்ற auditd plugin-ஐப் பயன்படுத்தலாம். இது ஒவ்வொரு நிகழ்வையும் decoded arguments கொண்ட ஒரு JSON object-ஆக மாற்றுகிறது. இது மற்ற plugin-களைப் போலவே /etc/audit/plugins.d/-ல் பதிவு செய்யப்படுகிறது, மேலும் sudo pkill -HUP auditd-ல் ஏற்படும் மாற்றங்களை auditd தானாகவே எடுத்துக்கொள்ளும்.
auditd-ன் உண்மையான செலவுகள்
ஒவ்வொரு பொருத்தமான syscall-ம் ஒரு பதிவாக (record) மாறுகிறது; அதை kernel வடிவமைத்து userspace-க்கு வழங்குகிறது. இதன் செலவு இரண்டு இடங்களில் ஏற்படுகிறது. மற்றவர்கள் வெளியிடும் எண்களை வைத்து ஊகிப்பதை விட, உங்கள் சொந்த பணிச்சுமையில் (workload) இதை அளவிட முடியும்.
- CPU மற்றும் latency: தொடர்ந்து fork செய்யும் ஒரு machine, அதாவது build host அல்லது CI runner, ஒவ்வொரு exec-க்கும் ஒரு பதிவை உருவாக்குகிறது. Kernel backlog நிரம்பும்போது,
--backlog_wait_timeஅந்த நிகழ்வை உருவாக்கிய process-ஐ, இடம் கிடைக்கும் வரை தற்காலிகமாக நிறுத்தி வைக்கும். எனவே, audit என்பது CPU சதவீதமாகத் தெரியாமல், மெதுவான build-களாகவே வெளிப்படும். உண்மையான பணிச்சுமையின் கீழ்sudo auditctl -s-ல்backlogமற்றும்lost-ஐக் கவனிக்கவும்.lostஅதிகரிப்பது என்பது பதிவுகள் கைவிடப்படுகின்றன (dropped) என்று பொருள். பதிவுகளில் இடைவெளி இருப்பது, பதிவு இல்லாமலிருப்பதை விட மோசமானது; ஏனெனில் நீங்கள் அதை இன்னும் நம்பிக் கொண்டிருப்பீர்கள். - Disk:
/etc/audit/auditd.conf-ஐப் படித்து, disk நிரம்பும்போது என்ன நடக்க வேண்டும் என்பதைத் திட்டமிட்டு முடிவு செய்யுங்கள். ஏனெனில், ஏற்கனவே உள்ள மதிப்புகள் வெறும் கருத்துகளே.max_log_file,num_logsமற்றும்max_log_file_actionஆகியவை rotation-ஐக் கட்டுப்படுத்துகின்றன.space_left_action,admin_space_left_actionமற்றும்disk_full_actionஆகியவை அவசரநிலையைக் கட்டுப்படுத்துகின்றன. இதில்haltமற்றும்singleபோன்ற சில செயல்கள், ஒரு பதிவை இழப்பதை விட machine-ஐ நிறுத்திவிடும் (take down).
/etc/audit/rules.d/audit.rules-ல் உள்ள -f வரி என்பது kernel மட்டத்தில் எடுக்கப்படும் அதே முடிவாகும்: -f 1 ஒரு audit தோல்வியை syslog-க்குத் தெரிவிக்கும், -f 2 kernel-ஐ panic நிலைக்குத் தள்ளும். ஒரு பதிவை இழப்பதை விட server-ஐ இழப்பதே மேல் என்று நீங்கள் உண்மையாகவே கருதினால் மட்டுமே 2-ஐத் தேர்ந்தெடுக்கவும். மக்கள் சார்ந்திருக்கும் ஒரு VPS-ல், rotation-ஐப் பயன்படுத்தி, சேமிப்புச் சிக்கலை அந்த machine-லிருந்து வெளியேற்றுவதே சிறந்தது.
Logs-ஐ நிகழ்நேரத்திற்கு அருகாமையில் server-லிருந்து வெளியேற்றுதல்
Incident write-up-கள் மீண்டும் மீண்டும் நிரூபிக்கும் பகுதி இதுதான். Compromised ஆன host-லேயே இருக்கும் logs-ஐ, அதை முடக்கிய நபர் மாற்றியமைக்க முடியும். Root பயனர் /var/log/auth.log-ஐ மாற்றியமைக்கலாம், /var/log/audit/audit.log-ஐ நீக்கலாம், மற்றும் daemon-ஐ நிறுத்தலாம். -e 2 விதிகளை நீக்குவதைத் தடுக்கும். ஆனால் அது rm-க்கு எதிராக எதையும் செய்யாது. ஒரு நகல் முதலில் அந்த machine-ஐ விட்டு வெளியேறினால் மட்டுமே, அதற்கு மேல் உள்ள ஒவ்வொரு அடுக்கிலும் ஆதாரங்கள் கிடைக்கும்.
Audit-ன் சொந்த transport வசதி audispd-plugins-லிருந்து வரும் audisp-remote plugin ஆகும். இதை /etc/audit/plugins.d/au-remote.conf-ல் இயக்கவும்:
active = yes
direction = out
path = /usr/sbin/audisp-remote
type = always
format = stringநீங்கள் reload செய்வதற்கு முன் command -v audisp-remote-க்கு எதிராக path-ஐ சரிபார்க்கவும், ஏனெனில் தவறான path இருந்தால் journal-ல் ஒரு வரியைத் தவிர வேறு எதுவும் கிடைக்காது. /etc/audit/audisp-remote.conf-ல் remote_server மற்றும் port ஆகியவற்றை அமைக்கவும், மேலும் collector-ல் அதன் சொந்த auditd.conf-ல் tcp_listen_port = 60-ஐ அமைக்கவும். sudo pkill -HUP auditd மூலம் reload செய்யவும். பல images-ல் systemctl restart auditd நிராகரிக்கப்படுகிறது, ஏனெனில் unit file RefuseManualStop=yes-ஐ அமைக்கிறது, எனவே signal-ஐப் பயன்படுத்துவதே நம்பகமான வழியாகும்.
மற்றொரு விருப்பம், audit-ஐ நீங்கள் ஏற்கனவே forward செய்யும் syslog stream-க்குள் கொண்டு செல்வதாகும். active = no உடன் /etc/audit/plugins.d/syslog.conf வருகிறது. அதை yes என அமைத்து, reload செய்யவும்; இப்போது audit நிகழ்வுகள் sudo-வின் வரிகள் மற்றும் பிறவற்றோடு இணைந்துவிடும். பின்னர் rsyslog-gnutls package தேவைப்படும் rsyslog over TLS (transport layer security) மூலம் அனைத்தையும் forward செய்யவும்:
# /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" எப்போதும் மீண்டும் முயற்சிக்கும், மேலும் queue.saveOnShutdown="on" கொண்ட disk-assisted queue, collector-ஐ அணுக முடியாதபோது பதிவுகளைத் தக்கவைத்துக்கொள்ளும், பின்னர் அது மீண்டும் இணைந்தவுடன் அவற்றை அனுப்பும். இந்த இரண்டு அமைப்புகளும் இல்லையென்றால், collector reboot ஆகும்போது உங்கள் ஆதாரங்களில் இடைவெளி ஏற்படும், அந்த இடைவெளி இருப்பதை உங்களுக்குத் தெரிவிக்க எந்த வழியும் இருக்காது. sudo systemctl restart rsyslog மூலம் நடைமுறைப்படுத்தவும், பின்னர் எதையும் நம்புவதற்கு முன்பு பதிவுகள் collector-க்கு வந்து சேருகின்றனவா என்பதை உறுதிப்படுத்தவும்.
முடிக்க வேண்டிய கடைசி விஷயம்: audited செய்யப்படும் நபர்கள் login செய்ய முடியாத ஒரு machine-ஆக collector இருக்க வேண்டும். அதே admin குழு log server-லும் root உரிமையைக் கொண்டிருந்தால், நீங்கள் கோப்பை நகலெடுத்திருக்கிறீர்கள், பாதுகாக்கவில்லை. தனித்தனி credentials, தனித்தனி keys, மற்றும் முடிந்தால் தனித்தனி provider account-ஐப் பயன்படுத்தவும். பல Linux servers-ஐ நிர்வகிக்கும் ஒரு மையப்படுத்தப்பட்ட வழிமுறையை உங்களுக்குத் தேவைப்படுவதற்கு முன்பே உருவாக்குவது ஏன் முக்கியம் என்பதற்கான அதே காரணம் இதுதான். Compromised ஆன 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, ஏனெனில் audit log பயன்முறை 600 மற்றும் root-க்கு சொந்தமானது; இயங்க மறுக்கும் பிழை, ஏனெனில் audit விதிகளை மாற்ற CAP_AUDIT_CONTROL தேவை; மற்றும் adm அல்லது systemd-journal ஆகிய இரண்டையும் கொண்டிருக்காத ஒரு குழு பட்டியல்.
அந்த கடைசி சோதனையில்தான் பலர் தவறு செய்கிறார்கள். adm-ல் உறுப்பினராக இருப்பது /var/log/auth.log-ஐ வாசிக்க அனுமதி அளிக்கும், மேலும் systemd-journal-ல் உறுப்பினராக இருப்பது முழு journal-ஐயும் வாசிக்க அனுமதி அளிக்கும். இவை இரண்டுமே எழுதும் அனுமதியை வழங்காது, எனவே இவை எதையும் மாற்ற அனுமதிக்காது. இவை இரண்டுமே ஒரு நபர் கணினியில் உள்ள ஒவ்வொரு அங்கீகார வரியையும் வாசிக்க அனுமதிக்கும், இது ஒரு forum பதிலிலிருந்து usermod -aG வரியை நகலெடுப்பதன் மூலம் அல்லாமல், திட்டமிட்டு எடுக்கப்பட வேண்டிய முடிவாகும்.
இறுதியாக, reboot-க்கு பிறகும் நிலைத்திருக்க வேண்டிய இரண்டு விஷயங்களை உறுதிப்படுத்தவும்:
sudo auditctl -s
systemctl is-enabled auditdenabled 2 என்பது அடுத்த boot வரை விதிகளின் தொகுப்பு பூட்டப்பட்டிருப்பதைக் குறிக்கிறது. இரண்டாவது கட்டளையிலிருந்து வரும் enabled என்பது அந்த boot-க்கு பிறகு auditd மீண்டும் தொடங்குவதைக் குறிக்கிறது. அடுத்த kernel update வரை மட்டுமே நீடிக்கும் விதிகளின் தொகுப்பு ஒரு audit trail ஆகாது.
FAQ
ஒரு குறிப்பிட்ட பயனர் இயக்கிய அனைத்து கட்டளைகளையும் நான் எவ்வாறு பார்ப்பது?
id -u alice மூலம் அவர்களின் uid-ஐக் கண்டறியவும், பின்னர் sudo ausearch -ul 1000 -ts today -i மூலம் audit log-ல் login uid-ஐத் தேடவும். execve விதிக்கு மட்டும் கட்டுப்படுத்த -k exec-ஐச் சேர்க்கவும். login uid என்பது login செய்யும்போதே அமைக்கப்பட்டு, su மற்றும் sudo -i-க்குப் பிறகும் மாறாமல் இருக்கும். எனவே, அந்த கணக்கின் மூலம் திறக்கப்பட்ட root shell-க்குள் இயக்கப்பட்ட கட்டளைகளையும் இது கண்டறியும். audit விதிகள் ஏற்றப்பட்ட பிறகு இயக்கப்பட்ட கட்டளைகளுக்கு மட்டுமே இது வேலை செய்யும், ஏனெனில் பதிவு செய்யப்படாத நிகழ்வுகளின் வரலாற்றை audit பராமரிப்பதில்லை. தரவுகளின் தன்மையை முதலில் பார்க்க விரும்பினால், sudo aureport -k --summary -i ஒவ்வொரு விதிக்கும் எத்தனை பதிவுகள் உள்ளன என்பதைக் காட்டும்.
ஒரு பயனர் தான் இயக்கியவற்றை மறைக்க bash history-ஐ நீக்க முடியுமா?
ஆம், இதற்கு எந்தவிதமான சிறப்பு அனுமதியும் தேவையில்லை. ~/.bash_history அந்த பயனரின் உரிமையிலேயே 600 mode-ல் இருப்பதால், அவர்கள் அதைத் திருத்தவோ, சுருக்கவோ அல்லது நீக்கவோ முடியும். unset HISTFILE மூலம் அதை எழுதுவதைத் தடுக்கலாம், set +o history மூலம் அமர்வின் நடுவில் பதிவு செய்வதை நிறுத்தலாம், அல்லது HISTCONTROL=ignorespace அமைக்கப்பட்டிருக்கும்போது கட்டளைக்கு முன்னால் ஒரு space விட்டுத் தட்டச்சு செய்வதன் மூலம் தனிப்பட்ட கட்டளைகளை மறைக்கலாம். shell வெளியேறும்போதுதான் Bash கோப்பை எழுதுகிறது, எனவே kill -9 $$ மூலம் கொல்லப்பட்ட அமர்வு எதையும் பதிவு செய்யாது. shell history-ஐ ஒரு குறிப்பாய் மட்டுமே கருத வேண்டும், ஆதாரமாக அல்ல.
sudo -i-க்குள் நடப்பவற்றை sudo பதிவு செய்யுமா?
இல்லை. sudo தான் இயக்க வேண்டிய கட்டளையை மட்டுமே பதிவு செய்கிறது, எனவே sudo -i shell-க்கு ஒரு வரியை மட்டுமே உருவாக்கும், அதற்குப் பிறகு எதையும் பதிவு செய்யாது. அந்த root shell-க்குள் தட்டச்சு செய்யப்படும் ஒவ்வொரு கட்டளையும் sudo-வுக்குத் தெரியாது, ஏனெனில் அந்தச் செயல்பாட்டில் sudo-வின் பங்கு முடிந்துவிடுகிறது. sudo su -, sudo bash மற்றும் shell escape வசதி கொண்ட எந்தவொரு அனுமதிக்கப்பட்ட நிரலும் இதேபோல் தான் செயல்படும். இந்த இடைவெளியை இரண்டு விஷயங்கள் சரிசெய்யும்: execve மீதான audit விதிகள், இவை அசல் login uid-உடன் ஒவ்வொரு நிரலையும் பதிவு செய்யும்; மற்றும் shell-ஐ வழங்காத sudoers விதிகள்.
auditd எனது server-ன் வேகத்தைக் குறைக்குமா?
இது உங்கள் workload எத்தனை process-களைத் தொடங்குகிறது என்பதைப் பொறுத்தது, எனவே ஒரு குறிப்பிட்ட எண்ணை நம்புவதை விட அதை அளவிடுவது சிறந்தது. பெரும்பாலும் கோரிக்கைகளுக்குப் பதிலளிக்கும் ஒரு server-ல் மிகக் குறைவான exec-களே நடக்கும், அங்கு பாதிப்பு தெரியாது. ஆனால், ஒரு build host அல்லது CI runner-ல் தொடர்ந்து exec நடக்கும், அங்கு பாதிப்பு அதிகமாக இருக்கலாம். kernel audit backlog நிரம்பும்போது, நிகழ்வை உருவாக்கிய process, இடம் கிடைக்கும் வரை இடைநிறுத்தப்படும். உண்மையான load இருக்கும்போது sudo auditctl -s-ஐ இயக்கி, backlog மற்றும் lost-ஐக் கவனிக்கவும். lost பூஜ்ஜியத்திற்கு மேல் இருந்தால், பதிவுகள் கைவிடப்பட்டுள்ளன என்று அர்த்தம். இதுவே மோசமான விளைவு, ஏனெனில் log-ல் மறைக்கப்பட்ட இடைவெளிகள் உருவாகிவிடும்.
audit logs எங்கே சேமிக்கப்பட வேண்டும்?
விநாடிகளில் அளவிடக்கூடிய தாமதத்துடன், மற்றொரு கணினியில் சேமிக்கப்பட வேண்டும். audited host-ல் root அனுமதியைப் பெறும் எவரும் /var/log/audit/audit.log-ஐ நீக்கிவிட்டு /var/log/auth.log-ஐ மீண்டும் எழுத முடியும். எனவே, உள்ளூர் பிரதிகள் யாரும் மறைக்க முயற்சிக்காத நிகழ்வுகளைப் பற்றி மட்டுமே பதிலளிக்கும். audisp-remote plugin மூலம் ஒரு மையப்படுத்தப்பட்ட auditd-க்கு அனுப்பவும், அல்லது audit syslog plugin-ஐ இயக்கி rsyslog மூலம் TLS வழியாக முழு syslog stream-ஐயும் அனுப்பவும். சேகரிக்கும் கணினிக்குத் தனிப்பட்ட credentials-ஐ வழங்கவும், மேலும் audited செய்யப்படும் கணக்குகளுக்கு அதற்கு அணுகல் இல்லை என்பதை உறுதிப்படுத்தவும்.