LINUX.ORG.RU
ФорумAdmin

Как грамотно пробросить порты KVM ?

 , , , ,


1

1

Всем Привет! В общем (не спрашивайте меня, к чему такое извращение) существует виртуалка Windows Server 2012R2 на CentOS6 , на удаленном сервере на одном выделенном хостером IP адресе, например 111.111.111.111 - на eth0.

Виртуалка virbr0 на 192.168.122.1-192.168.122.254. DHCP в ней включен. Айпи WindowsServer 192.168.122.253

Задача:

  • 1. На WindowsServer будет веб-сервер, который в итоге должен работать на 111.111.111.111:80.
  • 2. Пробросить порт для RDP (3389) подключения к Windows Server, чтобы извне подключаться к этому серверу, чтобы развернуть IIS веб-сервер.
  • 3. Пробросить порт для FTP (21) для удаленного подключения веб-девелопера.

инструменты имеются в виде: virt-manager, virsh. Оснащение: qemu-kvm. libvirt

Я набросал решение, скажите как вы видите?

  • 1)

    sudo iptables -t nat -A PREROUTING --dst 111.111.111.111 -p tcp --dport 80 -j DNAT --to-destination 192.168.122.253

    sudo iptables -I FORWARD 1 -i eth0 -o virbr0 -d 192.168.122.253 -p tcp -m tcp --dport 80 -j ACCEPT

  • 2)

    sudo iptables -t nat -A PREROUTING --dst 111.111.111.111 -p tcp --dport 3389 -j DNAT --to-destination 192.168.122.253

    sudo iptables -I FORWARD 1 -i eth0 -o virbr0 -d 192.168.122.253 -p tcp -m tcp --dport 3389 -j ACCEPT

  • 3) для FTP наружний порт сделать какой-нибудь другой (не 21), например 8888

    sudo iptables -t nat -A PREROUTING --dst 111.111.111.111 -p tcp --dport 8888 -j DNAT --to-destination 192.168.122.253

    sudo iptables -I FORWARD 1 -i eth0 -o virbr0 -d 192.168.122.253 -p tcp -m tcp --dport 21 -j ACCEPT

----------------------------------

Настройки iptables

iptables -L -v -n

Chain INPUT (policy ACCEPT 2755K packets, 7196M bytes)
pkts bytes target prot opt in out source destination
89 5755 ACCEPT udp — virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53
0 0 ACCEPT tcp — virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
44 17153 ACCEPT udp — virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67
0 0 ACCEPT tcp — virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
7234 23M ACCEPT all — * virbr0 0.0.0.0/0 192.168.122.0/24 state RELATED,ESTABLISHED
17343 1278K ACCEPT all — virbr0 * 192.168.122.0/24 0.0.0.0/0
0 0 ACCEPT all — virbr0 virbr0 0.0.0.0/0 0.0.0.0/0
0 0 REJECT all — * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 REJECT all — virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT 3136K packets, 3131M bytes)
pkts bytes target prot opt in out source destination

------------------------------

ifconfig

eth0 Link encap:Ethernet HWaddr 40:61:86:2B:91:3C
inet addr:111.111.111.111 Bcast:111.111.111.111 Mask:255.255.255.255
inet6 addr: ipv6.ipv6.ipv6.ipv6.ipv6.ipv6.ipv6/64 Scope:Link
inet6 addr: ipv6.ipv6.ipv6.ipv6.ipv6.ipv6.ipv6/64 Scope:Global
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:4539908 errors:0 dropped:0 overruns:0 frame:0
TX packets:2455250 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:5821314417 (5.4 GiB) TX bytes:1548994732 (1.4 GiB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:711472 errors:0 dropped:0 overruns:0 frame:0
TX packets:711472 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1618981503 (1.5 GiB) TX bytes:1618981503 (1.5 GiB)

virbr0 Link encap:Ethernet HWaddr 52:54:00:01:83:D2
inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:18822 errors:0 dropped:0 overruns:0 frame:0
TX packets:18251 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1523806 (1.4 MiB) TX bytes:23809308 (22.7 MiB)

vnet0 Link encap:Ethernet HWaddr FE:FE: FE:FE FE:FE
inet6 addr: fe80::fe80fe80fe80/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:18736 errors:0 dropped:0 overruns:0 frame:0
TX packets:28853 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:1758844 (1.6 MiB) TX bytes:24337728 (23.2 MiB)



Последнее исправление: Ozymandis (всего исправлений: 5)

каша ужасная. Никто такое смотеть не будет, приведи в порядок. Используй LORCODE

targitaj ★★★★★
()

sysctl config

### Hetzner Online GmbH installimage
# sysctl config
#net.ipv4.ip_forward=1
net.ipv4.conf.all.rp_filter=1
net.ipv4.icmp_echo_ignore_broadcasts=1
# ipv6 settings (no autoconfiguration)
net.ipv6.conf.default.autoconf=0
net.ipv6.conf.default.accept_dad=0
net.ipv6.conf.default.accept_ra=0
net.ipv6.conf.default.accept_ra_defrtr=0
net.ipv6.conf.default.accept_ra_rtr_pref=0
net.ipv6.conf.default.accept_ra_pinfo=0
net.ipv6.conf.default.accept_source_route=0
net.ipv6.conf.default.accept_redirects=0
net.ipv6.conf.default.forwarding=0
net.ipv6.conf.all.autoconf=0
net.ipv6.conf.all.accept_dad=0
net.ipv6.conf.all.accept_ra=0
net.ipv6.conf.all.accept_ra_defrtr=0
net.ipv6.conf.all.accept_ra_rtr_pref=0
net.ipv6.conf.all.accept_ra_pinfo=0
net.ipv6.conf.all.accept_source_route=0
net.ipv6.conf.all.accept_redirects=0
net.ipv6.conf.all.forwarding=0

Ozymandis
() автор топика

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

Nurmukh ★★★
()
Ответ на: комментарий от Nurmukh

Спасибо, я тоже так сначала подумал. Как же быть с RDP ?

Я так понял мне в любом случае придется писать скрипт ?

Ozymandis
() автор топика
Ответ на: комментарий от Ozymandis

Ребята, вы обкурились? Причем здесь «nginx»? Nurmukh убей себя (как говорилось в далекие годы) «аб стену».
ТС Если при твоем форматировании я ничего не пропустил, то вроде все правильно. Но если хочешь адекватной оценки от большинства, присоединюсь к targitaj «каша ужасная. Никто такое смотеть не будет, приведи в порядок. Используй LORCODE».

anc ★★★★★
()
Ответ на: комментарий от Ozymandis

Поставь себе на centos openvpn. ии все твои проблемы уйдут.

Nurmukh ★★★
()
Ответ на: комментарий от dyasny

Скрипт для hooks нерабочий, кстати. Я для себя накатал такой:

#!/bin/bash

hostif="eth0"
hostip=$(/sbin/ifconfig "$hostif" | /usr/bin/awk -F: '/inet addr/ {split($2, a, " "); print a[1]}')

# Format: guestname,sourceip,hostpt,guestip,guestpt per string
# leave sourceip field empty for connect from anywhere
datafile="/etc/libvirt/hooks/server_port_map"
iptables='/sbin/iptables'

while IFS=, read -r guestname sourceip hostpt guestip guestpt ; do
if [ -z $sourceip ] ; then
 sourceip="0.0.0.0/0"
fi
if [ $1 = $guestname ] ; then
 if [[ $2 == @(stopped|reconnect) ]] ; then
  $iptables -t nat -D PREROUTING -i $hostif -s $sourceip -d $hostip -p tcp --dport $hostpt -j DNAT --to-destination ${guestip}:${guestpt}
  $iptables -D FORWARD -i $hostif -s $sourceip -m state --state NEW -m tcp -p tcp -d $guestip --dport $guestpt -j ACCEPT
 fi
 if [[ $2 == @(start|reconnect) ]] ; then
  $iptables -t nat -I PREROUTING -i $hostif -s $sourceip -d $hostip -p tcp --dport $hostpt -j DNAT --to-destination ${guestip}:${guestpt}
  $iptables -I FORWARD -i $hostif -s $sourceip -m state --state NEW -m tcp -p tcp -d $guestip --dport $guestpt -j ACCEPT
 fi
fi
done < $datafile
Ну и /etc/libvirt/hooks/server_port_map, соответственно:
vm_name,$remote_ip1,3389,192.168.122.2,3389
vm_name,$remote_ip2,3389,192.168.122.2,3389

Deleted
()
Ответ на: комментарий от Deleted

использую его на 4 тестовых стендах, все пашет на ура. Но альтернатива это всегда хорошо, еще лучше если бы скрипт с инструкцией лежал на гитхабе с набором ключевых слов для тех кто что-то подобное ищет

dyasny ★★★★★
()
Ответ на: комментарий от Deleted

тот самый случай когда на ЛОРе не хватает кнопки «лайк»

dyasny ★★★★★
()
30 мая 2016 г.
Ответ на: комментарий от Deleted

Спасибо, возник вопрос, как пробросить пачку портов 6601-6615? И обязательно ли писать «$remote_ip1», я так понял это переменная, в скрипте qemu не видел ее обозначение

Ozymandis
() автор топика
Ответ на: комментарий от Ozymandis

Спасибо, возник вопрос, как пробросить пачку портов 6601-6615?

14 строк в файле server_port_map

И обязательно ли писать «$remote_ip1»

Не обязательно, если будет пустое поле, то откроется для всех (0.0.0.0)

Deleted
()
Ответ на: комментарий от Deleted

Спасибо!

Последний вопрос (скорее уточнение)

Я уже создал такой скрипт (для RDP, внешние сделал 8889 и 8888, для конспирации))) Будет ли «конфликт» скриптов?

Вот скрипт (файл /etc/libvirt/hooks/qemu_RDP):

#!/bin/bash
# used some from advanced script to have multiple ports: use an equal number of guest and host ports

# Update the following variables to fit your setup
Guest_name=wsvm
Guest_ipaddr=192.168.122.253
Host_ipaddr=внешний IP
Host_port=(  '8888' '8889' )
Guest_port=( '3389' '3389' )

length=$(( ${#Host_port[@]} - 1 ))
if [ "${1}" = "${Guest_name}" ]; then
   if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
       for i in `seq 0 $length`; do
               iptables -t nat -D PREROUTING -d ${Host_ipaddr} -p tcp --dport ${Host_port[$i]} -j DNAT --to ${Guest_ipaddr}:${Guest_port[$i]}
               iptables -D FORWARD -d ${Guest_ipaddr}/32 -p tcp -m state --state NEW -m tcp --dport ${Guest_port[$i]} -j ACCEPT
       done
   fi
   if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
       for i in `seq 0 $length`; do
               iptables -t nat -A PREROUTING -d ${Host_ipaddr} -p tcp --dport ${Host_port[$i]} -j DNAT --to ${Guest_ipaddr}:${Guest_port[$i]}
               iptables -I FORWARD -d ${Guest_ipaddr}/32 -p tcp -m state --state NEW -m tcp --dport ${Guest_port[$i]} -j ACCEPT
       done
   fi
fi

- Потом сделал так:

chmod +x /etc/libvirt/hooks/qemu_RDP
- И сделал рестар libvirtd

-----------------

Надеюсь доходчиво выразился)

Ozymandis
() автор топика
Ответ на: комментарий от Deleted

Спасибо, самый последний вопрос) возможно ли в одном скрипте задать правила для tcp и udp сразу, т.е для tcp: 6601-6615, и для udp: 6601-6615

Ozymandis
() автор топика
Ответ на: комментарий от Ozymandis

UDP я не пробрасывал. Видоизмени файл qemu, добавив туда правило -m udp, будет одновременно tcp/udp прокидываться.

Deleted
()
Ответ на: комментарий от Deleted

Спасибо, я так понял, в таком виде?


#!/bin/bash

hostif="eth0"
hostip=$(/sbin/ifconfig "$hostif" | /usr/bin/awk -F: '/inet addr/ {split($2, a, " "); print a[1]}')

# Format: guestname,sourceip,hostpt,guestip,guestpt per string
# leave sourceip field empty for connect from anywhere
datafile="/etc/libvirt/hooks/server_port_map"
iptables='/sbin/iptables'

while IFS=, read -r guestname sourceip hostpt guestip guestpt ; do
if [ -z $sourceip ] ; then
 sourceip="0.0.0.0/0"
fi
if [ $1 = $guestname ] ; then
 if [[ $2 == @(stopped|reconnect) ]] ; then
  $iptables -t nat -D PREROUTING -i $hostif -s $sourceip -d $hostip -p tcp --dport $hostpt -j DNAT --to-destination ${guestip}:${guestpt}
  $iptables -D FORWARD -i $hostif -s $sourceip -m state --state NEW -m tcp -p tcp -d $guestip --dport $guestpt -j ACCEPT
  $iptables -t nat -D PREROUTING -i $hostif -s $sourceip -d $hostip -p udp --dport $hostpt -j DNAT --to-destination ${guestip}:${guestpt}
  $iptables -D FORWARD -i $hostif -s $sourceip -m state --state NEW -m udp -p udp -d $guestip --dport $guestpt -j ACCEPT
 fi
 if [[ $2 == @(start|reconnect) ]] ; then
  $iptables -t nat -I PREROUTING -i $hostif -s $sourceip -d $hostip -p tcp --dport $hostpt -j DNAT --to-destination ${guestip}:${guestpt}
  $iptables -I FORWARD -i $hostif -s $sourceip -m state --state NEW -m tcp -p tcp -d $guestip --dport $guestpt -j ACCEPT
  $iptables -t nat -I PREROUTING -i $hostif -s $sourceip -d $hostip -p udp --dport $hostpt -j DNAT --to-destination ${guestip}:${guestpt}
  $iptables -I FORWARD -i $hostif -s $sourceip -m state --state NEW -m udp -p udp -d $guestip --dport $guestpt -j ACCEPT
 fi
fi
done < $datafile

Ozymandis
() автор топика
Ответ на: комментарий от Ozymandis

С телефона не очень наглядно видно, но вроде да, всё правильно.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Ozymandis

Да, libvirt restart можно не делать, можно сделать только ./qemu virtname reconnect.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Ozymandis

-m multiport и на выбор --dports/--sports/--ports 6601:6615
если порты не подряд идущие перечислять через запятую

anc ★★★★★
()
Ответ на: комментарий от anc

Спасибо, в таком виде?

#!/bin/bash
# used some from advanced script to have multiple ports: use an equal number of guest and host ports

# Update the following variables to fit your setup
Guest_name=wsvm
Guest_ipaddr=192.168.122.253
Host_ipaddr=внешний IP
Host_port=(  '8888' '8889' )
Guest_port=( '3389' '3389' )

length=$(( ${#Host_port[@]} - 1 ))
if [ "${1}" = "${Guest_name}" ]; then
   if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
       for i in `seq 0 $length`; do
               iptables -t nat -D PREROUTING -d ${Host_ipaddr} -p multiport --dports ${Host_port[$i]} -j DNAT --to ${Guest_ipaddr}:${Guest_port[$i]}
               iptables -D FORWARD -d ${Guest_ipaddr}/32 -p multiport -m state --state NEW -m multiport --dports ${Guest_port[$i]} -j ACCEPT
       done
   fi
   if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
       for i in `seq 0 $length`; do
               iptables -t nat -A PREROUTING -d ${Host_ipaddr} -p multiport --dports ${Host_port[$i]} -j DNAT --to ${Guest_ipaddr}:${Guest_port[$i]}
               iptables -I FORWARD -d ${Guest_ipaddr}/32 -p multiport -m state --state NEW -m multiport --dports ${Guest_port[$i]} -j ACCEPT
       done
   fi
fi

Ozymandis
() автор топика
Ответ на: комментарий от Ozymandis

1. Да нет, просто одной строкой можно делать типа
-A FORWARD -i eth0 -p tcp -d 192.168.0.5 -m multiport --dports 6000:10000,35234
т.е. не несколько строк где по одному порту отдельно прописывается.
2. а тут вы чего-то не доброе вообще написали -p multiport

anc ★★★★★
()
Ответ на: комментарий от Ozymandis

Это уж вам решать. Я только ответил на ваш вопрос «как пробросить пачку портов 6601-6615? » что это возможно и привел пример как.

anc ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.