Killing Process Network Access
Imagine this scenario: a particular process on your server is connecting to a host outside your internal network and you don’t like that. On the other hand, you can’t just kill that process because you need it.
The simple script below uses tcpkill
and iptables
to kill and block outbound connections initiated by processes matching the names you’ve provided. The tcpkill
utility is provided by the dsniff
package on CentOS/RHEL and can be installed like so:
yum -y install dsniff --enablerepo=epel
You can add the script to the cron
to run, say, every few minutes. Here’s an example using sudo
to source root’s environment (not necessary in this case – just an example):
*/15 * * * * sudo su - root -c '/var/adm/bin/pid_network_block.sh splunkd avastd' >/dev/null 2>&1
You may notice that multiple instances of tcpkill
are hanging around – one per each blocked IP. This is not an error. This utility will only kill connections if there is traffic.
This means that, if there was no traffic at the moment you ran the command, it will stick around and wait until it sees activity. However, because the script also tells iptables
to block traffic to these IPs, the tcpkill
instance will remain. You can certainly change this by prepending tcpkill
with timeout
instead of nohup
.
You can download the script here. This is what the script does exactly:
- Obtain the PIDs of the processes matching the process names you provided as CLI arguments
- Identify the IPs to which those PIDs are currently connected, excluding anything on your private network. Add those IPs to the array.
- Cycle through the array and run
tcpkill
andiptables
DROP for each new IP. - Clean up
iptables
configuration to get rid of duplicate entries.
#!/bin/bash if [ -z "" ] then exit 1 else procnames="${@}" s=0 fi function func_ipget() { # Get a list of IPs accessed by the specified process # Exclude private networks for procname in ${procnames} do a+=($(/usr/sbin/lsof -i -n $(pidof "${procname}" | sed 's/[^ ]* */-p &/g') 2>/dev/null | grep EST | grep -oP "(?<=->)([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})(?=:)" | grep -vP "(^127\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)")) done } function func_ipdrop() { # Block outbound access to those IPs for i in $(printf '%s\n' ${a[@]} | sort -u) do if [ $(/bin/ps -ef | grep -cE "[t]cpkill.*${i}$") -eq 0 ] then nohup /usr/sbin/tcpkill -9 host ${i} </dev/null >/dev/null 2>&1 & fi if [ $(/sbin/iptables -S | grep -cE " ${i}/") -eq 0 ] then /sbin/iptables -A OUTPUT -d ${i} -j DROP (( s = s + 1 )) fi done } function func_iptables_save() { # Remove duplicate entries from iptables tmpfile=$(mktemp) /sbin/iptables-save | awk '/^COMMIT$/ { delete x; }; !x[$0]++' > ${tmpfile} /sbin/iptables -F /sbin/iptables-restore < ${tmpfile} /sbin/service iptables save /sbin/service iptables restart /bin/rm -f ${tmpfile} } # RUNTIME func_ipget func_ipdrop if [ ${s} -gt 0 ] then func_iptables_save fi