绑定到 ruby​​ 中的网络接口 [英] Binding to networking interfaces in ruby

查看:46
本文介绍了绑定到 ruby​​ 中的网络接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在 linux 中不同网络接口上的 ruby​​ 应用程序中打开多个套接字.例如,假设我有一个 IP 为 192.168.1.2 的接口 eth0 和 IP 地址为 10.0.0.2 的接口 wlan0.我想同时连接到每个接口上都有一个套接字的服务器.我认为绑定到这些接口的 IP 地址会起作用,但情况似乎并非如此.在wireshark 中,当我绑定到wlan0 的IP 时,我成功地看到了使用正确源IP 发送的SYN 数据包,但wireshark 在eth0 上看到它们并且套接字从未打开.

I'm trying to open multiple sockets in a ruby application on different network interfaces in linux. 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. 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. 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.

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

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

这是我当前的代码.我还尝试了 Socket 的 ruby​​-doc 页面上记录的 Addrinfo 方法,结果相同.

Here is my current code. I have also tried the Addrinfo method documented on the ruby-doc page for Socket with the same results.

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)

感谢您的帮助!

推荐答案

解决方案是基于源的路由

我能够弄清楚,并认为我应该留下我的答案,以防其他人在此过程中遇到这个问题.

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.

我需要做的是基于源的路由.总体思路是创建两个路由表,一个在一个接口上强制流量,一个在另一个接口上强制流量,并有一个 ip 规则,根据源 IP 地址使用适当的路由表.我是这样设置的:

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. I set it up like this:

首先我必须编辑 /etc/iproute2/rt_tables 以添加以下几行:

First I had to edit /etc/iproute2/rt_tables to add the following lines:

128    multiplex0
129    multiplex1

这创建了两个 ID 为 128129 的路由表,分别称为 multiplex0multiplex1.

This created two routing tables with IDs 128 and 129 called multiplex0 and multiplex1.

接下来我为这些表创建了如下规则:

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

这些命令指定要在路由表中使用的默认网关.我的 10.0/16 网络的默认网关为 10.0.2.2,我的 192.168.1/24 网络的默认网关为 192.168.1.1.

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.

我相信您可以将 dev eth0(或任何您的接口)添加到上述命令中以指定一个接口,如果您的网络具有相同的默认网关,尽管我尚未对此进行测试.我会在了解更多信息后进行编辑.

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. 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.

接下来我需要创建规则来使用这些表:

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

这些规则表明,源 IP 在 10.0/16 范围内的任何数据包都应根据 Multiplex0 中的规则进行路由,而源 IP 在 192.168.1/24 范围内的任何数据包都应使用 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. When the packets use these tables they are directed to the appropriate gateway and corresponding interface. Viola!

EDIT:在这一步中只指定网络接口的 IP 会更准确!例如,如果两个接口都在 192.168.1/24 网络上,则这是必要的.

EDIT: It would be more accurate to specify just the IP of the network interface in this step! If both interfaces are on a 192.168.1/24 network for example, it would be necessary.

最后,我发布了 ip route flush cache 以使一切生效,使用上面的 ruby​​ 代码,我能够在正确的接口上打开我的两个套接字到同一个可公开路由的主机.

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.

这篇关于绑定到 ruby​​ 中的网络接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆