командная строка KVM nat

командная строка KVM nat

Как правильно настроить сетевое соединение NAT между виртуальной машиной KVM и хостом?

KVM-виртуальная машина:

Брандмауэр не установлен

$ sudo arp-scan -r 5 -t 1000 --interface=eth0 --localnet

10.0.2.2     52:55:0a:00:02:02    locally administered
10.0.2.3     52:55:0a:00:02:03    locally administered

$ ip r

default via 10.0.2.2 dev eth0 proto dhcp metric 100
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 metric 100

ifconfig

eth0: inet 10.0.2.15 netmask 255.255.255.0 broacast 10.0.2.255
      ether 52:54:00:12:34:56
lo: inet 127.0.0.1 netmask 255.0.0.0
      inet6 ::1

Хозяин:

:~$ ip r

0.0.0.0/1 via 10.211.1.10 dev tun0 
default via 192.168.1.1 dev wlan0 proto dhcp metric 600 
10.21xxxxxxxx dev tun0 proto kernel scope link src 10.21xxxxx 
xxxxxxxxxxxx dev wlan0 
128.0.0.0/1 via 10.211.1.10 dev tun0 
192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.172 metric 600 
192.168.4.0/22 dev eth0 proto kernel scope link src 192.168.4.8 metric 100 

:~$ ifconfig

 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    inet 10.0.2.3  netmask 255.0.0.0  broadcast 10.255.255.255
    inet6 fe80::76c8:79b4:88d4:7f5c  prefixlen 64  scopeid 0x20<link>
    ether ec:8e:b5:71:33:6e  txqueuelen 1000  (Ethernet)
    RX packets 1700  bytes 194730 (190.1 KiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 2862  bytes 246108 (240.3 KiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    device interrupt 16  memory 0xe1000000-e1020000  

 lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
    inet 127.0.0.1  netmask 255.0.0.0
    inet6 ::1  prefixlen 128  scopeid 0x10<host>
    loop  txqueuelen 1000  (Local Loopback)
    RX packets 13251  bytes 7933624 (7.5 MiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 13251  bytes 7933624 (7.5 MiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
    inet 10.211.1.69  netmask 255.255.255.255  destination 10.211.1.70
    inet6 fe80::a920:941c:ffa8:5579  prefixlen 64  scopeid 0x20<link>
    unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 100  (UNSPEC)
    RX packets 4348  bytes 2242726 (2.1 MiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 3823  bytes 404190 (394.7 KiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    inet 192.168.1.172  netmask 255.255.255.0  broadcast 192.168.1.255
    inet6 fe80::651b:5014:7929:9ba3  prefixlen 64  scopeid 0x20<link>
    ether d8:55:a3:d5:d1:30  txqueuelen 1000  (Ethernet)
    RX packets 114455  bytes 117950099 (112.4 MiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 67169  bytes 14855011 (14.1 MiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0 

~$ sudo arp-scan -r 5 -t 1000 --localnet

just hangs......

Хост не может пинговать 10.0.2.2

Не включен брандмауэр

Пытался

$ sudo ip route add default via 10.0.2.0
$ sudo ip route add default via 10.0.2.2
$ sudo ip route add default via 10.0.2.0/24

Может ли NAT работать без virsh?

Можно ли исправить NAT только из командной строки?

Обновлять:

$ sudo ip link add natbr0 type bridge
$ sudo ip link set dev natbr0 up
$ sudo ip link set dev eth0 up
$ sudo ip link set dev eth0 master natbr0

который работает для моста eth0 slave к kvm - vm может пинговать другие компьютеры в сети. но не хост @Tom Yan ответ в сочетании сarchlinux-сетевой_мостСозданные выше команды, которые могут пинговать другие сетевые IP-адреса

Поэтому я попытался изменить рабочее мостовое соединение, чтобы позволить хосту и KVM общаться.

Goal: host$ ping kvm

$ sudo ip link add natbr0 type bridge
$ sudo ip link set dev natbr0 up
$ sudo ip a add 10.0.2.1/24 dev natbr0
$ sudo kvm -m 3G -hdb /dev/sde  -nic bridge,br=natbr0
kvm$ sudo ip link add natbr0 type bridge
kvm$ sudo ip a add 10.0.2.2
kvm$ sudo ip link set dev natbr0 up
kvm can ping it self 

$ пинг 10.0.2.2

PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data
64 bytes from 10.0.2.2: icmp_seq=1 ttl=64 time=0.027 ms

но kvm$ping 10.0.2.1

Destination Host Unreachable

хост$ пинг 10.0.2.2

(just hangs)

Предпочитаю командную строку для проверки устойчивости скелета процесса/системы по сравнению с множеством скриптов, которые могут представлять большую уязвимость к сбоям. - командная строка работает или нет, а ошибки легче отследить, изолировать и воспроизводить. В зависимости от разновидности Linux, определенные скрипты/части скриптов (например, те, которые включены в предлагаемые альтернативные решения XML) могут работать или не работать. Если мост с kvm можно воспроизвести на любой разновидности Linux, выполнив команды выше... то кажется возможным, что kvm NAT также можно достичь с помощью команд cli - просто чтобы прояснить суть этого поста, шаги cli для NAT kvm будут более стандартизированы, поэтому предпочтительнее.

в целом ответ @NikitaKipriyanov был правильным, это был ответ, но требовал корректировки для управления

$ sudo kvm -m 3G -hdb /dev/sde -net nic -net пользователь,hostfwd=tcp::1810-:22

с помощью команды tweak vm может взаимодействовать с интернетом как по умолчанию, а также взаимодействовать с хостом через ssh. спасибо @NikitaKipriyanov и @cnst за настройкуhttps://stackoverflow.com/a/54120040

Пользователю необходимо будет подключиться по ssh, используя порт 1810, используя адрес localhost.

$ ssh p@localhost -p 1810

решение1

Общая идея NAT заключается в том, что выне вижупереведенные адреса. У вас нет маршрутов к ним. Они не существуют для вас. Вы видите только адреса, в которые они переведены.

Случай QEMU ничем не отличается. В этом случае ваш хост находится «снаружи», ваша виртуальная машина — «внутри», поэтому виртуальная машина никогда не может быть доступна по адресу, которому она назначена. У вас есть адрес виртуальной машины 10.0.2.2/24, но когда она попадает в Интернет, ее пакеты преобразуются в 192.168.1.172по процессу QEMU, поэтому хост считает эти пакеты созданными процессом QEMU и обрабатывает их как любые другие пакеты, скажем, от локально запущенного веб-браузера или чего-то подобного.

Как получить доступ к виртуальной машине с хоста? Когда у нас есть NAT, чтобы добраться до хостов, скрытых за ним, мы устанавливаемДНКАТправила. И снова, случай QEMU ничем не отличается, вы должны установить некоторые правила в нем, и затем вы можете общаться с виртуальной машиной с хоста (или с других хостов, если хотите), отправляя пакеты на выбранные портыхозяинадрес.

СогласноДокументация QEMU, чтобы настроить правила DNAT в его пользовательском NAT, вы используете hostfwdпредложение. Давайте введем следующее в его командную строку:

    -netdev user,id=usernet0,hostfwd=tcp::11111-:22 \
    -device virtio-net-pci,netdev=usernet0,mac=08:00:27:92:B0:51

Затем порт TCP 11111 будет занят процессом qemu-system-x86_64на моей машине, и если вы подключитесь клокальный хостпорт 11111, подключение будет выполнено к порту 22 виртуальной машины.

Общая форма — hostfwd=hostip:hostport-guestip:guestport, но если вы опустите hostip, это будет localhost, а если вы опустите guestip, это будет первый «не шлюзовой» адрес внутри гостевой сети.

Я заметил, что вас упомянули virsh. Вы бежите libvirt? Тогда вопрос дублируется; см. комментарии.

решение2

Вы можете использовать мост, не привязывая к нему ни один из физических интерфейсов Ethernet на хосте виртуальной машины.

Допустим, мы придерживаемся выбора подсети 10.0.2.0/24(что НЕ обязательно):

# ip l add natbr0 type bridge
# ip a add 10.0.2.1/24 dev natbr0

Затем создайте следующий файл:

$ echo 'allow natbr0' | sudo tee /etc/qemu/bridge.conf 
allow natbr0

Затем запустите qemu с помощью eg -nic bridge,br=natbr0или -netdev bridge,br=natbr0,id=nb0 -device virtio-net,netdev=nb0, что позволит tapвашей виртуальной машине динамически подключиться к мосту (т. е. tapинтерфейс будет удален после выключения виртуальной машины).

Вам также потребуется настроить статический IP-адрес на виртуальной машине:

# ip a add 10.0.2.2/24 dev ens3
# ip r add default via 10.0.2.1

Если только вы также не настроили DHCP-сервер (например, dnsmasq) на хосте. Не забудьте также настроить DNS-сервер для использования внутри виртуальной машины.

Обратите внимание, что виртуальные машины, использующие один и тот же мост, могут взаимодействовать друг с другом, если вы не заблокируете такое взаимодействие какими-либо средствами (например, ebtables).

Маршрут default(и DNS-сервер для использования) необходимы только в том случае, если вы хотите, чтобы виртуальная машина могла достичь «внешнего мира». Если вам нужно только, чтобы иметь возможность общаться с хостом виртуальной машины, вам следует пропустить вторую команду и прекратить чтение. (Ну, прочтите P.S.)


Вероятно, лучше всего будет настроить, например, dnsmasq на хосте в качестве DNS-пересылки, если вы не хотите использовать определенный «публичный» DNS-сервер в виртуальной машине, хотя использование DNAT для пересылки DNS-запросов, например, 192.168.1.1должно работать для базовых серверов.

Затем вам необходимо включить IP-пересылку:

# sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1

Если вы хотите избежать переадресации IP-адресов с/на определенный сетевой интерфейс (например tun0) в целях безопасности вам необходимо настроить брандмауэр.Например:

# iptables -A FORWARD -i tun0 -j DROP
# iptables -A FORWARD -o tun0 -j DROP

Поскольку у вас есть маршруты туннеля (VPN), которые фактически переопределяют маршрут default, трафик от VM в Интернет также будет поступать в туннель (если вы не добавили примеры правил выше). Если вы хотите, чтобы трафик шел, например, через ваш маршрутизатор, вам понадобится политика маршрутизации. Например:

# ip ru add iif natbr0 lookup table 123
# ip r add 192.168.1.1 dev wlan0 table 123 # probably optional
# ip r add default via 192.168.1.1 table 123

Вы также можете запретить вашим виртуальным машинам подключаться к хостам локальной сети:

# iptables -A FORWARD -i natbr0 -d 192.168.1.0/24 -j DROP

Сделайте исключения (обратите внимание на -I), если вы собираетесь перенаправлять DNS-запросы на свой маршрутизатор:

# iptables -I FORWARD -i natbr0 -d 192.168.1.1 -p tcp --dport 53 -j ACCEPT
# iptables -I FORWARD -i natbr0 -d 192.168.1.1 -p udp --dport 53 -j ACCEPT

Наконец, настройте iptables для динамического выполнения SNAT (в соответствии с исходящим интерфейсом) для вашей подсети виртуальных машин:

# iptables -t nat -A POSTROUTING -s 10.0.2.0/24 -j MASQUERADE

Обратите внимание, что это НЕ предназначено и не будет точно предотвращать определенные трафики из "вне" (ваши физические хосты LAN или Интернет; хост VM не считается) от возможности достичь ваших VM. Это просто прерывает связь как побочный эффект, когда исходный адрес ответного трафика от VM изменяется до их перенаправления. Для надлежащей изоляции вам понадобятся (дополнительные) соответствующие правила в цепочке FORWARD. Рассмотрите возможность установки "stateful" там, если у вас есть такая необходимость.

Кроме того, вы можете перенаправлять DNS-запросы к хосту с виртуальных машин на ваш маршрутизатор:

iptables -t nat -A PREROUTING -d 10.0.2.1 -p udp --dport 53 -j DNAT --to-destination 192.168.1.1
iptables -t nat -A PREROUTING -d 10.0.2.1 -p tcp --dport 53 -j DNAT --to-destination 192.168.1.1

Что более или менее позволит вам использовать его 10.0.2.1в качестве DNS-сервера в виртуальной машине.


P.S. Все манипуляции выше (кроме создания / write to /etc/qemu/bridge.conf) являются изменчивыми, т.е. они исчезнут после перезагрузки (если только ваш дистрибутив не сделает что-то глупое). Я не собираюсь углубляться в то, как вы можете сделать их постоянными, поскольку есть разные способы/подходы, и это может зависеть от дистрибутива.

Связанный контент