如何配置网络命名空间 Linux, 允许广播时事通讯 UDP

我正在努力使用

ip netns

B队的家庭B. Linux 创建网络命名空间,其中我可以使用广播新闻通讯运行程序 UDP. 我不需要访问root或根名中的任何接口 (但如果有必要工作,那绝对是可接受的).

这是一个示例服务器和客户端 Ruby (测试的S. Ruby 1.9.3, 但我希望它在其他版本中工作):

#! /usr/bin/env ruby

require 'socket'

PORT = 5000

case ARGV[0]
when 'server'
soc = UDPSocket.open
begin
soc.bind('', PORT)
puts "SERVER #{Process.pid} listening on #{PORT}"
msg = soc.recv(1)
puts "SERVER got msg: #{msg}"
ensure
soc.close
end
when 'client'
soc = UDPSocket.open
begin
soc.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
puts "CLIENT sending message"
soc.send('m', 0, '<broadcast>', PORT)
ensure
soc.close
end
else
abort "usage: #{$0} {server | client}"
end

它创建服务器或客户端。 服务器正在倾听

0.0.0.0

界面 (

soc.bind('', ...)

). 客户端向广播地址发送消息。 (

soc.send(..., ..., '<broadcast>', ...)

).

在从根本名称中开始时,它似乎它可以正常工作:

$ ./udp-broadcast.rb server &amp; sleep 0.5 &amp;&amp; sudo netstat --listen --udp -p | grep 5000 &amp;&amp; ./udp-broadcast.rb client
SERVER 22981 listening on 5000
udp 0 0 *:5000 *:* 22981/ruby
CLIENT sending message
SERVER got msg: m

以下是我正在尝试创建新的网络命名空间的脚本并启动相同的命令:

#!

set -e

NS=udp-broadcast-test
nsexec="ip netns exec $NS"

ip netns add $NS

trap "ip netns delete $NS" EXIT

$nsexec ip link set lo up

# Can loopback have a broadcast address?
# $nsexec ip link set lo broadcast 255.255.255.255
# RTNETLINK answers: Invalid argument
# $nsexec ip addr add broadcast 255.255.255.255 dev lo
# RTNETLINK answers: Invalid argument

$nsexec ip link add veth0 type veth peer name veth1
$nsexec ifconfig veth0 192.168.99.1/24 up

$nsexec ip link
$nsexec ip route
$nsexec ifconfig

timeout 2s $nsexec ./udp-broadcast.rb server &amp;
sleep 0.2
$nsexec netstat -n --udp --listen -p
timeout 2s $nsexec ./udp-broadcast.rb client
wait

启动时,它提供了以下结论:

$ sudo ./netns.sh
1: lo: <loopback,up,lower_up> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: veth1: <broadcast,multicast> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether e2:a1:c4:14:c4:5e brd ff:ff:ff:ff:ff:ff
3: veth0: <no-carrier,broadcast,multicast,up> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000
link/ether a6:2f:84:9f:08:36 brd ff:ff:ff:ff:ff:ff
192.168.99.0/24 dev veth0 proto kernel scope link src 192.168.99.1
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

veth0 Link encap:Ethernet HWaddr a6:2f:84:9f:08:36
inet addr:192.168.99.1 Bcast:192.168.99.255 Mask:255.255.255.0
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

SERVER 23320 listening on 5000
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 0.0.0.0:5000 0.0.0.0:* 23320/ruby
CLIENT sending message
./udp-broadcast.rb:23:in `send': Network is unreachable - sendto(2) (Errno::ENETUNREACH)
from ./udp-broadcast.rb:23:in `<main>'

现在,如果我更改了侦听服务器的地址,并且客户端向其发送消息

192.168.99.1

, 然后消息来了,所以我知道我的

veth0

至少部分地运行。

我如何设置,以便进行广播消息? 服务器代码 / 客户端从代码的较大代码中提取,更改它并不容易,因此我唯一可以改变, - 这是我的网络配置。
</main></no-carrier,broadcast,multicast,up></broadcast,multicast></loopback,up,lower_up></broadcast></broadcast>
已邀请:

詹大官人

赞同来自:

通过添加默认路由来解决这个特殊问题

veth0

:

$nsexec ip route add default via 192.168.99.1 dev veth0

在带来的行后立即添加此字符串

veth0

向上,脚本已成功执行。

君笑尘

赞同来自:

好吧,有许多原因它不起作用。

你创造了一对夫妇 veth, 然后,您无法向新的网络命名空间添加一侧。

分支的一个侧面没有提出。

指定广播地址

255.255.255.255

如在示例中,请在路由表中调用搜索并发送默认路由包。

因此,你不使用

SO_BINDTODEVICE

指定您真正要发送的界面。 请注意,这需要特权。 root, 在许多情况下并不完美。

此外,您未在子名称空间和父命名空间之间建立任何路由关系,因此它甚至不会使用主机的直接ping。

通常,除了提供基本网络服务之外的任何内容的通用广播地址都不是良好的做法。 您必须使用您努力的子网的广播地址。

我得到了你提到的一切,致力于编写网络空间名称。

# ip netns add TEST
# ip link add veth0 type veth peer name veth1
# ip link set dev veth1 netns TEST
# ip link set dev veth0 up
# ip netns exec TEST ip link set dev veth1 up
# ip netns exec TEST ip addr add 10.10.10.10/32 dev veth1
# ip route add 10.10.10.10/32 dev veth0
# ip netns exec TEST ip route add 192.168.1.3/32 dev veth1
# ping -c1 10.10.10.10
PING 10.10.10.10 (10.10.10.10) 56(84) bytes of data.
64 bytes from 10.10.10.10: icmp_seq=1 ttl=64 time=0.202 ms

--- 10.10.10.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.202/0.202/0.202/0.000 ms

以下是使用的脚本。 注意

SO_BINDTODEVICE

称呼..

#!/usr/bin/python
import socket as sock
import sys, time, os

if __name__ == "__main__":
if sys.argv[1] == "server":
s = sock.socket(sock.AF_INET, sock.SOCK_DGRAM)
s.bind(('0.0.0.0', 50000))
data = s.recvfrom(50)
print "Got {0}".format(data)

elif sys.argv[1] == "client":
s = sock.socket(sock.AF_INET, sock.SOCK_DGRAM)
s.setsockopt(sock.SOL_SOCKET, sock.SO_BROADCAST, 1)
s.setsockopt(sock.SOL_SOCKET, sock.SO_BINDTODEVICE, "veth0")
s.connect(('255.255.255.255', 50000))
s.send("hello world\n")

然后结果 ..

# ip netns exec TEST python test.py server &
[1] 24961
# python test.py client
Got ('hello world\n', ('192.168.1.3', 41971))

要回复问题请先登录注册