Дата и время публикации:
Проблемы и решение
1. Суть проблемы
Ранее, когда поднимал сетевой мост между центральным (физическим) узлом гипервизора и гостевой ВМ, особо не задумывался, что у режима nat, есть режим коммутации пакетов путем их фильтрации (Package filtering) и ретрансляции по адресу и порту(Network Address Translation) .
Особенно, как показано на рисунке 1.1, если гостевая виртуальная машина выполняет роль сервера, на котором запущены службы DNS, SSH, POP3, SMTP, IMAP, сборщика системных журналов и сообщений и т.д.
Дамп 1.1
Рисунок 1.1
Поэтому для перенаправления портов вышеперечисленных служб, воспользуемся ретрансляцией входящих и исходящих соединений по IP-адресам и портам, реализуемой с помощью программного межсетевого экрана iptables, о котором рассказывал ранее в обзорной статье, как использовать политику FORWARD и правила NAT
Теперь применим полученные теоретические знания в реальной схеме межсетевого взаимодействия, показанной на рисунке 1.1 и состоящей из двух узлов виртуальных машин (гостевых ОС) и одного связующего их – центрального узла гипервизора, где:
- узел виртуальной машины ВМ "ОС Debain-10", настраиваемый и запускаемый в виртуальных ящичках Gnome Boxes с использованием программной прослойки libvirt, предоставляющий пользовательский интерфейс для создания и управления виртуальными машинами и эмулируемого аппаратного обеспечения Qemu/KVM
- узел виртуальной машины ВМ "ОС Yocto/poky", настраиваемый и запускаемый в среде разработки (собственноручно комплектуемого и настраиваемого, custom) дистрибутива Yocto Poky на базе ядра ОС GNU/Linux
2. Решение
2.1 Сканирование на открытые порты
В ходе решения схемы межсетевого взаимодействия, показанной на рисунке 1.1, применял поверхностное тестирование на открытые (tcp-, udp-) порты гостевых ОС, которые запускал с центрального узла гипервизора с помощью программного сетевого сканера, утилиты nmap, как показано в дампе 2.1.1
Дамп 2.1.1
sudo nmap -A -T4 --max-retries 100 --min-parallelism 100 --max-parallelism 900 --min-hostgroup 1 --max-hostgroup 1 -sU -sT 192.168.2.10 ... Starting Nmap 7.80 ( https://nmap.org ) at 2021-10-29 18:21 MSK Nmap scan report for 192.168.2.10 Host is up (0.00045s latency). Not shown: 1986 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0) | ssh-hostkey: | 2048 ce:09:0e:a7:23:91:fc:44:c7:e9:54:55:5c:d1:e6:45 (RSA) | 256 61:a2:60:9c:a2:43:73:ae:76:1d:8f:c6:b6:4c:01:61 (ECDSA) |_ 256 44:ff:93:bb:89:0e:99:50:48:a4:6f:21:bb:0b:d9:91 (ED25519) 25/tcp open smtp Postfix smtpd |_smtp-commands: slpnet.tld, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING, | ssl-cert: Subject: commonName=debian10-uni | Subject Alternative Name: DNS:debian10-uni | Not valid before: 2021-04-17T10:36:40 |_Not valid after: 2031-04-15T10:36:40 |_ssl-date: TLS randomness does not represent time 53/tcp open domain ISC BIND 9.11.5-P4-5.1+deb10u5 (Debian Linux) 110/tcp open pop3 Courier pop3d |_pop3-capabilities: USER TOP PIPELINING IMPLEMENTATION(Courier Mail Server) UTF8(USER) STLS UIDL LOGIN-DELAY(10) | ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US | Subject Alternative Name: email:postmaster@example.com | Not valid before: 2021-04-19T16:11:49 |_Not valid after: 2022-04-19T16:11:49 |_ssl-date: TLS randomness does not represent time 143/tcp open imap Courier Imapd (released 2018) |_imap-capabilities: IMAP4rev1 UIDPLUS QUOTA IDLE UTF8=ACCEPTA0001 CAPABILITY ENABLE SORT NAMESPACE OK ACL2=UNION STARTTLS completed THREAD=REFERENCES CHILDREN THREAD=ORDEREDSUBJECT ACL | ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US | Subject Alternative Name: email:postmaster@example.com | Not valid before: 2021-04-19T16:11:36 |_Not valid after: 2022-04-19T16:11:36 |_ssl-date: TLS randomness does not represent time 514/tcp open shell? 993/tcp open ssl/imap Courier Imapd (released 2018) |_imap-capabilities: IMAP4rev1 UIDPLUS QUOTA IDLE AUTH=PLAIN UTF8=ACCEPTA0001 CAPABILITY ENABLE SORT NAMESPACE OK ACL completed THREAD=REFERENCES CHILDREN THREAD=ORDEREDSUBJECT ACL2=UNION | ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US | Subject Alternative Name: email:postmaster@example.com | Not valid before: 2021-04-19T16:11:36 |_Not valid after: 2022-04-19T16:11:36 |_ssl-date: TLS randomness does not represent time 995/tcp open ssl/pop3 Courier pop3d |_pop3-capabilities: USER TOP PIPELINING IMPLEMENTATION(Courier Mail Server) UTF8(USER) UIDL LOGIN-DELAY(10) | ssl-cert: Subject: commonName=localhost/organizationName=Courier Mail Server/stateOrProvinceName=NY/countryName=US | Subject Alternative Name: email:postmaster@example.com | Not valid before: 2021-04-19T16:11:49 |_Not valid after: 2022-04-19T16:11:49 2525/tcp open smtp Postfix smtpd |_smtp-commands: slpnet.tld, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING, | ssl-cert: Subject: commonName=debian10-uni | Subject Alternative Name: DNS:debian10-uni | Not valid before: 2021-04-17T10:36:40 |_Not valid after: 2031-04-15T10:36:40 |_ssl-date: TLS randomness does not represent time 53/udp open domain ISC BIND 9.11.5-P4-5.1+deb10u5 (Debian Linux) | dns-nsid: |_ bind.version: 9.11.5-P4-5.1+deb10u5-Debian 68/udp open|filtered dhcpc 69/udp open|filtered tftp 514/udp open|filtered syslog 5353/udp open mdns DNS-based service discovery | dns-service-discovery: | 9843/tcp webdav |_ Address=192.168.2.10 fe80::5054:ff:fe8b:7048 MAC Address: 52:54:00:8B:70:48 (QEMU virtual NIC) No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ). TCP/IP fingerprint: OS:SCAN(V=7.80%E=4%D=10/29%OT=22%CT=1%CU=2%PV=Y%DS=1%DC=D%G=Y%M=525400%TM=6 OS:17C1681%P=x86_64-pc-linux-gnu)SEQ(SP=104%GCD=1%ISR=108%TI=Z%CI=Z%II=I%TS OS:=A)OPS(O1=M5B4ST11NW7%O2=M5B4ST11NW7%O3=M5B4NNT11NW7%O4=M5B4ST11NW7%O5=M OS:5B4ST11NW7%O6=M5B4ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE OS:88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M5B4NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A= OS:S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q OS:=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A OS:%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y OS:%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T OS:=40%CD=S) Network Distance: 1 hop Service Info: Host: slpnet.tld; OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE HOP RTT ADDRESS 1 0.45 ms 192.168.2.10 OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 1315.13 seconds
Как показано в дампе 2.1.1, сканирование утилитой nmap скорее всего будет поверхностным, в случае применения опций -A, -T5, -sU и -sT
Опция -T5 указывает применять временной шаблона тестирования, устанавливающий временные характеристики тестирования udp- и tcp- соединений, которые можно замедлить или наоборот ускорить двигаясь от -T0 до и включая -T5
По умолчанию, используется временной шаблон, устанавливаемый -T3 и который предполагает, что тестирование идет в достаточно быстрой вычислительной сети, или речь о том, что мы готовы пожертвовать точностью ради ускорения процесса тестирования, т.е. сделать его поверхностным.
Опция -T4 не допускает превышение задержки динамического тестирования не выше 10 ms для портов TCP , в то время как опция -T5 устанавливает это значение к 5 ms. Вместе с опциями временных шаблонов можно использовать опции детализированного контроля [3.2].
Начиная с опции -T3 включается распараллеливание [3.3], которое ускоряет процесс тестирования портов и обнаружения узлов. Управлять этим процессом можно через опции --min-parallelism и --max-parallelism , а так же --min-hostgroup, --max-hostgroup . Первые две опции устанавливает минимальную и максимальную границу количества тестовых проходов, которым подвергается каждый узел из данной группы узлов, дипапазон которых указан в последних двух опциях. [3.4] Соответственно, в моем случае максимальные граничные значения обоих диапазонов были установлены равными диапазону 100 проб-тесирования (--max-parallelism) к одному узлу (--max-hostgroup).
Кроме того, были установлены опции тестирования udp- (-sU) и tcp- ( -sT) соединений, а также опция -A , которая заставляет nmap проводить проверки в полном объеме, такие как обнаружение типа и версии операционной системы, сканирования служб и версий (version scanning), трассировку маршрутизации и так называемого сканирования на основе сценария (script scanning), которое осуществляется одновременно со сканированием портов. С помощью опции --max-retries 10 установил приемлемое значение, в моем случае, для парирования предупреждения "giving up on port because retransmission cap hit (2)" [3.2].
Таким образом, после тестирования мной были обнаружены следующие открытые порты гостевой ОС, видные с центрального узла и которые перечислены в дампе 2.1.2
Дамп 2.1.2
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0) ... 25/tcp open smtp Postfix smtpd ... 53/tcp open domain ISC BIND 9.11.5-P4-5.1+deb10u5 (Debian Linux) 110/tcp open pop3 Courier pop3d … 143/tcp open imap Courier Imapd (released 2018) ... 514/tcp open shell? ... 993/tcp open ssl/imap Courier Imapd (released 2018) … 995/tcp open ssl/pop3 Courier pop3d ... 2525/tcp open smtp Postfix smtpd ... 53/udp open domain ISC BIND 9.11.5-P4-5.1+deb10u5 (Debian Linux) ... 9843/tcp webdav ... 68/udp open|filtered dhcpc ... 69/udp open|filtered tftp ... 514/udp open|filtered syslog ... 5353/udp open mdns DNS-based service discovery
Где, из всех открытых портов для клиента 192.168.2.10/32, согласно рисунку 1.1, должны быть перенаправлены порты: исходящие – в диапазоне 32678-65535 (ответные пакеты), входящие – в диапазоне 1-32000 портов (пакеты на запрос соединения )
Таким образом, из полученного распределения портов на узле ВМ "ОС Debain-11" можно заключить, что получаемые на входе шлюза virbr1 сообщения от узла ВМ "ОС Yocto/poky", будут содержат запросы к портам 22/tcp (SSH), 69/tcp (TFTP), 53/tcp (BIND) и других интересующих служб, запросы на соединения к которым будут приходит от узла ВМ "ОС Yocto/poky" в диапазоне портов 32001 до 32767. Поэтому порты во входящих сообщений на входе шлюза virbr1 должны быть перенаправлены на порты в диапазоне 1-32767 на узел ВМ "ОС Debain-11". При этом отправляемые обратно с выхода шлюза virbr1 сообщения должны передаваться на эмфиральные порты в диапазоне 32768-65535
2.1 Настройка nat в Gnome-boxes
Производил её таким же образом, как это делал в virt-manager во время создания мостовой сети для организации сетевого доступа к гостевой ОС "Debian-10". Но, с одним изменением, что в XML-настройках подсети 192.168.2.0/24 задействуются элементы <nat> и <ports>, с помощью которых устанавливается перенаправление трафика на эмфиральные порты в диапазоне 32768-65535 в virt-manager"ОС Yocto/poky" с использованием политик SNAT или MASQUERADE межсетевого экрана в iptables / netfilter . При этом, доступ к перечисленным на рисунке 1.1 портам из диапазона 1-32000 узла ВМ "ОС Debian-10" останется открытым, т.к. никакие ограничений к ним не применяются.
Для включения режима ретрансляции адреса указал значение "nat" в атрибуте mode элемента <forward> в сетевых настройках для подсети c ip:192.168.2.0/24 в XML-файле libvirt-slpnet.xml, как показано в листинге 2.2.1
Дамп 2.2.1
<network> <name>slpnet.tld</name> <uuid>52008539-dd34-4b5f-95f5-c9e8591e57c8</uuid> <forward mode='nat' dev='tap0'> <nat> <port start='32768' end='65535'/> </nat> <interface dev='tap0'/> </forward> <bridge name='virbr1' stp='on' delay='0'/> <mac address='52:54:00:77:1d:d5'/> <domain name='slpnet.tld'/> <dns> <forwarder domain='slpnet.tld' addr='192.168.2.10'/> <host ip='192.168.2.10'> <hostname>slpnet.tld</hostname> <hostname>mail.slpnet.tld</hostname> </host> </dns> <ip address='192.168.2.2' netmask='255.255.255.0'> <dhcp> <range start='192.168.2.100' end='192.168.2.254'/> <host mac='52:54:00:8b:70:48' name='mail.slpnet.tld' ip='192.168.2.10'/> </dhcp> </ip> </network>
Как показано в листинге 2.2.1, элемент <forward> отвечает за маршрутизацию пакетов из физической сети и обратно в режиме ретрансляции сетевого адреса, который устанавливается атрибутом mode='nat'. Дополнительно, также указывается сетевой интерфейс tap0, сопрягаемый эмулятором Qemu/KVM, на который будет производится продвижения пакетов с использованием ретрансляции по адресу.
Поэтому в нем указал два элемента <nat> и <interface>, первый отвечает за диапазоны портов, элемента <port>, и адресов, элемента <address>, на которые производится перенаправление трафика, а второй явно указывает сетевой интерфейс, участвующий в данном перенаправлении [3.9].
Диапазон перенаправляемых, так называемых, эмфиральных портов на узел ВМ "ОС Yocto/poky" с "ip: 192.168.7.2", диапазон которых начинается с 32768 и заканчивается 65535 портом и установлен во многих версиях ядра Linux [3.8]. При этом первые 768 портов, начиная с 32001 следует отдать службам ssh, tftp, bind9, smtp, pop и т.д., поэтому в элементе <port> указано перенаправлять все исходящие пакеты исходящие пакеты, передаваемые по эмфиральным портам (32768-65535), от узла подсети с ip:192.168.2.0/254 к узлам подсети ip:192.168.7.0/24 . При этом, как увидим ниже [2.5], порты остаются неизменными, а для указанного диапазона портов будет происходит лишь замена адреса при передачи пакетов получателя в обратном направлении к отправителю, но никак не самих портов.
В конечном итоге в таблицах mangle, filter и nat будут установлены правила программному межсетевому экрану (iptables) в определяемых libvirt цепочках, после создания сети slpnet.tld , процесс создания которой показан в дампе 2.2.2
Дамп 2.2.2
~$ sudo virsh [sudo] пароль для user: Добро пожаловать в virsh — интерактивный терминал виртуализации. Введите «help» для получения справки по командам «quit», чтобы завершить работу и выйти. virsh # net-create /home/user/libvirt-slpnet.xml Сеть slpnet.tld создана из /home/user/libvirt-slpnet.xml virsh #
2.3 Реализация режима роутера с помощью пакетной фильтрации в (iptables / netfilter) в IPTables
Обеспечивается за счет использования таблиц mangle, filter и nat, где будут установлены правила программному межсетевому экрану (iptables / netfilter) для организации перенаправления трафика, как показано на рисунке 2.3.1
Рисунок 2.3.1
Как показано на рисунке 2.3.1 существует два режима пакетной фильтрации (Packet filtering) и продвижение пакетов (Packet forwarding) в подсистеме ядра netfilter, когда задействуются правила фильтрации и перенаправления (коммутации) за счет изменения сетевого адреса или порта для каждого принимаемого или отправляемого пакета на уровне ядра. При этом таблица маршрутизации остается нетронутой и используется для перенаправления с "поправленным" заголовком пакетов на уровне ядра подсистемой netfilter.
Поэтому пакетная фильтрация (Packet filtering) является нечто большим чем просто продвижение пакетов (Packet forwarding), потому что последний использует лишь таблицу маршрутизиции, чтобы перенаправить пакет на тот узел-назначения куда нужно отправителю . В то время как пакетная фильтрация использует перечень правил позволяющий ей решать, на уровне ядра, что делать с каждым входящим (input) или выходящим (output) пакетом, а так же отфильтровывать пакеты с использованием политики FORWARD [3.10].
Соответственно, подсистема ядра netfilter настраиваетcя утилитой iptables в основном для фильтрации каждого пакета, проходящего через цепочки INPUT, FORWARD и OUTPUT таблицы filter на уровне сокета процесса. Например, как показано на рисунке 2.3.1, при обращении клиента (ВМ "ОС Yocto/poky") к их слушающему сокету, открытого на одном из портов 69 и 25, 2525 служб tftpd-hpa и postfix на сервере (ВМ "ОС Debian-10"), с помощью пакетной фильтрации можно контролировать какой именно узел отправитель (source host) создает соединение для передачи запроса к узлу отправителя (destionation source) и/или порт службы (service port). Так же как, с помощью неё можно контролировать куда обратно передавать запрашиваемые данные отправителем на один или несколько эмфиральных портов узла получателя.
Для этого Libvirt задействует цепочки LIBVIRT-{FWO,FWX,FWI, INP, OUT}, которые создаются сервером libvirtd в ходе реализации правил службы ядра Linux межсетевого экрана netfilter и задаются через ее интерфейс – утилиты iptables [3.11]
Приватные цепочки LIBVIRT-{FWO,FWX,FWI, INP, OUT} были введены в libvirt 5.1.0 из-за снижения производительности в следствии постоянной перезагрузки модуля ядра conntrack и последующего запуска им процедуры отслеживания и обработки соединений. Поэтому модуль conntrack не будет загружен до тех пор пока не будет поднята подсеть, как было показано ранее в дампе 2.2.2 для slpnet.tld, и когда libvirt не добавит правила во встраиваемые цепочки LIBVIRT-{FWO,FWX,FWI, INP, OUT} [3.12].
В таблицу filter цепочки LIBVIRT-{FWO,FWX,FWI, INP, OUT} встраиваются цепочки FORWARD, INPUT, OUTPUT таблицы filter, как показано в дампе 2.3.2
Дамп 2.3.2
~$ sudo iptables -t nat -S ... -P INPUT ACCEPT -P FORWARD ACCEPT ... -N LIBVIRT_FWI -N LIBVIRT_FWO -N LIBVIRT_FWX -N LIBVIRT_INP -N LIBVIRT_OUT -N LIBVIRT_OUT -A INPUT -j LIBVIRT_INP -A FORWARD -j LIBVIRT_FWX -A FORWARD -j LIBVIRT_FWI -A FORWARD -j LIBVIRT_FWO -A OUTPUT -j LIBVIRT_OUT ...
Как показано в дампе 2.3.2, сначала разрешается прохождение пакетов любых типов протоколов в цепочках INPUT, FORWARD, OUTPUT, что на первый взгляд не безопасно [3.13]. Но, вводимые ограничения в цепочках LIBVIRT-{FWO,FWX,FWI, INP, OUT} позволяют снять определенный градус накала страстей и сделать соединения безопасными. Далее, создаются определяемые пользователем цепочки LIBVIRT-{FWO,FWX,FWI, INP, OUT} (опция -N) и добавляются правила перехода (опция -j) к ним согласно той последовательности, как эти правила были добавлены.
Все только что перечисленные и создаваемые libvirt пользовательские цепочки образуют прямой и обратный канал движения трафика между узлами с ip:192.168.7.2 и 192.168.2.10. Прямой канал показан на рисунке 2.3.4, который был отработан ранее при перенаправлении трафика между двумя интерфейсами узлов гостевых ОС с ip:192.168.7.2 и 192.168.2.10
Рисунок 2.3.4
Как показано на рисунке 2.3.4, кроме добавленных правил libvirt, после инициализации сети с ip:192.168.2.0/24, мне пришлось добавить свои правила и пользовательские цепочки YP_FWI, YP_FWO в таблице фильтрации (filter) для обхода установленных правил и цепочек libvirt
Рисунок 2.3.5
Организация обратного канала показана на рисунке 2.3.5, который был реализован с использованием тех же самых цепочек и правил, что и прямой канал, как показано в листинге 2.3.6, от отправителя в направлении получателя.
Листинг 2.3.6
# Цепочка FORWARD: -P FORWARD ACCEPT 1:-A FORWARD -j LIBVIRT_FWX 2:-A FORWARD -j YP_FWI 3:-A FORWARD -j LIBVIRT_FWI 4:-A FORWARD -j LIBVIRT_FWO 5:-A FORWARD -j YP_FWO # Пользов. цепочка YP_FWI: 1: -A YP_FWI -s 192.168.2.10/32 -i virbr1 -o tap1 -j ACCEPT 2: -A YP_FWI -s 192.168.2.10/32 -i virbr1 -j YP_FWO 3: -A YP_FWI -s 192.168.7.0/24 -d 192.168.2.0/24 -i tap2 -j YP_FWO # Пользов. цепочка YP_FWO: 1: -A YP_FWO -s 192.168.7.2/32 -i tap1 -j RETURN 2: -A YP_FWO -s 192.168.7.2/32 -i tap2 -o virbr1 -j ACCEPT
Кроме правил фильтрации для организации продвижения пакетов трафика в нужном направлении, была использована политика MASQUERADE на выходе сетевого интерфейса virbr1 при передачи пакета к узлу-получателю ВМ "ОС Debian-10" и маскирования в заголовке IP-пакета IP-адреса 192.168.7.2 узла-отправителя ВМ "ОС Yocto/poky", как показано в листинге 2.3.7
Листинг 2.3.7
-P POSTROUTING ACCEPT # Цепочка POSTROUTING: 1:-A POSTROUTING -j YP_PRT 2:-A POSTROUTING -j LIBVIRT_PRT … # Цепочка YP_PRT -A YP_PRT ! -s 192.168.7.2/32 -i tap2 -j RETURN -A YP_PRT -d 192.168.2.0/24 -o virbr1 -j MASQUERADE
Как показано, в листинге 2.3.7, цепочка YA_PRT обеспечивает обход цепочки LIBVIRT_PRT, ранее определенной libvirt, и установку правил перенаправления пакета по сетевому адресу или портам, передаваемые в подсеть с ip:192.168.2.0/24
2.4 Процедура отслеживание соединений в режимах фильтрации и трансляции сетевого адреса (IPTables / NFTables / conntrack)
Перед тем, как рассмотреть все политики перенаправления сетевого адреса и портов NAT, предлагаю ознакомится с работой подсистемы отслеживания соединений, реализованной в модуле (nf_)conntrack ядра ОС GNU/Linux
Как вытекает из самого названия подсистемы, её основной задачей является отслеживание соединений, называемой в некоторых источниках "ct system" уровня ядра [3.17], и оценка пакетов вычислительных сетей IPv4 и/или IPv6 на их полезность и чтобы определить какие пакеты связаны друг с другом, например с точки зрения ореентированного на установление постоянного соединения протокола TCP
Эту задачу (nf_)conntrack выполняет в качестве беспристрастного наблюдателя (transparent observer) и не принимает активного участия в создании и управлении соединений между конечными точками, как и не имеет значение являются ли это соединение удаленным или локальным. Так же не играет роли, где находятся конечные точки соединения, даже если они находятся на удаленных узлах, в таком случае (nf_)conntrack будет рассматривать их до тех пор пока управляет им на узле, который выполняет маршрутизацию (routing packets) или соединение (bridging packets) пакетов соответствующего соединения. Как вариант, одна или даже обе конечных точек могут расположены на локальных сокетах того же самого узла, где выполняется (nf_)conntrack . Эта не вносит никаких различий, потому что (nf_)conntrack постоянно обновляет список всех отслеживаемых соединений, по установленному каждому из них собственному таймауту, и классифицирует сетевые пакеты, так как они проходят сетевой стек ядра, снабжая каждого из них ссылкой (указателем) на другой пакет отслеживаемых экземплярах соединений. Поэтому любой другой компонент ядра может иметь доступ к этой совокупности соединений и принимать на основе этого решение.
Главными кандидатами кто может задействовать (nf_)conntrack являются подсистемы фильтрации пакетов и проверки состояния пакетов, реализуемые для пользователя в качестве интерфейсов межсетевых экранов IPTables и Nftable [3.18]. При этом нужно понимать, что сам (nf_)conntrack никогда не отсеивает и управляет пакетами, а применяется на 3-ем сетевом и 4-м транспортном уровни модели OSI, что делает возможным отслеживания соединений на базе протоколов TCP, UDP, ICMP, ICMPv6, SCTP, DCCP и GRE. Очевидно, что определение термина «соединение» в (nf_)conntrack не ограничивается лишь ориентированными на устанавливающие постоянное соединения протоколов, так как несколько только что упомянутых протоколов такими не являются. Как например в случае с протоколом ICMP, где установленным соединением считается переданный пакет с эхо запросом (echo-request) и принятый в ответ (echo-reply). Так же (nf_)conntrack обеспечивает несколькими вспомогательными компонентами и расширениями, которые позволяют осуществлять отслеживание на 5-м прикладном уровне модели OSI, таких протоколов как TFTP, PPTP, SIP и т.д.
Теперь рассмотрим в каких цепочка IPTables, где и с какими приоритетами задействуется conntrack, как показано на рисунке 2.4.1
Рисунок 2.4.1
Как показано на рисунке 2.4.1, в случае использования NFTables нужно не забывать о приоритетах, иначе пакет не преодолеет conntrack и где-нибудь там «застрянет». Так, например, при прохождение PREROUTNIG и OUTPUT приоритет нужно устанавливать меньше -200 , а вот для цепочек INPUT и PREROUTING должно быть максимальное положительное значение, но уже в так называемых помощниках conntrack, которые определяет соответствие пакета выше перечисленных прикладного уровня [3.20].
Чтобы получить список соединений и их состояний следует обратить свой взор на файл /proc/net/nf_conntrack, который можно прочитать командой cat из консоли, как показано в дампе 2.4.2 . При этом, тот же самый список соединений возможно получить из файла /proc/net/ip_conntrack [3.22]
Листинг 2.4.2
sudo cat /proc/net/nf_conntrack | grep src=192.168.2.2 ... ipv4 2 udp 17 25 src=192.168.2.10 dst=192.168.2.2 sport=39182 dport=53 src=192.168.2.2 dst=192.168.2.10 sport=53 dport=39182 mark=0 zone=0 use=2 ipv4 2 tcp 6 431995 ESTABLISHED src=192.168.2.2 dst=192.168.2.10 sport=38452 dport=2525 src=192.168.2.10 dst=192.168.2.2 sport=2525 dport=38452 [ASSURED] mark=0 zone=0 use=2
В данном случае, было зарегистрировано два соединения: первое – TCP, а второе – UDP-соединение. Каждая строка файла /proc/net/nf_conntrack или /proc/net/ip_conntrack содержит информацию об зарегистрированном соединении и имеет определенный формат записи, которые перечислены в таблице 2.4.3
Поз. | Назначение поля записи | Поддержка в /proc/net/nf_conntrack | Поддержка в /proc/net/ip_conntrack |
---|---|---|---|
1 | Наименование сетевого протокола: ipv4 или ipv6 | + | – |
2 | Номер сетевого протокола | + | – |
3 | Наименование протокола транспортного уровня, может принимать значения: icmp, tcp, udp, dccp, gre, sctp, udplite, icmpv6 | + | + |
4 | Номер протокола транспортного уровня | + | + |
5 | Содержит значение таймера обратного отсчета срока истечения валидности соединения в секундах | + | + |
6 | Состояние соединения (поддерживается не всеми протоколами) | + | + |
7,... | Остальные поля содержат либо параметр соединения, состоящий из именованного ключа и его значения, или флаги в виде текстовых обозначений, напиример [UNREPLIED], [ASSURED],... | + | + |
Назначение флагов:
[ASSURED] трафик был передан в обоих направления: в направлении отправителя и с ответом от получателя (request and respond directions), т.е была зафиксирована передача пакета с запросом на установку соединения от отправителя (request directions) и прием им ответного пакета от получателя (respond directions).
[UNREPLIED] устанавливается в случае отсутствия каких либо пакетов обратного направления от получателя . В этом случае КЭШ отслеживаемых соединений неизбежно переполнится, поэтому такие соединения отбрасываются первыми.
[OFFLOAD] в 2017 году в подсистему фильтрации и ретрансляции сетевого адреса и портов была добавлена программная инфраструктура (flow offload infrastructure), обеспечивающая снижение нагрузки за отслеживаемыми на уровне подсистемы ядра netfilter соединений и оптимизации пути следования внутри пакетов TCP/IP (flow offload infrastructure), путем выгрузки такого соединения в таблицу передачи пакетов (flow table).
Таймер со стороны пользователя у таких записей (поле 5) в файле /proc/net/nf_conntrack выглядит застывшим. Это было сделано для того, чтобы такое соединение не выскользало из виду и не исчезало из файла /proc/net/nf_conntrack . Таймер [модуля] conntrack (на уровне ядра) периодически устанавливает произвольное большое значение этой записи в файле /proc/net/nf_conntrack, поэтому эта запись в нем не исчезает. Тем самым через такую блокировку conntrack позволяет сохранить битовую проверку пути следования (передачи) пакета [3.27], пример которой приводится в дампе 2.4.4 .
Дамп 2.4.4
# cat /proc/net/nf_conntrack ipv4 2 tcp 6 src=10.141.10.2 dst=147.75.205.195 sport=36392 dport=443 src=147.75.205.195 dst=192.168.2.195 sport=443 dport=36392 [OFFLOAD] mark=0 zone=0 use=2
В дампе приводится пример установки флага [OFFLOAD] из найденной мной документации [3.25], т.к. флаги [OFFLOAD] и [HW_OFFLOAD] в записях списка соединений возникают только при использовании NFTables, увы.
[HW_OFFLOAD] применяется начиная с версии ядра 5.13 в conntrack стал поддерживать выгрузку соединений сетевых интерфейсов в flow table [3.29].
Оба флага, OFFLOAD и HW_OFFLOAD, используются в политиках продвижения пакетов цепочки FORWARD и устанавливаются в более свежей реализации интерфейса управления NFTables подсистемы netfilter на уровне ядра Linux и позволяют высчитывать оптимальный путь следования их пакетов, например во время использования политики FORWARD, пример использования который взят с документации NFTables [3.30] и показан в дампе 2.4.5
Дамп 2.4.5
table inet x { flowtable f { hook ingress priority 0 devices = { eth0, eth1 }; } chain forward { type filter hook forward priority 0; policy drop; # offload established connections ip protocol { tcp, udp } flow offload @f ip6 nexthdr { tcp, udp } flow offload @f counter packets 0 bytes 0 # established/related connections ct state established,related counter accept # allow initial connection ip protocol { tcp, udp } accept ip6 nexthdr { tcp, udp } accept } }
Кроме выше перечисленных флагов [ASSURED] , [UNREPLIED] , [OFFLOAD] и [РЦ_OFFLOAD] в перемешку с ними могут идти параметры соединения, такие как параметры src, dst, sport и dport, содержащие значения IP-адрес/порт отправителя и получателя/назначения, таймаут , устанавливаемый в зависимости от состояний dccp-, sctp- и tcp- соединения, и т.д.
Кроме того, у некоторых протоколов, таких как icmp, dccp, sctp, tcp, udp, udplite, и gre, запись в списке (установленных) соединений могут иметь дополнительные параметры, которые следует рассматривать отдельно.
2.5 Применение MASQUERADE, SNAT / DNAT для перенаправления портов
2.5.1 Политика SNAT и MASQUERADE
Как можно было и ожидать, для полноценного обмена по протоколам прикладного уровня модели OSI, просто установки политики FORWARD оказалось недостаточно, чтобы реализовать схемe, ранее показанную на рисунке 1.1
Поэтому рассмотрим схему применения цепочки POSTROUTING для перенаправления пакета tcp- или udp- c порта отправления (source port) узла отправителя на порт назначения (destination port) узла получателя, как показано на рисунке 2.5.1
Рисунок 2.5.1
Который практически полностью повторяет рисунок 2.3.4, но с одной лишю разницей, что для определения наличия неустановленного соединения здесь будем использовать conntrack в цепочке YA_PRT, которая разделяет обмен ВМ "ОС Debian-10" с центрального узла гипервизора и ВМ "ОС Yocto/poky".
Для обмена ВМ "ОС Debian-10" с центрального узла гипервизора служит цепочка LIBVIRT_PRT, которая определена пользователем и задействуется в основной цепочки POSTROUTING таблицы nat
Цепочка LIBVIRT_PRT установливает правила, осуществляющие перенаправление исходящего трафика c ВМ "ОС Debian-10" на порты узлов, не относящихся к сети 192.168.2.0/24, используя политику MASQUERADE, как показано в дампе 2.5.2
Дамп 2.5.2
user@kvm-host: ~$ sudo iptables -t nat -S POSTROUTING ... -A LIBVIRT_PRT -s 192.168.2.0/24 ! -d 192.168.2.0/24 -o tap0 -p tcp -m -j MASQUERADE --to-ports 32768-65535 -A LIBVIRT_PRT -s 192.168.2.0/24 ! -d 192.168.2.0/24 -o tap0 -p udp -j MASQUERADE --to-ports 32768-65535 -A LIBVIRT_PRT -s 192.168.2.0/24 ! -d 192.168.2.0/24 -o tap0 -j MASQUERADE ...
Где производится маскирование, согласно выделенному диапазону эмфиральных портов (32768-65535), указанного ранее в листинге 2.2.1 и указаному в XML-конфигурации подсети с ip:192.168.2.0/24 с помощью элемента <port> для перенаправления всех исходящих пакеты, передаваемые по эмфиральным портам от узла подсети с ip:192.168.2.0/24 к узлам подсети ip:192.168.7.0/24, что на самом деле, как видно из дампа 2.5.2, здесь применяется маскирование диапазона эмфиральных портов протоколов транспортного уровня tcp и udp, а также для любых других передаваемых со шлюза (virbr1)
Листинг 2.5.3
# Цепочка YP_PRT 1:-A YP_PRT ! -s 192.168.7.2/32 -i tap2 -j RETURN 2:-A YP_PRT -d 192.168.2.0/24 -o virbr1 -j MASQUERADE
Как показано в листинге 2.5.3, цепочка YA_PRT служит для замещения или маскирования внутреннего ip:192.168.7.2 в передаваемом IP-пакете узла ВМ "ОС Yocto/poky" на внешний ip:192.168.2.2 , как показано в списке соединений в дампе 2.5.4 для udp-соединений.
Дампе 2.5.4
user@kvm-host: ~$ sudo cat /proc/net/nf_conntrack | grep 192.168.2.2 ipv4 2 udp 17 25 src=192.168.7.2 dst=192.168.2.10 sport=54069 dport=53 src=192.168.2.10 dst=192.168.2.2 sport=53 dport=54069 mark=0 zone=0 use=2 ipv4 2 udp 17 13 src=192.168.7.2 dst=192.168.2.10 sport=38511 dport=53 src=192.168.2.10 dst=192.168.2.2 sport=53 dport=38511 mark=0 zone=0 use=2 ipv4 2 udp 17 13 src=192.168.7.2 dst=192.168.2.10 sport=59803 dport=53 src=192.168.2.10 dst=192.168.2.2 sport=53 dport=59803 mark=0 zone=0 use=2 ipv4 2 tcp 6 431998 ESTABLISHED src=192.168.7.2 dst=192.168.2.10 sport=49648 dport=110 src=192.168.2.10 dst=192.168.2.2 sport=110 dport=49648 [ASSURED] mark=0 zone=0 use=2 ipv4 2 udp 17 25 src=192.168.7.2 dst=192.168.2.10 sport=34910 dport=53 src=192.168.2.10 dst=192.168.2.2 sport=53 dport=34910 mark=0 zone=0 use=2
Где, если верить параметрам зарегистрированных udp- и tcp- соединений, IP-адрес отправителя, инициатора соединения является IP:192.168.7.2, который наблюдаем в параметре src=192.168.7.2 в пятой позиции или седьмой позиции соответственно. Потому что в регистрационной записи файла /etc/net/nf_conntrack содержатся два похожих друг на друга набора именованных параметров.
В первом наборе (выделены подчеркиванием в дампе 2.5.4) отображаются оригинальные значения портов и IP-адрес заголовоку отправляемого tcp- или udp- пакета, начиная с 5-й позиции (udp) или 7-й позиции (tcp), ip-адрес отправителя (src=), ip-адрес получателя (dst=), порт отправителя (sport=), порт получателя (dport=) . Во втором наборе (выделен жирным в дампе 2.5.4), который сразу же следует за первым, отображаются содержимого заголовка ответного пакета, который пришел обратно от получателя. Поэтому, если посмотреть на дамп 2.5.4 с установленной политика MASQUERADE, IP-адрес узла получателя в ответном пакете, преподаваемого в направлении от получателя (destination direction), будет равен ip-адресу шлюза 192.168.2.2 (выделен жирным с курсивом в дампе 2.5.4 ).
Если же удалить политику MASQUERADE из цепочки YA_PRT(выделена жирным в листинге 2.5.6), тогда IP-адрес назначения в ответном пакете направлении от получателя (destination direction) будет равен IP-адресу инициатору соединения, т.е. узлу отправителю (source) и равен 192.168.7.2 (выделен жирным в дампе 2.5.5).
Листинг 2.5.6
# Цепочка YP_PRT:
1:-A YP_PRT ! -s 192.168.7.2/32 -i tap2 -j RETURN
2:-A YP_PRT -s 192.168.7.2 -d 192.168.2.10 -o virbr1 -j SNAT --to 192.168.2.2
В результате, добавленного правила (выделено жирным в дампе 2.5.6), IP-адрес назначения в направлении от получателя (destionation direction) будет снова равен 192.168.2.2 (выделен жирным), как показано в дампе 2.5.7
Дампе 2.5.7
user@kvm-host:~$ sudo cat /proc/net/nf_conntrack | grep 192.168.2 ipv4 2 tcp 6 431991 ESTABLISHED src=192.168.7.2 dst=192.168.2.10 sport=49660 dport=110 src=192.168.2.10 dst=192.168.2.2 sport=110 dport=49660 [ASSURED] mark=0 zone=0 use=2 ipv4 2 udp 17 12 src=192.168.7.2 dst=192.168.2.10 sport=42750 dport=53 src=192.168.2.10 dst=192.168.2.2 sport=53 dport=42750 mark=0 zone=0 use=2 ipv4 2 udp 17 12 src=192.168.7.2 dst=192.168.2.10 sport=42660 dport=53 src=192.168.2.10 dst=192.168.2.2 sport=53 dport=42660 mark=0 zone=0 use=2
2.5.2 Политика DNAT
Если же мы хотим перенаправить пакет на нужный номер порта отправителю или получателю в схеме, показанной на рисунке 1.1, то наш путь лежит в царство цепочки PREROUTING
Цепочка PREROUTING позволяет устанавливать нужные правила для перенаправления заданного порта передаваемого пакета получателю и отсеивать те пакеты отправителя, к портам которых доступ ему ограничен. Для чего, необходимо определить пользовательскую цепочку YP_PRRT, на которая показана на рисунке 2.5.8
Рисунок 2.5.8
Как показано на рисунке 2.8, пользовательская цепочка YP_PRRT производит замену порта на требуемый по указанным в нем значению порта-назначения узла отправителя, которым является ВМ "ОС Yocto/poky". При этом, пакет в направлении получателя с запросом на соединение может поступить из одного интерфейса tap1 или tap2 из-за путаницы эмулятором Qemu/KVM связки интерфесов eth0, eth1 на узле ВМ "ОС Yocto/poky" с интерфейсами tap1, tap2 на центральном узле гипервизора . При этом, в данной схеме поробуем в целях обучения игнорировать все пакеты в цепочке PREROUTING, которые не будут иметь значения, соотв. порта-назначения получателя (подсети с ip:192.168.2.10/24) в требуемом диапазоне 32001–32767
Согласно представленной схемы прохождения пакетом цепочек на рисунке 2.5.8, выполнение первого условия будет выполняться прямо в начале цепочки YP_PRRT, как показано в 1-й и 2-й ее позиции листинга 2.5.9
Листинг 2.5.9
-P PREROUTING ACCEPT -N YP_PRRT # Цепочка PRETROUTING: 1:-A PREROUTING -j YP_PRRT # Цепочка YP_PRRT: 1:-A YP_PRRT ! -d 192.168.2.0/24 -i tap1 -j RETURN 2:-A YP_PRRT ! -d 192.168.2.0/24 -i tap2 -j RETURN 3:-A YP_PRRT -d 192.168.2.10/32 -p udp -m udp ! --dport 32001:32767 -j REJECT 4:-A YP_PRRT -d 192.168.2.10/32 -p tcp -m tcp ! --dport 32001:32767 -j REJECT
Как показано в листинга 2.5.9, в нем зачеркнутыми являются правила в 3-й и 4-й позиции цепочке YP_PRRT, где пытался установить правила для отсеивания пакет при не соблюдении 2-го условия, показанного на рисунке 2.5.8
При попытки добавления правил в зачеркнутых 3-й и 4-й позиции цепочки YP_PRRT, пользовательский интерфейс iptables завершился с ошибкой, как показано в дампе 2.5.10
Листинг 2.5.10
user@kvm-host:~$ sudo iptables -t nat -D YP_PRRT -p udp --dst 192.168.2.10 ! --dport 32001:32767 -j REJECT iptables: Bad rule (does a matching rule exist in that chain?). user@kvm-host:~$ sudo iptables -t nat -D YP_PRRT -p tcp --dst 192.168.2.10 ! --dport 32001:32767 -j REJECT iptables: Bad rule (does a matching rule exist in that chain?).
Поэтому, как показано в листинге 2.5.11, правила в зачеркнутой 3-й и 4-й позиции цепочки YP_PRRT были приведены в соответствии со схемой, показанной ранее на рисунке 2.5.8
Листинг 2.5.11
# Цепочка YP_PRRT: 1:-A YP_PRRT ! -d 192.168.2.0/24 -i tap1 -j RETURN 2:-A YP_PRRT ! -d 192.168.2.0/24 -i tap2 -j RETURN 3:-A YP_PRRT -d 192.168.2.10/32 -s 192.168.7.2/32 -p udp -m udp ! --dport 32001:32767 -j RETRUN 4:-A YP_PRRT -d 192.168.2.10/32 -s 192.168.7.2/32 -p tcp -m tcp ! --dport 32001:32767 -j RETRUN
А именно, произведена передача пакета к цепочке FORWARD таблицы filter при условии, что порт назначения в tcp-, udp- пакетах не находится в ожидаемом диапазоне 32001-32767, произойдет его отбраковка в цепочки YP_FWO, которую рассмотрю ниже, после применения политики DNAT
Как показано в листинге 2.5.12, для ретрансляции пакетов в направлении получателя от отправителя (request direction) на нужный открытый порт ВМ "ОС Debian-10", добавил следующие правила согласно схеме, показанной на рисунке 1.1
Листинг 2.5.12
# Цепочка YP_PRRT: 1:-A YP_PRRT ! -d 192.168.2.0/24 -i tap1 -j RETURN 2:-A YP_PRRT ! -d 192.168.2.0/24 -i tap2 -j RETURN # Любые пакеты передаваемые 3:-A YP_PRRT -d 192.168.2.10/32 -s 192.168.7.2/32 -p udp -m udp ! --dport 32001:32767 -j RETRUN 4:-A YP_PRRT -d 192.168.2.10/32 -s 192.168.7.2/32 -p tcp -m tcp ! --dport 32001:32767 -j RETRUN # Ретрансляция порта получателя с 32001/tcp на реальный открытый 22/tcp 5:-A YP_PRRT -s 192.168.7.2/32 -d 192.168.2.10/32 -p tcp -m tcp --dport 32001 -j DNAT --to-destination 192.168.2.10:22 # Ретрансляция порта получателя с 32002/udp на реальный открытый 69/udp 6:-A YP_PRRT -s 192.168.7.2/32 -d 192.168.2.10/32 -p udp -m udp --dport 32002 -j DNAT --to-destination 192.168.2.10:69 # Ретрансляция порта получателя с 32004/tcp на реальный открытый 110/tcp 7:-A YP_PRRT -s 192.168.7.2/32 -d 192.168.2.10/32 -p tcp -m tcp --dport 32004 -j DNAT --to-destination 192.168.2.10:110 # Ретрансляция порта получателя с 32005/tcp на реальный открытый 143/tcp 8:-A YP_PRRT -s 192.168.7.2/32 -d 192.168.2.10/32 -p tcp -m tcp --dport 32005 -j DNAT --to-destination 192.168.2.10:143 # Ретрансляция порта получателя с 32006/tcp на реальный открытый 2525/tcp 9:-A YP_PRRT -s 192.168.7.2/32 -d 192.168.2.10/32 -p tcp -m tcp --dport 32006 -j DNAT --to-destination 192.168.2.10:2525 # Ретрансляция порта получателя с 32007/udp на реальный открытый 514/tcp 9:-A YP_PRRT -s 192.168.7.2/32 -d 192.168.2.10/32 -p tcp -m tcp --dport 32007 -j DNAT --to-destination 192.168.2.10:514 # Ретрансляция порта получателя с 32007/udp на реальный открытый 514/udp 10:-A YP_PRRT -s 192.168.7.2/32 -d 192.168.2.10/32 -p udp -m udp --dport 32007 -j DNAT --to-destination 192.168.2.10:514
Как показано в листинге 2.5.12, с 5-й по 10-ю позицию цепочки YP_PRRT устанавливаются правила, которые перенаправляют пакет в направлении получателя от отправителя (request direction) на нужный открытый порт ВМ "ОС Debian-10" в соответствии со схемой, показанной на рисунке 1.1. При этом, используется опция --to-destination , которая идет следом за -j DNAT и от нее зависящей.
Опция --to-destination [ipaddr[-ipaddr]][:port[-port]], зависимая от -j DNAT, используется для перенаправления tcp-, udp- соединений (на стороне получателя ) на новый IP-адрес или диапазон IP-адресов ([ipaddr[-ipaddr]]), так же как указанный через двоеточие новый порт или диапазон портов.
Кроме того, чтобы не наскочить на сообщение об неизвестной опции, например "--dport", как показано в дампе 5.13, следует четко понимать последовательность ввода оцпий, иначе ошибок типа "unknown option" не избежать.
Листинг 5.13
user@kvm-host:~$ sudo iptables -t nat -A YP_PRRT -s 192.168.7.2/32 -d 192.168.2.10/32 --dport 32001 -j DNAT --to-destination 192.168.2.10:22 iptables v1.8.7 (nf_tables): unknown option "--dport" Try `iptables -h' or 'iptables --help' for more information.
Правильной последовательностью опций будет следование сначала опции -s, --source address[/mask], за ней опции -d, --destination address[/mask]. Следом нужно указать опции протокола -p tcp -m tcp, последняя активирует более расширенное обнаружения соответствий протоколу TCP, которые в данном случае включают определение номера порта назначения в tcp-пакете отправителя в направление получателя. Поэтому следующий порядок следования опций, показанный в листинге 5.14, является правильным и распространяемый на все остальные позиции ниже в цепочке YP_PRRT
Листинг 5.14
# Ретрансляция порта получателя с 320001/tcp на реальный открытый 22/tcp 5:-A YP_PRRT -s 192.168.7.2/32 -d 192.168.2.10/32 -p tcp -m tcp --dport 32001 -j DNAT --to-destination 192.168.2.10:22 # Ретрансляция порта получателя с 320002/udp на реальный открытый 69/tcp 6: A YP_PRRT -s 192.168.7.2/32 -d 192.168.2.10/32 -p udp -m udp --dport 32002 -j DNAT --to-destination 192.168.2.10:69
Далее оставалось выполнить команду на стороне отправителя "ssh -p 32001 user@192.168.2.10", чтобы, как показано в дампе 5.15, увидеть следы на центральном узле гипервизора (kvm-host), перенаправления пакета порта 32001, вводимого отправителем, на реально открытый порт 22 на стороне получателя.
Дамп 5.15
user@kvm-host:~$ sudo iptables -t nat -v -nL YP_PRRT Chain YP_PRRT (1 references) pkts bytes target prot opt in out source destination 0 0 RETURN all -- tap1 * 0.0.0.0/0 !192.168.2.0/24 0 0 RETURN all -- tap2 * 0.0.0.0/0 !192.168.2.0/24 0 0 RETURN udp -- * * 192.168.7.2 192.168.2.10 udp dpts:!32001:32767 2 120 RETURN tcp -- * * 192.168.7.2 192.168.2.10 tcp dpts:!32001:32767 1 60 DNAT tcp -- * * 192.168.7.2 192.168.2.10 tcp dpt:32001 to:192.168.2.10:22 user@kvm-host:~$ sudo cat /proc/net/nf_conntrack | grep src=192.168.2.10 ipv4 2 tcp 6 431993 ESTABLISHED src=192.168.7.2 dst=192.168.2.10 sport=44338 dport=32001 src=192.168.2.10 dst=192.168.2.2 sport=22 dport=44338 [ASSURED] mark=0 zone=0 use=2
Как показано, в дампе 5.15, на стороне kvm-host можно обнаружить, что указанное в дампе 5.14 правило, сработало согласно выводу команды sudo iptables -t nat -v -nL YP_PRRT и было установлено двунаправленное соединение между отправителем и получателем в результате изменения в заголовке udp-пакета номера порта с 32001 на 22 соответственно, как показано в дампе 5.15
Дамп 5.15
user@kvm-host:~$ sudo cat /proc/net/nf_conntrack | grep src=192.168.2. ipv4 2 tcp 6 431998 ESTABLISHED src=192.168.7.2 dst=192.168.2.10 sport=44336 dport=32001 src=192.168.2.10 dst=192.168.2.2 sport=22 dport=44336 [ASSURED] mark=0 zone=0 use=2 ipv4 2 udp 17 15 src=192.168.2.10 dst=192.168.2.2 sport=57230 dport=53 src=192.168.2.2 dst=192.168.2.10 sport=53 dport=57230 [ASSURED] mark=0 zone=0 use=2 ipv4 2 tcp 6 116 TIME_WAIT src=192.168.7.2 dst=192.168.2.10 sport=44334 dport=32001 src=192.168.2.10 dst=192.168.2.2 sport=22 dport=44334 [ASSURED] mark=0 zone=0 use=2
А вот случае с UDP соединением нужно будет попотеть и внести изменения в цепочку YA_PRRT(политики DNAT). Потому что если верить дампам обмена по всем сетевым устройствам, участвующих в нем и показанным на рисунке 5.16, просто сделанных и установленных ранее правил недостаточно.
Рисунок 2.5.16
Как показано на рисунке 5.16, препятствием для дальнейшей передачи, стало правило, устанавливаемое, как раз с помощью SNAT, определенное во 2-й позиции цепочки YP_PRT и показанное в листинге 5.17
Дамп 5.17
# Цепочка YP_PRT:
...
2:-A YP_PRT -s 192.168.7.2/32 -d 192.168.2.10/32 -o virbr1 -j SNAT --to-source 192.168.2.2
Поэтому, чтобы восстановить обмен в обратном направлении от получателя (ВМ "ОС Debain-10") к отправителю (ВМ "ОС Yocto/poky"), мне понадобилось все udp-пакеты в диапазоне 32768-65535 перенаправить на с ip: 192.168.2.10 первого на ip: 192.168.7.2 последнего, как показано в 7-й позиции YP_PRRT листинга 5.18
Поэтому, чтобы восстановить обмен в обратном направлении от получателя (ВМ "ОС Debain-10") к отправителю (ВМ "ОС Yocto/poky"), мне понадобилось все udp-пакеты в диапазоне 32768-65535 перенаправить на с ip:192.168.2.10 первого на ip:192.168.7.2 последнего, как показано в 7-й позиции YP_PRRT листинга 5.18
Дамп 5.18
# Цепочка YP_PRRT:
1:-A YP_PRRT ! -d 192.168.2.0/24 -i tap1 -j RETURN
2:-A YP_PRRT ! -d 192.168.2.0/24 -i tap2 -j RETURN
3:-A YP_PRRT -s 192.168.7.2/32 -d 192.168.2.10/32 -p udp -m udp ! --dport 32001:32767 -j RETURN
4:-A YP_PRRT -s 192.168.7.2/32 -d 192.168.2.10/32 -p tcp -m tcp ! --dport 32001:32767 -j RETURN
5:-A YP_PRRT -s 192.168.7.2/32 -d 192.168.2.10/32 -p tcp -m tcp --dport 32001 -j DNAT --to-destination 192.168.2.10:22
6:-A YP_PRRT -s 192.168.7.2/32 -d 192.168.2.10/32 -p udp -m udp --dport 32002 -j DNAT --to-destination 192.168.2.10:69
...
11: -A YP_PRRT -s 192.168.2.10/32 -p udp -m udp --dport 32768:65535 -j DNAT --to-destination 192.168.7.2:32768-65535
...
В результате был получен полноценный обмен для UDP-соединения, реализуемого TFTP протоколом, на узле центрального гипервизора, как показано в дампе 5.19
Дамп 5.19
user@kvm-host:~$ sudo tcpdump -n -i any host 192.168.2.2 or 192.168.2.10
...
18:27:46.765171 tap2 In IP 192.168.7.2.58776 > 192.168.2.10.32002: UDP, length 38
18:27:46.765242 virbr1 Out IP 192.168.2.2.58776 > 192.168.2.10.69: TFTP, length 38, RRQ "tftserv-768s-charcters.txt" netascii
18:27:46.765252 tap0 Out IP 192.168.2.2.58776 > 192.168.2.10.69: TFTP, length 38, RRQ "tftserv-768s-charcters.txt" netascii
18:27:46.766493 tap0 P IP 192.168.2.10.39319 > 192.168.2.2.58776: UDP, length 516
18:27:46.766493 virbr1 In IP 192.168.2.10.39319 > 192.168.2.2.58776: UDP, length 516
18:27:46.766557 tap1 Out IP 192.168.2.10.39319 > 192.168.7.2.58776: UDP, length 516
...
Как показано в дампе 5.19 (строчка выделена), в результате изменения IP-адреса назначения на 192.168.7.2 в передаваемом UDP-пакете приведет к регистрации двух UDP-соединений, как показано в дампе 5.20
Дамп 5.20
user@kvm-host:~$ sudo cat /proc/net/nf_conntrack | grep src=192.168.2 ipv4 2 udp 17 25 src=192.168.2.10 dst=192.168.2.2 sport=39319 dport=58776 src=192.168.7.2 dst=192.168.2.10 sport=58776 dport=39319 [ASSURED] mark=0 zone=0 use=2 ipv4 2 udp 17 25 src=192.168.7.2 dst=192.168.2.10 sport=58776 dport=32002 [UNREPLIED] src=192.168.2.10 dst=192.168.2.2 sport=69 dport=58776 mark=0 zone=0 use=2
В списке соединений будет два соединения. Первое – однонаправленное в строну отправителя с флагом ([ASSURED]), а второе – двунаправленное с флагом [UNREPLIED], т.к. после переданного первого UDP-пакета с данными в обои стороны будут повторно передаваться UDP-пакеты согласно протоколу TFTP до тех пор пока не будет передано содержимое всего файла.
$ ∞ $
3. Библиография
3.1 Словарь Академик. Встроенная операционная система
3.2 explainshell.com. Network exploration tool and security / port scanner
3.3 SECLIST.ORG. nmap parallelization
3.5 Linux Packet Filtering and iptables. Chapter 11. Iptables targets and jumps
3.6 Linuxhint.Iptables Tutorial
3.9 Libvirt:Network XML format
3.10 Part V. iptables firewall. Chapter 8. iptables firewall
3.11 Red Hat Customer Portal. 2.8. FIREWALLS
3.12 [libvirt] [PATCH RFC] network: Delay creating private chains until starting network
3.13 CentOS community. Iptables FORWARD ACCEPT, is this not secure?
3.14 iptables: Small manual and tutorial with some examples and tips. Written by Guillermo Garron
3.15 Superuser. Linux Netfilter: How does connection tracking track connections changed by NAT?
3.16 Conntrack-tool. Support page
3.17 Connection tracking (conntrack) - Part 1: Modules and Hooks
3.18 https://netfilter.org/projects/nftables/
3.19 Connection tracking (conntrack) - Part 3: State and Examples
3.20 netfilter hacking HOWTO. 3. Netfilter Architecture
3.21 wiki.nftables.org. Netfilter hooks
3.22 Stackoverflow. Details of /proc/net/ip_conntrack and /proc/net/nf_conntrack
3.24 [PATCH 1/6] netfilter: nf_conntrack: add IPS_HW_OFFLOAD status bit
3.25 Hash Suite: Windows password security audit tool. GUI, reports in PDF.
3.26 LWN.net. netfilter flowtable hardware offload
3.27 [PATCH RFC,WIP 3/5] netfilter: nf_flow_offload: integration with conntrack
3.28 Netfilter’s flowtable infrastructure
3.29 [PATCH 1/6] netfilter: nf_conntrack: add IPS_HW_OFFLOAD status bit
3.30 WikDetails of /proc/net/ip_conntrack and /proc/net/nf_conntracki.nftables.org. Flowtables