Originally published December 19, 2018 @ 6:32 pm
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
Experienced Unix/Linux System Administrator with 20-year background in Systems Analysis, Problem Resolution and Engineering Application Support in a large distributed Unix and Windows server environment. Strong problem determination skills. Good knowledge of networking, remote diagnostic techniques, firewalls and network security. Extensive experience with engineering application and database servers, high-availability systems, high-performance computing clusters, and process automation.