V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
yalltd
V2EX  ›  Linux

linux,生成虚拟网卡,指定此虚拟网卡的数据流走向,如何做?

  •  
  •   yalltd · 2015-12-16 18:32:31 +08:00 · 14781 次点击
    这是一个创建于 3266 天前的主题,其中的信息可能已经有所发展或是发生改变。

    ubuntu 系的 OS ,跑几个虚拟机,每个虚拟机需要不同的代理,加上客户机的操作系统有些是偏门 linux 和过时的 XP ,调试不同的代理很麻烦,我想这样:

    [1] 在主机上生成几个虚拟网卡

    [2] 每个虚拟网卡分别设定不同的走向,比如
    vnet0 走 127.0.0.1:10000 ,
    vnet1 走 127.0.0.1:20000,
    vnet2 走 192.168.1.111:1080,
    vnet3 走 172.16.66.123:1024 ……

    [3] 每台虚拟机的网络设定为“桥接”到特定的虚拟网卡,实现该虚拟 OS 全系统走指定代理

    那么问题来了: linux 系统上生成虚拟网卡用什么程序来实现比较好?然后指定每个虚拟网卡的走向又要用什么程序来实现?(本人小白啊)

    谢谢各位大侠

    35 条回复    2016-01-25 08:18:12 +08:00
    billlee
        1
    billlee  
       2015-12-16 19:55:25 +08:00
    你这思路有问题
    应该让主机作为虚拟机的默认网关,用 iptables REDIRECT 来转代理
    不懂网络基础没那么容易做的
    yalltd
        2
    yalltd  
    OP
       2015-12-16 20:18:47 +08:00
    @billlee 确实,我不是科班出身的,网络基础比较欠缺…
    这会搜索了几轮,好像 iptables 是必须要用到的,您可以略微详细的说一下如何“让主机作为虚拟机的默认网关”吗?如果以 VMware 为例,虚拟机的网卡应该是 NAT 还是 host-only ?然后 iptables 的命令该怎么写?
    谢谢
    billlee
        3
    billlee  
       2015-12-16 20:51:50 +08:00   ❤️ 1
    @yalltd host-only
    重定向 TCP 连接到到 127.0.0.1:10000
    iptables -t nat -A PREROUTING -s 虚拟机的 IP -p tcp -j REDIRECT --to-ports 10000
    这里接受连接的代理服务器必须支持 iptables REDIRECT, 才能根据到 REDIRECT 之前目的地址来作代理。
    透明转发到其它主机的代理服务器恐怕不太好做
    raysonx
        4
    raysonx  
       2015-12-16 21:08:25 +08:00
    @billlee 看見樓主貼的其中一個代理服務器使用 1080 端口,我懷疑這些代理服務器是 SOCKS 代理。
    如果真的是 SOCKS 代理的話,就有些麻煩了,因為 SOCKS 畢竟是應用層的協議,直接轉發協議不兼容。

    個人建議,代理僅用於訪問 WEB 或者給個別應用使用,而不要使用代理組網。
    yalltd
        5
    yalltd  
    OP
       2015-12-17 01:07:47 +08:00
    @billlee 我试着运行了“ iptables -t nat -A PREROUTING -s 172.16.52.129 -p tcp -j REDIRECT --to-ports 1200 ”,但是虚拟系统无法上网, firefox 打不开网页, ping 外网也 ping 不通,这个方法可能不行

    然后,添加的这个规则怎么删除??
    yalltd
        6
    yalltd  
    OP
       2015-12-17 01:12:01 +08:00
    @raysonx 是的,是 socks 的代理

    现在的情况是:如果只是访问网页的话,虚拟系统里的浏览器是没有问题的,但是,浏览器之外的软件就很麻烦,我是希望做到整个虚拟机全局走代理,您可以给点建议吗?
    yalltd
        7
    yalltd  
    OP
       2015-12-17 01:26:07 +08:00
    @billlee 等一下,好像有哪里不对。我运行“ iptables --list-rules ”,找不到关于 172.16.52.×的规则,前面运行的那条命令没效?

    别笑我,这是第一次摸索 iptables ,处女摸
    raysonx
        8
    raysonx  
       2015-12-17 01:29:30 +08:00 via iPad   ❤️ 1
    @yalltd
    首先說 SOCKS 協議的限制: SOCKS 代理只支持 TCP 協議, UDP 協議的話需要 SOCK5 才支持。 ping 命令走的是 ICMP 協議,所以不可能 ping 得通的。
    如果非要實現全局走代理的話,需要配置透明代理,你需要一個支持透明代理軟件,配置透明代理比較麻煩。
    如果不涉及機密信息的話,建議題主仔細描述一下場景和需求,讓大家看看除了代理還有沒有其他方案。透明代理是最後的方法。

    刪除那條規則的話,先 iptables -t -L PREROUTING 數一數剛剛插入的規則是第幾條,然後 iptables -t nat -D 序號 刪除。也可以直接重啓防火牆。
    raysonx
        9
    raysonx  
       2015-12-17 01:30:27 +08:00 via iPad
    @raysonx iptables -t nat -L PREROUTING
    yalltd
        10
    yalltd  
    OP
       2015-12-17 03:14:45 +08:00
    @raysonx 运行 iptables -t nat -L PREROUTING 之后显示:
    Chain PREROUTING (policy ACCEPT)
    target prot opt source destination
    REDIRECT tcp -- 172.16.52.129 anywhere redir ports 1200
    REDIRECT udp -- 172.16.52.129 anywhere redir ports 1200

    udp 是我后来加的,没有看到编号,我就试着“ iptables -t nat -D 2 ”先删 udp 那个,但是错误,提示“ iptables: Bad rule (does a matching rule exist in that chain?)”,再试着“ iptables -t nat -D 1 ”还是一样的错误……

    我又试着运行“ iptables -t nat -L PREROUTING --line-number ”,这下看到编号了,就是 1 和 2 ,咋回事?删都不让我删?

    重启防火墙是不是 /etc/init.d/iptables stop 然后 /etc/init.d/iptables start ?如果重启规则就没有了的话,那岂不是每次重启机器都要把那些设置的命令再运行一次?

    摸索一个新东西还是蛮有挑战性的

    那啥,就一门心思的研究如何实现虚拟机全系统的透明代理吧,请您再指点指点:)
    msg7086
        11
    msg7086  
       2015-12-17 06:20:00 +08:00
    1. 删除一条规则就是把加入规则时候的 -I 或者 -A 换成 -D 就是删除了。
    2. 网卡是链路层设备,你的代理是应用层代理,两回事。底层的流量没法直接发往高层。
    3. Linux 自己就可以处理网卡生成。虚拟 IP 虚拟网卡都可以做。
    raysonx
        12
    raysonx  
       2015-12-17 09:36:26 +08:00 via Android
    @yalltd iptables -t nat -D PREROUTING 編號
    我漏了那個 PREROUTING 的名字。
    規則你要保存的話。要用
    service iptables save
    datocp
        13
    datocp  
       2015-12-17 09:54:46 +08:00 via Android
    stunnel 有个 socks vpn 透明代理实现,可以说所有的透明代理实例都没配置成功过。

    参考别人的 vpn 分流,差不多花了半个月才解决,很多文档转载转载再转载,很多关键步骤都遗漏了,这篇文档的 systl.conf 和 MASQUERADE 也是零星散步在网络论坛讨论中。
    http://aftermanict.blogspot.it/2015/11/bash-iptables-iproute2-and-multiple.html
    raysonx
        14
    raysonx  
       2015-12-17 12:57:41 +08:00
    用代理組網本身是一種很骯髒方式,樓主去搜一下有哪些好的透明代理吧。
    而建議的方式是配置多個網關,由路由規則指定走向。
    yalltd
        15
    yalltd  
    OP
       2015-12-17 15:06:22 +08:00
    @msg7086 Linux 自己就可以处理网卡生成。虚拟 IP 虚拟网卡都可以做
    怎么实现的?命令行还是改配置文件?
    msg7086
        16
    msg7086  
       2015-12-17 15:11:24 +08:00
    @yalltd 都可以。
    但是这要看你用的是哪个发行版了。不同发行版的配置方法都不一样的。
    yalltd
        17
    yalltd  
    OP
       2015-12-17 16:25:28 +08:00
    @msg7086 我现在的系统是 ubunt14.04 ,命令行怎么做?
    yalltd
        18
    yalltd  
    OP
       2015-12-17 16:33:11 +08:00
    @datocp 反复看了两遍,还是没抓住内涵,那些 iptables 的命令我看的云里雾里……但是好像他里面也出现了 tun ,我昨晚也搜到了 tun/tap 的东西,好像有我想要的,但是英文的东西看着累……
    yalltd
        19
    yalltd  
    OP
       2015-12-17 16:36:09 +08:00
    @raysonx 全局的透明代理我现在只搜到一个 Stunnel ,可以用它吗?
    billlee
        20
    billlee  
       2015-12-17 21:34:54 +08:00
    @yalltd redsocks 可以支持 iptables REDIRECT, 印象中 shadowsokcs-android 用的就是这个
    UDP 理论上 netfilter 的 TPROXY 可以支持,但是好像没见过有相关的用户空间程序。
    yalltd
        21
    yalltd  
    OP
       2015-12-18 03:29:39 +08:00
    @billlee 在 host 上安装 redsocks 然后配置 iptables REDIRECT ?
    msg7086
        22
    msg7086  
       2015-12-18 04:01:47 +08:00
    #18 @yalltd 因为这东西本来就很边缘啊。
    一个网卡流过一个 socks ,其实就是开着 socks 跑 openvpn 代理嘛。
    加虚拟网卡就是加 tun/tap 设备(然而这又是更复杂的课题了)。

    #17 加 IP 倒是简单,自己看看 ip a 命令吧。
    加网卡可以试试 ip l 命令。
    datocp
        23
    datocp  
       2015-12-18 10:40:22 +08:00
    基础太差。。。很多东西理解起来也困难。

    原先就是看了这篇文档以为很简单,结果还是有很多特定环境的限制,包括 ipv4+ipv6 环境,服务器不支持 ip6tables -t nat ,需要禁用 AAAA 查询,还包括 iproute2 的一些无底坑,这些坑在官方文档中都没有任何提及。
    OpenWrt VPN 按域名路由
    https://blog.sorz.org/p/openwrt-outwall/

    redsocks2 原先在 openwrt 下面配置成功过,可是 vps 。。。反正在透明代理这块基本上网上能找到的实例,命令打一遍最终没效果,也不知道坑在哪里。。。

    所以最终用 softether vpn ,这东东无比的强大,它本身就有虚拟网卡实现,最终基本甚至没用到任何的虚拟 L3 路由功能。目前实现的效果就是 就近访问日本 vps , vps 中一部分 youtube 流量中转的是美国 vps 上的流量,所以跟你想要实现的效果差不多。自己多试几遍吧,回头看看还是挺简单的,但是可扩展效果比透明代理好多了。实例虽然是用 dnsmasq ipset 特定域名,其实可以实现建立 ipset -N outwall4 nethash ,然后直接写路由表。

    vpn 采用 softether vpn server
    服务器端
    创建虚拟 HUB server/管理虚拟 HUB/并添加用于客户端连接用的 管理用户
    本地网桥设置 /将虚拟 HUB server 选择创建的类型 新 tap 设备的桥接,并输入设备名称 soft1
    ifconfig tap_soft1 192.168.60.100
    ifconfig tap_soft1 mtu 1392
    添加 ipv6 地址,只是为了以后不需要改动服务器配置所以固定一个地址
    ip address add fe80::4ac:20ff:fe9c:1000/128 dev tap_soft1
    #ip address del fe80::4ac:20ff:fe9c:1000/128 dev tap_soft1

    客户端
    创建虚拟 HUB client/管理虚拟 HUB/管理级联连接 创建到服务器端的连接
    本地网桥设置 /将虚拟 HUB client 选择创建的类型 新 tap 设备的桥接,并输入设备名称 soft1
    ifconfig tap_soft1 192.168.60.200
    ifconfig tap_soft1 mtu 1392
    #ip address add fe80::4ac:20ff:fe9c:2000/128 dev tap_soft1
    #ip address del fe80::4ac:20ff:fe9c:2000/128 dev tap_soft1

    如果能互相 ping 通 vpn 连接已经没有任何问题。
    ping 192.168.60.100
    ping6 -I tap_soft1 fe80::4ac:20ff:fe9c:1000


    * 2015 年 12 月 14 日星期一
    - [bash] iptables iproute2 and multiple routes
    http://aftermanict.blogspot.it/2015/11/bash-iptables-iproute2-and-multiple.html
    - 今天按这篇文档一路设置下来第一次用 fwmark 成功设置路由,由于服务器并没有 ip6table_nat 模块,所以仅能使用 iptable_nat
    - 另外似乎设置的 set-mark 3 和原先的 QOS 标记有冲突,只有在 iptables -t mangle -F 清空原先的标记时才有效果,应该是能解决的
    - 这次设置最成功的地方在于不会有 vpn 客户端拔号时出现因为接口的问题而无法访问网络
    - 另外第一次注意到 iptabes 的全局 ACCEPT 并不是万能的,像此例必须指定特定接口的 MASQUERADE 才可以成功。
    /etc/sysctl.conf
    net.ipv4.conf.default.rp_filter = 2
    net.ipv4.conf.all.rp_filter = 2
    net.ipv4.ip_forward = 1

    for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 >| $f ; done

    iptables -I OUTPUT -o eth0 -p udp --dport 53 -m string --hex-string "|07|youtube|03|com|00001c|" --algo bm -j DROP

    dnsmasq.conf
    ipset=/youtube.com/outwall4,outwall6

    iptables-restore /da/fw
    ipset destroy outwall6
    ipset -N outwall6 iphash family inet6
    ipset destroy outwall4
    ipset -N outwall4 iphash

    ##echo "200 outwall" >> /etc/iproute2/rt_tables
    ipset -L outwall4 >/tmp/outwall4.tmp
    for i in `sed -n "7,$ p" /tmp/outwall4.tmp`;do echo $i;ipset -D outwall4 $i;done
    kill -HUP $(pidof dnsmasq)
    nslookup www.youtube.com
    nslookup m.youtube.com
    nslookup youtube.com
    #ipset 需要 dnsmasq 通过本地像 192.168.40.253:53 进行查询,直接外部 dns 服务器会没结果
    ipset -L outwall4
    iptables -t mangle -D PREROUTING -m mark --mark 0x0/0xff00 -m set --match-set outwall4 dst -j MARK --set-xmark 0xfe00/0xff00
    iptables -t mangle -D OUTPUT -m mark --mark 0x0/0xff00 -m set --match-set outwall4 dst -j MARK --set-xmark 0xfe00/0xff00
    iptables -t mangle -I PREROUTING 2 -m mark --mark 0x0/0xff00 -m set --match-set outwall4 dst -j MARK --set-xmark 0xfe00/0xff00
    iptables -t mangle -I OUTPUT -m mark --mark 0x0/0xff00 -m set --match-set outwall4 dst -j MARK --set-xmark 0xfe00/0xff00
    ##ip route add 192.168.40.0/24 via 192.168.30.254 dev tap_soft
    ip route flush table outwall
    ip route add default via 192.168.30.254 dev tap_soft table outwall
    #ip route add 192.168.40.0/24 via 192.168.30.254 dev tap_soft table outwall
    ip rule del table outwall
    ip rule add fwmark 0xfe00/0xff00 table outwall prio 1
    #ip rule add from 192.168.50.0/24 table outwall prio 1
    ip route flush cache

    iptables -t nat -F POSTROUTING
    iptables -t nat -A POSTROUTING -o vpns+ -j MASQUERADE
    iptables -t nat -A POSTROUTING -o tap_soft -j MASQUERADE
    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE


    - 调整了原先的 qos 标记为 0x00/0xff ,路由标记为 0xfe00/0xff00,如果标记为 0xff00/0xff00 则变为 or 标记。注意使用 iptables -I 将规则放在最前面。有关 iptables xmark 的描述看不懂,有人说可以把不同的 mask 看成是 subnet 。
    - qos-scripts currently uses the last 8 bits to mark traffic e.g.-j MARK --set-xmark 0x44/0xff
    whereas multi-wan uses the next 8 bits (0xff00) to mask its marks:


    yalltd
        24
    yalltd  
    OP
       2015-12-18 12:10:27 +08:00
    @datocp 看不懂……泪崩……
    yalltd
        25
    yalltd  
    OP
       2015-12-18 12:28:35 +08:00
    @msg7086 您说到点子上了!~

    通过 socks 连 openvpn 好办,但是通过 socks 连 softether vpn 真不好办!一次都没成功过!所以想设计这样一个情况:虚拟机里的 softether vpn 去连服务器的时候是已经走在 socks 里面的了,虚拟机套虚拟机说不定可以,但是这样的效率肯定惨不忍睹……
    datocp
        26
    datocp  
       2015-12-18 12:57:08 +08:00
    先把这两篇基础的搞定,对 softether 就有个大概的了解。不懂为什么 softether 外面又有一层 socks 连接。如果用 vpn ,你原先的环境就要变化,按现在的设想是有个网关设备,统一将不同的代理服务器连接到本地虚拟机操作系统里的虚拟接口 soft soft1 soft2 soft3 ,然后用策略路由#ip rule add from 192.168.50.0/24 table outwall prio 1 或者干脆把相应的接口直接安装到特定的虚拟机里,原则上 xp 也是没问题的,太古董了没操作过。。。 linux ip route 策略路由不怎么熟悉,大体是这样。 softether 我已经好久没在国内网络用过了,担心穿墙时是否会被挡。

    Softether on VPS Using Local Bridge
    http://blog.lincoln.hk/blog/2013/05/17/softether-on-vps-using-local-bridge/
    Build a LAN-to-LAN VPN (Using L3 IP Routing)
    https://www.softether.org/4-docs/1-manual/A._Examples_of_Building_VPN_Networks/10.6_Build_a_LAN-to-LAN_VPN_(Using_L3_IP_Routing)
    yalltd
        27
    yalltd  
    OP
       2015-12-18 13:45:45 +08:00
    @datocp softether 和 openvpn 都是被 GFW 盯的死死的啊,不套一层加密的 socks 不可能连接成功啊

    openvpn 本身就可以设置 socks 代理或者 http 代理,大部分时候设置对了就可以成功连接,但是 softether 就讨厌了,他程序里虽然也有设置代理的地方,但是我从来没有成功过,即使设置了代理,连接某个服务器的时候是不是走代理都完全不是我能控制的,所以我才想到把要连接的那台虚拟机的网卡整个走代理以确定 softether 走上代理了……
    raysonx
        28
    raysonx  
       2015-12-18 14:33:44 +08:00
    @yalltd
    我又來了。。。
    樓主我覺得你真心沒有必要去折騰什麼透明代理,這些本來就不是什麼好的組網方案。
    如果是為了科學上網的話,建議在母機上配置 VPN ,然後用路由規則指定虛擬機網絡的路由。
    yalltd
        29
    yalltd  
    OP
       2015-12-18 16:23:43 +08:00
    @raysonx “用路由規則指定虛擬機網絡的路由”---完全不懂怎么搞路由……
    raysonx
        30
    raysonx  
       2015-12-18 18:21:00 +08:00
    @yalltd 路由其實是很簡單的東西,一條最簡單的路由就是「地址段,下一跳路由器的 IP ,連著哪張網卡」,而且這些「正統」的方法要比透明代理等「非主流」的方法容易得多。
    用代理組網的問題是,通過代理服務器後,虛擬機的原始地址被隱藏了,破壞了端到端的透明性,更不用說你的代理可能只支持 TCP 協議了。破壞這種透明性後,舉個例子,如果你要在虛擬機裡面運行一個 HTTP 服務器,想對外開放 80 端口,就需要搞端口穿透,這會異常的麻煩。當然我扯的成分比較多,樓主應該用不到這些。
    msg7086
        31
    msg7086  
       2015-12-22 04:40:53 +08:00
    很不巧的是,时隔 3 天后我也遇到了同样的需求。
    回头如果我们实作出办法以后会再来回报。
    yalltd
        32
    yalltd  
    OP
       2015-12-25 00:29:16 +08:00
    @raysonx 唉,我不需要什么端到端的透明性,我只需要实现虚拟系统全部走上代理...不透明更好...
    用路由命令可以实现指定某个虚拟网卡走本地的某个端口吗?
    yalltd
        33
    yalltd  
    OP
       2015-12-25 00:29:50 +08:00
    @msg7086 静侯佳音
    msg7086
        34
    msg7086  
       2016-01-25 05:50:20 +08:00
    我们现在的功能需求是,需要从客户端直接访问服务器上监听的某个任意 IP 的任意端口。
    现在是客户端和服务器用 OpenVPN 互联,然后把某个私有段路由到 OVPN 的对端,然后在用 iptables 做转发规则,转发到私有段上。

    感觉和你 32 楼的要求还是有点不同。
    但是你这实在不行的话可以试试 OpenVPN through Socks Proxy 的做法,让 OVPN 走 Socks 代理。
    yalltd
        35
    yalltd  
    OP
       2016-01-25 08:18:12 +08:00   ❤️ 1
    @msg7086 恩,现在我主要就是用的 OpenVPN through Socks Proxy 的做法。很奇怪,最早我都是用的 VMWare ,基本上 OpenVPN through Socks Proxy 很难连接成功,同一时刻同一个 OVPN 的配置文件和同一个 socks 代理, xp 的虚拟机下面可以连接成功,但是 win7 以上以及 linux 系统全部不成功,基本上都是 tls 错误……某天我突然想试试 Vbox ,没想到 Vbox 竟然这么听话好用不折腾,只要去连接基本上都是成功的……现在电脑的 VMWare 就等着被删了~~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   950 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 22:43 · PVG 06:43 · LAX 14:43 · JFK 17:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.