mirror of
https://github.com/springzfx/cgproxy.git
synced 2026-01-07 13:07:56 +08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
892c6587dc | ||
|
|
8ea4062384 | ||
|
|
85e7bb3317 | ||
|
|
9d2c26e765 | ||
|
|
00cd293842 | ||
|
|
b8b70dcad5 | ||
|
|
5398740bf3 |
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.14)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
project(cgproxy VERSION 0.17)
|
||||
project(cgproxy VERSION 0.18)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
@@ -12,8 +12,10 @@ add_compile_options(-Wall -Wextra -Wpedantic -Wno-unused-result -Wno-unused-para
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# option(with_execsnoop "enable program level proxy control feature, need bcc installed" ON)
|
||||
option(build_execsnoop_dl "build libexecsnoop.so which will be dynamic loaded, otherwise built directly into cgproxy" ON)
|
||||
option(build_static "build with static link prefered" OFF)
|
||||
option(build_tools OFF)
|
||||
option(build_test OFF)
|
||||
option(build_test "for develop" OFF)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(execsnoop-kernel)
|
||||
|
||||
@@ -77,10 +77,11 @@ get_available_route_table(){
|
||||
# echo "table: $table fwmark: $fwmark, mark_newin: $mark_newin"
|
||||
|
||||
## cgroup things
|
||||
cgroup_mount_point=$(findmnt -t cgroup2 -n -o TARGET)
|
||||
cgroup_type="cgroup2"
|
||||
cgroup_procs_file="cgroup.procs"
|
||||
|
||||
[ -z ${cgroup_mount_point+x} ] && cgroup_mount_point=$(findmnt -t cgroup2 -n -o TARGET | head -n 1)
|
||||
[ -z $cgroup_mount_point ] && { >&2 echo "iptables: no cgroup2 mount point available"; exit -1; }
|
||||
[ ! -d $cgroup_mount_point ] && mkdir -p $cgroup_mount_point
|
||||
[ "$(findmnt -M $cgroup_mount_point -n -o FSTYPE)" != "cgroup2" ] && mount -t cgroup2 none $cgroup_mount_point
|
||||
[ "$(findmnt -M $cgroup_mount_point -n -o FSTYPE)" != "cgroup2" ] && { >&2 echo "iptables: mount $cgroup_mount_point failed"; exit -1; }
|
||||
|
||||
stop(){
|
||||
iptables -t mangle -L TPROXY_PRE &> /dev/null || return
|
||||
@@ -108,6 +109,8 @@ stop(){
|
||||
## may not exist, just ignore, and tracking their existence is not reliable
|
||||
iptables -t nat -D POSTROUTING -m owner ! --socket-exists -j MASQUERADE &> /dev/null
|
||||
ip6tables -t nat -D POSTROUTING -m owner ! --socket-exists -s fc00::/7 -j MASQUERADE &> /dev/null
|
||||
## unmount cgroup2
|
||||
[ "$(findmnt -M $cgroup_mount_point -n -o FSTYPE)" = "cgroup2" ] && umount $cgroup_mount_point
|
||||
}
|
||||
|
||||
## parse parameter
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
# find libbpf
|
||||
find_library(LIBBPF bpf)
|
||||
if (build_static)
|
||||
find_library(LIBBPF libbpf.a)
|
||||
else()
|
||||
find_library(LIBBPF bpf)
|
||||
endif()
|
||||
|
||||
if (LIBBPF-NOTFOUND)
|
||||
message(FATAL_ERROR "libbpf not found")
|
||||
endif()
|
||||
|
||||
add_library(execsnoop MODULE execsnoop_share.cpp)
|
||||
target_link_libraries(execsnoop PRIVATE bpf)
|
||||
install(TARGETS execsnoop DESTINATION ${CMAKE_INSTALL_LIBDIR}/cgproxy/)
|
||||
if (build_execsnoop_dl)
|
||||
add_library(execsnoop MODULE execsnoop_share.cpp)
|
||||
install(TARGETS execsnoop DESTINATION ${CMAKE_INSTALL_LIBDIR}/cgproxy/)
|
||||
target_link_libraries(execsnoop PRIVATE ${LIBBPF} -lelf -lz)
|
||||
else()
|
||||
add_library(execsnoop STATIC execsnoop_share.cpp)
|
||||
target_link_libraries(execsnoop PRIVATE ${LIBBPF} -l:libelf.a -l:libz.a)
|
||||
endif()
|
||||
|
||||
@@ -10,9 +10,11 @@ namespace CGPROXY::EXECSNOOP {
|
||||
|
||||
extern "C" void startThread(function<int(int)> c, promise<void> _status);
|
||||
|
||||
#ifdef BUIlD_EXECSNOOP_DL
|
||||
// only for dlsym()
|
||||
using startThread_t=decltype(startThread);
|
||||
startThread_t *_startThread;
|
||||
#endif
|
||||
|
||||
} // namespace CGPROXY::EXECSNOOP
|
||||
#endif
|
||||
|
||||
@@ -6,7 +6,7 @@ set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "cgproxy will transparent proxy anything r
|
||||
## deb pack
|
||||
set(CPACK_DEBIAN_PACKAGE_NAME "cgproxy")
|
||||
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "systemd, libbpf0")
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "systemd")
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION "network")
|
||||
set(CPACK_DEBIAN_PACKAGE_PRIORITY "Optional")
|
||||
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/springzfx/cgproxy")
|
||||
@@ -15,7 +15,7 @@ set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/postinst;${C
|
||||
|
||||
## rpm pack
|
||||
set(CPACK_RPM_PACKAGE_ARCHITECTURE, "x86_64")
|
||||
set(CPACK_RPM_PACKAGE_REQUIRES "systemd, libbpf")
|
||||
set(CPACK_RPM_PACKAGE_REQUIRES "systemd")
|
||||
set(CPACK_RPM_PACKAGE_GROUP "network")
|
||||
set(CPACK_RPM_PACKAGE_URL "https://github.com/springzfx/cgproxy")
|
||||
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/postinst")
|
||||
|
||||
32
readme.md
32
readme.md
@@ -53,25 +53,33 @@ Main feature:
|
||||
|
||||
ubuntu 16.04, debian 9, fedora 27 and later are desired
|
||||
|
||||
## How to install
|
||||
## How to build and install
|
||||
|
||||
### main depency
|
||||
### distro install
|
||||
|
||||
| os | build depency | runtime depency | download |
|
||||
| --------- | ------------------------------------------------------------ | ----------------------------------------------------- | ------------------------------------------------------------ |
|
||||
| Archlinux | clang, nlohmann-json, libbpf | libbpf | [archlinux AUR](https://aur.archlinux.org/packages/?K=cgproxy) |
|
||||
| Ubuntu | clang, nlohmann-json, [libbpf-dev](https://packages.ubuntu.com/groovy/libbpf-dev) | [libbpf0](https://packages.ubuntu.com/groovy/libbpf0) | [Release page](https://github.com/springzfx/cgproxy/releases) |
|
||||
| Fedora | clang, nlohmann-json,[libbpf](https://src.fedoraproject.org/rpms/libbpf) | [libbpf](https://src.fedoraproject.org/rpms/libbpf) | [Release page](https://github.com/springzfx/cgproxy/releases) |
|
||||
- For debian and redhat series, download from [Release page](https://github.com/springzfx/cgproxy/releases)
|
||||
|
||||
tested in arch and ubuntu 20.04.
|
||||
- For archlinux series, see[archlinux AUR](https://aur.archlinux.org/packages/?K=cgproxy)
|
||||
|
||||
- **Tested on archlinux, fedora 32, ubuntu 18.04, ubuntu 20.04, deepin 15.11, deepin v20 beta**
|
||||
|
||||
### build
|
||||
|
||||
- before build, install depencies: clang, nlohmann-json, libbpf
|
||||
- then cmake standard build
|
||||
|
||||
```bash
|
||||
#
|
||||
mkdir build && cd build
|
||||
# cmake
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr .. && make install
|
||||
# ready build dir
|
||||
mkdir build
|
||||
cd build
|
||||
# generate
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-Dbuild_execsnoop_dl=ON \
|
||||
-Dbuild_static=OFF \
|
||||
..
|
||||
# compile
|
||||
make
|
||||
```
|
||||
|
||||
## Default usage
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
include_directories(${PROJECT_SOURCE_DIR})
|
||||
include_directories(${PROJECT_SOURCE_DIR}/execsnoop-kernel/)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_executable(main main.cpp
|
||||
common.cpp config.cpp cgroup_attach.cpp
|
||||
socket_client.cpp socket_server.cpp)
|
||||
target_link_libraries(main PRIVATE nlohmann_json::nlohmann_json Threads::Threads ${CMAKE_DL_LIBS})
|
||||
set_target_properties(main PROPERTIES LINKER_LANGUAGE CXX)
|
||||
|
||||
if (build_execsnoop_dl)
|
||||
add_definitions(-DBUIlD_EXECSNOOP_DL)
|
||||
set(DL_LIB "-ldl")
|
||||
set(EXECSNOOP_LIB "")
|
||||
else()
|
||||
set(EXECSNOOP_LIB "execsnoop")
|
||||
endif()
|
||||
|
||||
add_executable(main main.cpp common.cpp config.cpp cgroup_attach.cpp socket_client.cpp socket_server.cpp)
|
||||
target_link_libraries(main PRIVATE nlohmann_json::nlohmann_json ${DL_LIB} ${EXECSNOOP_LIB})
|
||||
set_target_properties(main PROPERTIES OUTPUT_NAME cgproxy)
|
||||
install(TARGETS main RUNTIME)
|
||||
|
||||
# # execsnoop related
|
||||
# set(execsnoop ${PROJECT_SOURCE_DIR}/execsnoop-libbpf/libexecsnoop.so)
|
||||
# add_custom_command(OUTPUT ${execsnoop}
|
||||
# COMMAND make CFLAGS=\"-O2 -Wall -s -DNDEBUG\" libexecsnoop.so
|
||||
# WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/execsnoop-libbpf
|
||||
# BYPRODUCTS ${PROJECT_SOURCE_DIR}/execsnoop-libbpf/build
|
||||
# )
|
||||
# add_custom_target(execsnoop ALL DEPENDS ${execsnoop})
|
||||
# install(PROGRAMS ${execsnoop} DESTINATION ${CMAKE_INSTALL_LIBDIR}/cgproxy/)
|
||||
if (build_static)
|
||||
target_link_libraries(main PRIVATE -static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive)
|
||||
else()
|
||||
target_link_libraries(main PRIVATE -lpthread)
|
||||
endif()
|
||||
|
||||
@@ -26,6 +26,7 @@ using namespace ::CGPROXY::CONFIG;
|
||||
using namespace ::CGPROXY::CGROUP;
|
||||
// using namespace ::CGPROXY::EXECSNOOP;
|
||||
|
||||
#ifdef BUIlD_EXECSNOOP_DL
|
||||
namespace CGPROXY::EXECSNOOP {
|
||||
bool loadExecsnoopLib() {
|
||||
try {
|
||||
@@ -48,6 +49,7 @@ bool loadExecsnoopLib() {
|
||||
}
|
||||
}
|
||||
} // namespace CGPROXY::EXECSNOOP
|
||||
#endif
|
||||
|
||||
namespace CGPROXY::CGPROXYD {
|
||||
|
||||
@@ -232,14 +234,21 @@ class cgproxyd {
|
||||
}
|
||||
|
||||
void startExecsnoopThread() {
|
||||
#ifdef BUIlD_EXECSNOOP_DL
|
||||
if (!EXECSNOOP::loadExecsnoopLib() || EXECSNOOP::_startThread == NULL) {
|
||||
error("execsnoop not ready to start, maybe missing libbpf");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
promise<void> status;
|
||||
future<void> status_f = status.get_future();
|
||||
#ifdef BUIlD_EXECSNOOP_DL
|
||||
thread th(EXECSNOOP::_startThread, handle_pid_static, move(status));
|
||||
#else
|
||||
thread th(EXECSNOOP::startThread, handle_pid_static, move(status));
|
||||
#endif
|
||||
|
||||
execsnoop_thread = move(th);
|
||||
|
||||
future_status fstatus = status_f.wait_for(chrono::seconds(THREAD_TIMEOUT));
|
||||
|
||||
@@ -14,19 +14,8 @@
|
||||
|
||||
namespace CGPROXY::CGROUP {
|
||||
|
||||
string cgroup2_mount_point = get_cgroup2_mount_point();
|
||||
string cgroup2_mount_point = CGROUP2_MOUNT_POINT;
|
||||
|
||||
string get_cgroup2_mount_point() {
|
||||
stringstream buffer;
|
||||
unique_ptr<FILE, decltype(&pclose)> fp(popen("findmnt -t cgroup2 -n -o TARGET", "r"),
|
||||
&pclose);
|
||||
if (!fp) return "";
|
||||
char buf[READ_SIZE_MAX];
|
||||
while (fgets(buf, READ_SIZE_MAX, fp.get()) != NULL) { buffer << buf; }
|
||||
string s = buffer.str();
|
||||
if (!s.empty()) s.pop_back(); // remove newline character
|
||||
return s;
|
||||
}
|
||||
|
||||
bool validate(string pid, string cgroup) {
|
||||
bool pid_v = validPid(pid);
|
||||
|
||||
@@ -8,7 +8,6 @@ using namespace std;
|
||||
namespace CGPROXY::CGROUP {
|
||||
extern string cgroup2_mount_point;
|
||||
bool validate(string pid, string cgroup);
|
||||
string get_cgroup2_mount_point();
|
||||
int attach(const string pid, const string cgroup_target);
|
||||
int attach(const int pid, const string cgroup_target);
|
||||
int write2procs(string pid, string procspath);
|
||||
|
||||
@@ -11,6 +11,7 @@ using namespace std;
|
||||
#define TPROXY_IPTABLS_CLEAN "/usr/share/cgproxy/scripts/cgroup-tproxy.sh stop"
|
||||
|
||||
#define LIBEXECSNOOP_SO "/usr/lib/cgproxy/libexecsnoop.so"
|
||||
#define CGROUP2_MOUNT_POINT "/var/run/cgproxy/cgroup2"
|
||||
#define PID_LOCK_FILE "/var/run/cgproxyd.pid"
|
||||
#define SOCKET_PATH "/tmp/cgproxy_unix_socket"
|
||||
#define LISTEN_BACKLOG 64
|
||||
|
||||
@@ -21,6 +21,7 @@ using json = nlohmann::json;
|
||||
namespace CGPROXY::CONFIG {
|
||||
|
||||
void Config::toEnv() {
|
||||
setenv("cgroup_mount_point", CGROUP2_MOUNT_POINT, 1);
|
||||
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);
|
||||
|
||||
@@ -2,11 +2,4 @@ include_directories(${PROJECT_SOURCE_DIR})
|
||||
include_directories(${PROJECT_SOURCE_DIR}/src)
|
||||
|
||||
add_executable(cgattach cgattach.cpp ../src/cgroup_attach.cpp ../src/common.cpp)
|
||||
install(TARGETS cgattach DESTINATION /usr/bin PERMISSIONS ${basic_permission})
|
||||
|
||||
if (with_execsnoop)
|
||||
add_executable(execsnoop_exec execsnoop.cpp ../src/common.cpp ../src/execsnoop.cpp)
|
||||
set_target_properties(execsnoop_exec PROPERTIES OUTPUT_NAME execsnoop)
|
||||
target_link_libraries(execsnoop_exec bcc)
|
||||
install(TARGETS execsnoop_exec DESTINATION /usr/bin PERMISSIONS ${basic_permission})
|
||||
endif()
|
||||
install(TARGETS cgattach DESTINATION /usr/bin PERMISSIONS ${basic_permission})
|
||||
@@ -1,24 +0,0 @@
|
||||
#include "execsnoop.h"
|
||||
#include "common.h"
|
||||
#include <unistd.h>
|
||||
using namespace std;
|
||||
using namespace CGPROXY::EXECSNOOP;
|
||||
|
||||
#define PATH_MAX_LEN 128
|
||||
|
||||
int handle_pid(int pid) {
|
||||
char path[PATH_MAX_LEN];
|
||||
auto size = readlink(to_str("/proc/", pid, "/exe").c_str(), path, PATH_MAX_LEN);
|
||||
if (size == -1) error("readlink: %s", to_str("/proc/", pid, "/exe").c_str());
|
||||
path[size] = '\0';
|
||||
info("%d %s", pid, path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
enable_debug = true;
|
||||
enable_info = true;
|
||||
callback = handle_pid;
|
||||
execsnoop();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user