尝试将 lsof -Pi 的一些输出传递给 geoiplookup

尝试将 lsof -Pi 的一些输出传递给 geoiplookup

寻找一种将输出的第二列传递给 geoiplookup 的方法,最好在同一行,但不一定。这是我能召集到的最好的了。它是可用的,但遗憾的是 geoiplookup 结果位于连接列表下方。我想要更综合的结果。如果有人可以提出改进建议,我们将受到欢迎。

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
}

目前的结果看起来像这样:

<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>

答案1

这就是我最终得到的结果,这在很大程度上要感谢 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
}

答案2

在改进方面,这取决于lsof -Pi您对哪些数据感兴趣。

这是一个打印命令、PID、用户、节点、IP、端口和 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

例如输出:

┌─[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

如果你想把它作为你的函数.bashrc或其他东西,你可以让它看起来更好一点:

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
}

请注意,这不适用于 IPv6 查找,因为您需要使用geoiplookup6它。您可以添加一个条件来检查 IP 类型,然后geoiplookup/6根据输出运行。例如:

...
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
...

但要将其与上述代码一起使用,您需要删除 IPv4 正则表达式,或添加到其中以包含 IPv6

相关内容