Raspberry-Pi

阻止應用程序使用埠上的所有 IP (0.0.0.0:34964)

  • April 6, 2017

我有兩個應用程序使用相同的埠進行網路通信 (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 Siemens 設備對話的 Profinet 控制器,我目前正在為此使用 Codesys,並且無權更改原始碼。

你有幾個選擇。

LD_PRELOAD

您可以使用LD_PRELOAD庫來攔截bind()系統呼叫以強制綁定到特定地址。一個例子是this,你可以這樣編譯:

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

您需要確保在您的主機 ( sysctl -w net.ipv4.ip_forward=1) 上啟用了 ip 轉發,並且您的 iptablesFORWARD鏈允許轉發連接 (請iptables -A FORWARD -d 192.168.99.2 -j ACCEPT記住,規則是按順序處理的,因此在此之前的拒絕規則將優先)。

引用自:https://unix.stackexchange.com/questions/356337