寻找一种将输出的第二列传递给 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