VPN 클라이언트 풀마다 대상 범위 하나를 차단하기
nftables 규칙 하나로 허용된 VPN 풀에 대상 프리픽스를 거부할 수 있습니다. 게이트웨이 자체 트래픽은 건드리지 않습니다. 훅과 위치를 맞추십시오.
규칙 하나로 허용된 VPN 풀을 대상 범위에서 멀어지게 할 수 있으며, 게이트웨이가 하는 다른 일은 방해하지 않습니다. 규칙 자체는 짧습니다. 작동 여부를 결정하는 것은 규칙이 사는 훅과 체인 내 위치입니다. 이 둘을 틀리면 올바르게 보이지만 동작이 일관되지 않은 방화벽이 됩니다. 규칙이 패킷을 볼 때 패킷이 무엇을 하는지부터 시작하십시오.
규칙이 실제로 일치시키는 것
이 규칙은 세 가지를 동시에 일치시킵니다. 입력 인터페이스, 출발지 프리픽스, 목적지 프리픽스입니다. 드롭이 적용되려면 셋 모두 참이어야 하며, 그것이 규칙을 좁게 유지합니다. 세 개의 별도 정책으로 읽는 것보다 하나의 표현식으로 읽는 편이 쉽습니다.
인터페이스 일치는 전달되는 클라이언트 트래픽을 게이트웨이 자체 연결과 구분합니다. 이것이 없으면 출발지 풀만 지정한 규칙은 게이트웨이가 그 주소에서 직접 생성하는 패킷에도 영향을 줍니다(그런 일이 있다면). 출발지 프리픽스는 정책을 허용된 클라이언트로 제한하고, 목적지 프리픽스는 하나의 범위로 제한합니다. 규칙은 목록이 아니라 교집합으로 읽으십시오.
무엇이든 편집하기 전에 세 값을 적어 두십시오. 터널 인터페이스 이름, 서버가 나눠 주는 풀, 거부하려는 프리픽스입니다. 어느 하나에 오타가 있으면 깔끔하게 파싱되지만 아무것도 보호하지 않는 규칙이 됩니다. 그 세 값은 규칙 옆 변경 기록에 남겨 두십시오.
훅이 규칙의 적용 대상을 결정한다
netfilter 체인은 훅에 연결되며, 어떤 패킷을 체인이 보는지 결정하는 것은 훅입니다. forward 훅은 게이트웨이를 거쳐 라우팅되는 트래픽을 봅니다. 이것이 클라이언트에서 목적지로 가는 트래픽입니다. 체인의 나머지는 다른 대상을 향합니다.
input 훅은 게이트웨이 자체로 향하는 트래픽을 보므로, 거기에 둔 규칙은 통과 트래픽이 아니라 자체 서비스 접근을 제어합니다. output 훅은 게이트웨이가 생성하는 트래픽을 보는데, 이는 클라이언트 풀 정책이 필요로 하는 것과 반대입니다. 체인 이름은 규칙 집합을 쓴 사람이 고른 임의의 레이블이므로 이름에서 훅을 추론하지 마십시오. 체인이 어디에 연결되어 있는지 확인한 뒤 무엇을 일치시킬 수 있는지 가정하십시오.
| Hook | Traffic it sees | Right for this policy |
|---|---|---|
| input | Addressed to the gateway | No, that is the host's own services |
| forward | Routed through the gateway | Yes, for client-to-destination traffic |
| output | Generated by the gateway | No, that is the opposite direction |
연결 지점을 읽는 것은 한 줄짜리 점검이며, 패킷을 결코 보지 못하는 체인에 규칙이 떨어지는 것을 막습니다.
넓은 accept보다 앞에 규칙을 두십시오
규칙은 순서대로 평가되고 첫 판정이 이깁니다. 체인 앞쪽의 넓은 accept는 자신이 일치시키는 패킷에 대한 평가를 끝내므로, 뒤에 추가한 드롭은 그 패킷에 대해 결코 실행되지 않습니다. 이 순서 규칙이 올바르게 보이는 규칙이 효과를 내지 못하는 이유의 전부입니다.
끝에 덧붙이지 말고 accept 앞에 삽입하십시오. 체인에 터널 인터페이스에 대한 일반 accept가 이미 있다면 새 규칙은 그보다 앞서야 하며, 그렇지 않으면 장식일 뿐입니다. 편집한 파일이 아니라 결과 순서를 확인하십시오. 여러 파일에서 조립한 규칙 집합은 어느 하나와도 일치하지 않을 수 있습니다. 그런 다음 풀에서 온 시험 패킷으로 확인하십시오.
sudo nft list chain inet filter forward
sudo nft insert rule inet filter forward iifname "tun0" ip saddr 10.90.0.0/24 ip daddr 198.51.100.0/24 drop
sudo nft -c -f /etc/nftables.conf
세 번째 명령은 파일을 적용하지 않고 파싱하므로 구문 오류가 장애가 되기 전에 잡습니다. 롤백 계획과 함께 적용하십시오. forward 체인의 잘못된 규칙은 작업 중인 터널을 끊을 수 있습니다.
기존 흐름은 새 규칙을 신경 쓰지 않는다
규칙이 존재하기 전에 만들어진 conntrack 항목은 이전 accept에 계속 일치합니다. 그래서 새 드롭이 새 연결에는 효과가 있는 것처럼 보이면서 시험 중인 연결에는 아무 일도 하지 않는 경우가 있습니다.
체인 맨 위의 상태 일치를 읽으십시오. 규칙보다 먼저 established와 related 트래픽을 수락한다면, 이미 진행 중인 모든 흐름은 닫힐 때까지 계속 흐릅니다. 긴급 규칙에서는 보통 이것이 원하는 동작이며, 즉시 차단을 기대할 때는 혼란스럽습니다. 배포 전에 어떤 효과를 원하는지 결정하십시오. 열린 연결을 재사용하는 시험은 잘못된 이야기를 들려줍니다.
sudo conntrack -L -s 10.90.0.14 -d 198.51.100.20
sudo nft list ruleset | grep -n -A3 'ct state'
첫 번째 명령은 흐름이 있는지 보여 주고, 두 번째는 초기 상태 규칙이 그것을 계속 수락하는지 보여 줍니다. 둘 다 읽기 전용이며 사고 중에 실행해도 안전합니다.
이 규칙이 아닌 것
이 규칙은 도메인 블랙리스트도, IPv6 정책도, 개별 애플리케이션 계정에 대한 제한도 아닙니다.
그 각각은 고유한 메커니즘이 필요합니다. 도메인 차단은 이름을 해석해야 하는데 패킷 필터는 그러지 않습니다. IPv6 트래픽은 자체 일치가 필요합니다. ip 표현식은 ip6 패킷에 대해 아무 말도 하지 않습니다. 애플리케이션 수준 제한은 프리픽스 일치가 아니라 서비스나 인증된 프록시에 속합니다. 이런 요구를 분리해 두는 것이 좁은 규칙 하나에 네 가지 일을 요구하지 않게 합니다.
이 규칙이 제공하는 계약은 정확합니다. 허용된 풀에서 하나의 목적지 프리픽스로 가는 트래픽은 거부되고, 무관한 게이트웨이 트래픽은 기존 정책을 유지합니다. 그 문장을 규칙 옆에 적어 두면 다음 사람이 무엇을 위한 것인지 알게 됩니다.