Доброго времени суток.
Столкнулся с задачей по пробросу портов в виртуальную машину на 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
Вот и все. Вам это может помочь, мне эта статья как напоминалка.
Такие дела.