:::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 RETURNiptables -t nat -A "$_table" -d 127.0.0.0/8 -j RETURNiptables -t nat -A "$_table" -p tcp -j REDIRECT --to-ports 12345iptables -t nat -A "$_table" -p udp -j REDIRECT --to-ports 10053iptables -t nat -A "$_table" -p icmp -j REDIRECT --to-ports 10053# 加入主链if [[ "$(iptables -t nat -L OUTPUT | grep "^$_table\s" -c)" == "0" ]]; theniptables -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" ]]; thenapt update && apt install -y redsocks iptablesif [ ! -f "redsocks.conf" ]; thencat /etc/redsocks.conf >./redsocks.conffised 's@^redsocks:.*@redsocks:x:0:5001::/var/run/redsocks:/bin/bash@' -i /etc/passwdfiif [[ "$(which redsocks | wc -l)" == "1" ]]; thensudo -u redsocks bash -c "nohup ./clash-linux-amd64 -d data/ >log/clash.log &"redsocks -c redsocks.conf__iptablesiptables -t nat -nvLfi
}
__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 sessionlog_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 consoledaemon = 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-relaytype = 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' andredudp’ 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模式,以便达到全局代理的功能
