Pythian Blog: Technical Track

How to immediately kill ALL processes for a Unix user

On occasion I have found it necessary to immediately kill all processes for a particular user on a Linux or Unix server. It has been quite some time since I found it necessary to do so, and the occasions for doing this have been rare. Even so, the following is a good thing to know. Let's say you found a user was running something on your database server that was consuming a lot of resources, and it appears there may be malicious intent. Or maybe the user has a runaway process that keeps spawning more processes, and neither you nor the user can kill the processes quickly enough to prevent spawning more processes. You might do something like this: First, check for the processes. Here we have 3 processes owned by baduser, and we want to kill these processes.
# top -b -n1 | head -12
 top - 15:40:26 up 25 days, 30 min, 10 users, load average: 0.46, 0.24, 0.28
 Tasks: 162 total, 5 running, 157 sleeping, 0 stopped, 0 zombie
 Cpu(s): 0.3%us, 0.1%sy, 0.0%ni, 99.4%id, 0.2%wa, 0.0%hi, 0.0%si, 0.0%st
 Mem: 760524k total, 713756k used, 46768k free, 137960k buffers
 Swap: 3047420k total, 81056k used, 2966364k free, 55660k cached
 
  PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 
 26489 baduser 20 0 115m 1608 1064 R 33.4 0.2 0:00.48 ls 
 26483 baduser 20 0 115m 1608 1064 R 31.4 0.2 0:00.49 ls 
 26488 baduser 20 0 115m 1608 1064 R 31.4 0.2 0:00.48 ls 
  10 root 20 0 0 0 0 R 2.0 0.0 0:33.43 rcu_sched 
  1742 root 20 0 252m 80m 6708 S 2.0 10.8 6:14.70 Xorg 
 
Now we login and attempt to kill those processes.
 [root@pythianvpn share]# kill -15 26489 26483 26488
 bash: kill: (26489) - No such process
 bash: kill: (26483) - No such process
 bash: kill: (26488) - No such process
 
 
What happened? Those ls processes have already completed, and another set has started:
# top -b -n1 | head -12
 top - 15:42:42 up 25 days, 33 min, 10 users, load average: 0.78, 0.61, 0.42
 Tasks: 162 total, 4 running, 158 sleeping, 0 stopped, 0 zombie
 Cpu(s): 0.3%us, 0.1%sy, 0.0%ni, 99.4%id, 0.2%wa, 0.0%hi, 0.0%si, 0.0%st
 Mem: 760524k total, 728668k used, 31856k free, 138136k buffers
 Swap: 3047420k total, 81056k used, 2966364k free, 69676k cached
 
  PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 
 26602 baduser 20 0 115m 1764 1064 R 33.0 0.2 0:01.18 ls 
 26605 baduser 20 0 115m 1760 1064 R 33.0 0.2 0:01.18 ls 
 26604 baduser 20 0 115m 1764 1064 R 31.1 0.2 0:01.17 ls 
  10 root 20 0 0 0 0 S 1.9 0.0 0:34.46 rcu_sched 
  1 root 20 0 19408 420 208 S 0.0 0.1 0:00.54 init 
 
Every time you try to kill these, a new set of processes has started. You could do this then; kill the parent processes as well.
# ps -ubaduser -o ppid,cmd
  PPID CMD
 16428 -bash
  1 /bin/bash /home/baduser/ck.sh 1
  1 /bin/bash /home/baduser/ck.sh 2
  1 /bin/bash /home/baduser/ck.sh 3
 26734 ls -lR /
 26735 ls -lR /
 26736 ls -lR /
 
So we need to kill all PIDs for ls -lR, and all PIDs for ck.sh There is potential for a lot of copying and pasting, so it is rather time consuming. Perhaps a little more command line fu is needed:
for pid in $(ps -ubaduser -o pid,ppid,cmd| tail -n +2| cut -f1 -d' ') 
 do
  kill -15 $pid
 done
 
That would work. But, there is an easier way to do this with kill -SIGNAL -1
\
 # time su - baduser -c 'kill -15 -1'
 
 real 0m0.112s
 user 0m0.003s
 sys 0m0.007s
 
 
 # top -b -n1 | head -12
 top - 15:51:27 up 25 days, 41 min, 10 users, load average: 1.73, 2.07, 1.28
 Tasks: 156 total, 1 running, 155 sleeping, 0 stopped, 0 zombie
 Cpu(s): 0.3%us, 0.1%sy, 0.0%ni, 99.4%id, 0.2%wa, 0.0%hi, 0.0%si, 0.0%st
 Mem: 760524k total, 710864k used, 49660k free, 137788k buffers
 Swap: 3047420k total, 81064k used, 2966356k free, 55708k cached
 
  PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 
  3 root 20 0 0 0 0 S 2.0 0.0 0:17.87 ksoftirqd/0 
  1 root 20 0 19408 420 208 S 0.0 0.1 0:00.54 init 
  2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd 
  5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H 
  6 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kworker/u:0 
 
 
As you can see, that worked very quickly. How does it work? Checking the man page for kill reveals the answer:
 From 'man kill' on Oracle Linux
 
  -1 All processes with pid larger than 1 will be signaled.
 
 
 From 'man kill' on Linux Mint 18
 
  kill -9 -1 Kill all processes you can kill.
 
 
The -1</> option (that is a 'one') indicates to kill all processes with a PID gt 1. When logging in as the user via sudo and issuing kill -15 -1, kill will send the SIGTERM to all processes for that user. The man page may say to use SIGKILL or -9, but that should normally only be used as a last resort. If for instance we are trying to kill runaway processes, we may want to give the processes an opportunity to perform any cleanup they would normally do before terminating. SIGTERM allows for that, while SIGKILL does not. Here is how to see the complete list of signals:
 $ kill -l
  1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
  6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
 63) SIGRTMAX-1 64) SIGRTMAX
 
This use of the kill command is quite powerful, so be very careful about how you use it.

No Comments Yet

Let us know what you think

Subscribe by email