阻止應用程式使用連接埠上的所有 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 設備並與西門子 Profinet 控制器通信,我可以存取該應用程式的原始程式碼。第二個應用程式應充當與 Profinet 西門子設備通訊的 Profinet 控制器,我目前正在使用 Codesys 來實現此目的,並且無權更改原始程式碼。

答案1

你有幾個選擇。

LD_預先載入

您可以使用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) 並且您的 iptablesFORWARD鏈允許轉送連線 ( iptables -A FORWARD -d 192.168.99.2 -j ACCEPT,請記住,規則是按順序處理的,因此拒絕規則這一項將優先)。

相關內容