배경

배경

cgroup v2 계층 구조에서 실행 중인 프로세스 cgroupiptables.

$ grep CGROUP <kernel_config>
CONFIG_CGROUPS=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
# CONFIG_CGROUP_RDMA is not set
CONFIG_CGROUP_FREEZER=y
# CONFIG_CGROUP_HUGETLB is not set
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
# CONFIG_CGROUP_BPF is not set
# CONFIG_CGROUP_DEBUG is not set
CONFIG_SOCK_CGROUP_DATA=y
**CONFIG_NETFILTER_XT_MATCH_CGROUP=m**
CONFIG_NET_CLS_CGROUP=m
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y

$ lsmod | grep cgroup
xt_cgroup              16384  2
x_tables               36864  7 xt_LOG,xt_cgroup,iptable_mangle,ip_tables,iptable_filter,xt_mark,ipt_MASQUERADE

이는 다음 cgroup이 설치된 systemd-235를 사용하는 Debian 기반 배포판입니다.

$ mount | grep cgroup
tmpfs on /sys/fs/cgroup type tmpfs (rw,mode=755)
cgroup on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)

cgroup v1을 사용하고 다음을 수행하는 경우 net_cls:

$ cd /sys/fs/cgroup/net_cls,net_prio/
$ mkdir test
$ echo 1 > test/net_cls.classid
$ iptables -A OUTPUT -m cgroup --cgroup 1 -j LOG
$ ping -i 2 google.com &>/dev/null &
$ pgrep ping > test/tasks

로그에서 패킷을 볼 수 있습니다. cgroup v2에 대해 동일한 작업을 수행하면 iptables 규칙이 성공적으로 추가되었지만 일치하지 않습니다.

$ cd /sys/fs/cgroup/unified/
$ mkdir test
$ iptables -A OUTPUT -m cgroup --path test -j LOG
$ ping -i 2 google.com &>/dev/null &
$ pgrep ping > test/cgroup.procs

프로세스는 이 cgroup 내에서 실행됩니다.

$ cat /proc/<pid>/cgroup
0::/test

그리고 iptables잘못된 cgroup 경로에 대한 불만은 없지만 로그에는 아무 것도 표시되지 않습니다.

배경

LAN 외부의 모든 패킷을 처리하려면 VPN 트래픽 외부에서 Tor 릴레이를 실행해야 합니다. 나는 다음에 설명된 접근 방식을 따랐습니다.이 답변그리고 그것은 훌륭하게 작동합니다(cgroup v1 사용). 문제는 시작 시 사용자 정의 cgroup을 생성하고( cgmanagercgroup v2 지원이 부족하여 시작할 수 없음) 여기에 tor 프로세스를 할당하는 간단한 방법을 찾지 못한다는 것입니다(서비스에서 이 작업을 수행하는 방법은 무엇입니까 systemd?). 그러나 systemd통합 cgroup v2 계층 내에서 각 서비스에 대해 별도의 cgroup을 생성하므로 tor 프로세스는 system.slice/system-tor.slice위의 간단한 예에서 볼 수 있듯이 iptables가 이 트래픽을 일치시킬 수 없는 것 같습니다.

답변1

귀하의 질문에 대한 답변 중 일부는 귀하가 링크한 답변에 있습니다.

이미 실행 중인 프로세스를 cgroup으로 옮기고 싶다면... 그럴 수 없습니다! (...) iptables (...) cgroup 전환 시 불일치

음, iptables는 일치합니다때때로이 경우 cgroup v1 로깅 규칙과 같습니다.

그럼에도 불구하고 iptables는 항상 이동된 프로세스와 일치하는 것 같습니다.어린이들, 올바른 cgroup을 사용하여 즉시 생성되기 때문입니다. 따라서 해결책은 새 셸을 시작하고, 셸을 cgroup으로 이동하고, 이 새 셸에서 필요한 명령을 실행하는 것입니다.

sh -c "echo \$$ > /sys/fs/cgroup/unified/test/cgroup.procs && ping 8.8.8.8"

cgroup에 네트워크 활동이 없는 경우(또는 해당 네트워크 트래픽이 cgroup 규칙의 영향을 받는지 상관하지 않는 경우) subsheel을 호출하는 대신 cgroup에서 호출 스크립트를 직접 이동할 수도 있습니다.

echo $$ > /sys/fs/cgroup/unified/test/cgroup.procs && ping 8.8.8.8

편집 : 업데이트노바티스 네트웍스-2플래그로 cgroups v2를 지원합니다 .

하지만 작동해야 할까요?

cgroup v2에 대한 이 답변이 실제로 작동한다는 사실에 조금 놀랐습니다.이 문제- 자세한 내용은노트이 페이지의.

cgroup 컨트롤러는 하나의 계층 구조(v1 또는 v2)에만 설치할 수 있습니다.

$ cat /proc/cgroups
#subsys_name    hierarchy   num_cgroups enabled
...
net_cls         3           1           1

이는 net_cls 컨트롤러가 cgroup v1에 바인딩되어 있지만(그렇지 않으면 계층 구조가 0이 됨) iptables는 여전히 cgroup v2 매개변수를 사용할 수 있음을 의미합니다. 내 이해는 다음과 같습니다. net_cls 네트워크 컨트롤러는 cgroup v2 cgroup 네임스페이스로 대체된 cgroup v1 개념일 뿐입니다. 따라서 운영 체제가 cgroup v1과 v2를 모두 지원하는 경우 iptables cgroup v1 및 iptables cgroup v2 규칙을 모두 사용할 수 있는 것으로 보입니다.

네트워크 제어 그룹에서 서비스 실행에 대한 배경 정보:

기본적으로 cgroup v2로 전환된 Fedora 31을 제외하면 현재 대부분의 배포판에서는 여전히 기본적으로 cgroup v1을 사용합니다. cgmanager실제로 필요하지 않으며 최근에 연결된 답변의 요구 사항에서 제거했습니다.

cgmanagersystemd자체 cgroup 관리 구현을 위해 Bionic에서는 더 이상 사용되지 않고 제거되었습니다 . 불행하게도 systemd관리자는떨어졌다cgroup v2에 초점을 맞춘 cgroup v1의 NetClass 옵션입니다.

systemd따라서 cgroup v1을 사용하면 도움말 서비스 실행 프로그램 없이 필요한 서비스 기본 프로세스(예: Tor 릴레이, Apache 실행 파일 등)를 실행하기 전에 이러한 모든 단계를 수행해야 하므로 네트워크 제어 그룹에서 서비스를 실행하는 것이 까다로워집니다 .

  1. cgroup 생성
  2. iptables 규칙 생성(cgroup v2에도 동일한 문제가 있음)
  3. 올바른 cgroup에서 서비스 기본 프로세스를 시작(이동하지 않음)합니다. 예를 들어 apache2의 경우 직접 상위 프로세스가 cgroup으로 이동할 수 있는 임의의 하위 쉘이 아니라 일반적으로 시스템화(PID=1)되기 때문에 까다롭습니다.

이는 시스템 단위 서비스 초기화 스크립트를 통해 달성할 수 있습니다. 그렇지 않으면 cgconfig사용할 수 있습니다.이 질문/답변cgrulesengdUbuntu의 경우 - 방해가 될 수 있으므로 멀리하겠습니다 systemd.

답변2

~에 따르면https://www.spinics.net/lists/netdev/msg352495.htmlv2 cgroup의 올바른 구문은 다음과 같습니다.

iptables -A OUTPUT -m cgroup ! --path test -j LOG

관련 정보