2020-05-16 17:26:38 +08:00
2020-05-16 17:26:38 +08:00
2020-04-28 19:58:40 +08:00
2020-05-01 11:55:57 +08:00
2020-05-14 13:57:39 +08:00
2020-04-26 00:28:10 +08:00
2020-05-14 16:16:45 +08:00
2020-04-24 00:47:25 +08:00
2020-04-26 00:28:10 +08:00
2020-05-14 16:16:45 +08:00
2020-05-14 14:28:08 +08:00
2020-04-22 03:12:33 +08:00
2020-05-14 16:16:45 +08:00

Transparent Proxy with cgroup v2

Introduction

cgproxy will transparent proxy anything running in specific cgroup. It resembles with proxychains and tsock, but without their disadvantages, and more powerfull.

It aslo supports global transparent proxy and gateway proxy. See Global transparent proxy and Gateway proxy.

Prerequest

  • cgroup2

    Both cgroup and cgroup2 are enabled in linux by default. So you don't have to do anything about this.

    • systemd-cgls to see the cgroup hierarchical tree.
    • Why cgroup v2? Because simple, elegant and intuitive.
  • TPROXY

    A process listening on port (e.g. 12345) to accept iptables TPROXY, for example v2ray's dokodemo-door in tproxy mode.

How to install

mkdir build && cd build && cmake .. && make && sudo make install

How to use

  • First enable and start service

    sudo systemctl enable --now cgproxy.service
    
  • Then prefix with cgproxy with your command, just like proxychains

    cgproxy <CMD>
    
  • For example, test proxy

    cgproxy curl -vIs https://www.google.com
    
  • To completely stop

    sudo systemctl disable --now cgproxy.service
    

More config in /etc/cgproxy.conf (click to expand)
###################################################################################
## any process in cgroup_proxy will be proxied, and cgroup_noproxy the opposite
## note, cgroup must start with slash '/'
## the value can be string or bash array
## for array, only the first element will be created if not exist
## and the rest elements will not, so won't be applied if not exist

### global proxy with v2ray service
# cgroup_proxy="/"
# cgroup_noproxy=("/noproxy.slice" "/system.slice/v2ray.service")

### global proxy with manual `cgnoporxy qv2ray`
# cgroup_proxy="/"
# cgroup_noproxy="/noproxy.slice"

### default
cgroup_proxy="/proxy.slice"
cgroup_noproxy="/noproxy.slice"


###################################################################################
## allow as gateway for local network
enable_gateway=false


###################################################################################
## listening port of another proxy process, for example v2ray 
port=12345


###################################################################################
## if you set to false, it's traffic won't go through proxy,
## but still can go direct to internet
enable_dns=true
enable_tcp=true
enable_udp=true
enable_ipv4=true
enable_ipv6=true


###################################################################################
## do not modify this if you don't known what you are doing
table=100
fwmark=0x01
mark_newin=0x02
If you changed config, remember to restart service
sudo systemctl restart cgproxy.service

Global transparent proxy

  • Set cgroup_proxy="/" in /etc/cgproxy.conf, this will proxy all connection

  • And allow your proxy program (v2ray) direct to internet, two ways:

    • active way

      run cgnoproxy <PROXY PROGRAM>

      example: cgnoproxy sudo v2ray -config config_file

      example: cgnoproxy qv2ray

    • passive way, useful if you run v2ray as service

      set cgroup_noproxy="<PROXY PROGRAM's CGROUP>"

      example: cgroup_noproxy=("/noproxy.slice" "/system.slice/v2ray.service")

  • Finally, restart cgproxy service, that's all

Gateway proxy

  • Set enable_gateway=true in /etc/cgproxy.conf
  • And allow your proxy software (v2ray) direct to internet, described above
  • Other device set this host as gateway, and set public dns if necessary

Other useful tools provided in this project

  • cgnoproxy run program wihout proxy, very useful in global transparent proxy

    cgnoproxy <CMD> 
    
  • run_in_cgroup run command in specific cgroup which will create if not exist , cgroup can be only one level down exist cgroup, otherwise created fail.

    run_in_cgroup --cgroup=CGROUP <COMMAND>
    # example
    run_in_cgroup --cgroup=/mycgroup.slice ping 127.0.0.1
    
  • cgattach attach specific process pid to specific cgroup which will create if not exist , cgroup can be only one level down exist cgroup, otherwise created fail.

    cgattch <pid> <cgroup>
    # example
    cgattch 9999 /proxy.slice
    

NOTES

  • cgattach has suid bit set by default, be careful to use on multi-user server for securiry. To avoid this situation, you can remove the suid bit , then it will fallback to use sudo, with sudoer you can restrict permission or set NOPASSWD for youself.

  • v2ray TPROXY need root or special permission

    sudo setcap "cap_net_admin,cap_net_bind_service=ep" /usr/lib/v2ray/v2ray
    
  • Why not outbound mark solution, because in v2ray when "localhost" is used, out-going DNS traffic is not controlled by V2Ray, so no mark at all, that's pity.

TIPS

  • systemd-cgls to see the cgroup hierarchical tree.
  • Check cgroup2 support findmnt -t cgroup2
  • Offer you v2ray service and full config exmaple in v2ray_config
  • Offer you qv2ray config example

Qv2ray config example

Licences

cgproxy is licenced under License: GPL v3

Description
Transparent Proxy with cgroup v2。透明代理,配合v2ray/Qv2ray食用最佳
Readme GPL-2.0 2.2 MiB
Languages
C++ 50%
C 29.7%
Shell 12.6%
CMake 7.7%