저는 NixOS 22.11(최신 XanMod 커널 패치 및 acpid 및 irqbalance 활성화됨)을 실행하는 라우터에서 nftables를 사용하고 있습니다. 이 기계에는 인터넷에 연결되는 enp4s0과 서로 다른 IP LAN을 제공하는 두 개의 로컬 WiFi 액세스 포인트 wlp1s0 및 wlp5s0의 3가지 인터페이스가 있습니다.
내 nftables 구성은 다음과 같습니다. 로컬 네트워크에서 인바운드 DNS, DHCP 및 SSH 트래픽만 허용하고 인터넷으로의 아웃바운드 및 전달 트래픽과 SNAT를 허용합니다.
table ip filter {
chain conntrack {
ct state vmap { invalid : drop, established : accept, related : accept }
}
chain dhcp {
udp sport 68 udp dport 67 accept comment "dhcp"
}
chain dns {
ip protocol { tcp, udp } th sport 53 th sport 53 accept comment "dns"
}
chain ssh {
ip protocol tcp tcp dport 22 accept comment "ssh"
}
chain in_wan {
jump dns
jump dhcp
jump ssh
}
chain in_iot {
jump dns
jump dhcp
}
chain inbound {
type filter hook input priority filter; policy drop;
icmp type echo-request limit rate 5/second accept
jump conntrack
iifname vmap { "lo" : accept, "wlp1s0" : goto in_wan, "enp4s0" : drop, "wlp5s0" : goto in_iot }
}
chain forward {
type filter hook forward priority filter; policy drop;
jump conntrack
oifname "enp4s0" accept
}
}
table ip nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oifname "enp4s0" snat to 192.168.1.2
}
}
table ip6 global6 {
chain input {
type filter hook input priority filter; policy drop;
}
chain forward {
type filter hook forward priority filter; policy drop;
}
}
이 간단한 구성에서는 KDE Connect가 작동하지 않을 것으로 예상했습니다.1714-1764 포트를 열어야 하기 때문에. 실제로 컴퓨터를 wlp1s0에 연결하고 휴대폰을 wlp5s0(다른 인터페이스)에 연결하면 장치가 서로를 볼 수 없으며 로깅 규칙이나 nftrace를 사용하여 tcpdump 및 nftables를 통해 패킷을 볼 수 있습니다.
그러나 이제 두 시스템을 동일한 인터페이스(예: wlp1s0)에 배치하면 KDE Connect가 제대로 작동하고 장치가 서로를 볼 수 있습니다. 내 추측으로는 연결 추적 때문에 이런 일이 발생하는 것 같지만, 추가하더라도
chain trace_wan {
type filter hook prerouting priority filter - 1; policy accept;
iifname "wlp1s0" oifname "wlp1s0" meta nftrace set 1
}
테이블 로 filter
이동하면 실행할 때 패킷이 표시되지 않습니다 nft monitor trace
. 마찬가지로 체인의 인덱스 0에 로깅 규칙을 삽입하면 syslog에 어떤 패킷도 표시되지 않습니다 forward
. 그러나 런타임에는 tcpdump -i wlp1s0 port 1716
nftables에서도 볼 수 있었으면 하는 패킷을 볼 수 있습니다.
14:33:59.943462 IP 192.168.2.11.55670 > 192.168.2.42.xmsg: Flags [.], ack 20422, win 501, options [nop,nop,TS val 3319725685 ecr 2864656484], length 0
14:33:59.957101 IP 192.168.2.42.xmsg > 192.168.2.11.55670: Flags [P.], seq 20422:20533, ack 1, win 285, options [nop,nop,TS val 2864656500 ecr 3319725685], length 111
두 장치가 동일한 인터페이스에 연결되어 있을 때 nftables가 이러한 패킷을 볼 수 없는 이유는 무엇입니까? nftables가 기본적으로 전달된 모든 패킷을 삭제하도록 하려면 어떻게 해야 합니까?
의견에서 요청한 추가 정보:
❯ ip -br link
lo UNKNOWN <LOOPBACK,UP,LOWER_UP>
enp2s0 DOWN <BROADCAST,MULTICAST>
enp3s0 DOWN <BROADCAST,MULTICAST>
enp4s0 UP <BROADCAST,MULTICAST,UP,LOWER_UP>
wlp5s0 UP <BROADCAST,MULTICAST,UP,LOWER_UP>
wlp1s0 UP <BROADCAST,MULTICAST,UP,LOWER_UP>
❯ ip -4 -br address
lo UNKNOWN 127.0.0.1/8
enp4s0 UP 192.168.1.2/24
wlp5s0 UP 192.168.3.1/24
wlp1s0 UP 192.168.2.1/24
❯ bridge link
❯ ip route
default via 192.168.1.1 dev enp4s0 proto static
192.168.1.0/24 dev enp4s0 proto kernel scope link src 192.168.1.2
192.168.1.1 dev enp4s0 proto static scope link
192.168.2.0/24 dev wlp1s0 proto kernel scope link src 192.168.2.1
192.168.3.0/24 dev wlp5s0 proto kernel scope link src 192.168.3.1
❯ sysctl net.bridge.bridge-nf-call-iptables
sysctl: error: 'net.bridge/bridge-nf-call-iptables' is an unknown key
답변1
경고: 이것은 일반적인 Linux 답변입니다. 이 답변에서는 NixOS와의 특정 통합 및 자체 네트워크 구성 방법이나 구성에서 임의 명령을 호출하는 방법을 다루지 않습니다.
홍보회의
OP의 첫 번째 경우(두 개의 서로 다른 인터페이스)라우터실제로 두 인터페이스 간의 경로wlp1s0그리고wlp5s0: 전달된 IPv4 트래픽은 다음에 표시됩니다.nftables'홈 IP, 필터 전달 후크.
두 번째 경우의 유량은 다음과 같습니다.브리지된라우터의 액세스 포인트 인터페이스를 통해wlp1s0:nftables'홈 IP테이블에는 브리지 트래픽이 표시되지 않고 IPv4 트래픽만 표시됩니다.
게다가 이 브리징은 표준 Linux 브리징 수준에서도 발생하지 않고 액세스 포인트(AP)의 드라이버(및/또는 하드웨어 가속기)에 의해 직접 수행됩니다. 두 Wi-Fi 장치는 둘 사이에서 통신합니다(여전히 AP) 해당 프레임은 실제 네트워크 스택에 도달하지 않습니다.
시스템이 실제로 이 트래픽을 필터링하려면 다음 세 가지 일이 발생해야 합니다.
- 트래픽이 네트워크 스택을 통과하도록 AP 설정을 변경합니다.
- 네트워크 스택이 프레임을 삭제하지 않도록 AP와 연결된 Linux 브리지를 갖습니다.nftables다리 수준에서 볼 수 있습니다.
- 충분하다nftables브리지 가족 규칙. ~을 위한Bridge 시리즈의 IP 상태 저장 방화벽, Linux 커널 5.3 이상이 필요합니다(NixOS 22.11이면 충분함).
선택하지 않은 다른 옵션:
2+3에 대한 대안으로 상태 저장 방화벽이 없을 경우 다음을 사용하는 것을 상상할 수 있습니다.nftables'웹 개발자입구와 출구가 있는 집(필수)리눅스 커널 >= 5.17수출용
fwd
), 그러나 처리해야 할 특수한 경우가 많이 있을 것입니다. 하지 않는 것이 좋습니다.3 대신에 다음을 사용하십시오.오래된 브리지 네트워크 필터 코드브리지 경로에 사용하기 위한 상태 저장 방화벽iptables(그리고 Docker에서 사용됨) 모든 규칙을 동일한 테이블에 넣습니다.
nftables역시 영향을 받는 는 이 코드에 의존하지 않도록 의도되었기 때문에 올바른 사용을 위한 기능이 부족합니다(대부분 다음과 동등한 기능이 부족합니다).iptables'
physdev
모듈 방식동일한 규칙 세트에서 브리지 트래픽과 라우팅 트래픽 구별). 이렇게 하면 상황이 여전히 의존하게 됩니다.iptables따라서 여전히 여러 테이블이 필요합니다. (Docker에서 이러한 복잡한 사용법의 예:nftables 화이트리스트 도커).경고로서, Docker를 라우터에 추가하면 아래 설명된 설정이 중단될 수 있습니다.
설정
변화주인설정
두 가지 관련 설정을 변경해야 합니다.주인설정:
프레임이 네트워크 스택에 의해 처리되어야 하고 드라이버에 의해 단락되지 않아야 함을 알려줍니다.
구성은 다음과 같습니다주인~을 위한wlp1s0변화해야 합니다. 두 Wi-Fi 인터페이스 모두에 대해 단일 구성이 있었다면 이제 두 개의 별도 구성이 있어야 할 것입니다. 이 답변에서는 이 통합에 대해 논의하지 않지만 단일 인터페이스에 중점을 둡니다.wlp1s0.
AP 격리다음에서 활성화해야 합니다
hostapd.conf
.ap_isolate=1
이제 두 스테이션 클라이언트(STA) 간의 프레임이 AP 드라이버에 의해 직접 처리되지 않고 네트워크 스택에 도착합니다.
구성주인브리지를 사용하고 무선 인터페이스를 브리지 포트로 설정
이전 설정에서만 라우터와 주고받는 프레임만 라우터에서 처리됩니다.라우팅스택의 일부회로망더미. 라우터에 속하지 않거나 라우터에서 오는 프레임은 간단히 삭제됩니다. 이는 이더넷 인터페이스가 해당 MAC 주소에 속하지 않는 유니캐스트 프레임을 수신하는 경우 발생합니다. 이것이 설정 이름이 지정된 이유입니다
ap_isolate
. STA는 기본적으로 서로 격리되어 있습니다.이 문제를 해결하려면 브리지가 필요합니다. 말하다주인설정wlp1s0AP 모드로 구성되면 브리지 포트로 작동할 수 있습니다. 제공된 이름을 사용하여 브리지를 생성하거나 (바람직하게는) 기존 브리지를 재사용하고 런타임 시 인터페이스를 브리지 포트로 설정합니다. 아무 이름이나 골랐어요brwlan1.
브리지 구성존재하다
hostapd.conf
:bridge=brwlan1
브리지 사용과 관련된 네트워크 설정 변경
연결 포트가 없고 대기 시간이 없는 브리지 구성
수동으로 다음과 같습니다.
ip link add name brwlan1 up type bridge forward_delay 0
참고:
hostapd
Wi-Fi 인터페이스를 브리지에 연결하는 도구입니다. 브리지 포트로 설정하려면 먼저 AP로 설정해야 하기 때문입니다.아무거나 움직여라우팅(계층 3) 설정 정보wlp1s0도착하다brwlan1:
ip addr delete 192.168.2.1/24 dev wlp1s0 ip addr add 192.168.2.1/24 dev brwlan1
여기에는 DHCP 설정과 같은 다양한 애플리케이션의 인터페이스 참조 변경도 포함됩니다.
...그리고nftables그러나 이에 대해서는 다음 섹션에서 논의할 것입니다.
가지다주인달리기
한번 확인해보세요wlp1s0인스턴스가 실행 중입니다.wlp1s0로 설정brwlan1브리지 포트:
사람들은 다음과 비슷한 내용을 보게 될 것입니다.
# bridge link show dev wlp1s0 6: wlp1s0 <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master brwlan1 state forwarding priority 32 cost 100
그런 다음 개별 브리지 포트에서 헤어핀 모드를 활성화합니다.
현재 STA-to-STA 통신은 여전히 불가능하며 STA-to-AP 또는 AP-to-STA만 가능합니다. STA-to-STA는 단일 브리지 포트에 프레임이 도착해야 합니다.wlp1s0동일한 브리지 포트에서 다시 보냅니다. 이러한 프레임을 전달하기 위한 브리지가 있지만 아직은 그렇지 않습니다. 기본적으로 이더넷 브리지(또는 스위치)는 일반 유선 설정에서는 의미가 없기 때문에 원래 포트로 다시 전달하는 것을 비활성화합니다.
그래서머리 핀다음에서 활성화해야 합니다.wlp1s0따라서 이 포트에서 수신된 프레임은 동일한 포트에서 재전송될 수 있습니다. 현재는 개발 버전(브랜치)만기본) 의주인새 구성 매개변수 승인
bridge_hairpin=1
이 작업을 자동으로 수행합니다(버전 2.10은 아직 충분히 새롭지 않습니다). 이 작업은 다음을 사용하여 수동으로 수행할 수 있습니다.bridge
명령(사용되지 않는brctl
명령은 이 기능을 지원하지 않음):bridge link set dev wlp1s0 hairpin on
이 부분은 올바른 운영 체제 통합이 필요합니다.주인함께 제공wlp1s0브리지 포트에서만 사용할 수 있으므로 브리지 포트로 사용됩니다.
hostapd
설정하고 싶습니다wlp1s0데몬 앞에서 브리지 포트 역할을 한 다음 네트워크 구성 도구가 명령을 실행하도록 합니다. 그렇지 않고 경쟁 조건이 발생하는 경우sleep 3;
명령이 실행될 때 인터페이스가 브리지 포트인지 확인하기 위해 이 명령 앞에 지연(예: )을 삽입하는 것을 고려할 수 있습니다.wlp1s0브리지를 분리/재연결하려면(예: 재부팅hostapd
) 이 명령을 다시 실행해야 합니다. 네트워크 구성에서 호출해야 합니다.
적응하다nftables규칙 세트
... 사용브리지 패밀리IP 시리즈 대신. 이는 라우팅과 매우 유사합니다. 라우터용 프레임은 입력 후크에서 볼 수 있고, 라우터의 프레임은 출력 후크에서 볼 수 있으며, STA-STA 프레임은 정방향 후크에서 볼 수 있습니다.
개체 네임스페이스는 테이블별로 적용되므로 둘 간에 규칙을 재사용할 수 없으므로 일부 중복이 필요합니다. 방금 관련 라우팅 규칙의 관련 부분을 복사하고 조정했습니다.앞으로. 예를 들어 일부 카운터를 사용하여 ping 및 KDE 연결 포트를 활성화했습니다. 일부 상용구는 실제로 필요하지 않습니다(예: 처음에 IPv6에 대한 범용 삭제 규칙이 있는 경우
ether type ip ip protocol tcp tcp dport 1714
이를 그냥으로 바꿀 수 있습니다. 이 명령은 커널에 규칙을 제공할 때 필요한 상용구를 내부적으로 삽입합니다).tcp dport 1714
nft
table bridge filter # for idempotence delete table bridge filter # for idempotence table bridge filter { chain conntrack { ct state vmap { invalid : drop, established : accept, related : accept } } chain kdeconnect { udp dport 1714-1764 counter accept tcp dport 1714-1764 counter accept } chain forward { type filter hook forward priority filter; policy drop; jump conntrack ether type ip6 drop # just like OP did: drop any IPv6 icmp type echo-request counter accept jump kdeconnect ether type arp accept # mandatory for IPv4 connectivity counter } }
~해야 한다wlp5s0나중에 동일한 것이 자체 별도 브리지로 구성될 예정이며, 브리지 포트당 또는 브리지당(예:
iifname wlp1s0
또는ibrname brwlan1
필요한 경우) 필터링이 필요합니다.다른 경우는 여전히 OP 초기 규칙 세트의 표준 라우팅에 의해 처리됩니다. 입력 및 출력 필터 후크가 구성되지 않으므로 라우터로 들어오고 나가는 트래픽이 허용되거나 다른 인터페이스로/부터 라우팅되는 트래픽이 됩니다.
OPnftables라우팅도 조정되어야 합니다.
table ip filter
이 단어가 나타날 때마다 현재 라우팅에 참여하고 있는 인터페이스wlp1s0
로 대체되어야 합니다 .brwlan1