Em termos de melhorias, dependerá de quais dados de lsof -Pi
você está interessado.
Aqui está um "one liner" (não muito ...) que imprime o comando, PID, usuário, nó, IP, porta & geoip:
echo -e "COMMAND\tPID\tUSER\tNODE\tIP\tPORT\tGEO"; IFS=$'\n'; for line in $(lsof -Pi | grep ESTABLISHED | grep -E '*(([0-9]{1,3})\.){3}([0-9]{1,3}){1})*'); do cmdpidusr=$(echo $line | awk '{print $1,$2,$3}'); node=$(echo $line | awk '{print $8}'); ipadd=$(echo $line | awk '{print $9}' | cut -d ">" -f 2 | cut -d ":" -f 1); port=$(echo $line | awk '{print $9}' | cut -d ">" -f 2 | cut -d ":" -f 2); geoip=$(geoiplookup $ipadd | cut -d : -f 2); echo -e "$cmdpidusr\t$node\t$ipadd\t$port\t$geoip"; done | column -t; unset IFS
por exemplo. saída:
┌─[root@Fedora]─[~]─[10:22 am]
└─[$]› echo -e "COMMAND\tPID\tUSER\tNODE\tIP\tPORT\tGEO"; IFS=$'\n'; for line in $(lsof -Pi | grep ESTABLISHED | grep -E '*(([0-9]{1,3})\.){3}([0-9]{1,3}){1})*'); do cmdpidusr=$(echo $line | awk '{print $1,$2,$3}'); node=$(echo $line | awk '{print $8}'); ipadd=$(echo $line | awk '{print $9}' | cut -d ">" -f 2 | cut -d ":" -f 1); port=$(echo $line | awk '{print $9}' | cut -d ">" -f 2 | cut -d ":" -f 2); geoip=$(geoiplookup $ipadd | cut -d : -f 2); echo -e "$cmdpidusr\t$node\t$ipadd\t$port\t$geoip"; done | column -t; unset IFS
COMMAND PID USER NODE IP PORT GEO
synergys 16444 user1 TCP 172.1.1.1 59116 IP Address not found
ssh 21557 root TCP 1.2.3.4 2291 GB, United Kingdom
se você quisesse isso como uma função em seu .bashrc
ou algo assim, você pode fazer com que pareça um pouco melhor:
iplookup() {
echo -e "COMMAND\tPID\tUSER\tNODE\tIP\tPORT\tGEO"
IFS=$'\n' # set field separator to new line
for line in $(lsof -Pi | grep ESTABLISHED | grep -E '*(([0-9]{1,3})\.){3}([0-9]{1,3}){1})*'); do # this is just a regex grep to pull lines with valid IPv4 addresses only
cmdpidusr=$(echo $line | awk '{print $1,$2,$3}')
node=$(echo $line | awk '{print $8}')
ipadd=$(echo $line | awk '{print $9}' | cut -d ">" -f 2 | cut -d ":" -f 1)
port=$(echo $line | awk '{print $9}' | cut -d ">" -f 2 | cut -d ":" -f 2)
geoip=$(geoiplookup $ipadd | cut -d : -f 2)
echo -e "$cmdpidusr\t$node\t$ipadd\t$port\t$geoip"
done | column -t # organise the columns
unset IFS # set field separator to default
}
observe que isso não funcionaria para pesquisas IPv6, porque você precisaria usar geoiplookup6
para isso. Você pode adicionar uma condicional que verifica o tipo de IP e executa geoiplookup/6
dependendo da saída. por exemplo :
...
type=$(echo $line | awk '{print $5}')
if [ "$type" = "IPv4" ]; then
geoip=$(geoiplookup $ipadd | cut -d : -f 2)
else
geoip=$(geoiplookup6 $ipadd | cut -d : -f 2)
fi
...
mas para usar isso com o código acima, você precisará remover o regex do IPv4 ou adicioná-lo para incluir o IPv6