Tentando passar alguma saída de lsof -Pi para geoiplookup

1

Procurando uma maneira de passar a segunda coluna de saída para geoiplookup, idealmente na mesma linha, mas não necessariamente. Isso é o melhor que posso reunir. É utilizável, mas os resultados do geoiplookup estão infelizmente abaixo da lista de conexões. Eu queria resultados mais integrados. Se alguém puder sugerir melhorias, será bem-vindo.

ns () {
  echo ""
  while sleep 1; do
    lsof -Pi |
    grep ESTABLISHED |
    sed "s/[^:]*$//g" |
    sed "s/^[^:]*//g" |
    sed "s/://g" |
    sed "s/->/\t/g" |
    grep -v localdomain$ |
    tee >(for x in 'grep -o "\S*$"'; do geoiplookup $x | sed "s/GeoIP.*: /\t/g"; done)
  done
}

Os resultados atualmente parecem com algo assim:

<Port>    <URL or IP if no reverse available #1>
<Port>    <URL or IP if no reverse available #2>
    <geoiplookup trimmed result #1>
    <geoiplookup trimmed result #2>
    
por Jer 07.04.2018 / 12:12

2 respostas

0

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

    
por 11.04.2018 / 11:42
1

Aqui está o que eu acabei fazendo, graças em grande parte ao RobotJohnny.

ns () {
 echo ""
 while sleep 1; do
  IFS=$'\n'
  for line in $(lsof -Pi |
   grep ESTABLISHED |
   grep -ve "localdomain:[0-9]* .EST" \
    -e "search.msn.com:[0-9]* .EST" \
    -e "spider.yandex.com:[0-9]* .EST" \
    -e "google.com:[0-9]* .EST"); do
   cmdpidusr=$(echo $line | awk -v OFS='\t' '{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 1 | cut -d ":" -f 2 | cut -d "-" -f 1)
   geoip=$(geoiplookup $ipadd | sed "s/GeoIP.*: \S* //g")
   echo -e "$cmdpidusr\t$node\t$port\t$ipadd\t$geoip" | sed "s/\s*resolve hostname.*//g" | grep -v root
  done | column -t -s $'\t' | sed "s/  \s*/  /g"
  unset IFS
 done
}
    
por 11.04.2018 / 18:53

Tags