Giter Club home page Giter Club logo

cgtproxy's Introduction

cgtproxy

cgtproxy is a transparent proxy RULE manager written in go inspired by cgproxy.

cgtproxy make it easier to set per-app transparent proxy dynamically. It will automatically update your nft ruleset according to your configuration, redirect network traffic in each cgroup to a target.

Currently supported target are:

  • DIRECT
  • DROP
  • TPROXY

The way how cgtproxy works.

Netfliter can be configured to filter network traffic by cgroup, as well as redirect some traffic to a TPROXY server.

Systemd has a work-in-progress XDG integration documentation suggest that XDG applications should be launched in a systemd managed unit.

For example, telegram comes from flatpak launched by desktop environment from the graph session of user whose uid is 1000 should has all its processes running in a cgroup like:

/user.slice/user-1000.slice/[email protected]/app.slice/[email protected]

That means the cgroup path of an application instance has a pattern, which can be match by a regex expression.

cgtproxy will listening cgroupfs change with inotify. And update the nftable rules when new cgroup hierarchy created, according to your configuration.

Why you might need such program?

On a linux desktop environment, there are only few ways to configure network proxy settings at app level.

  1. Set some network proxy environment variables, only for some applications.

    There is no elegant way to do this, but you can update the .desktop file of that application.

    But there is a problem that some applications might just ignore environment variables.

    That's why you might need a transparent network proxy setting.

  2. If you using a proxy client such as clash, which can route packets based on the name of process that is sending the packet.

    Clash implement this feature by going through procfs when new connection created.

    If there is a lot of processes, this implementation seems to have some performance issues.

    And if you need that executable, which you have configured to use proxy, temporarily connect to Internet directly. You have to update your clash configuration and restart clash, which means to close all old connections, which is quite annoying.

  3. If your proxy client support TPROXY, you can use cgproxy.

    It can only update iptables for exsiting cgroup.

    For processes in cgroups that create later, it use BPF hooked on execve to match executable filename and move matched process to some other cgroup.

    This design has some serious problems:

    1. It will make processes removed from the original cgroup, even out of user slice.
    2. The cgnoproxy command it provided make any program can easily escape from original cgroup without any authentication.
    3. It create cgroup hierarchy without let systemd known. This behavior break the single-writer rule of design rules of the systemd cgroup API.

By using cgtproxy, you can have flexible user-level per-app transparent network proxy settings without any problems above.

Differences between cgproxy

There are some differences between cgproxy and cgtproxy:

  • cgproxy using iptables, but cgtproxy use nftables.

    Go check differences between iptables and nftables here.

  • cgproxy can only working with exsiting cgroup, but cgtproxy can update rules dynamically for newly created cgroups;

  • cgproxy use BPF to move your process from its original cgroup, but cgtproxy not;

    cgproxy implement per-app proxy by using BPF to trace the execve syscall. If the new executable file of that process matched some pattern, cgproxy daemon will put that process into a special hierarchy proxy.slice.

    This weird behavior make process escape from the user-level hierarchy, which means the systemd resource control settings will not take any effect.

    But cgtproxy implement per-app proxy by update nftable rules to match newly created cgroups. It do not write anything to cgroupv2 filesystem at all.

  • cgproxy requires more capability (permission) than cgtproxy;

    cgtproxy requires at least CAP_NETWORK_ADMIN and CAP_BPF, but cgtproxy require only CAP_NETWORK_ADMIN.

    Check the systemd service file for details.

Usage

Install cgtproxy, then enable and start the systemd service by:

# Run the line below if you have old cgtproxy running as systemd service already.
# systemctl daemon-reload
systemctl enable --now cgtproxy.service

You could check the nft rules generated by default (empty) configuration by:

sudo nft list ruleset

Write your own configuration file according to the configuration guide, place it on /etc/cgtproxy/config.yaml then restart systemd service by:

systemctl restart cgtproxy.service

TODO

  • optional cgroup monitor implementation listening on D-Bus instead of filesystem;

    notify makes the filesystem monitor much more stable, there is no need to implement another monitor for my person usage.

  • DNS hijack for fake-ip;

    • ipv4;

    • ipv6;

      I don't have any ipv6 only device, so I don't need this feature.

  • builtin TPROXY server.

    Clash Clash.Meta MetaCubeX/mihomo is good enough for me.

If you need any feature above, PR is welcome.

cgtproxy's People

Contributors

black-desk avatar comixhe avatar dependabot[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

cgtproxy's Issues

[Feature request] Gateway mode

Will cgtproxy supports gateway mode like cgproxy have been? It is quite handy to deploy it on VPS and use the VPS to route client traffic. This would require gateway mode.

note

  1. This project have to be a pure go project, we do not accept:
    1. call some command via sh;
    2. use cgo.
  2. We need to reduce the amount of dependencies for easy packaging;
  3. When a upstream project cannot satisfy our requirements, we should vendor and update it. Contribute into upstream project should consider only when this project is ready for daily use.

refer: https://github.com/mk-fg/systemd-cgroup-nftables-policy-manager

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.