我们的首届 “命令行挑战赛” 非常受欢迎,吸引了来自世界各地的 80 多份参赛作品。
注意:由于比赛条款和条件,一些开源爱好者没有资格赢得 T 恤,因为他们居住在某些国家/地区或提交了多个解决方案(仅考虑参赛者的第一个解决方案)。但请不要担心,我仍然能够在本文中表彰其中一些人。
挑战
“命令行挑战赛”的目的是创建一个单行命令行程序,以计算尝试使用 SSH 访问我的主机的每个 IP 地址的电子邮件数量。请参阅文章《迎接伟大的命令行挑战》
我对这个挑战有自己的简单解决方案,但它不是获胜方案。事实上,许多参赛作品提供的解决方案比我自己的更好
grep -i banned admin.index | grep SSH | awk '{print $4}' | sort -n | uniq -c | sort -n
我的解决方案提供了一个按 IP 地址升序排列的列表,其中 admin.index 文件中的条目最多。最后一次排序不是赢得比赛的要求,但这是我喜欢做的事情,以了解攻击主要来自哪里。此解决方案产生 5377 行输出,因此大约有那么多唯一的 IP 地址。但是,我的解决方案没有考虑一些异常条目,这些条目中没有 IP 地址。当我在思考本次挑战的目标应该是什么时,我决定不指定应该生成的行数,因为我认为这可能过于限制,并且会对条目施加不必要的约束。我认为这是一个好主意,因为我收到的大多数条目产生的数字都有点不同。因此,一个获胜的解决方案不需要产生与我的解决方案相同行数的数据。
Opensource.com 的读者能够提出如此多不同的问题解决方案,这让我感到惊讶。在大多数情况下,即使是相似的条目也存在一些差异。
优胜者
事不宜迟,让我们宣布优胜者!
第一个提交解决方案的参赛者
Michael DiDomenico,美国新泽西州汉密尔顿
Michael 提交了比赛的第一个参赛作品,这是一个可行的解决方案。我特别喜欢 Michael 使用 sort 命令来确保输出按 IP 地址顺序排序。他的参赛作品产生 5,295 行输出,这与我自己的结果相差不大。这也是许多其他参赛作品产生的输出行数。
grep "SSH: banned" admin.index | sed 's/","/ /g'| cut -f4 -d" " | grep "^[0-9]" | sort -k1,1n -k2,2 -k3,3n -k4,4n -t. | uniq -c
最短解决方案
Víctor Ochoa Rodríguez,西班牙马德里
Victor 提交了一个 65 个字符的解决方案,该解决方案非常简洁,并且巧妙地使用 egrep 仅选择包含 SSH 和 IP 地址的行,同时仅打印每行中与表达式匹配的部分。我从这个条目中了解了“-o”选项,所以感谢 Víctor 提供的这个新知识。这个解决方案以及下面的荣誉提名都产生 5,295 行输出。
egrep -o '".F.*H.*\.[0-9]+' admin.index|cut -d\ -f4|sort|uniq -c
最短解决方案荣誉提名
Teresa e Junior 提交了一个长度为 58 个字符的条目;但是,她没有资格赢得 T 恤。
grep SSH admin.index|grep -Po '(\d+\.){3}\d+'|sort|uniq -c
最具创意解决方案
一点背景信息:前两个类别可以纯粹根据客观标准来判断,因此此类别的目的是提供一个机会来表彰更具创意的条目。因此,此类别的获胜者是根据我的主观意见确定的。
而且,我们打成平手!(两人都将获得一件 T 恤。)
Przemo Firszt,爱尔兰科克郡
Przemo 提交了一个有趣且富有创意的条目,因为它使用了 tee 和 xargs 命令。它也很独特,因为除了使用管道之外,它还使用 tee 命令将中间数据存储在一个文件中,该命令还将数据传递到 STDOUT,并且最终输出被重定向到另一个文件,而不是允许其转到 STDOUT。它甚至在最后通过删除临时文件来清理。此解决方案产生 7,403 行输出。这似乎是因为许多 IP 地址都有多行。因此,虽然这不是一个完美的解决方案,但只需稍作修改即可为每个 IP 地址生成单行输出。
grep SSH admin.index | awk '{print $4}' | grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sed 's/\".*//' | tee ips | xargs -I % sh -c "echo -ne '%\t' ; grep -o % ips | wc -w" | sort | uniq > results ; rm ips
Tim Chase,美国德克萨斯州弗里斯科
Tim 的条目很独特,因为它使用了 curl 命令从服务器下载文件,然后使用 awk 命令来选择文件中的所需行并仅从每行中选择 IP 地址。此解决方案产生 5,295 行输出。
curl -s http://www.millennium-technology.com/downloads/admin.index|awk -F, '$1~/SSH: banned/{print $1}'|grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+'|sort|uniq -c
额外学分解决方案
许多参赛作品都针对比赛的额外学分选项,即为每个 IP 地址提供国家/地区名称。 此类别没有奖品,只有在 Opensource.com 上提及的满足感。
有两个条目特别引起了我的兴趣;两者都使用 GeoIP 软件包来提供本地数据库以获取国家/地区信息。其他几个条目使用了 whois 命令,但除此之外,whois 使用远程数据库,并且当从单个 IP 地址访问速度过快时,可能会受到阻止。GeoIP 软件包在标准 Fedora 存储库和 CentOS 的 EPEL 存储库中可用。
Gustavo Yzaguirre,阿根廷
Gustavo 提交了一个条目,该条目首先列出了带有计数的裸 IP 地址列表,然后列出了国家/地区。它产生 16,419 行输出,其中许多是重复项。Gustavo 说它没有优化,但这不是要求之一。
awk '/SSH: banned/ && $4 ~ /^[0-9]/ {print $4}' admin.index | sed 's/[^0-9.]*//g' | sort | uniq -c | awk '{printf $1 " " $2 " "; system("geoiplookup "$2)};' | sort -gr | sed 's/ GeoIP Country Edition: / /g'
Dejan Bogdanovic,塞尔维亚贝尔格莱德
Dejan 提交了一个有趣的条目,该条目按频率降序列出了 IP 地址以及国家/地区信息。Dejan 的条目产生 5,764 行输出。
cat admin.index | egrep -o '([0-9]*\.){3}[0-9]*' | sort -n | uniq -c | sort -nr | awk '{ORS=" "} {print $1} {print $2} {system("geoiplookup " $2 "| cut -d: -f 2 | xargs")}'
结论
感谢所有提交“命令行挑战赛”参赛作品的人员。祝贺我们的优胜者,以及那些没有获胜但其参赛作品值得一提的人们!
看到你们对问题的多种解读和解决方案真是太有趣和令人愉快了。此外,有几个人提到他们非常喜欢这次比赛,并希望 Opensource.com 举办更多此类比赛。工作人员和我学到了很多关于举办此类比赛的知识,因此我们希望举办更多比赛,并在前进的过程中吸取“经验教训”。
4 条评论