Назад | Перейти на главную страницу

Связь через отдельные сетевые карты

Предположим, у вас есть веб-сервер с двумя сетевыми картами (и связанными с ними портами), назовем их A и B. Идея состоит в том, чтобы подключить один порт (A) к Интернету, а другой (B) к некоторой изолированной сети серверов для различные вычисления. Это кажется относительно обычным явлением: одна сеть, доступная в Интернет для фактической отправки и получения информации, и частная сеть для безопасного хранения данных, административного контроля и т. Д.

Как будет направлен трафик через один или другой? Единственная сторона, которую я видел в этом, - это сторона кода, и на всех языках, с которыми я знаком, вы инициируете связь (например, TCP), предоставляя адрес назначения, а не адрес происхождения. Если вы хотите поговорить с конкретной машиной, подключенной (через коммутатор) к одному или другому порту, как бы вы указать, какой? Более того, что, если бы у вас были машины, подключенные как через A, так и через B, но некоторый трафик (возможно, финансовая информация) нужно было бы отправлять через B, в то время как другой трафик (например, данные REST) ​​лучше подходил бы для A?

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

Предположим, что ваши имена хостов - host001 и host002, а ваша сеть выглядит так:

<-----internet --------+------------------------------+-------whatever else--->
                       |                              |
          157.38.5.6   |                  157.38.5.7  |
       +---------------+--+             +-------------+--+
       |  host001         |             |  host002       |
       +---------------+--+             +-------------+--+
          192.168.1.1  |                  192.168.1.2 |
                       +------------------------------+-------admin lan--->

157.38.5 / 24 - это диапазон адресов, назначенный вам вашим провайдером. Оба хоста доступны из Интернета, и вы должны указать

host001.mycompany.com. IN A 157.38.5.6
host002.mycompany.com. IN A 157.38.5.7

в ваши официальные записи DNS.

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

На внутренний DNS-сервер вашей компании, записи которого не публикуются в Интернете, вы должны поместить

host001.dmz.company.com IN A 157.38.5.6
host002.dmz.company.com IN A 157.38.5.7
host001.mgm-net.company.com IN A 192.168.1.1
host002.mgm-net.company.com IN A 192.168.1.2

Теперь, когда вы хотите открыть соединение по внутренней сети, вы должны использовать одно из имен хостов в mgm-net домен. Это выберет 192.168.1 адресов, и, поскольку каждый из хостов имеет один из них, он будет использовать этот сетевой интерфейс. Если вы хотите использовать общедоступную сеть, используйте dmz доменные адреса.

Как локальный хост выбирает исходящий интерфейс?

Для этого и предназначена таблица маршрутизации. Ваша таблица маршрутизации будет выглядеть примерно так:

destination     netmask             gateway      metric  interface
    0.0.0.0     0.0.0.0             157.38.5.1        1       eth0
 157.38.5.0     255.255.255.0                         0       eth0
 192.168.1.0    255.255.255.0                         0       eth1

Точный формат таблицы зависит от вашей ОС, версии ОС и команды, использованной для ее отображения. Также могут отличаться абсолютные значения метрики. Ключевым моментом здесь является то, что из всех записей таблицы маршрутизации ядро ​​удалит те, которые не соответствуют адресу назначения. Если вы подключитесь к 192.168.1.1, это удалит вторую запись (157 ...) из списка. Маршрут по умолчанию (0.0.0.0) на данный момент все еще удобен.

Затем из всех оставшихся возможностей выбирается тот, у которого лучшая метрика. Классически метрика была синонимом количества переходов к месту назначения, поэтому самая низкая метрика была лучшей. Windows использует другой способ, лучше всего наивысший показатель. В любом случае, именно комбинация возможных маршрутов и показателей в вашей локальной таблице маршрутизации определяет, какой локальный интерфейс используется.

Это особенно важно, если вы пытаетесь подключиться из места «дальше по сети» внутри вашей компании, где между вашим ПК и целевыми сетями есть один или несколько маршрутизаторов.

Возможности для дальнейшего улучшения

  • Возможно, вы захотите дать своим хостам разные имена хостов вместо разных сетевых доменов. Таким образом, у вас может быть запись host001-ext.mycompany.com и host001-adm.mycompany.com, поэтому вам не нужно «указывать» домен каждый раз, когда вы подключаетесь к определенному хосту. Однако, изменив порядок поиска доменов на разных ПК, вы можете проделать некоторые трюки, когда ПК A предпочитает dmz.company.com, ПК B предпочитает mgm-net.company.com, а "автоматический выбор" правильной сети, если только см. "host001" в файле конфигурации.

  • У вас будет меньше путаницы, если вы синхронизируете последние байты IP; 157.38.5.6 снаружи должен соответствовать 192.178.1.6 внутри, а не 192.168.1.1. Согласованность последних байтов позволяет вам создать сценарий, который автоматически генерирует внутренние адреса из внешних.

  • «Опасные» службы, такие как порт 22 / ssh (в unix) или 3389 / удаленный рабочий стол, могут / должны быть привязаны только к адресам 192.168.1.X. Таким образом, вы все еще можете подключиться к своей машине по ssh, если вы находитесь во внутренней сети, но вы удалили вектор атаки извне.

Конфигурация / Программирование

Одна из функций API-интерфейсов ОС - скрыть кровавые подробности всего этого, чтобы вы не заметили никаких различий в том, «из какого интерфейса берутся данные», если только вы специально не попросите об этом.

Из API сокета C вы можете использовать getsockname() и getpeername() функции, чтобы узнать о локальных / удаленных адресах сокета. И когда вы используете bind() чтобы настроить прослушивающий сокет, одним из параметров является sockaddr структура, в которой вы должны установить порт, и в которой вы может установить IP-адрес. Обычно вы просто устанавливаете его на 0.0.0.0, что означает, что сокет привязан к этому порту по любому адресу.

В Java у вас есть Socket.getRemoteSocketAddress() и Socket.getInetAddress делать то же самое, и ServerSocket() имеет 3-параметрическую версию, которая позволяет вам установить адрес для прослушивания.

У приложений обычно есть файлы конфигурации, чтобы делать то же самое. Например, sshd конфигурация в /etc/sshd/sshd_config имеет ListenAddress параметр. Если вы скажете ListenAddress 192.168.1.1 вот тогда sshd пройдет это 192.168.1.1 к bind() при создании сокета, и ваша ОС не будет принимать пакеты ssh, предназначенные для 157.38.5.6.

Точно так же веб-сервер apache имеет параметр конфигурации Listen который позволяет вам установить порт и, возможно, адрес для прослушивания.

Обычно в программах Windows это есть в некоторых настройках. В IIS вы привязываете службы к серверам, используя порт и IP-адрес (где адрес может быть "*" для всех адресов), что фактически делает то же самое.

Непонятно, что и зачем нужно делать.

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

Пример 1: вы подключены к 2 сетям:

  • 10.0.0.0, где у вас IP-адрес 10.10.10.2
  • 192.168.1.0, где у вас IP-адрес 192.168.1.2

Теперь, если вы хотите подключиться к 192.168.1.5, ваш веб-сервер, скорее всего, выберет вторую сеть (192.168.1.0), поскольку пункт назначения напрямую доступен там.

Пример 2:, подключено только к 1 сети:

  • 192.168.1.0, где у вас IP-адрес 192.168.1.2 и шлюз 192.168.1.1

Теперь, если вы хотите подключиться к 10.10.10.2, ваш веб-сервер просто отправит пакеты на шлюз по умолчанию (маршрутизатор), поскольку 10.10.10.2 не находится в вашей сети (192.168.1.0). Ваш сервер не знает, что происходит с вашими пакетами на шлюзе и как шлюз (маршрутизатор) доставит их в конечный пункт назначения. Это головная боль только шлюза (роутера).

Во втором примере таблица локальной маршрутизации на вашем сервере будет выглядеть довольно просто:

  • 192.168.1. * Напрямую подключен
  • 0.0.0.0 (все остальное) подключается через 192.168.1.1 (ваш шлюз)

Вывод:

Со стороны кода вы не можете выбрать исходящий интерфейс, если вы не пишете программное обеспечение маршрутизации. Это разумно, поскольку ваше приложение не имеет представления о протоколах маршрутизации, информации и правилах. Операционная система делает выбор за вас в зависимости от таблицы маршрутизации. Таблица маршрутизации создается и обновляется операционной системой в зависимости от статуса ваших сетевых подключений, политик, правил, протоколов маршрутизации (если ваш сервер выступает в роли маршрутизатора) и так далее.

Если вам НЕОБХОДИМО связываться с одним и тем же местом назначения через 2 разных исходящих интерфейса, в зависимости от ПОРТА назначения, вам следует настроить маршрутизацию на сервере. Пример для Linux: https://unix.stackexchange.com/questions/21093/output-traffic-on-different-interfaces-based-on-destination-port

Вы, вероятно, сделаете это с маршрутизацией - одна подсеть будет на порту A, а другая подсеть на порту B. Тогда ОС будет маршрутизировать пакеты через правильный интерфейс в соответствии с услугой, которую она должна получить.

Из вашего текста я не уверен, действительно ли вы говорите о двух действительно разных сетях, а именно:

  1. Один отдельный коммутатор для каждой подсети (или один управляемый коммутатор с более чем одной VLAN);

  2. Каждый коммутатор подключается к одной сетевой карте (NIC) на вашем сервере;

  3. все остальные компьютеры подключаются только к одному коммутатору;

  4. Каждая подсеть имеет собственную адресацию, например, одна имеет адреса типа 192.168.0. *, А другая - 192.1.68.1. *

Если это действительно так, то:

  1. Linux на сервере должен маршрутизировать трафик автоматически из одной сети в другую (если нет, Google iptables, маршрутизация между двумя NICS и сообщает нам, какой Linux вы используете)

  2. Сервер также является хорошим местом для настройки брандмауэр для ограничения трафик, который вы не хотите маршрутизировать через сети.

  3. Различие в том, куда идет трафик, просто зависит от IP-адресов (см. 4 выше).

  4. Обычно вы не подключаете ПК к обеим подсетям, вы предпочитаете работать с маршрутизацией и брандмауэром (в одной точке, на сервере), чтобы точно настроить то, что проходит через подсети.