Запретить приложению использовать все IP-адреса на порту (0.0.0.0:34964)

Запретить приложению использовать все IP-адреса на порту (0.0.0.0:34964)

У меня есть два приложения, которые используют один и тот же порт для сетевой связи (34964). У меня есть контроль над (исходным кодом) первого приложения, и оно использует 192.168.0.4:34964. В то время как другое приложение пытается использовать/"заявить" все IP-адреса (0.0.0.0:34964), но это приложение у меня нет контроля. Каждое приложение работает отдельно, однако, когда я пытаюсь запустить их одновременно, я получаю ошибку: Не удалось привязать адрес.

Вопрос

Есть ли способ запретить второму приложению использовать/заявлять все IP-адреса (0.0.0.0) и вместо этого использовать 192.168.0.5. Либо перед его запуском, либо инкапсулировав его в сетевое пространство имен?

Я ничего не пробовала, и у меня закончились идеи...

Более подробная версия: Два приложения для связи в двух отдельных сетях Profinet. Первое приложение действует как устройство Profinet и взаимодействует с контроллером Siemens Profinet, у меня есть доступ к исходному коду этого приложения. Второе приложение должно действовать как контроллер Profinet, взаимодействующий с устройством Profinet Siemens, в настоящее время я использую для этого Codesys и не имею доступа для изменения исходного кода.

решение1

У вас есть несколько вариантов.

LD_PRELOAD

Вы можете использовать LD_PRELOADбиблиотеку для перехвата bind()системного вызова для принудительной привязки к определенному адресу. Один из примеров этого:этот, который вы компилируете следующим образом:

gcc -nostartfiles -fpic -shared bind.c -o bind.so -ldl -D_GNU_SOURCE

И используйте вот так:

BIND_ADDR=127.0.0.1 LD_PRELOAD=./bind.so /path/to/myprogram

Сетевые пространства имен с Docker

Вы также можете выбрать запуск своей программы внутри ее собственного сетевого пространства имен.самый простойДля этого можно создать образ Docker для вашего приложения, а затем запустить его в Docker и использовать возможности сопоставления портов Docker, чтобы предоставить доступ к службе на IP-адресе хоста по вашему выбору.

Здесь есть драконы.

Я настоятельно рекомендую одно из вышеперечисленных решений. Я включил следующее только потому, что вы спросили о сетевых пространствах имен.

Сетевые пространства имен с macvlan

Если вы хотите сделать это без Docker, это возможно, но немного больше работы. Сначала создайте новое сетевое пространство имен:

# ip netns add myns

Затем создайте macvlanинтерфейс, связанный с одним из интерфейсов вашего хоста, и поместите его в пространство имен:

# ip link add myiface link eth0 type macvlan mode bridge
# ip link set myiface netns myns

И назначьте ему адрес в вашей локальной сети:

# ip netns exec myns \
  ip addr add 192.168.0.4/24 dev myiface
# ip netns exec myns \
  ip link set myiface up

И создайте соответствующие правила маршрутизации внутри пространства имен (заменив ваш фактический адрес шлюза на 192.168.0.1):

# ip netns exec myns \
  ip route add default via 192.168.0.1

Теперь запустите вашу программу внутри сетевого пространства имен:

# ip netns exec myns \
  /path/to/myprogram

Теперь ваша программа запущена и будет привязана только к 192.168.0.4, поскольку это единственный адрес, видимый внутри пространства имен. Но! Помните об ограничении интерфейсов mavclan: в то время как другие хосты в вашей сети смогут подключаться к службе, вы не сможете подключиться к этому адресу с хоста, на котором она запущена (если только вы не создадите другой macvlanинтерфейс на хосте и не направите соединения 192.168.0.4через этот интерфейс).

Сетевые пространства имен с интерфейсами veth

Вместо использования macvlanинтерфейсов вы можете создать vethпару интерфейсов, один конец которой будет внутри сетевого пространства имен, а другой — на вашем хосте. Вы будете использовать ip-маскарад для передачи пакетов из пространства имен в вашу локальную сеть.

Создайте сетевое пространство имен:

# ip netns add myns

Создайте пару интерфейсов:

# ip link add myiface-in type veth peer name myiface-out

Назначьте один конец пары пространству имен вашей сети:

# ip link setns myiface-in myns

Настройте адрес на каждом конце пары и поднимите ссылки:

# ip addr add 192.168.99.1/24 dev myiface-out
# ip link set myiface-out up
# ip netns exec myns ip addr add 192.168.99.2/24 dev myiface-in
# ip netns exec myns ip link set myiface-in up

Настройте ip-маскарадинг на вашем хосте. Это перенаправит входящие пакеты в 192.168.0.4ваше пространство имен:

# iptables -t nat -A PREROUTING -d 192.168.0.4 -p tcp --dport 34964 -j DNAT --to-destination 192.168.99.2
# iptables -t nat -A OUTPUT -d 192.168.0.4 -p tcp --dport 34964 -j DNAT --to-destination 192.168.99.2

А это замаскирует исходящие пакеты:

# iptables -t nat -A POSTROUTING -s 192.168.99.2 -j MASQUERADE

Вам необходимо убедиться, что на вашем хосте включена переадресация IP ( sysctl -w net.ipv4.ip_forward=1) и что ваша цепочка iptables FORWARDразрешает переадресацию соединения ( iptables -A FORWARD -d 192.168.99.2 -j ACCEPT, имея в виду, что правила обрабатываются последовательно, поэтому правило отклонениядоэтот будет иметь приоритет).

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