背景

背景

cgroup v2階層で実行されているcgroupプロセスiptables

$ 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コントローラは、1つの階層(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

関連情報