iobee / shuttle

A web proxy in Golang with amazing features.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Shuttle

Shuttle是一个基于Go开发的全平台网络代理工具。欢迎加入讨论 Slack or Telegram。 (logo**@不二**)

Shuttle

介绍

Shuttle 是基于Go实现的全平台网络代理:

  • 支持SOCKS5SOCKS5 over TLSshadowsocks协议
  • 支持规则代理:域名、IP段、GEO-IP
  • 支持代理方式:直连、拒绝、代理
  • 多代理服务器选择,支持分组管理。组中服务器选择方式:往返时间选择(rtt)和手动选择(select)
  • 支持HTTP/HTTPS 抓包,反向代理、请求头修改、返回头修改、返回值伪造等
  • 支持DNS解析方式:静态解析(static)、直连解析(direct)、代理服务器解析(remote)

结构模块:

shuttle_architecture

截图示例:

Introduction

功能

  • 代理功能
    • TCP(HTTP/HTTPS)
    • UDP
  • 扩展功能
    • HTTP抓包
    • HTTPS抓包(MITM)
    • 反向代理
    • 复用连接内请求切分
    • 请求头修改
    • 返回头修改
    • 请求mapping
  • 远端多服务器管理
    • 服务器分组包含
    • 服务器协议支持
      • shadowsocks
      • SOCKS5
      • SOCKS5 over TLS
    • 服务器选择
      • RTT(往返时间)选择
      • Select(手动)选择
  • 代理模式
    • 全局代理
    • 全局直连
    • 全局拒绝
    • 规则代理
      • DOMAIN:域名全匹配
      • DOMAIN-SUFFIX:域名后缀匹配
      • DOMAIN-KEYWORD:域名关键字匹配
      • IP-CIDR:ip段匹配
      • GEO-IP: 支持GEO-IP路由
      • USER-AGENT:HTTP头字匹配
  • DNS
    • static:静态地址映射
    • direct:直连DNS解析
    • remote:远程服务器DNS解析(防止DNS污染)
    • GEO-IP判断
  • 外部窗口
    • API
      • 获取服务器列表
      • RTT分组刷新
      • Select分组手动选择
      • DNS缓存获取
      • DNS缓存刷新
      • 请求记录列表获取
      • 请求记录清空
      • CA证书生成
      • CA证书下载
      • HTTP Dump开关
      • MITM 开关
      • HTTP/HTTPS抓包内容获取
      • 关闭Shuttle
      • 重载配置
      • 全局代理开关
      • 支持Websocket,完成内容增量更新
    • Web UI
      • Web UI (angular6 + ant design)
  • 优化
    • 内存优化
    • log日志

安装与启动

MacOS

准备

下载release文件并解压,完成后目录结构:

shuttle
   ├── GeoLite2-Country.mmdb
   ├── RespFiles/ #mock文件存方
   ├── shuttle  #shuttle主程序
   ├── shuttle.yaml #配置文件
   ├── start.sh #启动脚本
   └── view/ #web界面目录

打开配置文件:shuttle.yaml,启动前要注意的是端口号冲突,配置文件中预设的是:8080,8081,8082

General:
  http-port: "8080"  #http/https 代理端口
  socks-port: "8081" #socks 代理端口
  controller-port: "8082" #控制台服务端口

启动

在命令行中进入该目录,运行

./start.sh #不会有任何输出

此时不会有任何输出,此时在浏览器中打开http://localhost:8082(以controller-port: "8082"为例),如果能打开控制台页面就说明启动成功,如果打开失败可以查看shuttle.log查看原因,如果排查不出原因可以去提Issues

系统配置

打开系统偏好设置 => 网络 => 高级 => 代理,这里主要设置三个:

  • Web 代理(HTTP) 设置为127.0.0.1:8080(以http-port: "8080"为例)
  • Web 代理(HTTPS) 设置为127.0.0.1:8080(以http-port: "8080"为例)
  • SOCKS 代理 设置为127.0.0.1:8080(以socks-port: "8081"为例)

然后点击OK,再点击应用,此时用浏览器打开http://c.sipt.top这时如果已经设置代理成功这个url也是对应到控制台页面。

命令行走代理:

export https_proxy="http://127.0.0.1:8080"
export http_proxy="http://127.0.0.1:8080"
export all_proxy="socks5://127.0.0.1:8081"

Windows

准备

下载release文件并解压,完成后目录结构:

shuttle
   ├── GeoLite2-Country.mmdb
   ├── RespFiles/ #mock文件存方
   ├── shuttle  #shuttle主程序
   ├── shuttle.yaml #配置文件
   ├── startup.bat #启动
   └── view/ #web界面目录

打开配置文件:shuttle.yaml,启动前要注意的是端口号冲突,配置文件中预设的是:8080,8081,8082

General:
  http-port: "8080"  #http/https 代理端口
  socks-port: "8081" #socks 代理端口
  controller-port: "8082" #控制台服务端口

启动

双击打开startup.bat,此时不会有任何输出,此时在浏览器中打开http://localhost:8082(以controller-port: "8082"为例),如果能打开控制台页面就说明启动成功,如果打开失败可以查看shuttle.log查看原因,如果排查不出原因可以去提Issues

系统配置

打开系统偏好设置 => 网络 => 代理:设置为127.0.0.1:8080(以http-port: "8080"为例)

此时用浏览器打开http://c.sipt.top这时如果已经设置代理成功这个url也是对应到控制台页面。

Linux

准备

下载release文件并解压,完成后目录结构:

shuttle
   ├── GeoLite2-Country.mmdb
   ├── RespFiles/ #mock文件存方
   ├── shuttle  #shuttle主程序
   ├── shuttle.yaml #配置文件
   ├── start.sh #启动脚本
   └── view/ #web界面目录

打开配置文件:shuttle.yaml,启动前要注意的是端口号冲突,配置文件中预设的是:8080,8081,8082

General:
  http-port: "8080"  #http/https 代理端口
  socks-port: "8081" #socks 代理端口
  controller-port: "8082" #控制台服务端口

启动

在命令行中进入该目录,运行

./start.sh #不会有任何输出

此时不会有任何输出,此时在浏览器中打开http://localhost:8082(以controller-port: "8082"为例),如果能打开控制台页面就说明启动成功,如果打开失败可以查看shuttle.log查看原因,如果排查不出原因可以去提Issues

配置

版本

ver: v1.0.1

当前配置文件版本只支持v1.0.1,不可修改

常规配置

General:
  loglevel: "info"
  dns-server:
  - "114.114.114.114"
  - "223.5.5.5"
  http-port: "8080"
  http-interface: "0.0.0.0"
  socks-port: "8081"
  socks-interface: "0.0.0.0"
  controller-port: "8082"
  controller-interface: "0.0.0.0"
名称 描述
loglevel 打印log的等级,建议info或error trace,debug,info,error
dns-server DNS服务器地址 IP地址数组
http-port HTTP/HTTPS 代理端口
http-interface HTTP/HTTPS 代理访问控制
socks-port SOCKS 代理端口
socks-interface SOCKS 代理访问控制
controller-port 控制器服务端口
controller-interface 控制器服务访问控制

代理服务器配置

服务器名与服务器分组名相互都不能有重复,包括保留名:DIRECT, REJECT, GLOBAL

服务器

Proxy:
  "🇯🇵JP_a": ["ss", "jp.a.example.com", "12345", "rc4-md5", "123456"]
  "🇯🇵JP_b": ["ss", "jp.b.example.com", "12345", "rc4-md5", "123456"]
  "🇯🇵JP_c": ["ss", "jp.c.example.com", "12345", "rc4-md5", "123456"]
  "🇭🇰HK_a": ["ss", "hk.a.example.com", "12345", "rc4-md5", "123456"]
  "🇭🇰HK_b": ["ss", "hk.b.example.com", "12345", "rc4-md5", "123456"]
  "🇭🇰HK_c": ["ss", "hk.c.example.com", "12345", "rc4-md5", "123456"]
  "🇺🇸US_a": ["ss", "us.a.example.com", "12345", "rc4-md5", "123456"]
  "🇺🇸US_b": ["ss", "us.b.example.com", "12345", "rc4-md5", "123456"]
  "🇺🇸US_c": ["ss", "hk.c.example.com", "12345", "rc4-md5", "123456"]
  "socks": ["socks", "localhost", "12345"]
  "socks-tls": ["socks-tls", "localhost", "12345", "skip-verify"]
  "socks-auth": ["socks", "localhost", "12345", "user", "password"]
  "socks-tls-auth": ["socks-tls", "localhost", "12345", "skip-verify", "user", "password"]
  ...

服务器协议:

  • ss: shadowsocks;

    配置格式:

    "服务器名": ["ss", "服务器地址(域名/IP)", "端口号", "加密方式", "密码"]

    目前支持加密方式:

    • aes-128-cfb
    • aes-192-cfb
    • aes-256-cfb
    • aes-128-ctr
    • aes-192-ctr
    • aes-256-ctr
    • des-cfb
    • bf-cfb
    • cast5-cfb
    • rc4-md5
    • chacha20
    • chacha20-ietf
    • salsa20
    • aes-256-gcm
    • aes-192-gcm
    • aes-128-gcm
    • chacha20-ietf-poly1305
  • socks: SOCKS5;

    支持用户名/密码认证。

    配置格式:

    "服务器名": ["socks", "服务器地址(域名/IP)", "端口号"] 
    "服务器名": ["socks", "服务器地址(域名/IP)", "端口号", "用户名", "密码"]
  • socks-tls: SOCKS5 over TLS;

    支持用户名/密码认证。对于服务器的证书可以配置是否验证:skip-verifyverify 配置格式:

    "服务器名": ["socks-tls", "服务器地址(域名/IP)", "是否验证证书", "端口号"] 
    "服务器名": ["socks-tls", "服务器地址(域名/IP)", "是否验证证书", "端口号", "用户名", "密码"]

服务器组

Proxy-Group:
  "Auto": ["rtt", "🇭🇰HK_a", "🇭🇰HK_b", "🇭🇰HK_c", "🇯🇵JP_a", "🇯🇵JP_b", "🇯🇵JP_c", "🇺🇸US_a", "🇺🇸US_b", "🇺🇸US_c"]
  "HK": ["select", "🇭🇰HK_a", "🇭🇰HK_b", "🇭🇰HK_c"]
  "JP": ["select", "🇯🇵JP_a", "🇯🇵JP_b", "🇯🇵JP_c"]
  "US": ["select", "🇺🇸US_a", "🇺🇸US_b", "🇺🇸US_c"]
  "Proxy": ["select", "Auto", "HK", "JP", "US"]
  "nProxy": ["select", "DIRECT"]

配置格式:

"分组名": ["选择方式", "服务器名/服务器分组名", ... ]
选择方式 描述
select 手动选择
rtt 本机穿过远端到达www.gstatic.com的往返时间评出最优

DNS配置

Local-DNS:
- ["DOMAIN", "localhost", "static", "127.0.0.1"]
- ["DOMAIN-KEYWORD", "google", "remote", ""]
- ["DOMAIN-SUFFIX", "baidu.com", "direct", "114.114.114.114"]

配置格式:

- ["匹配方式", "值", "解析方式", "参数"]
匹配方式 描述
DOMAIN-SUFFIX 域名后缀匹配 域名后缀
DOMAIN 域名全匹配 域名
DOMAIN-KEYWORD 域名关键字匹配 关键字
解析方式 描述 参数
static 静态解析 对应的IP地址
direct 直连DNS服务器解析 DNS服务器地址
remote 让远端服务器解析

请求/返回修改及反向代理

HTTPS必须开始MitM才生效

Http-Map:
  Req-Map: #配置请求的修改
    - url-rex: "^http://www.zhihu.com"
      type: "UPDATE"
      items:
        - ["HEADER", "Scheme", "http"]
  Resp-Map: #配置返回值的修改
      - url-rex: "^http://www.zhihu.com"
      type: "UPDATE"
      items:
         - ["STATUS", "", "301"]
         - ["HEADER", "Location", "http://www.jianshu.com"]
名称 描述
url-rex 正则表达式用来匹配请求的URL
type UPDATE(修改)和MOCK(本地数据返回),(Resp-Map只支持UPDATE)
items 是一个["修改类型", "Key", "Value"]的数组(详见另表)
修改类型 描述 使用条件
HEADER 添加/修改头信息(示例) (Req-MaporResp-Map) type:(UPDATEorMOCK)
STATUS 修改返回状态码(示例) (Resp-Map) type:(UPDATEorMOCK)
BODY Response Body(示例)
(HTTPS链接域名必须存在并支持HTTPS)
(Resp-Map) type:(MOCK)
URL url-rex替换成URL
暂时不支持HTTPS (反向代理)
(Req-Map) type:(UPDATE)

例:

请求头修改

把符合^http://www.zhihu.com的请求,都添加一个请求头Scheme: http

Http-Map:
  Req-Map:
      - url-rex: "^http://www.zhihu.com"
      type: "UPDATE"
      items:
        - ["HEADER", "Scheme", "http"]
请求回本地数据

type是MOCK时:HTTP链接域名随意;HTTPS链接域名必须存在并支持HTTPS

把符合^http://www.baidu.com/$的请求,都直接返回数据:

{
  "name": "Shuttle",
  "github-link": "https://github.com/sipt/shuttle",
  "data": "response mock"
}

在安装目录的RespFiles目录下面创建一个文件mocks.json写入数据以上数据。

配置:

Http-Map:
  Req-Map:
    - url-rex: "^http://www.wogaoxing.abcascb" #HTTP时,链接域名随意
      type: "MOCK"
      items:
        - ["STATUS", "", "200"] #返回状态码:200 OK
        - ["HEADER", "Content-Type", "application/json"] #添回返回头
        - ["BODY", "", "mock.json"] #返回数据对应RespFiles下mock.json文件
    - url-rex: "^https://www.baidu.com" #HTTPS时,链接域名必须存在并支持HTTPS
      type: "MOCK"
      items:
        - ["STATUS", "", "200"] #返回状态码:200 OK
        - ["HEADER", "Content-Type", "application/json"] #添回返回头
        - ["BODY", "", "mock.json"] #返回数据对应RespFiles下mock.json文件
反向代理

暂时不支持HTTPS

把符合^http://www.baidu.com的请求,都反向代理到http://www.zhihu.com

Http-Map:
  Req-Map:
    - url-rex: "^http://www.baidu.com"
      type: "UPDATE"
      items:
       - ["URL", "", "http://www.zhihu.com"]

MitM

MITM: 
  rules: ["*.baidu.com", "*.zhihu.com"] #允许MitM的域名
  ca: (base64) # CA证书和私钥,不需要配置,由程序自动生成,保存在这里
  key: (base64)

规则配置

Rule: # 代理规则
- ["DOMAIN-SUFFIX", "gitlab.anjian.com", "DIRECT", ""]
# - [域名全匹配,域名,走分组Proxy,]
- ["DOMAIN", "sipt.top", "Proxy", ""]
# - [域名关键字匹配,关键字,拒绝连接,]
- ["DOMAIN-KEYWORD", "zjtoolbar", "REJECT", ""]
# - [IP网段断匹配,IP网段,直连,]
- ["IP-CIDR", "127.0.0.0/8", "DIRECT", ""]
# - [GEOIP匹配,**,走nProxy组规则,]
- ["GEOIP", "CN", "nProxy", ""]
# - [以上都不满足,,走Proxy组规则,]
- ["FINAL", "", "Proxy", ""]

格式:

- ["匹配方式","值","连接方式","备注"]
匹配方式 描述
DOMAIN-SUFFIX 域名后缀匹配 域名后缀
DOMAIN 域名全匹配 域名
DOMAIN-KEYWORD 域名关键字匹配 关键字
IP-CIDR IP网段断匹配 IP网段
GEOIP GEOIP匹配 国家编码
FINAL 以上都不满足 [无]
连接方式 描述
DIRECT 直接连接目标服务器
REJECT 拒绝连接
配置的服务器名
配置的服务器分组名

Web控制台

http://c.sipt.top

Servers

Servers

图中加了标注,可放大查看说明

DNS Cache

dns-cache 查看当前系统的入网所有域名的DNS解析 左下角提供刷新和清空按钮,目前还只支持全量刷新

Records

Records 查看当前系统的入网所有请求,匹配了哪条规则等 当前只会保留1000条数据,

抓包教程

HTTP抓包只需打开Dump,Records列表中显示为 下载 图标的就是已经Dump数据的记录,可以直接点击查看。

HTTPS抓包需要几个步骤:

Cert

  1. 生成证书:Generate生成证书,每次点击都会生成新的CA证书,生成完成后并保存到配置文件。
  2. 点击Download按钮下载下来
  3. 加入到系统证书里,并信任它
  4. HTTPS抓包要Dump和MITM同时打开(具体哪些可以HTTPS抓包要配合配置文件中MitM 中的 rules

About

A web proxy in Golang with amazing features.

License:Apache License 2.0


Languages

Language:Go 100.0%Language:Shell 0.0%Language:HTML 0.0%