특정 cgroup(버전 2)의 프로세스에 의해 생성된 모든 패킷의 소스 주소를 변경하고 싶습니다. 가능합니까?
나는 가지고있다:
nftables 1.0.2
,linux 5.15
(우분투 버전)/system.slice/system-my-service.slice/[email protected]
그룹
나는 이전에 시도했습니다:
- 테이블 만들기
nft add table ip myservice
- 라우팅 후 NAT 체인 생성
nft add chain ip myservice postrouting { type nat hook postrouting priority 100 \; }
- 포스트 라우팅 규칙을 만들어 보십시오 (실험 중에는 nft 에 cgroup 이름에 문제가 있었고 이것은 레벨 2 문제이기 때문에
nft add rule ip myservice postrouting socket cgroupv2 level 1 'system.slice' snat 10.0.0.1
이것을 사용했습니다 :-).'system.slice'
@
또한 int32 매개변수가 필요한 일치 항목을 찾았습니다 cgroup
. 경로 스타일 cgroup을 int로 변환하기 위한 힌트를 찾을 수 없었기 때문에 cgroup 버전 1인 것으로 추측했습니다(따라서 나에게는 적용되지 않음).
나는 이 표현이 그림 1에 표시된 socket
것처럼 라우팅 후 nat 체인에 적용되지 않는다고 생각합니다 .nft
Error: Could not process rule: Operation not supported
모든 실패는 이것이 완전히 잘못된 접근 방식이라는 것을 의미합니까? 아니면 제가 뭔가 분명한 것을 놓치고 있는 걸까요?
답변1
두 가지 질문에 대한 답변은 다음과 같습니다.
통사론
cgroupv2
문자열인 경로가 필요합니다. 문자열은 항상 큰따옴표로 표시되며, 특수 문자가 포함된 경우 필요합니다. 이러한 큰따옴표는nft
셸이 아닌 명령에서 사용하기 위한 것입니다. 직접 명령(예: read 를 사용하는 파일이 아닌 경우nft -f
)의 경우 이러한 큰따옴표 자체는 이스케이프되거나 작은따옴표로 묶어야 합니다. 그렇지 않으면 쉘이 이를 사용합니다.또한 경로는 다음과 같이 기록됩니다.비교적
/
쉘에서 직접 제공하면 선행이 필요하지 않습니다 (어쨌든 다시 표시될 때 허용되고 제거됩니다).socket cgroupv2 level 3 '"system.slice/system-my-service.slice/[email protected]"'
마지막으로,
nft
여러 태그가 있는 단일 인수를 제공하는지, 아니면 한 번에 하나의 태그를 여러 인수에 제공하는지 여부는 중요하지 않습니다. 라인의 어셈블리와 구문 분석은 동일합니다. 따라서 쉘에 특수 문자(here )가 있을 때마다 문자를 이스케이프할 위치( 기본 체인에서"
와 같이)를 찾는 대신 작은따옴표로 모든 줄을 인용하십시오 .\;
제한사항 해결
출력 후크에서 패킷에 태그를 지정하고 NAT용 포스트 경로 후크에서 태그를 확인할 수 있습니다.
nft 'add chain ip myservice { type filter hook output priority 0; policy accept; }' nft 'add rule ip myservice output socket cgroupv2 level 3 "system.slice/system-my-service.slice/[email protected]" meta mark set 0xcafe' nft add rule ip myservice postrouting meta mark 0xcafe snat to 10.0.0.1
최종 결과는 처음에 두 개의 접착제 명령을 사용하여 자체 파일에 배치할 수 있습니다.멱등성. 자체 파일이 있으면 쉘 구문 분석과의 상호 작용이 방지되고 원자성 업데이트가 이루어집니다. 여전히 "..."
경로 매개변수를 우회 해야 합니다 .nftables@
역할을 설명하세요 .
myservice.nft
:
table ip myservice
delete table ip myservice
table ip myservice {
chain postrouting {
type nat hook postrouting priority 100; policy accept;
meta mark 0xcafe snat to 10.0.0.1
}
chain output {
type filter hook output priority 0; policy accept;
socket cgroupv2 level 3 "system.slice/system-my-service.slice/[email protected]" meta mark set 0xcafe
}
}
nft -f myservice.nft
cgroup이 이미 존재하는 한 로드할 수 있습니다(이는 부팅 시 서비스를 시작해야 함을 의미할 수 있음).nftables이 규칙을 로드합니다).
결국 :
나가는 모든 패킷은 필터/출력을 통과합니다.
- 적절한 과정을 거쳐 나온 것이라면그룹패킷은 0xcafe 태그를 수신합니다.
새로운 흐름의 모든 첫 번째 패킷은 nat/postrouting 규칙을 통과합니다.
- 0xcafe 태그와 일치하는 경우(적절한 위치에 있음을 의미)그룹) 그러면 흐름에 대한 SNAT 규칙이 트리거됩니다(그러면 태그는 더 이상 중요하지 않습니다).