SSD Nodes Learn 🎉 VPS $5.50/ماہ سے
تعلیمی Matt Connorتحریر: Matt Connor

سرور پر صارفین کی کمانڈز کا آڈٹ کیسے کریں

Shell history قابل اعتماد نہیں ہے۔ sudo لاگنگ، سیشن ریکارڈنگ، shell hooks اور auditd execve رولز کا موازنہ کریں اور لاگز کو سرور سے باہر محفوظ کرنے کا طریقہ سیکھیں۔

سرور پر صارفین کے چلائے گئے کمانڈز کا ریکارڈ کیسے رکھا جاتا ہے

سرور پر صارفین کے چلائے گئے کمانڈز کا آڈٹ کرنے کے لیے آپ کو ایسے ریکارڈ کی ضرورت ہے جسے صارف تبدیل نہ کر سکے۔ Shell history ایسا ریکارڈ نہیں ہے۔ یہ صرف سہولت کے لیے ایک فائل ہے، جس کا مالک وہی اکاؤنٹ ہوتا ہے جس نے اسے لکھا ہے، اور جو بھی اس شیل میں ٹائپ کر سکتا ہے وہ اسے بند یا حذف بھی کر سکتا ہے۔

چار تہیں ایک حقیقی ریکارڈ برقرار رکھتی ہیں، اور ہر ایک کی اپنی قیمت ہے۔ sudo ہر کمانڈ کی ایک لائن syslog میں لکھتا ہے۔ sudo I/O logging ایک اکاؤنٹ کے پورے سیشن کو محفوظ کرتی ہے۔ ایک shell hook جیسے کہ PROMPT_COMMAND، یہ لاگ کرتا ہے کہ ایک انٹرایکٹو bash صارف نے کیا ٹائپ کیا۔ kernel audit subsystem خود execve syscall کو ریکارڈ کرتا ہے، اسی لیے یہ واحد تہہ ہے جو ہر عمل (process) کو دیکھتی ہے۔ یہ گائیڈ اس سیڑھی پر اوپر چڑھتی ہے، بتاتی ہے کہ ہر تہہ کہاں رکتی ہے، اور اس حصے پر ختم ہوتی ہے جو یہ فیصلہ کرتا ہے کہ آیا ان میں سے کوئی بھی چیز کارآمد ہے یا نہیں: یعنی ریکارڈز کو مشین سے باہر منتقل کرنا، اس سے پہلے کہ وہ شخص جس کا آپ آڈٹ کر رہے ہیں ان تک پہنچ سکے۔

شروع کرنے سے پہلے ایک انتباہ۔ audit subsystem کرنل کا کام ہے، لہذا ان میں سے کسی کو بھی ایسے کنٹینر کے اندر ٹیسٹ نہیں کیا جا سکتا جو ہوسٹ کرنل کا اشتراک کرتا ہو۔ ان کمانڈز کو KVM VPS پر چلائیں جہاں کرنل آپ کا اپنا ہو۔

شیل ہسٹری آڈٹ ٹریل کیوں نہیں ہے

~/.bash_history چار عام وجوہات کی بنا پر ثبوت کے طور پر ناکام ہو جاتی ہے، اور ان میں سے کسی کے لیے بھی کسی ہوشیار حملہ آور کی ضرورت نہیں ہے۔

یہ صارف کی ملکیت ہے۔ فائل کا موڈ 600 ہے اور اس کا مالک وہی اکاؤنٹ ہے، لہذا rm ~/.bash_history کو کسی استحقاق (privilege) کی ضرورت نہیں ہے۔ اسے کسی ایڈیٹر میں کھول کر وہ بیس لائنیں حذف کر دینا بھی اتنا ہی آسان ہے جو اہم ہیں۔

یہ شیل کے بند ہونے پر لکھی جاتی ہے۔ کوئی سیشن جو kill -9 $$ کے ساتھ ختم ہو، یا جس کا کنکشن منقطع ہو جائے، کچھ بھی نہیں لکھتا۔ exit سے پہلے history -c کا بھی یہی اثر ہوتا ہے اور ایسا لگتا ہے جیسے کچھ ہوا ہی نہ ہو۔

یہ ایک لفظ سے بند ہو جاتی ہے۔ unset HISTFILE اس سیشن کے لیے فائل میں کچھ بھی لکھنے سے روک دیتا ہے۔ set +o history ریکارڈنگ کو فوری طور پر بند کر دیتا ہے۔ HISTCONTROL=ignorespace شروع میں اسپیس کے ساتھ ٹائپ کی گئی ہر کمانڈ کو چھپا دیتا ہے۔ یہ سب man bash میں موجود ہے، کیونکہ اس کا مقصد صارف کے کنٹرول میں رہنا ہے۔

یہ وہ ریکارڈ کرتی ہے جو ٹائپ کیا گیا، نہ کہ وہ جو چلا۔ کسی عرفی نام (alias) یا شیل فنکشن کا مطلب یہ ہے کہ فائل میں موجود متن وہ پروگرام نہیں ہے جسے کرنل نے چلایا تھا۔

اس میں ٹائم اسٹیمپ بھی نہیں ہوتے، سوائے اس کے کہ جب اندراج لکھا جا رہا ہو تو HISTTIMEFORMAT سیٹ ہو، کیونکہ bash اپنے #1755043200 مارکر لائنز تبھی لکھتا ہے جب وہ ویری ایبل سیٹ ہو۔

مشترکہ لاگ ان پر یہ یہ بھی نہیں بتا سکتی کہ کون تھا۔ ایک 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 میں رہتا ہے اور ہر لائن اگلے ریبوٹ پر ختم ہو جاتی ہے۔ اسے مستقل بنائیں:

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

اب حد کی بات۔ sudo صرف اس کمانڈ کو لاگ کرتا ہے جسے چلانے کے لیے کہا گیا ہو۔ یہ اس بات کو لاگ نہیں کرتا کہ وہ کمانڈ بعد میں کیا کرتی ہے۔ لہذا ایک لائن ٹریل کو ختم کر دیتی ہے:

sudo -i

لاگ میں شیل (shell) کے لیے صرف ایک ریکارڈ آتا ہے۔ اس روٹ شیل کے اندر ٹائپ کی گئی ہر کمانڈ sudo کی نظروں سے اوجھل ہوتی ہے، کیونکہ sudo اب راستے (path) میں نہیں ہوتا۔ sudo su -، sudo bash، اور sudo vim /etc/shadow کے بعد :!bash سب ایک ہی شکل رکھتے ہیں۔ sudoers کا کوئی ایسا اصول جو شیل اسکیپ (shell escape) والی کسی بھی پروگرام کو اجازت دیتا ہو، جیسے کہ vim یا find، دراصل غیر لاگ شدہ روٹ رسائی فراہم کرنے والا اصول ہے۔ کسی اکاؤنٹ پر بھروسہ کرنے سے پہلے یہ پڑھ لیں کہ وہ اصل میں کہاں تک رسائی حاصل کر سکتا ہے:

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 کو غیر معاون (not supported) قرار دیا گیا ہے، اور اگست 2026 تک یہ بات درست تھی۔ یہ اہم ہے کیونکہ ان releases میں sudo-rs ڈیفالٹ sudo ہے، لہذا اپ گریڈ کرنے سے وہ کنٹرول ختم ہو سکتا ہے جس کے بارے میں آپ کا خیال تھا کہ وہ موجود ہے۔ sudo-rs کے رویے میں تبدیلیوں کی مکمل فہرست کو پڑھنا کسی بھی sudo پر مبنی لاگنگ کی منصوبہ بندی سے پہلے ضروری ہے۔

اصل 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 کا استعمال کریں، کیونکہ یہ ایسی فائل کو محفوظ کرنے سے انکار کر دیتا ہے جو پارس (parse) نہ ہو سکے۔ ایک خراب sudoers فائل ہر کسی کو sudo سے باہر کر دیتی ہے۔ اس کے بعد سیشن کو دوبارہ چلائیں (replay):

sudo sudoreplay -l user=deploy
sudo sudoreplay 000001

sudoreplay -l سیشنز کو ان کی IDs کے ساتھ دکھاتا ہے اور اگر log_output اس صارف پر کبھی لاگو نہیں ہوا تو کچھ بھی پرنٹ نہیں کرتا۔ اس کی قیمت: ٹرمینل سے گزرنے والا ہر بائٹ /var/log/sudo-io کے تحت محفوظ ہوتا ہے، لہذا ایک طویل سیشن کافی جگہ لے سکتا ہے۔ sudoers کی دوسری لائن ری پلے کو خود کو ریکارڈ کرنے سے روکتی ہے۔ اصل قیمت خفیہ معلومات (secrets) کی ہے، کیونکہ ایک I/O لاگ میں وہ سب کچھ محفوظ ہوتا ہے جو ٹائپ کیا گیا یا پرنٹ ہوا، بشمول سیشن کے اندر پرامپٹ میں ٹائپ کیا گیا پاس ورڈ، لہذا اسے پاس ورڈ اسٹور جیسی حفاظت کی ضرورت ہوتی ہے۔ اس کا دائرہ کار بھی محدود ہے۔ یہ صرف ان کمانڈز کو دیکھتا ہے جو sudo کے ذریعے چلائی جاتی ہیں۔ کوئی شخص جو لاگ ان ہو کر مکمل طور پر اپنے طور پر کام کرتا ہے، وہ بالکل ریکارڈ نہیں ہوتا۔

Shell hooks، اور ان کو بائی پاس کرنے کا طریقہ

"ہر کمانڈ کو لاگ کرنے" کے لیے جو نسخہ گردش کرتا ہے وہ ایک 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 کے ساتھ چیک کریں، یا ایسے امیج پر journalctl -t cmdlog -f استعمال کریں جس میں rsyslog نہ ہو۔

پھر یہ پانچ طریقوں سے کام کرنا چھوڑ دیتا ہے، جنہیں آپ ہر منٹ میں دہرا سکتے ہیں۔

  • نان انٹرایکٹو شیل کبھی پرامپٹ ڈرا نہیں کرتے۔ ssh you@server 'id' کمانڈ چلاتا ہے اور واپس آ جاتا ہے، اور کچھ بھی لاگ نہیں ہوتا، کیونکہ PROMPT_COMMAND کبھی ایویلیویٹ نہیں ہوا۔
  • یہ ایک ویری ایبل ہے۔ unset PROMPT_COMMAND اسے سیشن کے باقی حصے کے لیے غیر فعال کر دیتا ہے اور اس کے لیے کسی استحقاق (privilege) کی ضرورت نہیں ہوتی۔
  • فائل کو لاگ ان شیلز پڑھتے ہیں۔ bash --noprofile --norc کبھی بھی /etc/profile.d/ کو سورس نہیں کرتا۔
  • یہ bash تک محدود ہے۔ zsh، sh، python3 -c 'import os; os.system("id")' اور :!id جو vim کے اندر ہوتے ہیں، وہ سب ایسے پروگرام چلاتے ہیں جنہیں کوئی بھی bash پرامپٹ ہک کبھی نہیں دیکھ پائے گا۔
  • یہ لائن کو اسی طرح لاگ کرتا ہے جیسے ٹائپ کی گئی ہو، لہذا ایک عرفی نام (alias) یا فنکشن اب بھی اس کمانڈ کو چھپا دیتا ہے جو اصل میں چلی تھی۔

شیل ہک کو سہولت کے طور پر استعمال کریں۔ یہ تعاون کرنے والے صارفین کے لیے "میں نے گزشتہ منگل کو کیا چلایا تھا" کا جواب دیتا ہے۔ کسی چیک لسٹ کو اسے کنٹرول کا نام نہ دینے دیں۔

کرنل کا آڈٹ سب سسٹم ہر execve کو دیکھتا ہے

Linux آڈٹ سب سسٹم، جو auditd ڈیمن کے ذریعے چلتا ہے، یہاں واحد ایسی تہہ ہے جسے صارف نظر انداز نہیں کر سکتا، کیونکہ ریکارڈ کرنل کے اندر اسی لمحے بن جاتا ہے جب syscall چلتا ہے۔ اگر کوئی پروسیس پروگرام ایگزیکیوٹ کرتا ہے، تو ایک ایونٹ بنتا ہے۔ شیل، لینگویج اور ٹرمینل کی موجودگی سے کوئی فرق نہیں پڑتا۔

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 سیشن شروع ہوتے وقت ایک login uid سیٹ کرتا ہے، اور کرنل اس کے بعد سے ہر چائلڈ پروسیس پر اسے برقرار رکھتا ہے۔ اپنا چیک کریں:

cat /proc/self/loginuid

ایک انٹرایکٹو SSH سیشن آپ کا uid پرنٹ کرتا ہے، کیونکہ /etc/pam.d/sshd میں pam_loginuid.so شامل ہے۔ 4294967295 ویلیو کا مطلب ہے کہ loginuid کبھی سیٹ نہیں ہوا، جو کہ بوٹ کے وقت سسٹم ڈیمن سے شروع ہونے والے پروسیس کے لیے معمول ہے۔ اہم بات یہ ہے کہ sudo -i اسے تبدیل نہیں کرتا: alice کی طرف سے کھولا گیا root شیل اب بھی auid 1000 رکھتا ہے، لہذا اس کے اندر ہر کمانڈ alice سے منسوب ہوتی ہے۔ یہی وہ خلا ہے جو sudo چھوڑ دیتا ہے۔ ایک بار سیٹ ہونے کے بعد loginuid کو تبدیل کرنے کے لیے CAP_AUDIT_CONTROL کی ضرورت ہوتی ہے، جو عام صارفین کے پاس نہیں ہوتی، اور sudo auditctl --loginuid-immutable اسے اگلی ریبوٹ تک root کے لیے بھی بند کر دیتا ہے۔

تصدیق کریں کہ /etc/pam.d/sshd، /etc/pam.d/login اور /etc/pam.d/cron میں سے ہر ایک میں pam_loginuid.so شامل ہے، ورنہ ایونٹس بغیر کسی شناخت کے پہنچیں گے۔ یہ وہی فائل لسٹ ہے جسے آپ hardening SSH access on a VPS کے دوران استعمال کرتے ہیں، لہذا دونوں کام ایک ساتھ کریں۔

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 یو آئی ڈی (uids) اور سسٹم کال نمبرز کو ناموں میں تبدیل کرتا ہے، اور عملی طور پر یہ اختیاری نہیں ہے۔ -ts recent آخری دس منٹ کا احاطہ کرتا ہے۔ ہر ایگزیکیوشن ریکارڈز کے ایک گروپ کی صورت میں آتی ہے: ایک SYSCALL ریکارڈ جس میں uid، auid، ایگزٹ اسٹیٹس اور کی (key) ہوتی ہے، ایک EXECVE ریکارڈ جس میں مکمل آرگومنٹ لسٹ ہوتی ہے، نیز سیاق و سباق کے لیے CWD اور PATH ریکارڈز۔

ایک ایماندارانہ حد، کیونکہ یہ لوگوں کو الجھا دیتی ہے۔ audit سسٹم کالز کو ریکارڈ کرتا ہے، اور شیل کا بلٹ ان فنکشن اپنی کوئی سسٹم کال نہیں کرتا۔ 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، اور کسی بھی رول کو شامل کرنے یا حذف کرنے کی کوشش Operation not permitted کے ساتھ ناکام ہو جاتی ہے، جس میں root بھی شامل ہے۔ اس فائل کو سب سے آخر میں شامل کریں، اور جب بھی آپ کو رول تبدیل کرنا ہو تو ریبوٹ کی توقع رکھیں۔ یہی سودا اس کا مقصد ہے: ایک ایسا رول سیٹ جسے کوئی بھی خاموشی سے بند کر سکے، وہ ثبوت نہیں ہوتا۔

ایک آڈٹ لاگ جسے کوئی نہیں پڑھتا، صرف ایک تعمیل کا نمونہ ہے

auditd کا ناکامی کا پہلو یہ نہیں ہے کہ یہ چیزیں ریکارڈ نہیں کرتا۔ بلکہ یہ اتنا کچھ ریکارڈ کرتا ہے کہ کوئی اسے کبھی دیکھتا ہی نہیں، اور پھر یہ لاگ کسی سوال کا جواب دینے کے بجائے صرف ایک چیک لسٹ کو پورا کرنے کے لیے موجود رہتا ہے۔

کسی بھی چیز کو ٹیون کرنے سے پہلے اپنے باکس پر خود حساب کتاب کریں:

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

ایک واحد sudo apt upgrade ہزاروں مختصر مدتی پروسیسز چلاتا ہے، اور ان میں سے ہر ایک آپ کا auid اٹھائے پھرتا ہے، لہذا ایک پیکیج اپ ڈیٹ انسانی ٹائپنگ کے ایک ہفتے کے کام سے زیادہ ڈیٹا پیدا کر سکتا ہے۔ یہی وجہ ہے کہ اوپر دی گئی suppressions میں dpkg اور اس کے معاونین کا نام لیا گیا ہے۔ ہمیشہ ایگزیکیوٹیبل کے ذریعے suppression کریں، کبھی بھی صارف کے ذریعے نہیں: /usr/bin/dpkg کے لیے ایک استثنا (exclusion) ایک ایسا سوراخ ہے جسے آپ ایک جملے میں بیان کر سکتے ہیں، جبکہ کسی اکاؤنٹ کے لیے استثنا ایک ایسا سوراخ ہے جس کی شکل بالکل اسی چیز جیسی ہے جسے آپ پکڑنے کی کوشش کر رہے تھے۔

ہر رول پر موجود -k کلید وہ چیز ہے جو ایک ماہ بعد لاگ کو تلاش کے قابل بناتی ہے۔ ausearch -k sudoers ایک ایسا سوال ہے جس کا جواب موجود ہے۔ بغیر فلٹر کے ausearch متن کی ایک ایسی دیوار ہے جو آپ کو پڑھنا چھوڑ دینے کی تربیت دیتی ہے۔ اگر آپ کا کلیکٹر مقامی فارمیٹ کے بجائے JSON چاہتا ہے، تو laurel ایک auditd پلگ ان ہے جو ہر ایونٹ کو ایک JSON آبجیکٹ کے طور پر دوبارہ لکھتا ہے جس کے آرگیومنٹس ڈی کوڈ شدہ ہوتے ہیں۔ یہ کسی بھی دوسرے پلگ ان کی طرح /etc/audit/plugins.d/ میں رجسٹر ہوتا ہے، اور auditd پلگ ان کی تبدیلیوں کو sudo pkill -HUP auditd پر اٹھا لیتا ہے۔

auditd کی حقیقی قیمت

ہر مماثل syscall ایک ریکارڈ بن جاتا ہے جسے kernel فارمیٹ کر کے userspace کے حوالے کر دیتا ہے۔ اس کی قیمت دو جگہوں پر ادا کرنی پڑتی ہے، اور دونوں کو آپ اپنے ورک لوڈ پر خود ماپ سکتے ہیں، بجائے اس کے کہ کسی اور کے شائع کردہ اعداد و شمار پر انحصار کریں۔

  • CPU اور لیٹنسی۔ ایک ایسی مشین جو مسلسل forks کرتی ہے، جیسے کہ build host یا CI runner، ہر exec پر ایک ریکارڈ بناتی ہے۔ جب kernel کا 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 لائن kernel کی سطح پر وہی فیصلہ ہے: -f 1 audit کی ناکامی کو syslog میں رپورٹ کرتا ہے، اور -f 2 kernel کو پینک (panic) کر دیتا ہے۔ 2 کا انتخاب صرف تب کریں اگر آپ واقعی ریکارڈ کھونے کے بجائے سرور کھونا ترجیح دیتے ہیں۔ کسی ایسے VPS پر جس پر لوگ انحصار کرتے ہوں، روٹیشن کا استعمال کریں اور اسٹوریج کے مسئلے کو مشین سے باہر منتقل کریں۔

لاگز کو سرور سے باہر بھیجیں، تقریباً حقیقی وقت میں

یہ وہ حصہ ہے جسے incident write-ups بار بار ثابت کرتے ہیں۔ جو لاگز compromised ہوسٹ پر رہ جاتے ہیں، انہیں وہی شخص تبدیل کر سکتا ہے جس نے اسے compromise کیا ہو۔ root صارف /var/log/auth.log کو دوبارہ لکھ سکتا ہے، /var/log/audit/audit.log کو حذف کر سکتا ہے، اور daemon کو روک سکتا ہے۔ -e 2 قوانین کو ہٹانے سے تو روکتا ہے، لیکن یہ rm کے بارے میں کچھ نہیں کرتا۔ اوپر بیان کردہ ہر پرت صرف اسی صورت میں ثبوت فراہم کرتی ہے اگر اس کی ایک کاپی پہلے مشین سے باہر بھیج دی جائے۔

Audit کا اپنا ٹرانسپورٹ audispd-plugins کا audisp-remote پلگ ان ہے۔ اسے /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 کو چیک کریں، کیونکہ غلط پاتھ ہونے پر 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 کو اس syslog اسٹریم میں ڈالنا ہے جسے آپ پہلے ہی فارورڈ کر رہے ہیں۔ /etc/audit/plugins.d/syslog.conf، active = no کے ساتھ آتا ہے۔ اسے yes پر سیٹ کریں، reload کریں، اور audit ایونٹس 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" ہمیشہ دوبارہ کوشش کرتا ہے، اور queue.saveOnShutdown="on" کے ساتھ disk-assisted queue ریکارڈز کو اس وقت تک محفوظ رکھتی ہے جب تک collector تک رسائی نہ ہو، پھر رابطہ بحال ہونے پر انہیں بھیج دیتی ہے۔ ان دو کے بغیر، collector کے reboot ہونے سے آپ کے ثبوتوں میں خلا پیدا ہو جاتا ہے اور آپ کو یہ بتانے والا بھی کوئی نہیں ہوتا کہ وہاں خلا موجود ہے۔ sudo systemctl restart rsyslog کے ساتھ لاگو کریں، اور اس پر بھروسہ کرنے سے پہلے تصدیق کریں کہ ریکارڈز واقعی collector پر پہنچ رہے ہیں۔

ایک آخری کام باقی ہے: collector ایسی مشین ہونی چاہیے جس میں audited افراد لاگ ان نہ ہو سکیں۔ اگر وہی ایڈمن گروپ لاگ سرور پر بھی root رسائی رکھتا ہے، تو آپ نے صرف فائل کاپی کی ہے، اسے محفوظ نہیں کیا۔ الگ credentials، الگ keys، اور مثالی طور پر ایک الگ provider اکاؤنٹ استعمال کریں۔ یہی وہ استدلال ہے جو بہت سے Linux سرورز کو منظم کرنے کا مرکزی طریقہ بنانے کو اس وقت قابل قدر بناتا ہے جب آپ کو اس کی ضرورت ہو، اور یہی وہ فرق ہے جو 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، کیونکہ آڈٹ لاگ کا موڈ 600 ہے اور اس کا مالک root ہے؛ چلانے سے انکار کرنے والی ایک غلطی، کیونکہ آڈٹ رولز تبدیل کرنے کے لیے CAP_AUDIT_CONTROL کی ضرورت ہوتی ہے؛ اور ایک گروپ لسٹ جس میں نہ تو adm شامل ہے اور نہ ہی systemd-journal۔

یہ آخری چیک وہ ہے جس میں لوگ ناکام ہو جاتے ہیں۔ adm کی رکنیت /var/log/auth.log تک رسائی دیتی ہے، اور systemd-journal کی رکنیت پورے جرنل تک رسائی دیتی ہے۔ ان میں سے کوئی بھی تحریری رسائی (write access) نہیں دیتا، لہذا کوئی بھی چھیڑ چھاڑ کی اجازت نہیں دیتا۔ دونوں کسی شخص کو سرور پر موجود ہر تصدیقی لائن پڑھنے کی اجازت دیتے ہیں، جو کہ کسی فورم کے جواب سے usermod -aG لائن کاپی کرنے کے بجائے جان بوجھ کر کیا جانے والا فیصلہ ہونا چاہیے۔

آخر میں، ان دو چیزوں کی تصدیق کریں جنہیں ریبوٹ کے بعد برقرار رہنا چاہیے:

sudo auditctl -s
systemctl is-enabled auditd

enabled 2 کا مطلب ہے کہ رول سیٹ اگلے بوٹ تک مقفل ہے۔ دوسرے کمانڈ سے enabled کا مطلب ہے کہ auditd اس بوٹ کے بعد دوبارہ شروع ہو جاتا ہے۔ وہ رول سیٹ جو صرف اگلی کرنل اپ ڈیٹ تک قائم رہے، وہ آڈٹ ٹریل نہیں ہوتا۔

FAQ

میں کسی مخصوص صارف کی چلائی گئی تمام کمانڈز کیسے دیکھ سکتا ہوں؟

ان کا uid معلوم کرنے کے لیے id -u alice استعمال کریں، پھر audit log میں login uid کے ذریعے تلاش کریں: sudo ausearch -ul 1000 -ts today -i۔ execve رول تک محدود کرنے کے لیے -k exec کا اضافہ کریں۔ login uid لاگ ان کے وقت سیٹ ہوتا ہے اور su اور sudo -i کے دوران بھی برقرار رہتا ہے، لہذا یہ اس اکاؤنٹ کے ذریعے root shell میں چلائی گئی کمانڈز کو پکڑ لیتا ہے۔ یہ صرف ان کمانڈز کے لیے کام کرتا ہے جو رولز لوڈ ہونے کے بعد چلائی گئی ہوں، کیونکہ audit ان ایونٹس کی ہسٹری نہیں رکھتا جنہیں ریکارڈ کرنے کے لیے اسے کنفیگر نہ کیا گیا ہو۔ اگر آپ پہلے ڈیٹا کی نوعیت دیکھنا چاہتے ہیں تو sudo aureport -k --summary -i آپ کو فی رول تعداد دکھا دے گا۔

کیا کوئی صارف اپنی 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 میرے سرور کو سست کر دے گا؟

یہ مکمل طور پر اس بات پر منحصر ہے کہ آپ کا ورک لوڈ کتنے پروسیسز شروع کرتا ہے، لہذا کسی اعداد و شمار پر بھروسہ کرنے کے بجائے اسے خود ناپیں۔ ایک ایسا سرور جو زیادہ تر درخواستوں کا جواب دیتا ہے، بہت کم execs کرتا ہے اور اسے کوئی فرق محسوس نہیں ہوگا۔ ایک build host یا CI runner مسلسل execs کرتا ہے اور اسے کافی فرق محسوس ہو سکتا ہے، کیونکہ جب kernel audit بیک لاگ بھر جاتا ہے، تو ایونٹ پیدا کرنے والا پروسیس تب تک رک جاتا ہے جب تک جگہ نہ بن جائے۔ حقیقی لوڈ کے تحت sudo auditctl -s چلائیں اور backlog اور lost پر نظر رکھیں۔ صفر سے اوپر کوئی بھی lost کا مطلب ہے کہ ریکارڈز ضائع ہوئے ہیں، جو کہ بدترین صورتحال ہے، کیونکہ اب لاگ میں غیر مرئی خلا موجود ہے۔

audit لاگز کہاں محفوظ ہونے چاہئیں؟

کسی دوسری مشین پر، جس میں تاخیر سیکنڈوں میں ہو۔ جو بھی audited ہوسٹ پر root تک پہنچ جائے وہ /var/log/audit/audit.log کو ڈیلیٹ اور /var/log/auth.log کو دوبارہ لکھ سکتا ہے، لہذا مقامی کاپیاں صرف ان واقعات کے بارے میں سوالات کا جواب دیتی ہیں جنہیں کسی نے چھپانے کی کوشش نہیں کی۔ audisp-remote پلگ ان کے ساتھ مرکزی auditd پر فارورڈ کریں، یا audit syslog پلگ ان کو فعال کریں اور rsyslog کے ذریعے TLS پر پورا syslog اسٹریم فارورڈ کریں۔ کلیکٹر کو اپنی اسناد (credentials) دیں، اور یقینی بنائیں کہ جن اکاؤنٹس کی آڈٹ ہو رہی ہے ان کی اس تک کوئی رسائی نہ ہو۔