---
description: The working in progess tun mode by comzyh
---

# \[WIP]Tun

## 简介

[Clash ](https://github.com/Dreamacro/clash)PR [#393](https://github.com/Dreamacro/clash/pull/393) 是一个正在实现中的 Tun 模式。

Tun 模式可以通过新建一个  Tun 虚拟网卡接受操作系统的三层流量，从而拓展 Clash 入口（inbound) 转发能力。Tun 模式有以下潜在的优点：

* 提升 Clash 处理 UDP 的能力
* 从Inbound发回三层流量时，IP 源地址可由 Clash 控制
  * 因此在使用 socks5或shadowsoks协议时，可以表达 socks5/ss 协议发回的 UDP 流量中不同的源IP地址
  * 因此，有可能通过 OutBound 代理实现 STUN
  * 因此，对在代理条件下很多游戏的体验会有提升
* 可以劫持任何三层流量，Clash 可以在任何IP地址和任何端口提供某些服务，非常灵活
  * 因而可以实现 DNS 劫持
* 可以与操作系统的网络栈结合，利用 iptables 等组件的能力

## 实现

Tun 模式的核心问题有两个：

1. 使用操作系统的 API 建立 Tun NIC（Network Interface Card），得到 IP Packet
2. 由三层IP Packet 重组传输层 TCP stream / UDP Packet，交由 Clash 进行转发

其中，创建 NIC 并得到三层网络包可以由一系列系统调用实现。而由三层流量重组四层流量需要用户态网络栈。因为 Clash 使用 Go 语言，PR393 使用了 [gvisor ](https://github.com/google/gvisor/tree/go/pkg/tcpip)的网络栈。gvisor 的网络栈前身是 [netstack](https://github.com/google/netstack) 。

## 配置

启用 Tun 模式需要在 Clash 配置文件中加入 `tun` 字段。

```yaml
tun:
  enable: true
  device-url: dev://utun # macOS
# device-url: dev://clash0 # Linux
# device-url: fd://5 # Linux
  dns-listen: 0.0.0.0:53  # additional dns server listen on TUN
```

`enable` 决定 Tun 是否开启

`device-url` 控制 Tun NIC 的相关参数。`dev://IfName` 控制操作系统中网卡的名称，Linux 下可以为任何长度不超过16的英文，MacOS 下则必须设置为 `dev://utun`，实际生成的 NIC 名可能是 utun0-utun9，由MacOS决定。

{% hint style="info" %}
在MacOS 下请不要将 `device-url` 后主动加入数字。例如 \`dev://utun1
{% endhint %}

`dns-listen` 控制 Tun 模式下额外 DNS 服务器的行为。IP 地址决定 DNS 服务器监听的地址，若设置为`0.0.0.0` 则劫持所有 IP 地址。

## Linux 使用

### 编译

有能力的用户建议自行编译 PR #393 运行。为了方便，[这里](https://github.com/comzyh/clash/releases)提供一些编译好的可执行文件供下载。

### &#x20;自动创建NIC

如果 device-url 指定的网卡不存在，Clash 将会尝试创建网卡。如果想要由Clash 创建网卡，则必须满足以下二者条件之一

* clash 运行在 root 用户下
* clash 获得 CAP\_NET\_ADMIN 特权能力

可以用以下命令给 Clash 可执行文件添加 CAP\_NET\_ADMIN  能力：

```bash
sudo setcap cap_net_admin+ep ss-compose/clash/clash-linux-amd64
```

可以用 `getcap` 命令验证

```bash
getcap clash-linux-amd64
```

应返回

> clash-linux-amd64 = cap\_net\_admin+ep

### 提前创建NIC（推荐） <a href="#create-nic-ahead" id="create-nic-ahead"></a>

很多情况下，我们不希望 clash 可执行文件以 root 身份运行。而且我们经常会给 Clash Tun NIC 配置一些路由表/IP Rules 等。我们不希望 Clash 停止运行后重新设置这些配置，那么可以提前手动创建 Tun NIC。假设我们希望 clash 运行在 alice 用户下。那么我们可以创建 `utun` NIC 并将其 Owner 设置为  alice，这样 Clash 就可以使用这块虚拟网卡了。

```bash
sudo ip tuntap add mode tun user alice name utun
sudo ifconfig utun up
```

{% hint style="warning" %}
Clash 启动 Tun 前，请确保相应的 NIC 处于 UP（工作） 状态
{% endhint %}

Clash 使用的 Tun NIC 在 Linux 下并不需要设置 IP 地址。是否设置 IP 地址**不影响** Clash Tun 模式的工作。

### 将流量导入 Clash

用户需要配置**路由表**使得流量被导入到 Tun NIC。

PR393 的 Tun 模式可以工作在 Fake-IP 模式下，也可以接受真实 IP 地址（Real-IP)。其中 Fake-IP 模式配置**简单**。而 Real-IP 模式使用真实 IP地址则需要比较**复杂**的配置过程，但是其工作状态最接近真实网络环境，兼容性好。有些应用如游戏/OneDrive/STUN 等应用只能使用真实 IP 进行连接，则必须使用 RealIP 模式。

如果使用 FakeIP模式，假设网段位 `198.18.0.0/16`可以添加路由将该 Fake-IP 网段的流量发向 Clash Tun:

```bash
sudo route add -net 198.18.0.0/16 dev utun
```

Real-IP 模式比较复杂，同 Clash Redir 模式类似需要解决流量回环问题。这里提供一配置案例。

{% content-ref url="real-ip-tun-example" %}
[real-ip-tun-example](real-ip-tun-example)
{% endcontent-ref %}
