:::tips 由于笔记本经常重启, 于是把开发环境放到了远程, 在 docker container 进行开发, 但是远程的 Linux 系统不能”上网”, 于是有了本文档 :::
原理和方法
- 将本机所有的流量 通过 iptables 重定向到 redsocks, 再由 redsocks 转发到代理端口
- 本文使用中关键的技术点在使用 iptables owner 模块过滤掉 redsocks 和代理程序本身流量, 来解决代理流量死循环的问题
- redsocks 可以转发 udp 流量, 这意味着你配置得当, 就能避免 DNS 污染
Docker API 访问, 设置 tls 认证 - 进行 vscode 远程容器开发
运行容器
- 运行一个容器, 用于运行 redsocks 和 clash
- 这是我用于 vscode 开发的远程容器镜像, 本身不包含任何应用服务
- 编辑这和镜像启动后运行的文件
/root/workspace/.vscode.init/start.sh
(root目录是映射到外部的, 可以从外面编辑) ```bash __run_container() { _name=”service-clash” docker rm -f “$_name” docker run -itd \
}--name="$_name" \
--network="host" \
--restart=unless-stopped \
--privileged \
-v /proc:/host \
-v /data/docker-data/$_name:/root \
registry.cn-hangzhou.aliyuncs.com/lwmacct/vscode:docker-env-v1.0.4-20221104
__run_container
<a name="bpbDX"></a>
# 启动脚本
- 注意下面的内容是在容器 service-clash 内部的操作
- 编辑容器内的启动
```bash
/root/workspace/.vscode.init/start.sh
- 目录
/root/workspace/app/
下的clash-linux-amd64
以及 clash 的data
文件需要自己下载 - redsocks 配置需要根据自身情况修改
- clash-linux-amd64 https://github.com/Dreamacro/clash
- Country.mmdb https://github.com/Dreamacro/maxmind-geoip/releases
```bash
!/usr/bin/env bash
__iptables() { _table=”M_OUTPUT_REDSOCKS_CLASH” iptables -t nat -F $_table iptables -t nat -X $_table iptables -t nat -N $_table
iptables -t nat -A "$_table" -m owner --gid-owner 5001 -j RETURN
iptables -t nat -A "$_table" -d 127.0.0.0/8 -j RETURN
iptables -t nat -A "$_table" -p tcp -j REDIRECT --to-ports 12345
iptables -t nat -A "$_table" -p udp -j REDIRECT --to-ports 10053
iptables -t nat -A "$_table" -p icmp -j REDIRECT --to-ports 10053
# 加入主链
if [[ "$(iptables -t nat -L OUTPUT | grep "^$_table\s" -c)" == "0" ]]; then
iptables -t nat -I OUTPUT 1 -j $_table
# iptables -t nat -D OUTPUT -j M_OUTPUT_REDSOCKS_CLASH # 解除代理状态
fi
# iptables -t nat -nvL
}
__main() { cd /root/workspace/app/ || return 0
if [[ "$(which redsocks | wc -l)" == "0" ]]; then
apt update && apt install -y redsocks iptables
if [ ! -f "redsocks.conf" ]; then
cat /etc/redsocks.conf >./redsocks.conf
fi
sed 's@^redsocks:.*@redsocks:x:0:5001::/var/run/redsocks:/bin/bash@' -i /etc/passwd
fi
if [[ "$(which redsocks | wc -l)" == "1" ]]; then
sudo -u redsocks bash -c "nohup ./clash-linux-amd64 -d data/ >log/clash.log &"
redsocks -c redsocks.conf
__iptables
iptables -t nat -nvL
fi
}
__main
<a name="pUC7X"></a>
# redsocks 配置模板, 仅供参考
redsocks.conf 文件
base { // debug: connection progress & client list on SIGUSR1 log_debug = off;
// info: start and end of client session
log_info = on;
/* possible `log' values are:
* stderr
* "file:/path/to/file"
* syslog:FACILITY facility is any of "daemon", "local0"..."local7"
*/
log = "syslog:daemon";
// detach from console
daemon = on;
/* Change uid, gid and root directory, these options require root
* privilegies on startup.
* Note, your chroot may requre /etc/localtime if you write log to syslog.
* Log is opened before chroot & uid changing.
*/
user = redsocks;
group = redsocks;
// chroot = "/var/chroot";
/* possible `redirector' values are:
* iptables - for Linux
* ipf - for FreeBSD
* pf - for OpenBSD
* generic - some generic redirector that MAY work
*/
redirector = iptables;
}
redsocks { /* `local_ip’ defaults to 127.0.0.1 for security reasons,
* use 0.0.0.0 if you want to listen on every interface.
* `local_*' are used as port to redirect to.
*/
local_ip = 127.0.0.1;
local_port = 12345;
// `ip' and `port' are IP and tcp-port of proxy-server
// You can also use hostname instead of IP, only one (random)
// address of multihomed host will be used.
ip = 127.0.0.1;
port = 7890;
// known types: socks4, socks5, http-connect, http-relay
type = socks5;
// login = "foobar";
// password = "baz";
}
redudp { // `local_ip’ should not be 0.0.0.0 as it’s also used for outgoing // packets that are sent as replies - and it should be fixed // if we want NAT to work properly. local_ip = 127.0.0.1; local_port = 10053;
// `ip' and `port' of socks5 proxy server.
ip = 127.0.0.1;
port = 7890;
// login = username;
// password = pazzw0rd;
// kernel does not give us this information, so we have to duplicate it
// in both iptables rules and configuration file. By the way, you can
// set `local_ip' to 127.45.67.89 if you need more than 65535 ports to
// forward ;-)
// This limitation may be relaxed in future versions using contrack-tools.
dest_ip = 127.0.0.53;
dest_port = 53;
udp_timeout = 30;
udp_timeout_stream = 180;
}
dnstc { // fake and really dumb DNS server that returns “truncated answer” to // every query via UDP, RFC-compliant resolver should repeat same query // via TCP in this case. local_ip = 127.0.0.1; local_port = 5300; }
// you can add more redsocks' and
redudp’ sections if you need.
差异对比
root@localhost:/# diff /etc/redsocks.conf /root/workspace/app/redsocks.conf 48c48
< port = 1080;
port = 7890;
66,69c66,69 < ip = 192.0.2.1; < port = 1080; < login = username;
< password = pazzw0rd;
ip = 127.0.0.1;
port = 7890;
// login = username;
// password = pazzw0rd;
76c76
< dest_ip = 192.0.2.2;
dest_ip = 127.0.0.53;
推荐阅读
clash可以用作全局代理程序吗? · Issue #292 · Dreamacro/clash
Clash作为透明代理是否有意义? · Issue #158 · Dreamacro/clash
GitHub - darkk/redsocks: transparent TCP-to-proxy redirector
GitHub - blue7wings/clash-tun: 在Linux环境中设置clash tun模式,以便达到全局代理的功能