5个版本 (3个破坏性更新)
0.9.0 | 2023年8月23日 |
---|---|
0.7.1 | 2022年3月13日 |
0.7.0 | 2022年3月12日 |
0.5.0 | 2022年1月23日 |
0.4.0 | 2021年12月12日 |
#1530 in 网络编程
每月24次下载
125KB
3K SLoC
tobaru
使用Rust编写的端口转发工具,具有以下高级功能:
- 多个目标地址:根据IP和TLS SNI/ALPN转发到不同的目标地址
- IPv4/IPv6允许列表:仅转发来自已知IP范围的连接
- 支持TLS:
- 在单个端口上允许TLS和非TLS客户端
- 连接到TLS和非TLS端点
- 热重载:更新后的配置会自动重新加载
- iptables支持:自动配置iptables以丢弃来自不允许范围的包
- IP组:可以在不同的服务器配置中重复使用的IP名称组
以下是一个快速示例
- address: 0.0.0.0:443
transport: tcp
targets:
# target 1: non-TLS clients from any IP will be forwarded to 127.0.0.1:2999.
- location: 127.0.0.1:2999
allowlist: 0.0.0.0/0
# target 2: TLS clients from specified IP masks asking for SNI example.com and
# ALPN protocol http/1.1 will be forwarded to a listening UNIX domain socket.
- location: /run/service.sock
server_tls:
cert: cert.pem
key: key.pem
sni_hostnames: example.com
alpn_protocols: http/1.1
allowlist:
- 1.2.3.4
- 2.3.0.0/16
# target 3: TLS clients from ip 1.2.3.4 asking for SNI example.com or test.com,
# and any other ALPN protocol, or no ALPN negotiation, will be forwarded here.
- location: 127.0.0.1:3001
server_tls:
cert: cert.pem
key: key.pem
sni_hostnames:
- example.com
- test.com
alpn_protocols:
- any
- none
allowlist: 1.2.3.4
安装
在GitHub发行版上提供了预编译的二进制文件,适用于x86_64和Apple aarch64。
否则,如果您在系统上安装了较新的Rust和cargo,可以使用cargo
安装tobaru。
cargo install tobaru
用法
USAGE:
tobaru [OPTIONS] <CONFIG PATH or CONFIG URL> [CONFIG PATH or CONFIG URL] [..]
OPTIONS:
-t, --threads NUM
Number of worker threads, defaults to an estimated amount of parallelism.
--clear-iptables-all
Clear all tobaru-created rules from iptables and exit immediately.
--clear-iptables-matching
Clear tobaru-created rules for the addresses specified in the specified
config files and exit immediately.
-h, --help
Show this help screen.
IPTABLES PERMISSIONS:
To run iptable commands, this binary needs to have CAP_NET_RAW and CAP_NET_ADMIN
permissions, or else be invoked by root.
EXAMPLES:
tobaru -t 1 config1.yaml config2.yaml
Run servers from configs in config1.yaml and config2.yaml on a single thread.
tobaru tcp://127.0.0.1:1000?target=127.0.0.1:2000
Run a tcp server on 127.0.0.1 port 1000, forwarding to 127.0.0.1 port 2000.
sudo tobaru --clear-iptables-matching config1.yaml
Clear iptable configs only for the config addresses in config1.yaml.
基于URL的配置
可以使用配置URL格式执行简单的TCP转发
tcp://<bind ip>:<bind port>?target=<target ip>:<target port>
可以使用target-path
键将TCP转发到UNIX域套接字
tcp://<bind ip>:<bind port>?target-path=<unix domain socket path>
基于文件的配置
配置文件格式为YAML或JSON。tobaru期望读取一个对象数组,其中每个对象都是一个服务器配置或一个IP掩码组。
服务器对象配置
address
:要监听的地址。
transport
:传输协议,字符串为tcp
或udp
。
use_iptables
(《可选》默认值:false
):是否启用iptables支持。
- 在目标中指定的允许列表中的IP掩码会被添加到iptables中,未指定的IP掩码会被拒绝。
targets
(或target
):指定转发到的目标位置对象或目标位置对象数组。
tcp_nodelay
(《可选》默认值:true
):指定是否在已接受的套接字上禁用Nagle算法。
- 仅在
transport
为tcp
时才接受。
目标对象配置(TCP传输)
locations
(或 location
):单个TCP位置,或TCP位置的数组。
- 当提供多个位置的数组时,连接将以轮询方式转发。
allowlist
:单个IP掩码或IP组名称,或IP掩码或IP组名称的数组。
tcp_nodelay
(可选,默认:true
):指定是否在目标连接套接字上禁用Nagle算法。
server_tls
(可选,默认:null
):服务器TLS对象。当非空时,仅接受此目标的TLS连接。对象键为
cert
:TLS证书的文件路径。key
:TLS私钥的文件路径。optional
(可选,默认:false
):指定TLS是否可选。当为真时,这意味着还将接受并转发非TLS流。sni_hostnames
(可选,默认:any, none
):SNI主机名,或SNI主机名的数组,具有特殊关键字any
:接受任何提供的SNI主机名。none
:接受没有SNI协商的手shake。
alpn_protocols
(可选:默认:any, none
):接受的ALPN协议,或支持的ALPN协议的数组,具有特殊关键字any
:接受任何提供的ALPN协议。none
:接受没有ALPN协议选择的handshake。
TCP位置配置
TCP位置可以指定为
-
地址字符串。例如:
127.0.0.1:1234
-
UNIX域套接字路径。例如:
/path/to/something.sock
-
具有以下键的对象
address
:地址字符串。- 只能指定
address
或path
中的一个。
path
:UNIX域套接字路径。- 只能指定
address
或path
中的一个。
client_tls
(可选,默认:false
):指定是否在连接到此位置时处理TLS。支持的值是true
:启用客户端TLS处理,并进行证书验证。no-verify
:启用客户端TLS处理,不进行证书验证。false
:禁用客户端TLS处理。
- 只能指定
目标对象配置(UDP传输)
addresses
(或 address
):单个地址字符串,或 host:port
地址字符串的数组
allowlist
:单个IP掩码或IP组名称,或IP掩码或IP组名称的数组。
association_timeout_secs
(可选,默认:200
):不活跃的UDP关联超时前的秒数。
IP组对象配置
group
:IP组名称
ip_masks
(或 ip_mask
):单个IP掩码或IP组名称,或IP掩码或IP组名称的数组。
自动添加一个默认的IP组,名称为 all
,IP掩码为 0.0.0.0/0
。
示例
TCP到TCP转发,允许所有IP
- address: 0.0.0.0:8080
transport: tcp
target:
location: 192.168.8.1:80
allowlist: all
或使用多个服务器和特定的IP范围
# Forward port 8080 to 192.168.8.1 port 80 for some IP ranges.
- address: 0.0.0.0:8080
transport: tcp
targets:
- address: 192.168.8.1:80
allowlist:
# Some local IP ranges..
- 192.168.9.0/24
- 192.168.10.0/24
# .. and some specific IPs
- 12.34.56.78
- fa71::e09d:92fa:beef:1234
- address: 192.168.8.2:80
allowlist:
- 192.168.11.0/24
- 192.168.12.0/24
# Forward port 8081 to 192.168.8.2 port 80 for all IPs.
- address: 0.0.0.0:8081
transport: udp
target:
- address: 192.168.8.3:80
allowlist:
- all
来自未在 allowlist
中指定的地址的连接将被丢弃(如果 iptables
设置为 true
),或者在接收后立即关闭。
轮询转发
{
// Listen on all interfaces, port 8080.
"bindAddress": "0.0.0.0:8080",
"transport": "tcp",
"target": {
// Round-robin forward to different addresses.
"addresses": [
"192.168.8.1:80",
"192.168.8.2:80",
"192.168.8.3:80",
"192.168.8.4:80"
],
"allowlist": "all"
}
}
基于IP地址的多重目的地
{
// Listen on port 8080
"bindAddress": "0.0.0.0:8080",
"transport": "tcp",
"targets": [
// Forward some IP ranges to 192.168.8.1 port 80.
{
"address": "192.168.8.1:80",
"allowlist": [
"192.168.1.0/24",
"192.168.2.0/24"
]
},
// Forward other IP ranges to 192.168.8.2 port 80.
{
"address": "192.168.8.2:80",
"allowlist": [
"192.168.3.0/24",
"192.168.4.0/24"
]
}
]
}
支持TLS
[
// Server listening on port 443 (HTTPS).
{
"bindAddress": "192.168.0.1:443",
"target": {
// All connections need to use TLS.
// Enable TLS by specifying the path to the certificate and private key.
"serverTls": {
"cert": "/path/to/cert.pem",
"key": "/path/to/key.pem",
// Allow clients to connect without TLS.
"optional": true
},
// Also connect to the destination HTTPS server using TLS.
// '+' (plus sign) means to use TLS.
"address": "192.168.2.1:+443",
"allowlist": "all"
}
},
// Server listening on port 443 (HTTPS).
// Forward in a round-robin manner to various HTTP servers that do not have
// TLS enabled.
{
"bindAddress": "192.168.0.2:443",
"target": {
"serverTls": {
"cert": "/path/to/cert.pem",
"key": "/path/to/key.pem"
},
"addresses": [
"192.168.2.1:80",
"192.168.2.2:80",
"192.168.2.3:80"
],
"allowlist": "all"
}
}
]
iptables支持
请注意,tobaru需要root权限才能配置iptables。可能可以通过使用 setcap(8)
来不使用root权限完成此操作。如果您能够这样做,请提交一个带有说明的pull request。
{
"bindAddress": "0.0.0.0:8080",
// Enable iptables auto-configuration.
"iptables": true,
"target": {
"address": "192.168.8.1:80",
// Allow only the following IP ranges. Packets from other IPs will be dropped.
"allowlist": [
"192.168.2.2/24",
"192.168.2.3/24",
"192.168.100.50"
]
}
}
IP组
IP组可以用于在多个服务器中快速指定IP组。请注意,IP范围可以指定在任何文件中,并且可以在不同的文件中重复使用,例如,可以方便地在一个单独的文件中调用所有IP组:tobaru ip_groups.json http_servers.json ssh_servers.json
{
"ipGroups": {
"local": [
"192.168.0.0/24",
"192.168.1.0/24",
"192.168.2.0/24",
"192.168.3.0/24"
],
"friends": [
"1.2.3.4",
"2.3.4.5"
]
},
"servers": [
{
"bindAddress": "0.0.0.0:8080",
"target": {
"address": "192.168.5.1:8080",
// Only allow IP ranges from 'local' and 'friends' to connect.
"allowlist": [
"local",
"friends"
]
}
},
{
"bindAddress": "0.0.0.0:8081",
"target": {
"address": "192.168.5.2:8080",
// Only allow IP ranges from 'local'.
"allowlist": "@local"
}
}
]
}
从0.7.1或更低版本升级
请参阅 UPGRADING.md。
依赖项
~18–30MB
~557K SLoC