7 Commits
v0.07 ... v0.08

Author SHA1 Message Date
fancy
2838ffbb70 bump version 2020-05-14 14:28:08 +08:00
fancy
749fe38ca8 add local aur build 2020-05-14 14:21:40 +08:00
fancy
c0668fd8d2 use macro 2020-05-14 13:57:39 +08:00
fancy
06ae0b9fc5 update readme 2020-05-14 12:07:12 +08:00
fancy
4e04dcf84a update readme 2020-05-14 04:53:23 +08:00
fancy
c0e9ea24c1 allow array input for cgroup_proxy and cgroup_noproxy 2020-05-14 04:47:29 +08:00
fancy
f8e0abbb55 check root, and check iptables before clean 2020-05-13 23:42:05 +08:00
7 changed files with 139 additions and 36 deletions

View File

@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.10)
project(cgproxy VERSION 3.7)
project(cgproxy VERSION 3.8)
add_executable(cgattach cgattach.cpp)
install(TARGETS cgattach DESTINATION /usr/bin

View File

@@ -0,0 +1,40 @@
# Maintainer: Fancy Zhang <springzfx@gmail.com>
pkgname=cgproxy-git
pkgver=v3.8.r1.gc0668fd
pkgrel=1
pkgdesc="A transparent proxy program with cgroup2, like proxychains"
arch=('x86_64')
url="https://github.com/springzfx/cgproxy"
license=('')
groups=('')
makedepends=('cmake')
depends=('systemd')
provides=('cgproxy')
conflicts=('cgproxy')
curr_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
source=("${pkgname}::git+file://${curr_dir}/../.git")
# source=("${pkgname}::git+file:///home/fancy/workspace/cgproxy/.git")
md5sums=('SKIP')
pkgver() {
cd "$pkgname"
( set -o pipefail
git describe --long --tags 2>/dev/null | sed 's/\([^-]*-g\)/r\1/;s/-/./g' ||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
)
}
backup=('etc/cgproxy.conf')
install="cgproxy.install"
build(){
cd "$pkgname"
mkdir -p build && cd build && cmake .. && make
}
package_cgproxy-git(){
cd "$pkgname"/build
make DESTDIR=$pkgdir install
}

View File

@@ -0,0 +1,8 @@
#!/bin/sh
post_install(){
cat <<'DOC'
to start service:
systemctl enable --now cgproxy.service
DOC
}

View File

@@ -10,6 +10,10 @@
#include <unistd.h>
using namespace std;
#define error(...) {fprintf(stderr, __VA_ARGS__);fprintf(stderr, "\n");}
#define debug(...) {fprintf(stdout, __VA_ARGS__);fprintf(stdout, "\n");}
void print_usage() { fprintf(stdout, "usage: cgattach <pid> <cgroup>\n"); }
bool exist(string path) {
@@ -26,7 +30,7 @@ bool validate(string pid, string cgroup) {
if (pid_v && cg_v)
return true;
fprintf(stderr, "paramater validate error\n");
error("paramater validate error");
print_usage();
exit(EXIT_FAILURE);
}
@@ -37,22 +41,21 @@ string get_cgroup2_mount_point(){
int count=fscanf(fp,"%s",&cgroup2_mount_point);
fclose(fp);
if (count=0){
fprintf(stderr, "cgroup2 not supported\n");
error("cgroup2 not supported");
exit(EXIT_FAILURE);
}
return cgroup2_mount_point;
}
int main(int argc, char *argv[]) {
setuid(0);
setgid(0);
if (getuid() != 0 || getgid() != 0) {
fprintf(stderr, "cgattach need suid sticky bit or run with root\n");
int flag=setuid(0);
if (flag!=0) {
perror("cgattach setuid");
exit(EXIT_FAILURE);
}
if (argc != 3) {
fprintf(stderr, "only need 2 paramaters\n");
error("only need 2 paramaters");
print_usage();
exit(EXIT_FAILURE);
}
@@ -69,20 +72,19 @@ int main(int argc, char *argv[]) {
if (!exist(cgroup_target_path)) {
if (mkdir(cgroup_target_path.c_str(),
S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0) {
fprintf(stdout, "created cgroup %s success\n", cgroup_target.c_str());
debug("created cgroup %s success", cgroup_target.c_str());
} else {
fprintf(stderr, "created cgroup %s failed, errno %d\n",
cgroup_target.c_str(), errno);
error("created cgroup %s failed, errno %d", cgroup_target.c_str(), errno);
exit(EXIT_FAILURE);
}
// fprintf(stderr, "cgroup %s not exist\n",cgroup_target.c_str());
// error("cgroup %s not exist",cgroup_target.c_str());
// exit(EXIT_FAILURE);
}
// put pid to target cgroup
ofstream procs(cgroup_target_procs, ofstream::app);
if (!procs.is_open()) {
fprintf(stderr, "open file %s failed\n", cgroup_target_procs.c_str());
error("open file %s failed", cgroup_target_procs.c_str());
exit(EXIT_FAILURE);
}
procs << pid.c_str() << endl;
@@ -90,7 +92,7 @@ int main(int argc, char *argv[]) {
// maybe there some write error, for example process pid may not exist
if (!procs) {
fprintf(stderr, "write %s to %s failed, maybe process %s not exist\n",
error("write %s to %s failed, maybe process %s not exist",
pid.c_str(), cgroup_target_procs.c_str(), pid.c_str());
exit(EXIT_FAILURE);
}

View File

@@ -1,26 +1,47 @@
## cgroup transparent proxy
## see how to configure, https://github.com/springzfx/cgproxy
###################################################################################
## any process in cgroup_proxy will be proxied, and cgroup_noproxy the opposite
## note, cgroup must start with slash '/'
# cgroup_proxy="/" # for global tproxy
# cgroup_noproxy="/system.slice/v2ray.service" # for v2ray service
## 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
### 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
###################################################################################
## 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

View File

@@ -30,6 +30,13 @@ cat << 'DOC'
DOC
}
check_root(){
uid=$(id -u)
[ ! $uid -eq 0 ] && { >&2 echo "permission denied, need root";exit 0; }
}
check_root
## any process in this cgroup will be proxied
cgroup_proxy="/proxy.slice"
cgroup_noproxy="/noproxy.slice"
@@ -62,6 +69,7 @@ for i in "$@"
do
case $i in
stop)
echo "stopping tproxy iptables"
iptables -t mangle -D PREROUTING -j TPROXY_PRE
iptables -t mangle -D OUTPUT -j TPROXY_OUT
iptables -t mangle -F TPROXY_PRE
@@ -90,7 +98,6 @@ case $i in
--config=*)
config=${i#*=}
source $config
shift
;;
--help)
print_help
@@ -127,8 +134,12 @@ iptables -t mangle -A TPROXY_OUT -p icmp -j RETURN
iptables -t mangle -A TPROXY_OUT -m connmark --mark $make_newin -j RETURN
iptables -t mangle -A TPROXY_OUT -m addrtype --dst-type LOCAL -j RETURN
iptables -t mangle -A TPROXY_OUT -m addrtype ! --dst-type UNICAST -j RETURN
iptables -t mangle -A TPROXY_OUT -m cgroup --path $cgroup_noproxy -j RETURN
iptables -t mangle -A TPROXY_OUT -m cgroup --path $cgroup_proxy -j MARK --set-mark $fwmark
for cg in ${cgroup_noproxy[@]}; do
iptables -t mangle -A TPROXY_OUT -m cgroup --path $cg -j RETURN
done
for cg in ${cgroup_proxy[@]}; do
iptables -t mangle -A TPROXY_OUT -m cgroup --path $cg -j MARK --set-mark $fwmark
done
iptables -t mangle -A OUTPUT -j TPROXY_OUT
#ipv6#
@@ -154,8 +165,12 @@ ip6tables -t mangle -A TPROXY_OUT -p icmpv6 -j RETURN
ip6tables -t mangle -A TPROXY_OUT -m connmark --mark $make_newin -j RETURN
ip6tables -t mangle -A TPROXY_OUT -m addrtype --dst-type LOCAL -j RETURN
ip6tables -t mangle -A TPROXY_OUT -m addrtype ! --dst-type UNICAST -j RETURN
ip6tables -t mangle -A TPROXY_OUT -m cgroup --path $cgroup_noproxy -j RETURN
ip6tables -t mangle -A TPROXY_OUT -m cgroup --path $cgroup_proxy -j MARK --set-mark $fwmark
for cg in ${cgroup_noproxy[@]}; do
ip6tables -t mangle -A TPROXY_OUT -m cgroup --path $cg -j RETURN
done
for cg in ${cgroup_proxy[@]}; do
ip6tables -t mangle -A TPROXY_OUT -m cgroup --path $cg -j MARK --set-mark $fwmark
done
ip6tables -t mangle -A OUTPUT -j TPROXY_OUT
## allow to disable, order is important
@@ -190,8 +205,8 @@ ip6tables -t mangle -I TPROXY_PRE -m addrtype ! --src-type LOCAL -m conntrack --
## message for user
cat << DOC
noproxy cgroup: $cgroup_noproxy
proxied cgroup: $cgroup_proxy
noproxy cgroup: ${cgroup_noproxy[@]}
proxied cgroup: ${cgroup_proxy[@]}
DOC

View File

@@ -46,7 +46,7 @@ It aslo supports global transparent proxy and gateway proxy. See [Global transpa
mkdir build && cd build && cmake .. && make && sudo make install
```
- It is alreay in [archlinux AUR](https://aur.archlinux.org/packages/cgproxy-git/).
- It is alreay in [archlinux AUR](https://aur.archlinux.org/packages/?K=cgproxy).
- DEB and RPM are packaged in [release page](https://github.com/springzfx/cgproxy/releases).
@@ -79,32 +79,47 @@ mkdir build && cd build && cmake .. && make && sudo make install
<summary>More config in <i>/etc/cgproxy.conf</i> (click to expand)</summary>
```bash
########################################################################
## cgroup transparent proxy
###################################################################################
## any process in cgroup_proxy will be proxied, and cgroup_noproxy the opposite
## cgroup must start with slash '/'
## 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
### global proxy with v2ray service
# cgroup_proxy="/"
# cgroup_noproxy="/system.slice/v2ray.service"
# 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
###################################################################################
## 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
@@ -128,11 +143,13 @@ sudo systemctl restart cgproxy.service
example: `cgnoproxy sudo v2ray -config config_file`
- passive way
example: `cgnoproxy qv2ray`
- passive way, useful if you run v2ray as service
set `cgroup_noproxy="<PROXY PROGRAM's CGROUP>"`
example: `cgroup_noproxy="/system.slice/v2ray.service"`
example: `cgroup_noproxy=("/noproxy.slice" "/system.slice/v2ray.service")`
- Finally, restart cgproxy service, that's all