2 个不稳定版本
0.2.0 | 2023 年 8 月 13 日 |
---|---|
0.1.0 | 2023 年 8 月 13 日 |
#1386 in 网络编程
78KB
1.5K SLoC
wgslirpy
一个用于在 Wireguard 链接内接受传入连接并将其通过操作系统常规套接字 API 路由到外部网络的命令行工具(以及一个 Rust 库)。
这允许在不具有 root 访问权限的情况下创建 VPN 服务器,例如从 Android 应用或在使用非特权容器时。
特性
- 使用 Boringtun 库与一个对等体维护 Wireguard 连接。
- 使用 smoltcp 库解码传入的 TCP 或 UDP 连接。
- 将 Wireguard 中的 TCP 和 UDP 连接转发到外部世界,交换用户空间和真实套接字的流量。
- 对于 UDP,应该可以实现打洞/NAT穿越(尚未测试)
- 对于 TCP,半关闭连接和背压应该工作
- 一个粗略的 DNS 服务器,用于使用主机 DNS 实现解析 IPv4 和 IPv6 地址
限制
- 没有 ICMP(除了针对特定地址的 ping 测试)。这会影响 UDP 的“端口不可达”。
演示会话
设置
peer# wg genkey
4Khaa5tgPI9NJsO2R896Yd6748k9fW4aapGZnIcUM14=
peer# wg pubkey <<< 4Khaa5tgPI9NJsO2R896Yd6748k9fW4aapGZnIcUM14=
rPpCjWzIv/yAtZZi+C/pVprie8D0QaGlPtJXlDi6bmI=
gateway$ wg genkey
SG43Zi0wGp4emfJ/XpTnnmtnK8SSjjIHOc3Zh37c928=
gateway$ wg pubkey <<< SG43Zi0wGp4emfJ/XpTnnmtnK8SSjjIHOc3Zh37c928=
MR2RF5Tp+6BKt9k+deKg1GqR3re3ckJKti+uwZA84DU=
peer# ip link add wgslirpyspeer type wireguard
peer# wg set wgslirpyspeer listen-port 9796 private-key <(echo 4Khaa5tgPI9NJsO2R896Yd6748k9fW4aapGZnIcUM14=) peer MR2RF5Tp+6BKt9k+deKg1GqR3re3ckJKti+uwZA84DU= allowed-ips 0.0.0.0/0,::/0
peer# ip netns add testing-wgslirp
peer# ip link set wgslirpyspeer netns testing-wgslirp
peer# ip netns exec testing-wgslirp ip link set wgslirpyspeer up
peer# ip netns exec testing-wgslirp ip addr add 192.168.76.1/32 dev wgslirpyspeer
peer# ip netns exec testing-wgslirp ip addr add fc00::01/128 dev wgslirpyspeer
peer# ip netns exec testing-wgslirp route -4 add default dev wgslirpyspeer
peer# ip netns exec testing-wgslirp route -6 add default dev wgslirpyspeer
peer# mkdir -p /etc/netns/testing-wgslirp
peer# echo nameserver 192.168.72.2 > /etc/netns/testing-wgslirp/resolv.conf
激活
gateway$ RUST_LOG=debug wgslirpy --private-key SG43Zi0wGp4emfJ/XpTnnmtnK8SSjjIHOc3Zh37c928= -b 127.0.0.1:9797 --peer-key rPpCjWzIv/yAtZZi+C/pVprie8D0QaGlPtJXlDi6bmI= --keepalive-interval 10 --dns 192.168.72.2:53 --pingable 192.168.72.2
DEBUG boringtun::noise: Sending handshake_initiation
DEBUG boringtun::noise: Received handshake_response local_idx=1 remote_idx=2743606023
DEBUG boringtun::noise: New session session=1
DEBUG boringtun::noise: Sending keepalive
peer# ip netns exec testing-wgslirp wg
interface: wgslirpyspeer
public key: rPpCjWzIv/yAtZZi+C/pVprie8D0QaGlPtJXlDi6bmI=
private key: (hidden)
listening port: 9796
peer: MR2RF5Tp+6BKt9k+deKg1GqR3re3ckJKti+uwZA84DU=
endpoint: 127.0.0.1:9797
allowed ips: 0.0.0.0/0, ::/0
latest handshake: 46 seconds ago
transfer: 340 B received, 92 B sent
测试
peer# # ip netns exec testing-wgslirp ping -c 2 192.168.72.2
64 bytes from 192.168.72.2: icmp_seq=1 ttl=64 time=0.705 ms
64 bytes from 192.168.72.2: icmp_seq=2 ttl=64 time=0.435 ms
gateway$
INFO wgslirpy::router: New NAT entry for Pingable
DEBUG wgslirpy::router: Finished serving Pingable
peer# ip netns exec testing-wgslirp curl http://example.com/
<!doctype html>
...
</html>
gateway$
DEBUG wgslirpy::router::serve_dns: DNS query example.com:0
DEBUG wgslirpy::router: Sending DNS reply
INFO wgslirpy::router: New NAT entry for Tcp { client_side: Endpoint { addr: Ipv4(Address([192, 168, 76, 1])), port: 48004 }, external_side: Endpoint { addr: Ipv4(Address([93, 184, 216, 34])), port: 80 } }
DEBUG wgslirpy::router::serve_tcp: Connected to upstream TCP
DEBUG wgslirpy::router::serve_tcp: Accepted the connection
DEBUG wgslirpy::router::serve_tcp: EOF received from client
DEBUG wgslirpy::router::serve_tcp: Shutdown finished
DEBUG wgslirpy::router::serve_tcp: EOF
DEBUG wgslirpy::router::serve_tcp: Client TCP socket no longer active
DEBUG boringtun::noise::timers: KEEPALIVE(PERSISTENT_KEEPALIVE)
DEBUG wgslirpy::router: Finished serving Tcp { client_side: Endpoint { addr: Ipv4(Address([192, 168, 76, 1])), port: 48004 }, external_side: Endpoint { addr: Ipv4(Address([93, 184, 216, 34])), port: 80 } }
peer# ip netns exec testing-wgslirp dig +short github.com @8.8.8.8
140.82.112.3
gateway$
01:26:14 INFO wgslirpy::router: New NAT entry for Udp
...
01:27:46 DEBUG wgslirpy::router::serve_udp: Timed out a UDP connection
安装
从 GitHub 发布 下载预构建的可执行文件或使用 cargo install --path .
或 cargo install wgslirpy
从源代码安装。
CLI 选项
wgslirpy --help 输出
Usage: wgslirpy [-k <private-key>] [-f <private-key-file>] -K <peer-key> [-p <peer-endpoint>] [-a <keepalive-interval>] -b <bind-ip-port> [-D <dns>] [-P <pingable>] [--mtu <mtu>] [--tcp-buffer-size <tcp-buffer-size>] [--transmit-queue-capacity <transmit-queue-capacity>] [-u <incoming-udp...>] [-t <incoming-tcp...>]
Expose internet access without root using Wireguard
Options:
-k, --private-key main private key of this Wireguard node, base64-encoded
-f, --private-key-file
main private key of this Wireguard node (content of a
specified file), base64-encoded
-K, --peer-key peer's public key
-p, --peer-endpoint
address of the peer's UDP socket, where to send keepalives
-a, --keepalive-interval
keepalive interval, in seconds
-b, --bind-ip-port
where to bind our own UDP socket for Wireguard connection
-D, --dns use this UDP socket address as a simple A/AAAA-only DNS
server within Wireguard network
-P, --pingable reply to ICMP pings on this single address within Wireguard
network
--mtu maximum transfer unit to use for TCP. Default is 1420.
--tcp-buffer-size in-application socket TCP buffer size. Note that operating
system socket buffer also applies.
--transmit-queue-capacity
nubmer of outgoing (to wireguard) packets to hold in a queue
-u, --incoming-udp
forward this host UDP port into Wireguard network. You need
to specify triplet of socket addresses: host, source
(optional) and dest. Host address is address to bind
operating system socket to. source and dest addreses are
used within Wireguard network. Example: -u
0.0.0.0:1234,10.0.2.1:1234,10.0.2.15:1234
-t, --incoming-tcp
forward this host TCP port into Wireguard network. You need
to specify triplet of socket addresses: host, source
(optional) and dest. Host address is address to bind
operating system socket to. source and dest addreses are
used within Wireguard network. If source port is 0,
roundrobin is used. Example: -t 0.0.0.0:1234,,10.0.2.15:1234
--help display usage information
另请参阅
依赖项
~18–29MB
~540K SLoC