# \[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="/pages/-M79Po4\_iZOkLoPRWzke" %}
[Real-IP Tun Example](/clash/real-ip-tun-example.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://comzyh.gitbook.io/clash/master.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
