KVM VPS на Proxmox за NAT с пробросом портов и DHCP

Часто, когда сервер арендуется у какого-либо хостинг-провайдера, к нему прилагается от одного до нескольких IP-адресов. Если сервер «каноничный» и все сервисы устанавливаются прямо на ОС, деля ресурсы между собой как придется, то данной проблемы может и не возникнуть. Но если же планируется четкое разделение ресурсов сервера посредством виртуализации, то в какой-то момент может появиться надобность либо в дополнительных IP-адресах, либо в организации NAT и пробросе портов. Если, конечно, сервисы смотрят наружу.

Сетевой мост (Bridge)

Организовать NAT для нескольких виртуальных машин довольно просто. В Proxmox «из коробки» доступно создание сетевых мостов (хотя удобнее это делать сразу в конфиге, т.к. PVE съедает комментарии и меняет форматирование). Для наших целей создадим бридж vmbr1  с ip-адресом 192.168.1.1  и стандартной маской 255.255.255.0 , которая предоставит в наше распоряжение все 256 адресов.

После того как он заработает, идем в /etc/network/interfaces  и немного правим конфигурацию созданного бриджа:

Здесь мы разрешаем виртуальным машинам на vmbr1  подключаться к интернету через vmbr0 . Стоит отметить, что последние две строчки с добавлением и удалением правил файрвола могут отличаться по причине того, что в моем случае главным интерфейсом сервера является бридж vmbr0  и сеть настраивается на него. У меня он работает для получения несколькими виртуальными машинами реальных IP-адресов от внешнего гейта. Если у вас сеть настраивается на eth0 , то он и должен быть вместо vmbr0 . В остальном разницы никакой нет.
Также, включать ip_forward  можно в /etc/sysctl.conf .

Проброс портов (Port forwarding)

Далее, если необходимо пробросить определенные порты на нужные виртуальные машины. Это можно сделать с помощью iptables:

Где

%ext_ip_on_vmbr0%  — внешний IP-адрес, который находится на vmbr0 . Если не указать этого параметра, то порт будет пробрасываться со всех адресов на этом бридже.
%ext_port%  — внешний порт по которому будут обращаться к серверу из интернета.
%int_ip_on_vmbr1%  — внутренний IP виртуальной машины на vmbr1 .
%int_port%  — внутренний порт, на котором будет работать сервис в виртуальной машине.

Ну и после применения правил для нужных портов можно посмотреть все ли правильно:

Сохранение правил файрвола

Если все верно — остается сделать так, чтобы при перезагрузке правила восстанавливались. Для этого можно воспользоваться iptables-save  и скриптами инициализации сети.

Создадим скрипт загрузки правил:

И впишем в него команду загрузки правил из сохраненного ранее файла:

Не забудем дать права на исполнение этому файлу:

Более простой альтернативой будет установка пакета iptables-persistent , который сам будет сохранять правила при выключении или перезагрузке, а при загрузке загружать их снова. Более подробно — здесь (англ).

Все. Проброс портов работает.

Настройка сети в гостевой ОС

Ручная настройка (static)

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

Для этого в настройках гостевой ОС прописываем такие параметры:

address  — ip-адрес данной машины. Естественно, у всех машин этой подсети он должен быть разный.

netmask  — это маска подсети. Точно такая же как указывалось при создании сетевого моста.

gateway  — ip-адрес, на котором сидит сам хост, через который будет происходить роутинг во внешнюю сеть.

Динамическая конфигурация (DHCP)

Чтобы не настраивать сеть вручную можно установить DHCP-сервер. Особенно это будет полезно, если в подсети будет находиться много виртуальных машин — настраивать сеть вручную на каждой не придётся.

Устанавливаем сервер:

В файле  /etc/dhcp/dhcpd.conf большинство параметров можно оставить неизменными, однако директиву  authoritative; нужно раскомментировать. Также может быть полезным увеличить время выдачи адресов с помощью параметров:

И, самое главное, нужно описать настройки нашей подсети:

Здесь range  — это диапазон адресов, которые будет выдавать DHCP-сервер. domain-name-servers  — это DNS-сервера, которые будут использоваться на гостевых машинах. В данном примере это Google Public DNS.

Далее в файле  /etc/default/isc-dhcp-server настраиваем какие интерфейсы будет слушать наш сервер:

Для надёжности можно ещё прикрыть его файрволом от запросов извне.

После настройки перезапускаем DHCP

Настройка закончена. Теперь гостевые машины будут получать настройки сети автоматически во время установки ОС.

 

19 Comments

 Add your comment
  1. Да, год уже прошел с написания поста, но я сейчас наткнулся, это единственная статья с внятным объяснением, спасибо огромное

  2. ❓ А как быть например если хост проксмока нее имеет прямого выхода в инет?
    Например с маршрутизатором с NAT.
    Пробрасывать порты на маршрутизаторе не сложно но как быть например что VNC консоли через веб запускаются на следующем свободном порту из диапазона 5900-6000. Как в таком случае пробросить?

    • Не до конца понял, но вам, очевидно, надо диапазон портов пробросить. Это уже легко загуглить по «iptables пробросить диапазон портов».

  3. Добрый день! Случайно нашел вашу статью, где вы все просто и доходчиво объяснили. Однако у меня чего-то не заработало. Вот конфигурация бриджа
    auto vmbr1
    iface vmbr1 inet static
    address 192.168.1.1
    netmask 255.255.255.0
    bridge_ports eth1
    bridge_stp off
    bridge_fd 0
    post-up echo 1 > /proc/sys/net/ipv4/ip_forward
    post-up iptables -t nat -A POSTROUTING -s ‘192.168.1.0/24’ -o vmbr0 -j MASQUERADE
    post-down iptables -t nat -D POSTROUTING -s ‘192.168.1.0/24’ -o vmbr0 -j MASQUERAD
    у меня главный интерфейс vmbr0 если его поставить мащине она есть в интернете, я хочу создать виртуальную машину которая будет одновременно и в локальной сети 192.168.1.0/24 и что б оона выходила в инет. Делал все по вашему описанию, только в бридже прописал еще eth1. Так как машина должна быть и в локальной сети. Но интернета у нее нету))) Если Вам не трудно направть меня по пправильному пути, а то я запутался. (

    • Если вам нужна виртуалка, которая будет торчать за NAT — тогда у вас как бы никаких проблем не будет, если сделаете всё точно по инструкции. Если же и без NAT и в локалке — тогда либо с подсетью, которая будет на одном бридже работать, либо у виртуалки два интерфейса — на внешний IP под vmbr0 и на локальный IP под vmbr1.

      • Здравстуйте еще раз. Спасибо за быстрый ответ). Мне нужна виртуалка, которая будет торчать за NAT и в локалке. Причем локалка также будет входить в мир. Я так понял, что мне прийдется сделать две виртуалки. Одну с двумя интерфейсами — на мир под vmbr0 и на локалку под vmbr1. На ней настроить шлюз для выхода локалки в мир. И другую на которой запустить базу и сервисы для локалки, которая также будет торчать в локалке и ходить в мир через шлюз. Я правильно вас понял? Если я создаю виртуалку под vmbr0 она сразу смотрит в мир. Мне нужна виртуалка которая смотрит в сеть и к ней можно б было подключиться извне для изменения настроек. Я думал если сделаю по инструкции, то разрешу виртуальным машинам на vmbr1 подключаться к интернету через vmbr0. Хотя я делаю по вашей инструкции и делал как описано в http://pve.proxmox.com/wiki/Network_Model#Masquerading_.28NAT.29. Моя виртуалка на vmbr1 в мир не ходит(((. Если меняю на vmbr0. Я сразу в интернете. Даже отключал eth1, хотя он здесь точно ни при чем. Никак не могу настроить ))). В Proxmox я новичок, всего неделю))). Хотя ихняя задумка мне нравится)

        • Я правильно вас понял?

          Нет! Перечитайте ответ еще раз, пожалуйста. Ключевые слова — «либо». То есть это разные варианты, а не всё в одном. Да и вы вообще что-то не то вычитали.

          Мне нужна виртуалка которая смотрит в сеть и к ней можно б было подключиться извне для изменения настроек.

          Делаете так, как описано здесь и пробрасываете нужные порты с помощью iptables (Google). Тогда сможете подключиться к вашей виртуалке снаружи не выделяя ей отдельный IP. Данная инструкция именно о виртуалках за NAT — то есть, не имеющих своего IP.
          Чтобы виртуалка могла иметь доступ в интернет здесь используется маскарад (те два правила для iptables). Чтобы подключиться к ней снаружи — нужно пробросить порты (тот же самый гугл). Либо же вы можете просто с помощью того же SSH подключиться к ней с хоста — тогда не нужно пробрасывать порты.

          Никак не могу настроить ))). В Proxmox я новичок, всего неделю)))

          Неважно, сколько вы пользуетесь Proxmox VE. Вам нужно разобраться с сетью в Linux-системах.

          • Спасибо за ответ. Пошел читать инфу. В линуксе я тоже неделю))). Когда я делаю все по вашей инструкции у меня нету интернета на виртуальной машине, для простоты я на виртуалку винду накатил. Когда включаю на vmbr0, на виртуалке появляется интернет, но она висит в мире, и ее видно из интернета, она получает белый ip. По инструкции интернета нету))). Пока спасибо за информацию — буду искать инфу))). Если получится — отпишусь 😉

            • Значит, что-то в конфигурации не так, как описано. Только что повторял данную настройку на новом сервере.
              Удачи.

  4. Обновил пост. Добавил информацию про пакет автоматически сохраняющий правила iptables и настройку DHCP-сервера.

  5. Как настроить сеть, так чтобы VM со шлюзом общалась через eth0 с провайдером, через eth1 c локалкой, а также через третий мост с другими VM на proxmoxe?

    Настроил мосты! Все отлично работает! Только не могу теперь попасть в веб интерфейс самого proxmoxa, так как не открывается страница https://xx.xx.xx.yxx:8006, а если просто набрать xx.xx.xx.yxx то попадаю в веб интерфейс самой VM_101. Как разрешить ситуацию так, чтоб был доступ извне и к VM_101 и к веб интерфейсу самого proxmoxa?
    (VM_101 он же шлюз для локалки и других VM)

    PROXMOX
    /etc/network/interfaces
    # network interface settings
    auto lo
    iface lo inet loopback

    auto eth0
    iface eth0 inet manual

    auto eth1
    iface eth1 inet manual

    auto vmbr0
    iface vmbr0 inet static
    address xx.xx.xx.yxx
    netmask 255.255.255.0
    gateway xx.xx.xx.yx
    bridge_ports eth0
    bridge_stp off
    bridge_fd 0

    auto vmbr1
    iface vmbr1 inet static
    address 192.168.100.254
    netmask 255.255.255.0
    bridge_ports eth1
    bridge_stp off
    bridge_fd 0

    iface vmbr2 inet static
    address 192.168.1.1
    netmask 255.255.255.0
    bridge_ports eth2
    bridge_stp off
    bridge_fd 0

    VM_101 он же шлюз для локалки и других VM

    /etc/network/interfaces

    # The loopback network interface
    auto lo
    iface lo inet loopback

    # The primary network interface
    auto eth1
    iface eth1 inet static
    address xx.xx.xx.yxx(тот же что и у vmbr0 proxmoxa)
    netmask 255.255.255.0
    network xx.xx.xx.0
    broadcast xx.xx.xx.255
    gateway xx.xx.xx.1
    dns-nameservers 89.28.1.1
    ###################################
    auto eth2
    iface eth2 inet static
    address 192.168.100.254
    netmask 255.255.255.0
    ##########################
    auto eth0
    iface eth0 inet static
    address 192.168.1.1
    netmask 255.255.255.0
    pre-up iptables-restore < /etc/network/firewall.rules

    • Ну, вы немного упустили подробности про то, как у вас вообще выдаются адреса, например. Если взять тот же Hetzner, там есть два способа получить адреса:
      1. Вам выдаётся адрес через DHCP по MAC самим Hetzner’ом. Таких адресов может быть до пяти на сервер. Виртуалки, которые должны получать эти IP должны быть на том бридже, который настроен на основной адрес из них — адрес вашего хоста.
      2. Вы можете получить подсеть. Тогда вам нужно настроить отдельный мост под эту подсеть, самим хостом занять её первый адрес и остальным виртуалкам выдавать вручную или через DHCP адреса в этой подсети, а гейтом на виртуалках указывать адрес хоста в этой подсети. Таким образом в данной конфигурации у вас хост имеет два внешних адреса — свой изначальный из пункта 1 (такой там всегда один выдают) и первый адрес из подсети.

      Я прошу прощения, но не очень понял из ваших конфигов что и как должно быть. Также непонятно, сколько у вас адресов, чего вы хотите добиться — NAT или выдачи внешнего IP виртуальной машине.
      А если у вас вместо хоста отвечает виртуальная машина — значит вы либо что-то не так настроили — очевидность, но без подробностей сложно что-то сказать.

      Попробуйте обратиться на unixforum, например. Там есть специальные разделы и вам могут помочь достаточно быстро.

  6. Добрый день , спасибо за вашу статью все получилось , но виртуалки имеющие адреса 192.168.1.XX спокойно пингуют хост машину 192.168.1.1 , но не видят друг друга. Подскажите как сконфигурировать так , чтобы машины могли соединять друг с другом как в локальной сети ?

    • Они и так должны соединяться, если висят на одном бридже.
      Возможно, у вас где-то слишком жестоко настроен файрвол: на хосте или на самих виртуалках.

  7. Спасибо!

  8. Дмитрий

    Все сделал в соответсвии со статьей, получаю вот такую ошибку

    Job for isc-dhcp-server.service failed.See ‘systemctl status isc-dhcp-server.service’ and ‘journalctl -xn’ for details.

    • Очевидно, что по какой-то причине DHCP-сервер не может запуститься. В общем-то, в сообщении об ошибке и написано, куда можно посмотреть за причинами.

  9. Виталий

    Отличная статья, у меня заработало. Делал первый раз.

Leave a Comment

Your email address will not be published.

Яндекс.Метрика Лицензия Creative Commons