Время от времени я хочу найти диапазон CIDR в моих файлах журнала Apache. Это легко сделать для диапазонов, которые попадают в естественные границы (/ 8, / 16 и / 24), но не так просто для других диапазонов, таких как / 17 и / 25.
Примеры:
# 192.168.0.0/16: (easy)
grep " 192\.168\." access_log
# 192.168.128.0/17: (more thought required)
grep -E " 192\.168\.(12[89]|1[3-9][0-9]|2[0-5][0-9])\." access_log
# 192.168.0.0/17: (more thought required)
grep -E " 192\.168\.([0-9]|[0-9][0-9]|1[01][0-9]|12[0-7])\." access_log
# 192.168.128.0/18: (straining my brain)
grep -E " 192\.168\.(1[2-8][0-9]|19[01])\." access_log
Эти регулярные выражения игнорируют IP-адреса, содержащие ведущие нули, например 192.168.001.001
, что не является проблемой в файлах журнала Apache, но может быть в других файлах журнала. Принтерам особенно нравятся начальные нули. Достаточно легко добавить необязательные нули в регулярное выражение, но это лишь немного усложняет задачу. Должен быть способ попроще.
Есть ли простой способ выбрать строки из файла, соответствующие любому диапазону CIDR?
Будут рассмотрены причудливые расширения регулярных выражений, как и различные инструменты (например, awk
или perl
если необходимо, но я хочу, чтобы это было однострочно), если они облегчают работу. В идеале я бы хотел что-то вроде
grep "[:CIDR 192.168.128.0/18:]" access_log
Также подойдет инструмент, который преобразует диапазон CIDR в соответствующее регулярное выражение.
$ cidr2regex 192.168.0.0/18
192\.168\.(1[2-8][0-9]|19[01])\.[0-9]{1,3}
или
$ grep -E "$(cidr2regex 192.168.0.0/18)" access_log
Бонусные баллы, если ваш ответ также касается IPv6.
Неудивительно, что для этого есть инструмент: grepcidr
.
Он не включен по умолчанию ни в одну известную мне систему, но вы можете скачать его. отсюда, и он есть как в репозитории пакетов Ubuntu, так и в коллекции портов FreeBSD.
(Версия 2.0 также работает с сетями IPv6)
Недавно выпущенный rgxg
инструмент командной строки генерирует регулярные выражения, соответствующие всем адресам в блоке CIDR:
$ rgxg cidr 192.168.128.0/18
192\.168\.(19[01]|1[3-8][0-9]|12[89])\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])
или
$ rgxg cidr 2001:db8:a:b:c:d::/112
2001:0?[Dd][Bb]8:0?0?0?[Aa]:0?0?0?[Bb]:0?0?0?[Cc]:0?0?0?[Dd]((::[0-9A-Fa-f]{1,4}|::|:0?0?0?0(::|:[0-9A-Fa-f]{1,4}))|:0\.0(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){2})
Для получения дополнительной информации см. http://rgxg.sf.net.