Доброго времени суток.
Столкнулся с задачей по пробросу портов в виртуальную машину на QEMU. Проблема заключалась в том, что на машинах-пациентах установленных одинаково уже был сделан скрипт-хук на libvirt для проброса портов, который валялся в /etc/libvirt/config/hooks или как-то так. Это не особо важно, так как этот хук не отработал при миграции и первоначальной раскатке тачки. В любом случае, пришлось писать его подобие из всего двух команд.
Итак, чтобы пробросить порт в виртуалку на QEMU, сетевой интерфейс которой представляет собой NAT, необходимо всего две команды в iptables. Если после этого ничего не будет работать — значит, помимо iptables есть еще файрволлы. Рекомендую посмотреть есть ли ufw. На AL он, как оказалось, есть.
Содержание
Команды
iptables -t nat -A PREROUTING --dst 10.10.10.10 -p tcp --dport 445 -j DNAT --to-destination 192.168.122.10
- Подставляем вместо 10.10.10.10 IP хостовой машины на Астре;
- Вместо 445 можете указать свой нужный TCP порт;
- Вместо 192.168.122.20 ставим IP виртуальной машины под NAT.
iptables -I FORWARD 1 -i eth0 -o virbr0 -d 192.168.122.10 -p tcp -m tcp --dport 445 -j ACCEPT
- Вместо eth0 подставьте интерфейс хостовой машины;
- Вместо virbr0 интерфейс от QEMU, обычно он так и называется;
- Вместо 192.168.122.10 — IP виртуальной машины под NAT;
- Вместо 445 — нужный вам порт для проброса.
Простой скрипт
Далее, по наитию, пишем простенький скрипт, чтобы вручную это все не вводить:
astraIP=10.10.10.10 winIP=192.168.122.10 for vport in 139 445 3389 do iptables -t nat -A PREROUTING --dst $astraIP -p tcp --dport $vport -j DNAT --to-destination $winIP iptables -I FORWARD 1 -i eth0 -o virbr0 -d $winIP -p tcp -m tcp --dport $vport -j ACCEPT done iptables-save
Тут просто в переменные пишем нужные IP адреса. В цикле через пробел — порты.
Чтобы запустить это чудо на Astra Linux нужны root права, так как из-под юзеров система не даст использовать iptables.
Сначала выдаете права на запуск:
chmod +x <путь или имя скрипта>
Потом просто выполняете скрипт, как обычно вы это делаете:
./script.sh
Автоматический скрипт
Нововведения:
- Cкрипт сам забирает IP адрес Астры;
- Скрипт сам забирает IP адрес виртуальной Windows 10;
- Скрипт умеет проверять, есть ли уже подобные правила, но только те, которые пишет он в этой версии. Если правила есть, он сотрет старые и напишет новые;
- Скрипт говорит о проблемах или об успехе операций;
- Переписал и упростил правила для iptables, проверил, все работает.
# Script for configure port forwarding between host ALSE and Win10 vm # Ports: 135, 139, 443, 445, 389 # version 3 # # © Kireev D.Y., Cybersec, Greenatom, 2023 # забираем ip адрес eth0 astraIP=$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1) # забираем ip адрес winvm winIP=$(virsh net-dhcp-leases default | grep 192.168.122 | awk '{print $5}' | cut -d/ -f1) # CHECKING THAT IP WAS TAKEN if [[ $astraIP == *"10."* ]]; then echo " > GA > Successfully taken IP ($astraIP) of Host Machine"; qResHO="1"; fi if [[ $winIP == *"192.168."* ]]; then echo " > GA > Successfully taken IP ($winIP) of Virtual Machine"; qResVM="1"; fi # APPLYING RULES IF ALL IS GOOD if [[ $qResHO == 1 ]] && [[ $qResHO == $qResVM ]]; then echo " > GA > Ready to configure port forwarding rules."; echo " > GA > Trying to apply rules:"; echo " " for vport in 135 139 443 445 389 do # CHECKING PREROUTING RULES iptables -t nat -C PREROUTING -i eth0 -p tcp --dport $vport -j DNAT --to-destination $winIP &> /dev/null if [[ $? == 1 ]]; then # echo "1"; echo " - PREROUTING rule for port $vport is not exists, applying..." iptables -t nat -A PREROUTING -i eth0 -p tcp --dport $vport -j DNAT --to-destination $winIP echo " - PREROUTING rules for $vport is applied." else # echo "0"; echo " - PREROUTING rule for port $vport is already exists, rewriting..." iptables -t nat -D PREROUTING -i eth0 -p tcp --dport $vport -j DNAT --to-destination $winIP iptables -t nat -A PREROUTING -i eth0 -p tcp --dport $vport -j DNAT --to-destination $winIP echo " - PREROUTING rules for $vport is applied." fi #CHECKING FORWARD RULES iptables -C FORWARD -i eth0 -o virbr0 -p tcp -m tcp --dport $vport -j ACCEPT &> /dev/null if [[ $? == 1 ]]; then # echo "1"; echo " - FORWARD rule for port $vport is not exists, applying..." iptables -I FORWARD 1 -i eth0 -o virbr0 -p tcp -m tcp --dport $vport -j ACCEPT echo " - FORWARD rules for $vport is applied." else # echo "0"; echo " - FORWARD rule for port $vport is already exists, rewriting..." iptables -D FORWARD -i eth0 -o virbr0 -p tcp -m tcp --dport $vport -j ACCEPT iptables -I FORWARD 1 -i eth0 -o virbr0 -p tcp -m tcp --dport $vport -j ACCEPT echo " - FORWARD rules for $vport is applied." fi # iptables -t nat -A PREROUTING -i eth0 -p tcp --dport $vport -j DNAT --to-destination $winIP # iptables -I FORWARD 1 -i eth0 -o virbr0 -p tcp -m tcp --dport $vport -j ACCEPT echo " - iptables rule for" $vport "is applied." done iptables-save > /dev/null echo " " echo " " echo " > GA > iptables saved." echo " > GA > Port forwarding is successfully done." echo " " echo " > GA > Please, check the connection via Powershell ex: (TNC $astraIP -Port 445) or (telnet $astraIP 445)" else echo " > GA > ERROR! Bad results of compairing results" fi
Вот и все. Вам это может помочь, мне эта статья как напоминалка.
Такие дела.