====== Ubuntu - Processes - List all non-kernel processes ======
Usually kernel processes are safe and clean.
For kernel processes, either PID (process id) is 2 or PPID (parent process id) is 2.
Here is how to get all non-kernel processes.
ps --ppid 2 -p 2 -p 1 \
--deselect -o uid,pid,rss,%cpu,command
returns:
UID PID RSS %CPU COMMAND
0 411 1848 0.0 /lib/systemd/systemd-
0 572 2904 0.0 dhclient -1 -v -pf /r
102 902 1244 0.0 dbus-daemon --system
0 912 1948 0.0 /lib/systemd/systemd-
0 5869 388 0.0 upstart-socket-bridge
200 1953 904 0.0 /usr/sbin/apache2 -k
200 3463 3700 0.0 /usr/sbin/apache2 -k
... ...
... ...
0 5098 4224 0.0 sshd: ubuntu [priv]
0 5139 1748 0.0 /usr/bin/python /usr/
200 5140 3484 0.0 /usr/bin/python /usr/
200 5176 1904 0.0 sshd: ubuntu@pts/3
200 5177 3860 0.0 -bash
200 5193 1200 0.0 tmux attach -t denny
0 5297 4224 0.0 sshd: ubuntu [priv]
... ...
... ...
**NOTE**:
* **rss** (resident set size): real RAM usage.
* **-deselect**: rule out matched processes.
----
===== Rule out trusted procsses =====
We may have many processes running, which are expected and trusted. e.g apache2, tomcat7, mysqld, etc.
To avoid distraction, build a white list especial for your project.
----
===== Sort processes by memory and cpu =====
We’re more concerned about suspicious processes using noticeable resource.
# Sort by memory first, then cpu
ps --ppid 2 -p 2 -p 1 --deselect \
-o uid,pid,rss,%cpu,command, \
--sort -rss,-cpu
----
===== Automate Detection Process and Get Alerts =====
We hide all the complexities and white list configuration in a python script (detect_suspicious_process.py).
If you issue the python command, you may see output like "**Identified processes count: XXX.**" Define a scheduled task to run periodical check and confirm the number.
If the number is not 0 or it changes, send alerts.
It might take a while to build a suitable white list.
Once it’s done, your servers are always more secured and managed!
wget -O /tmp/detect_suspicious_process.py \
https://raw.githubusercontent.com/\
DennyZhang/devops_public/tag_v2/python/\
detect_suspicious_process/\
detect_suspicious_process.py
# Detect suspicious process
python /tmp/detect_suspicious_process.py
# Detect by customized whitelist
python /tmp/detect_suspicious_process.py \
--whitelist_file /tmp/whitelist.txt
----
===== detect_suspicious_process.py =====
# -*- coding: utf-8 -*-
#!/usr/bin/python
##-------------------------------------------------------------------
## @copyright 2015 DennyZhang.com
## File : detect_suspicious_process.py
## Author : DennyZhang.com
## Description : http://www.dennyzhang.com/suspicious_process/
## python ./detect_suspicious_process.py
## python ./detect_suspicious_process.py --whitelist_file /tmp/whitelist.txt
## --
## Created : <2016-01-15>
## Updated: Time-stamp: <2016-08-20 13:32:55>
##-------------------------------------------------------------------
import argparse
import subprocess
import os, sys
################################################################################
# TODO: move to common library
def string_in_regex_list(string, regex_list):
import re
for regex in regex_list:
regex = regex.strip()
if regex == "":
continue
if re.search(regex, string) is not None:
# print "regex: %s, string: %s" % (regex, string)
return True
return False
################################################################################
DEFAULT_WHITE_LIST = '''
/sbin/getty -.*
dbus-daemon .*
acpid -c /etc/acpi/events -s /var/run/acpid.socket$
atd$
cron$
/lib/systemd/systemd-udevd --daemon$
/lib/systemd/systemd-logind$
dbus-daemon --system --fork$
/usr/sbin/sshd -D$
rsyslogd$
/usr/sbin/mysqld$
/usr/sbin/apache2 -k start$
'''
COMMAND_GET_NONKERNEL = '''
sudo ps --ppid 2 -p 2 -p 1 --deselect \
-o uid,pid,rss,%cpu,command \
--sort -rss,-cpu
'''
def get_nonkernel_process():
process_list = subprocess.check_output(COMMAND_GET_NONKERNEL, shell=True)
return process_list
def load_whitelist(fname):
white_list = ""
if fname is None:
print "No white list file is given. Use default value."
white_list = DEFAULT_WHITE_LIST
else:
print "load white list from %s" % (fname)
with open(fname) as f:
white_list = f.readlines()
return white_list
def list_process(process_list, white_list):
import re
l = []
for line in process_list.split("\n"):
line = line.strip()
if line == "":
continue
if not string_in_regex_list(line, white_list.split("\n")):
l.append(line)
return l
################################################################################
if __name__=='__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--whitelist_file', required=False,
help="config file for whitelist", type=str)
args = parser.parse_args()
white_list = load_whitelist(args.whitelist_file)
nonkernel_process_list = get_nonkernel_process()
process_list = list_process(nonkernel_process_list, white_list)
# Remove header
print "Identified processes count: %d." % (len(process_list) - 1)
print "\n".join(process_list)
## File : detect_suspicious_process.py ends