简体   繁体   English

绑定到ruby中的网络接口

[英]Binding to networking interfaces in ruby

I'm trying to open multiple sockets in a ruby application on different network interfaces in linux. 我正在尝试在linux中的不同网络接口上的ruby应用程序中打开多个套接字。 For example lets say I have the interface eth0 with an IP of 192.168.1.2 and the interface wlan0 with the IP address 10.0.0.2. 例如,假设我的接口eth0的IP为192.168.1.2,接口wlan0的IP地址为10.0.0.2。 I would like to simultaneously connect to a server with a socket on each interface. 我想在每个接口上同时连接到带有套接字的服务器。 I thought that binding to the IP address of these interfaces would work however that doesn't seem to be the case. 我认为绑定到这些接口的IP地址会起作用,但似乎并非如此。 In wireshark when I bind to the IP of wlan0 I successfully see the SYN packets send with the correct source IP, but wireshark sees them on eth0 and the socket is never opened. 在wireshark中,当我绑定到wlan0的IP时,我成功地看到SYN数据包使用正确的源IP发送,但wireshark在eth0上看到它们,并且套接字永远不会打开。

Ruby version: ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] Ruby版本:ruby 1.9.3p194(2012-04-20修订版35410)[x86_64-linux]

Here is my current code. 这是我目前的代码。 I have also tried the Addrinfo method documented on the ruby-doc page for Socket with the same results. 我还尝试了针对Socket的ruby-doc页面上记录的Addrinfo方法,结果相同。

require 'socket'

ip = "192.168.1.2" # IP of internal interface
port = 8000
server = "" # IP of the server I'm trying to connect to goes here

lhost = Socket.pack_sockaddr_in(0, ip)
rhost = Socket.pack_sockaddr_in(port, server)
socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
socket.bind(lhost)
socket.connect(rhost)

Thank you for any help! 感谢您的任何帮助!

The solution is source based routing 解决方案是基于源的路由

I was able to figure it out, and thought I should leave my answer in case anyone else gets stuck with this problem down the road. 我能够弄清楚,并认为我应该留下我的答案,以防其他人在路上遇到这个问题。

What I needed to do was source based routing. 我需要做的是基于源的路由。 The general idea is to create two routing tables, one that forces traffic on one interface and one that forces traffic on the other, and have an ip rule that uses the appropriate routing table based on the source IP address. 一般的想法是创建两个路由表,一个强制一个接口上的流量,另一个强制另一个接口上的流量,并且具有使用基于源IP地址的相应路由表的ip规则。 I set it up like this: 我这样设置:

Creating the tables 创建表

First I had to edit /etc/iproute2/rt_tables to add the following lines: 首先,我必须编辑/etc/iproute2/rt_tables以添加以下行:

128    multiplex0
129    multiplex1

This created two routing tables with IDs 128 and 129 called multiplex0 and multiplex1 . 这创建了两个ID为128129路由表,称为multiplex0multiplex1

Adding routes to tables 添加到表的路由

Next I created rules for these tables as follows: 接下来,我为这些表创建了如下规则:

ip route add default via 10.0.2.2 table multiplex0 
ip route add default via 192.168.1.1 table multiplex1

These commands specify the default gateways to use in the routing tables. 这些命令指定要在路由表中使用的默认网关。 My 10.0/16 network had a default gateway of 10.0.2.2 and my 192.168.1/24 network had a default gateway of 192.168.1.1. 我的10.0 / 16网络的默认网关为10.0.2.2,而我的192.168.1 / 24网络的默认网关为192.168.1.1。

What if the two networks had the same default gateway? 如果两个网络具有相同的默认网关怎么办?

I believe you can add dev eth0 (or whatever your interface is) to the above commands to specify an interface if your networks have the same default gateway, though I have not yet tested this. 我相信如果你的网络有相同的默认网关,你可以在上面的命令中添加dev eth0 (或者你的接口是什么)来指定接口,尽管我还没有测试过。 I will make an edit when I learn more. 当我了解更多信息时,我会进行编辑。

EDIT : I have tested this and it does indeed work. 编辑 :我测试了这个,它确实有效。 Both routes can have the same default gateway if you specify the interface in the route. 如果在路由中指定接口,则两个路由都可以具有相同的默认网关。

Source based rules 基于来源的规则

Next I needed to create rules to use these tables: 接下来我需要创建规则来使用这些表:

ip rule add from 10.0.0.0/16 table multiplex0
ip rule add from 192.168.1.1/24 table multiplex1

These rules say that any packet with a source IP in the 10.0/16 range should route based on the rules in multiplex0, while any packet with a source IP in the 192.168.1/24 range should use multiplex1. 这些规则规定,任何源IP为10.0 / 16范围的数据包都应根据multiplex0中的规则进行路由,而源IP为192.168.1 / 24范围的任何数据包都应使用multiplex1。 When the packets use these tables they are directed to the appropriate gateway and corresponding interface. 当数据包使用这些表时,它们被定向到适当的网关和相应的接口。 Viola! 中提琴!

EDIT : It would be more accurate to specify just the IP of the network interface in this step! 编辑 :在此步骤中仅指定网络接口的IP会更准确! If both interfaces are on a 192.168.1/24 network for example, it would be necessary. 例如,如果两个接口都在192.168.1 / 24网络上,则有必要。

Flushing the cache 刷新缓存

Lastly I issued ip route flush cache to make everything take effect and using the ruby code above I was able to open my two sockets on the correct interfaces to the same publicly route-able host. 最后我发布了ip route flush cache以使一切生效并使用上面的ruby代码我能够在正确的接口上打开我的两个套接字到同一个可公共路由的主机。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM