AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 407214
Accepted
ilyaigpetrov
ilyaigpetrov
Asked: 2017-11-27 22:11:52 +0800 CST2017-11-27 22:11:52 +0800 CST 2017-11-27 22:11:52 +0800 CST

如何在 Linux 中让所有流量通过一个接口

  • 772

我有一个自写的接口 tun0(基于TUN/TAP),它输出它接收到的内容。
我需要系统的所有流量都流过这个接口。
接口的作用是:

  1. 找出可能被审查的数据包并通过隧道传输它们。
  2. 通过所有其他交通不受影响。

正如你猜想的那样,我正在尝试构建一个反审查工具。
关于隧道的决定必须在 tun0 进程内进行,
因为只有在那里我们才能使用受信任的 DNS。

我需要你的帮助来告诉我如何让所有的流量通过一个自写的接口 tun0。如果 tun0 需要更改,我要求您提供此类更改。

以下是我如何尝试让所有流量通过 tun0 并失败(ping 失败)。

编译

  1. gcc tun0.c
  2. sudo ./a.out

配置

  1. sudo ip addr add 10.0.0.1/24 dev tun0
  2. 创建表约翰

    $ cat /etc/iproute2/rt_tables 
    #
    # reserved values
    #
    255     local
    254     main
    253     default
    0       unspec
    #
    # local
    #
    #1      inr.ruhep
    
    200 John
    

顺序很重要:

  1. sudo ip rule add from all lookup John
  2. sudo ip route add default dev tun0 table John
  3. sudo ip rule add iif tun0 lookup main priority 500

    $ ip rule
    0:      from all lookup local 
    500:    from all iif tun0 lookup main 
    32765:  from all lookup John 
    32766:  from all lookup main 
    35000:  from all lookup default 
    

故障排除

  1. sudo tcpdump -i wlp2s0 -qtln icmp然后ping -I tun0 8.8.8.8显示没有捕获到数据包,这意味着没有数据包通过iif tun0 lookup main规则从 tun0 传输到 wlp2s0。

  2. 当我替换tun0为lo到处时,它对我有用。

也试过

  1. 关闭反向路径过滤,rp_filter=0在/etc/sysctl.conf

解答疑难解答

iptables -I FORWARD -j LOG --log-prefix "filter/FORWARD " 
iptables -t nat -I OUTPUT -j LOG --log-prefix "nat/OUTPUT " 
iptables -t nat -I PREROUTING -j LOG --log-prefix "nat/PREROUTING " 
iptables -t nat -I POSTROUTING -j LOG --log-prefix "nat/POSTROUTNG "
tail -f /var/log/syslog

来自答案的修改来源也在这里。

linux iptables
  • 1 1 个回答
  • 8807 Views

1 个回答

  • Voted
  1. Best Answer
    tifssoft
    2017-11-30T17:31:26+08:002017-11-30T17:31:26+08:00

    因此,在您的配置中,您尝试发送到网络的所有数据包最初都来自10.0.0.1(因为它们正在通过tun0接口并且其本地地址是10.0.0.1)。你捕获数据包,到目前为止一切都很好。
    现在,tun0进一步发送数据包。源地址是10.0.0.1并且您希望数据包通过不同的接口(wlp2s0在您的情况下)离开。这就是路由,所以让我们先启用路由:

    sysctl -w net.ipv4.ip_forward=1
    

    在那之后,如果你看一下tcpdump,wlp2s0你会注意到数据包离开的是源地址10.0.0.1,而不是 wlan 接口的源地址(我猜是你所期望的)。所以我们需要更改源地址,它被称为源 NAT。在 linux 中,借助netfilter/iptables很容易:

    iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.1 -j MASQUERADE
    

    还请检查您的FORWARD连锁店是否有ACCEPT政策,或者您需要允许转发,例如:

    iptables -A FORWARD -i tun0 -o wlp2s0 -s 10.0.0.1 -j ACCEPT
    iptables -A FORWARD -i wlp2s0 -o tun0 -d 10.0.0.1 -j ACCEPT
    

    现在一切都应该正常工作了:Linux 内核进行路由,它将数据包从tun0接口移动到wlp2s0. netfilter应该将源 IP 更改10.0.0.1为您wlp2s0为输出数据包分配的接口地址。它会记住所有连接,并且当回复数据包返回时(如果有),它会将wlp2s0分配地址的接口的目标地址更改为10.0.0.1(“conntrack”功能)。
    嗯,它应该,但它没有。看起来,netfilter对这种复杂的路由配置以及同一个数据包首先通过OUTPUT链然后被路由并进入PREROUTING链的事实感到困惑。至少在 Debian 8 机器上它不起作用。
    排除netfilter 故障的最佳方法是该TRACE功能:

    modprobe ipt_LOG
    iptables -t raw -A OUTPUT -p icmp -j TRACE
    iptables -t raw -A PREROUTING -p icmp -j TRACE
    

    我只启用了对 ICMP 数据包的跟踪,您可以使用其他过滤器进行调试。
    它将显示数据包经过哪些表和链。而且我可以看到数据包没有进一步进入FORWARD链(并且它没有被nat/POSTROUTING实际执行的链捕获SNAT)。
    以下是实现这项工作的几种方法。

    方法#1

    消除netfilter混淆的最好方法是在应用程序中更改数据包的源 IP 地址tun0.c。这也是最自然的方式。我们需要在向外的路上将 10.0.0.1 更改为 10.0.0.2 ,在返回的路上将 10.0.0.2 更改为 10.0.0.1。
    我已经修改tun0.c了源地址更改代码。这是新文件,这是您的tun0.c. IP 标头的更改还涉及校验和校正,因此我从OpenVPN 项目中获取了一些代码。以下是我在干净重启和启动后执行的完整命令列表 tun0_changeip.c:

    ifconfig tun0 inet 10.0.0.1/30 up
    sysctl -w net.ipv4.ip_forward=1
    ip route add default dev tun0 table John
    ip rule add from all lookup John
    ip rule add from 10.0.0.2 lookup main priority 500
    iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.2 -j MASQUERADE
    

    请注意,在这种情况下您不需要关闭反向路径过滤,因为一切都是合法的 -tun0只接收和发送属于其子网的数据包。您也可以执行基于源的路由而不是基于接口的路由。

    方法#2

    可以SNAT在数据包到达tun0接口之前执行此操作。但这不是很正确。在这种情况下,您肯定需要关闭反向路径过滤:

    sysctl -w net.ipv4.conf.tun0.rp_filter=0
    # It won't work without also changing the "all" value
    sysctl -w net.ipv4.conf.all.rp_filter=0
    

    现在,做SNAT: iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source ip.address.of.your.wlan.interface

    在这里,我们在数据包到达设备之前更改源地址tun0。tun0.c代码“按原样”重新发送这些数据包(更改了源地址),它们通过 wlan 接口成功路由。但是您可能在 wlan 接口上有一个动态 IP 并且想要使用MASQUERADE(为了不明确指定接口地址)。以下是您可以使用的方法MASQUERADE:

    iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source 10.0.55.1
    iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.55.1 -j MASQUERADE
    

    请注意“ 10.0.55.1” IP 地址 - 它是不同的。你可以在这里使用任何IP,没关系。如果我们之前更改源 IP,数据包会在接口上到达nat/POSTROUTING链。wlp2s0现在它不依赖于 wlan 接口的静态 IP。

    方法#3

    您也可以使用fwmark. 这样你就不需要SNAT,但你只会捕获传出的数据包:
    首先我们需要禁用反向路径过滤,tun0因为它会转发属于另一个网络的数据包:

    sysctl -w net.ipv4.conf.tun0.rp_filter=0
    # It won't work without also changing the "all" value
    sysctl -w net.ipv4.conf.all.rp_filter=0
    
    Now let's alter the routing rules a bit:
    # Delete old rules
    ip rule del iif tun0 lookup main
    ip rule del from all lookup John
    
    # Packets will start going from wlan interface so they will have source address of it
    iptables -t mangle -A OUTPUT -o wlp2s0 -j MARK --set-mark 1
    ip rule add fwmark 0x1 lookup John
    

    这是在我的 Debian 8 机器上工作的路由和网络过滤器的另一个“hack” ,但我仍然建议采用第一种方法,因为它更自然并且不使用任何 hack。


    您也可以考虑将您的应用程序构建为透明代理。我认为这比分析来自 tun 设备的数据包要容易得多。

    • 10

相关问题

  • 有没有办法让 ls 只显示某些目录的隐藏文件?

  • 使用键盘快捷键启动/停止 systemd 服务 [关闭]

  • 需要一些系统调用

  • astyle 不会更改源文件格式

  • 通过标签将根文件系统传递给linux内核

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    JSON数组使用jq来bash变量

    • 4 个回答
  • Marko Smith

    日期可以为 GMT 时区格式化当前时间吗?[复制]

    • 2 个回答
  • Marko Smith

    bash + 通过 bash 脚本从文件中读取变量和值

    • 4 个回答
  • Marko Smith

    如何复制目录并在同一命令中重命名它?

    • 4 个回答
  • Marko Smith

    ssh 连接。X11 连接因身份验证错误而被拒绝

    • 3 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Marko Smith

    systemctl 命令在 RHEL 6 中不起作用

    • 3 个回答
  • Marko Smith

    rsync 端口 22 和 873 使用

    • 2 个回答
  • Marko Smith

    以 100% 的利用率捕捉 /dev/loop -- 没有可用空间

    • 1 个回答
  • Marko Smith

    jq 打印子对象中所有的键和值

    • 2 个回答
  • Martin Hope
    EHerman JSON数组使用jq来bash变量 2017-12-31 14:50:58 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Drux 日期可以为 GMT 时区格式化当前时间吗?[复制] 2017-12-26 11:35:07 +0800 CST
  • Martin Hope
    AllisonC 如何复制目录并在同一命令中重命名它? 2017-12-22 05:28:06 +0800 CST
  • Martin Hope
    Steve “root”用户的文件权限如何工作? 2017-12-22 02:46:01 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST
  • Martin Hope
    Cbhihe 将默认编辑器更改为 vim for _ sudo systemctl edit [unit-file] _ 2017-12-03 10:11:38 +0800 CST
  • Martin Hope
    showkey 如何下载软件包而不是使用 apt-get 命令安装它? 2017-12-03 02:15:02 +0800 CST
  • Martin Hope
    youxiao 为什么目录 /home、/usr、/var 等都具有相同的 inode 编号 (2)? 2017-12-02 05:33:41 +0800 CST
  • Martin Hope
    user223600 gpg —list-keys 命令在将私钥导入全新安装后输出 uid [未知] 2017-11-26 18:26:02 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve