文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

终端程序不支持SOCKS5/HTTP代理怎么办?有了这个神器后,终于可以跨越高山和大海了!

2024-12-24 21:21

关注

你是否经常有在终端下通过一些实用程序进行工作的需求呢,比如:Git 等。但是由于这些终端程序默认并不支持 Socks 5 代理或 HTTP 代理,在访问一些需要科学上网的网络服务时速度或许会非常的慢。

通常我们的解决方法就是使用环境变量 export ALL_PROXY=socks5://proxyAddress:port 或者 export http_proxy=http://proxyAddress:port 给所有终端程序配置一个全局代理,这样做虽然有效但并不是最佳解决方案。

今天就给大家介绍一款神器 graftcp,graftcp 可以把任何指定的终端程序的 TCP 连接重定向到 SOCKS5 或 HTTP 代理,并且不会影响其它的终端程序。是不是很好的解决了你的痛点呢?

简介

graftcp 可以把任何指定程序(应用程序、脚本、shell 等)的 TCP 连接重定向到 SOCKS5 或 HTTP 代理。

对比 tsocks、proxychains 或 proxychains-ng,graftcp 并不使用 LD_PRELOAD 技巧来劫持共享库的 connect()、getaddrinfo() 等系列函数达到重定向目的,这种方法只对使用动态链接编译的程序有效。

对于静态链接编译出来的程序,例如默认选项编译的 Go 程序,proxychains-ng 就无效了。graftcp 使用 ptrace(2) 系统调用跟踪或修改任意指定程序的 connect 信息,对任何程序都有效。工作原理后面将会解释。   

  1. 项目地址:https://github.com/hmgle/graftcp 

安装

graftcp 在 Linux 系统内运行。graftcp-local 使用 Go 编写, Go 环境是必需的。 

  1. $ git clone https://github.com/hmgle/graftcp.git  
  2. $ cd graftcp  
  3. $ make 

make 执行完后,即可运行 graftcp-local/graftcp-local 和 ./graftcp。你也可以把它们都安装进系统: 

  1. $ sudo make install 

之后 graftcp-local 会随着系统启动而自动运行。

用法参数

graftcp-local: 

  1. $ graftcp-local/graftcp-local -h  
  2. Usage of graftcp-local/graftcp-local:  
  3.   -config string  
  4.         Path to the configuration file  
  5.   -http_proxy string  
  6.         http proxy address, e.g.: 127.0.0.1:8080  
  7.   -listen string  
  8.         Listen address (default ":2233")  
  9.   -logfile string  
  10.         Write logs to file  
  11.   -loglevel value  
  12.         Log level (0-6) (default 1)  
  13.   -pipepath string  
  14.         Pipe path for graftcp to send address info (default "/tmp/graftcplocal.fifo")  
  15.   -select_proxy_mode string  
  16.         Set the mode for select a proxy [auto | random | only_http_proxy | only_socks5] (default "auto")  
  17.   -service string  
  18.         Control the system service: ["start" "stop" "restart" "install" "uninstall"]  
  19.   -socks5 string  
  20.         SOCKS5 address (default "127.0.0.1:1080")  
  21.   -syslog  
  22.         Send logs to the local system logger (Eventlog on Windows, syslog on Unix) 

graftcp: 

  1. $ graftcp -h  
  2. Usage: graftcp [options] prog [prog-args]  
  3. Options:  
  4.   -a --local-addr=<graftcp-local-IP-addr>  
  5.                     graftcp-local's IP address. Default: localhost  
  6.   -p --local-port=<graftcp-local-port>  
  7.                     Which port is graftcp-local listening? Default: 2233  
  8.   -f --local-fifo=<fifo-path>  
  9.                     Path of fifo to communicate with graftcp-local.  
  10.                     Default: /tmp/graftcplocal.fifo  
  11.   -b --blackip-file=<black-ip-file-path>  
  12.                     The IP in black-ip-file will connect direct  
  13.   -w --whiteip-file=<white-ip-file-path>  
  14.                     Only redirect the connect that destination ip in the  
  15.                     white-ip-file to SOCKS5  
  16.   -n --not-ignore-local  
  17.                     Connecting to local is not changed by default, this  
  18.                     option will redirect it to SOCKS5  
  19.   -h --help  
  20.                     Display this help and exit 

使用示例

假设你正在运行默认地址 "localhost:1080" 的 SOCKS5 代理,首先启动 graftcp-local: 

  1. $ graftcp-local/graftcp-local 

通过 graftcp 安装来自 golang.org 的 Go 包: 

  1. $ ./graftcp go get -v golang.org/x/net/proxy 

通过 graftcp 打开 Chromium / Chrome / Firefox 浏览器,网页的所有请求都会重定向到 SOCKS5 代理: 

  1. $ ./graftcp chromium-browser 

通过 graftcp 启动 Bash / Zsh / Fish,在这个新开的 shell 里面执行的任何新命令产生的 TCP 连接都会重定向到 SOCKS5 代理:

 

  1. % ./graftcp bash  
  2. $ wget https://www.google.com 

工作原理

要达到重定向一个 app 发起的的 TCP 连接到其他目标地址并且该 app 本身对此毫无感知的目的,大概需要这些条件:

这里可能有个疑问:既然可以修改任何系统调用的参数,那么通过修改 app 的 write(2) / send(2) 的参数,直接往 buffer 里面附加原始目标地址信息给 graftcp-local 不是更简单吗?答案是这无法做到。如果直接往运行在子进程的被跟踪程序的 buffer 添加信息,可能会造成缓冲区溢出,造成程序崩溃或者覆盖了其他数据。

另外,execve(2) 会分离所有的共享内存,所以也不能通过共享内存的方式让被跟踪的 app 的 write buffer 携带更多的数据,因此这里采用管道方式给 graftcp-local 传递原始的目标地址信息。

简单的流程如下: 

  1. +---------------+             +---------+         +--------+         +------+  
  2. |   graftcp     |  dest host  |         |         |        |         |      |  
  3. |   (tracer)    +---PIPE----->|         |         |        |         |      |  
  4. |      ^        |  info       |         |         |        |         |      |  
  5. |      | ptrace |             |         |         |        |         |      |  
  6. |      v        |             |         |         |        |         |      |  
  7. |  +---------+  |             |         |         |        |         |      |  
  8. |  |         |  |  connect    |         | connect |        | connect |      |  
  9. |  |         +--------------->| graftcp +-------->| SOCKS5 +-------->| dest |  
  10. |  |         |  |             | -local  |         |  or    |         | host |  
  11. |  |  app    |  |  req        |         |  req    | HTTP   |  req    |      |  
  12. |  |(tracee) +--------------->|         +-------->| proxy  +-------->|      |  
  13. |  |         |  |             |         |         |        |         |      |  
  14. |  |         |  |  resp       |         |  resp   |        |  resp   |      |  
  15. |  |         |<---------------+         |<--------+        |<--------+      |  
  16. |  +---------+  |             |         |         |        |         |      |  
  17. +---------------+             +---------+         +--------+         +------+ 

常见问题解答及技巧

有哪些重定向 TCP 连接的方式?

主要有:全局式、设置环境变量式和仅针对程序(或进程)式。

全局式:比如使用 iptables + RedSocks 可以把系统符合一定规则的流量转换为 SOCKS5 流量。这种方式的优点是全局有效;缺点是所有满足该规则的流量都被重定向了,影响范围较大。

设置环境变量方式:一些程序启动时会读取 proxy 相关的环境变量来决定是否将自己的数据转换为对应代理协议的流量,比如 curl 会读取 http_proxy, ftp_proxy, all_proxy 环境变量并根据请求 scheme 来决定转换为哪种代理流量。这种方法只有程序本身实现了转换的功能才有效,局限性较大。

仅针对程序方式:这种方式可以仅针对特定的程序执行重定向,比如 tsocks 或 proxychains。如前面提到,它们之前都是使用 LD_PRELOAD 劫持动态库方式实现,对 Go 之类默认静态链接编译的程序就无效了。graftcp 改进了这一点,能够重定向任何程序的 TCP 连接。

如果应用程序连接的目标地址是本机,使用 graftcp 会把该连接重定向到 SOCKS5 代理吗?

不会。默认会忽略目标地址为本地的连接,如果想重定向所有地址的话,可以使用 -n选项。如果想忽略更多的地址,可以把它们加入黑名单 IP 文件;如果想仅重定向某些 IP 地址,可以把这些地址加入白名单 IP 文件。使用 graftcp --help 获取设置参数。

我的 DNS 请求受到污染,graftcp 会处理 DNS 请求吗?

不会。graftcp 目前仅处理 TCP 连接。建议使用 dnscrypt-proxy 或 ChinaDNS 等方式解决 DNS 污染问题。

clone(2) 参数有个叫 CLONE_UNTRACED 的标志位,可以避免让父进程跟踪到自己,graftcp 是如何做到强制跟踪的?

graftcp 在子进程调用 clone(2) 之前会把它拦截,清除这个 CLONE_UNTRACED 标志位,所以被跟踪的子进程最终还是难逃被跟踪的命运。另外,这个 CLONE_UNTRACED 标志位本意是给内核使用的,普通程序不应该去设置它。

Linux 提供了一种限制被 ptrace(2) 跟踪的方法:设置 /proc/sys/kernel/yama/ptrace_scope 的值,若 ptrace(2) 失效,请检查该值是否被修改过。

支持 macOS 吗?

不。macOS 的 ptrace(2) 是个半残品。不过理论上参考 DTrace那一套也能实现,见issue 12。或许有兴趣的同学可以趟下这趟浑水。 

 

来源:运维之美内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯