diff --git a/cgroup-tproxy.sh b/cgroup-tproxy.sh index 2c8100b..ef4bcfa 100644 --- a/cgroup-tproxy.sh +++ b/cgroup-tproxy.sh @@ -31,7 +31,7 @@ DOC } ## check root -[ ! $(id -u) -eq 0 ] && { >&2 echo "need root to modify iptables";exit -1; } +[ ! $(id -u) -eq 0 ] && { >&2 echo "iptables: need root to modify iptables";exit -1; } ## any process in this cgroup will be proxied if [ -z ${cgroup_proxy+x} ]; then @@ -150,10 +150,10 @@ 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 for cg in ${cgroup_noproxy[@]}; do -iptables -t mangle -A TPROXY_OUT -m cgroup --path $cg -j RETURN +iptables -t mangle -A TPROXY_OUT -m cgroup --path $cg -j RETURN || { >&2 echo "iptables: $cg not exist, won't apply"; } done for cg in ${cgroup_proxy[@]}; do -iptables -t mangle -A TPROXY_OUT -m cgroup --path $cg -j MARK --set-mark $fwmark +iptables -t mangle -A TPROXY_OUT -m cgroup --path $cg -j MARK --set-mark $fwmark || { >&2 echo "iptables: $cg not exist, won't apply"; } done iptables -t mangle -A OUTPUT -j TPROXY_OUT @@ -181,10 +181,10 @@ 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 for cg in ${cgroup_noproxy[@]}; do -ip6tables -t mangle -A TPROXY_OUT -m cgroup --path $cg -j RETURN +ip6tables -t mangle -A TPROXY_OUT -m cgroup --path $cg -j RETURN || { >&2 echo "iptables: $cg not exist, won't apply"; } done for cg in ${cgroup_proxy[@]}; do -ip6tables -t mangle -A TPROXY_OUT -m cgroup --path $cg -j MARK --set-mark $fwmark +ip6tables -t mangle -A TPROXY_OUT -m cgroup --path $cg -j MARK --set-mark $fwmark || { >&2 echo "iptables: $cg not exist, won't apply"; } done ip6tables -t mangle -A OUTPUT -j TPROXY_OUT diff --git a/src/cgproxyd.hpp b/src/cgproxyd.hpp index 25f0694..3e96e5d 100644 --- a/src/cgproxyd.hpp +++ b/src/cgproxyd.hpp @@ -92,15 +92,16 @@ class cgproxyd { v = config.program_noproxy; if (find(v.begin(), v.end(), path) != v.end()) { - if (CGROUP::getCgroup(pid) != config.cgroup_noproxy_preserved) { + if (!belongToCgroup(getCgroup(pid), config.cgroup_noproxy)) { info("execsnoop noproxy: %d %s", pid, path); free(path); return attach(pid, config.cgroup_noproxy_preserved); } } + v = config.program_proxy; if (find(v.begin(), v.end(), path) != v.end()) { - if (CGROUP::getCgroup(pid) != config.cgroup_proxy_preserved) { + if (!belongToCgroup(getCgroup(pid), config.cgroup_proxy)) { info("execsnoop proxied: %d %s", pid, path); free(path); return attach(pid, config.cgroup_proxy_preserved); @@ -215,14 +216,14 @@ class cgproxyd { debug("process running program"); for (auto &path : config.program_noproxy) for (auto &pid : bash_pidof(path)) { - if (CGROUP::getCgroup(pid) != config.cgroup_noproxy_preserved) { + if (!belongToCgroup(getCgroup(pid), config.cgroup_noproxy)) { int status = attach(pid, config.cgroup_noproxy_preserved); if (status == 0) info("noproxy running process %d %s", pid, path.c_str()); } } for (auto &path : config.program_proxy) for (auto &pid : bash_pidof(path)) { - if (CGROUP::getCgroup(pid) != config.cgroup_proxy_preserved) { + if (!belongToCgroup(getCgroup(pid), config.cgroup_proxy)) { int status = attach(pid, config.cgroup_proxy_preserved); if (status == 0) info("proxied running process %d %s", pid, path.c_str()); } diff --git a/src/cgroup_attach.cpp b/src/cgroup_attach.cpp index 2667727..111f309 100644 --- a/src/cgroup_attach.cpp +++ b/src/cgroup_attach.cpp @@ -27,34 +27,6 @@ string get_cgroup2_mount_point() { return s; } -string getCgroup(const pid_t &pid) { return getCgroup(to_str(pid)); } - -string getCgroup(const string &pid) { - string cgroup_f = to_str("/proc/", pid, "/cgroup"); - if (!fileExist(cgroup_f)) return ""; - - stringstream buffer; - string cgroup; - FILE *f = fopen(cgroup_f.c_str(), "r"); - char buf[READ_SIZE_MAX] = ""; - char *flag = buf; - while (flag != NULL) { - buffer.clear(); - while (!flag || buf[strlen(buf) - 1] != '\n') { - flag = fgets(buf, READ_SIZE_MAX, f); - if (flag) buffer << buf; - } - string line = buffer.str(); - if (line[0] == '0') { // 0::/user.slice/user-1000.slice - cgroup = (*(line.end() - 1) == '\n') ? line.substr(3, line.length() - 4) - : line.substr(3); - break; - } - } - fclose(f); - return cgroup; -} - bool validate(string pid, string cgroup) { bool pid_v = validPid(pid); bool cg_v = validCgroup(cgroup); diff --git a/src/cgroup_attach.h b/src/cgroup_attach.h index 34f81be..43623eb 100644 --- a/src/cgroup_attach.h +++ b/src/cgroup_attach.h @@ -9,8 +9,6 @@ namespace CGPROXY::CGROUP { extern string cgroup2_mount_point; bool validate(string pid, string cgroup); string get_cgroup2_mount_point(); -string getCgroup(const pid_t &pid); -string getCgroup(const string &pid); int attach(const string pid, const string cgroup_target); int attach(const int pid, const string cgroup_target); diff --git a/src/common.cpp b/src/common.cpp index 2879597..b569ede 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -22,6 +22,8 @@ string join2str(const int argc, char **argv, const char delm) { return s; } +bool startWith(string s, string prefix) { return s.rfind(prefix, 0) == 0; } + bool validCgroup(const string cgroup) { return regex_match(cgroup, regex("^/[a-zA-Z0-9\\-_./@]*$")); } @@ -89,4 +91,41 @@ string getRealExistPath(const string &name) { path = bash_readlink(path); if (!fileExist(path)) return ""; return path; -} \ No newline at end of file +} + +bool belongToCgroup(string cg1, string cg2) { return startWith(cg1 + '/', cg2 + '/'); } + +bool belongToCgroup(string cg1, vector cg2) { + for (const auto &s : cg2) { + if (startWith(cg1 + '/', s + '/')) return true; + } + return false; +} + +string getCgroup(const pid_t &pid) { return getCgroup(to_str(pid)); } + +string getCgroup(const string &pid) { + string cgroup_f = to_str("/proc/", pid, "/cgroup"); + if (!fileExist(cgroup_f)) return ""; + + stringstream buffer; + string cgroup; + FILE *f = fopen(cgroup_f.c_str(), "r"); + char buf[READ_SIZE_MAX] = ""; + char *flag = buf; + while (flag != NULL) { + buffer.clear(); + while (!flag || buf[strlen(buf) - 1] != '\n') { + flag = fgets(buf, READ_SIZE_MAX, f); + if (flag) buffer << buf; + } + string line = buffer.str(); + if (line[0] == '0') { // 0::/user.slice/user-1000.slice + cgroup = (*(line.end() - 1) == '\n') ? line.substr(3, line.length() - 4) + : line.substr(3); + break; + } + } + fclose(f); + return cgroup; +} diff --git a/src/common.h b/src/common.h index 9d297db..6d94be5 100644 --- a/src/common.h +++ b/src/common.h @@ -75,6 +75,7 @@ template string to_str(T... args) { string join2str(const vector t, const char delm = ' '); string join2str(const int argc, char **argv, const char delm = ' '); +bool startWith(string prefix); bool validCgroup(const string cgroup); bool validCgroup(const vector cgroup); @@ -88,4 +89,12 @@ string bash_which(const string &name); string bash_readlink(const string &path); string getRealExistPath(const string &name); +/** + * whether cg1 belongs to cg2 + */ +bool belongToCgroup(string cg1, string cg2); +bool belongToCgroup(string cg1, vector cg2); +string getCgroup(const pid_t &pid); +string getCgroup(const string &pid); + #endif diff --git a/src/config.cpp b/src/config.cpp index f2c2d22..412f76e 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -21,7 +21,6 @@ using json = nlohmann::json; namespace CGPROXY::CONFIG { void Config::toEnv() { - mergeReserved(); setenv("program_proxy", join2str(program_proxy, ':').c_str(), 1); setenv("program_noproxy", join2str(program_noproxy, ':').c_str(), 1); setenv("cgroup_proxy", join2str(cgroup_proxy, ':').c_str(), 1); @@ -95,6 +94,8 @@ int Config::loadFromJsonStr(const string js) { toRealProgramPath(program_noproxy); toRealProgramPath(program_proxy); + mergeReserved(); + return 0; } @@ -151,4 +152,8 @@ void Config::toRealProgramPath(vector &v) { v = tmp; } +#undef tryassign +#undef add2json +#undef merge + } // namespace CGPROXY::CONFIG \ No newline at end of file diff --git a/src/config.h b/src/config.h index 1da4ccf..7e5798e 100644 --- a/src/config.h +++ b/src/config.h @@ -13,8 +13,8 @@ public: const string cgroup_proxy_preserved = CGROUP_PROXY_PRESVERED; const string cgroup_noproxy_preserved = CGROUP_NOPROXY_PRESVERED; - vector program_proxy; - vector program_noproxy; + vector program_proxy = {cgroup_proxy_preserved}; + vector program_noproxy = {cgroup_noproxy_preserved}; vector cgroup_proxy; vector cgroup_noproxy; bool enable_gateway = false;