Bash: Como imprimir uma coluna adicional correspondente ao endereço IP ao nome

1

Estou usando netstat para coletar informações sobre IPs conectados. E eu tenho o seguinte formato:

netstat -tn 2>/dev/null | awk '/:80 / {print $5}' | sed 's/.*::ffff://' | sed 's/:.*//' | sor t | uniq -c | sort -nr
      5 81.133.113.200
      4 80.229.142.126
      2 94.136.36.29
      2 92.19.231.69
      2 85.159.56.230
      2 83.70.246.152
      2 81.131.118.236
      2 185.106.92.42
      1 92.19.232.88
      1 86.47.113.169
      1 86.168.206.46
      1 79.77.175.210
      1 46.19.141.238
      1 206.221.184.2
      1 192.198.95.6

O que eu estava tentando realizar é combinar um IP com um nome de host.

Então, se eu tiver name=$(IPADDRESSNAME) armazenado em algum lugar e o nome corresponder ao endereço IP 81.133.113.200

Eu gostaria que ele fosse impresso em um formato como esse:

  5 81.133.113.200 - IPADDRESSNAME
  4 80.229.142.126
  2 94.136.36.29
  2 92.19.231.69

Eu tenho lido coluna para tentar fazer isso, mas não tenho certeza de como combinar a coluna com uma correspondência no endereço.

Estou executando isso com um script Bash, então eu estaria armazenando os nomes de host lá.

Eu estava pensando em algo como:

string=$(netstat -tn 2>/dev/null | awk '/:80 / {print $5}' | sed 's/.*::ffff://' | sed 's/:.*//' | sort | uniq -c | sort -nr)
if [[ $string == "81.133.113.200" ]]
then
  echo "Its XXXXXXXX HOST";
fi

Algo parecido com isso, embora isso não funcione, a lógica é o que existe depois, mas em linha.

    
por Dave Hamilton 22.03.2016 / 11:39

4 respostas

2

Experimente esta versão testada:

netstat -tn 2>/dev/null | awk '/:80 / {print $5}' | sed 's/.*::ffff://' | sed 's/:.*//' | sor t | uniq -c | sort -nr |\
while read index ipaddress ; do \
  printf "%s " "${index}" ;\
  getent hosts "${ipaddress}" ;\
  if [ $? -eq 2 ]; then \
    printf "%s\n" "${ipaddress}" ;\
  fi ;\
done

Ele está usando o getent padrão para consultar o banco de dados hosts para recuperar o nome do host dado seu endereço IP.

O teste:

5 81.133.113.200  host81-133-113-200.in-addr.btopenworld.com
4 80.229.142.126  garnerhome.plus.com
2 94.136.36.29    mail.e-trackit.co.uk
2 92.19.231.69    host-92-19-231-69.static.as13285.net
2 85.159.56.230
2 83.70.246.152   83-70-246-152-dynamic.b-ras1.prp.dublin.eircom.net
2 81.131.118.236  host81-131-118-236.range81-131.btcentralplus.com
2 185.106.92.42
1 92.19.232.88    host-92-19-232-88.static.as13285.net
...
    
por 22.03.2016 / 13:40
1

Eu esqueço que Sed pode ser usado para acrescentar uma linha e não apenas remover o conteúdo. Então eu usei Sed para localizar a String e acrescentar uma linha depois dela. Bastante simples quando você pensa sobre isso.

Acho que estava complicando demais a situação com a saída em colunas

Simple one liner como exemplo:

  netstat -tn 2>/dev/null | awk '/:80 / {print $5}' | sed 's/.*::ffff://' | sed 's/:.*//' | sed '/8.8.8.8/s/$/ Its Google/' | sort | uniq -c | sort -nr
    
por 22.03.2016 / 13:14
1

Você pode processar a saída linha a linha e imprimir conforme suas necessidades. Supondo que você queira mapear endereços para nomes de host de / etc / hosts, você poderia fazer algo assim:

get_connected_hosts() {
  netstat -tn 2>/dev/null | awk '/:80 / {print $5}' | sed 's/.*::ffff://' | sed 's/:.*//' | sort | uniq -c | sort -nr
}

get_connected_hosts | while read line; do
  set -- $line
  result=$(grep $2 /etc/hosts | head -1 | awk '{ print $2 }')
  # or a reverse DNS lookup, result=$(dig +short -x $2)
  echo "$1 $2 - $result"
done | column -t
    
por 22.03.2016 / 13:18
1
netstat -tn | awk '/:80 / {print $5}' | sed -e 's/:.*//' | 
    xargs -i sh -c 'echo {} $(getent hosts {})' | 
    awk '$1 == $2 {print $2, $3; next}; {print}' | 
    sort | uniq -c | sort -nr

(pode ser tudo em uma linha, adicionei feeds de linha para evitar barras de rolagem horizontais e torná-lo mais legível)

Isso usa xargs -i (com -L 1 implícito) para fazer uma pesquisa getent hosts antes de executar sort | uniq -c . Isso é mais complicado do que precisa porque getent não produz saída se a pesquisa não retornar nada, por isso, precisamos garantir que o endereço IP seja impresso por echo -ing antes do getent . O segundo awk garante que apenas um endereço IP seja impresso por linha.

Outras alternativas seriam usar nslookup , dig -x ou host -i para fazer o IP para a consulta do nome do host, mas todas elas exigiriam ainda mais processamento da saída.

O sed após awk na primeira linha não é realmente necessário, poderíamos fazer a mesma coisa usando a função awk gsub() para modificar $5 antes de imprimi-lo, mas acho que desta forma é mais legível e mais fácil de entender.

    
por 22.03.2016 / 22:57