Назад | Перейти на главную страницу

Могут ли таблицы IP разрешать определенные запросы DNS на основе имени домена?

На данный момент у меня есть iptables, блокирующие весь UDP-трафик, однако я хочу разрешить прохождение только определенных DNS-запросов.

В качестве примера возьмем google.com.

Я пытаюсь использовать сопоставление строк, чтобы найти доменное имя в запросе и разрешить его. Вот что я придумал.

iptables -A OUTPUT -o eth0 -p udp --sport 53 -m string --string "google.com" --algo bm -j ACCEPT

Я тоже пробовал --dport 53 вместо того --sport. Никаких кубиков.

Если кто-нибудь знает, как это можно сделать, или посмотрите, где я ошибся?

точка "." в запросе DNS не представлен как символ, а как длина следующей за ним строки. Например, www.google.com запрашивается как

0x03 w w w 0x06 g o o g l e 0x03 c o m

вы можете легко разрешить / заблокировать DNS-запросы, сопоставив имена доменов с помощью --hex-string. В твоем случае:

-m string --algo bm --hex-string '|06 676f6f676c65 03 636f6d|' -j ACCEPT

примет каждый пакет DNS, содержащий ".google.com".

Я часто использую эту технику против атаки с усилением DNS-запросов.

источник: DNS RFC 1035

В дополнение к nrc anwser, где есть быстрая команда для преобразования доменов в шестнадцатеричную строку:

DOMAIN=google.com
perl -e 'print map {chr(length($_)).$_} split /\./, "'$DOMAIN'" | xxd -p

Итак, в вашем случае:

DOMAIN=google.com
HEX=$(perl -e 'print map {chr(length($_)).$_} split /\./, "'$DOMAIN'"' | xxd -p)

iptables -A OUTPUT -o eth0 -p udp --sport 53 \
  -m string --hex-string "|$HEX|" --algo bm -j ACCEPT
DOMAIN=www.example.com
str=$(perl -e 'print "|".join("|", map { sprintf("%02X", length($_))."|".$_ }  split(/\./, "'$DOMAIN'") )."|"')
echo $str
iptables -I INPUT -p udp --dport 53 -m string --hex-string "$str" --algo bm -j ACCEPT

Вывод:

|03|www|07|example|03|com|
iptables -I INPUT -p udp --dport 53 -m string --hex-string "$str" --algo bm -j ACCEPT