Доброго времени суток.

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

Автоматический скрипт

Нововведения:

  1. Cкрипт сам забирает IP адрес Астры;
  2. Скрипт сам забирает IP адрес виртуальной Windows 10;
  3. Скрипт умеет проверять, есть ли уже подобные правила, но только те, которые пишет он в этой версии. Если правила есть, он сотрет старые и напишет новые;
  4. Скрипт говорит о проблемах или об успехе операций;
  5. Переписал и упростил правила для 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

Вот и все. Вам это может помочь, мне эта статья как напоминалка.

Такие дела.

You May Also Like