在日志中用主机名替换IP地址

4

我正在寻找一段bash脚本,它可以读取日志并将IP地址替换为主机名。有没有人知道如何做到这一点?


5
我尝试在 Stack Overflow 发帖,但现在卡在等待回答的状态。 - Kaz
IPv4还是IPv6或者两者都支持?你在/etc/hosts中有主机名吗? - user unknown
5个回答

4

以下脚本应该可以工作。您可以像这样使用它:

将其保存为ip_to_hostname.sh,然后:

./ip_to_hostname.sh 您的日志文件 > 已解析的IP

#!/bin/bash

logFile=$1

while read line
do
        for word in $line
        do
                # if word is ip address change to hostname
                if [[ $word =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
                then
                        # check if ip address is correct
                        OIFS=$IFS
                        IFS="."
                        ip=($word)
                        IFS=$OIFS
                        if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
                        then
                                echo -n `host $word | cut -d' ' -f 5`
                                echo -n " "
                        else
                                echo -n "$word"
                                echo -n " "
                        fi
                # else print word
                else
                        echo -n $word
                        echo -n " "
                fi
        done
        # new line
        echo
done < "$logFile"

这个脚本运行得非常好。回想起来,我应该更好地描述我的日志格式(它来自一个Netgear路由器)。我进行了一些微小的修改,现在它完美地工作了,谢谢! - zkxs

1

谈到IPv4:您可以从主机文件中生成sed命令列表:

sed -rn 's/^(([0-9]{1,3}\.){3}([0-9]{1,3}))[ \t]([^ \t]+)[ \t].*/s#\1#\4#/p' /etc/hosts > hosts.sed 

然后将其应用于您的日志文件:
sed -f hosts.sed LOGFILE

当然,您的hosts文件名必须在hostfile中列出。

另一种相反的方法是使用logresolve

从manpage中可以看到:

NAME
   logresolve - Resolve IP-addresses to hostnames in Apache log files

SYNOPSIS
   logresolve [ -s filename ] [ -c ] < access_log > access_log.new

SUMMARY
   logresolve is a post-processing program to resolve IP-addresses in Apache's access logfiles. To minimize
   impact on your nameserver, logresolve has its very own internal hash-table cache. This means  that  each
   IP number will only be looked up the first time it is found in the log file.

   Takes  an  Apache  log file on standard input. The IP addresses must be the first thing on each line and
   must be separated from the remainder of the line by a space.

因此,您可以使用正则表达式提取所有IP地址,将它们放入一个新文件中两次,一次放入第一列,并使用logresolve进行转换。然后使用此表格生成上述sed文件。


1

可以这样解决:

ip=72.30.38.140
hostname=nslookup $ip | grep name
hostname=${hostname#*name = }
hostname=${hostname%.}

这样IP地址就不必在/etc/hosts中了。

脚本本身取决于您的日志是什么样子的。您能发一个例子吗?


1
在使用sed进行替换时,要注意常见的错误。想想如果您有IP地址72.30.38.140和72.30.38.14会发生什么。当您替换72.30.38.14时,它也将被替换为72.30.38.140,因为它包含72.30.38.14。您必须使用IP字段分隔符进行替换。 - Eran Ben-Natan

0

这是我最终使用的wisent脚本的修改版本:

#!/bin/bash

logFile=$1

while read line
do
       for word in $line
       do
               # if word is ip address change to hostname
               if [[ $word =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\:[0-9]{1,5}$ ]]
               then
                       port=$(echo "$word" | sed -e "s/.*://")
                       word=$(echo "$word" | sed -e "s/:.*//")
                       OIFS=$IFS
                       IFS="."
                       ip=($word)
                       IFS=$OIFS
                       # check if ip address is correct and not 192.168.*
                       if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 && ${ip[0]}${ip[1]} -ne 192168 ]]
                       then
                               host=$(host $word | cut -d' ' -f 5)
                               if [[ $host =~ ^[0-9]{1,3}\(.*\)$ ]] # check for resolver errors
                               then
                                       # if the resolver failed
                                       echo -n "$word"
                                       echo -n ":$port"
                                       echo -n " "
                               else
                                       # if the resolver worked
                                       host=$(echo "$host'" | sed -e "s/\.'//" | sed ':a;N;$!ba;s/.*\n//g') # clean up cut's output
                                       echo -n "$host"
                                       echo -n ":$port"
                                       echo -n " "
                               fi
                       else
                               # if the ip address isn't correct
                               echo -n "$word"
                               echo -n ":$port"
                               echo -n " "
                       fi
               # else print word
               else
                       echo -n $word
                       echo -n " "
               fi
       done
       # new line
       echo
done < "$logFile"

0

我有一段时间前将这个添加到了我的 .bashrc 文件中...

function resolve-hostname-from-ip()
{
    if [ ! $1 ]
    then 
        echo -e "${red}Please provide an ip address...${no_color}"
        return 1
    fi
    echo "" | traceroute $1|grep " 1 "|cut -d ' ' -f4|cut -d '.' -f1
}

我已经预定义了终端颜色,如果你喜欢的话可以省略它们。=D

[root@somehostname ~ 08:50 AM] $ resolve-hostname-from-ip 111.22.33.444
someotherhostname

我已经在RHEL和SUSE上成功测试过了。不过,我还没有在我所属域之外的IP地址上进行过测试,因此无法百分之百确定它在所有情况下都能正常工作...希望这能帮到你 =)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接