nftables를 사용하여 새로운 Centos 8에 DNAT를 설정하려고 합니다. 이 유틸리티(및 centos 8)는 나에게 새로운 기능입니다. 저는 오랫동안 iptables(centos부터 6까지)를 사용해 왔습니다.
내 가정은 DNAT가 시작될 수 있도록 뭔가를 제대로 설정하지 않았지만 도구를 제대로 사용하지 않았을 수도 있다는 것입니다. 아니면 둘다.
어쨌든 중요한 경우를 대비해 동일한 상자의 일부 라우팅 문제에 대한 이전 질문은 다음과 같습니다.다중 인터넷 연결, 잘못된 NIC 포트에서 패킷 수신(인바운드 라우팅 문제?)(문제는 ARP 플럭스였으며 해결되었습니다).
다음은 현재 설정에 대한 스케치이며 파란색 선은 내가 원하는 것(예상되는 "경로")을 표시합니다.
기본적으로 패킷은 인터넷에서 들어와 인터페이스 2(ens2)를 거쳐 로컬 인터페이스(ens5, 로컬 IP 192.168.1.10)를 통해 192.168.1.2로 DNATed됩니다. (이것이 작동하면 동일한 LAN에 있는 두 개의 다른 VM으로 이동하여 ens 3과 4에 대해 동일하게 설정됩니다)
패킷이 올바른 인터페이스(예상되는 nft 로그 트리거)로 들어오는지 확인했지만 conntrack -E
아무 것도 표시되지 않습니다.
또한 centos 6 상자(실제 대상, 192.168.1.2)의 iptables 로깅에는 아무 것도 표시되지 않습니다(오래 전에 실행된 동일한 로깅은 몇 달 전 마지막으로 확인했을 때 예상되는 출력을 표시했기 때문에 해당 상자). 이론적으로는 괜찮을 것입니다)
현재 내 nftables 스크립트는 IP/IF가 스케치와 일치하도록 변환된 상태 그대로입니다.
table ip nat {
chain PREROUTING {
type nat hook prerouting priority -100; policy accept;
iif "ens2" goto PREROUTING_RDS2
iif "ens3" goto PREROUTING_RDS3
}
chain PREROUTING_RDS2 {
tcp dport { http, https } log prefix "RDS2_dnat-3 "
tcp dport { http, https } dnat to IP_6
}
chain PREROUTING_RDS3 {
tcp dport { http, https } log prefix "RDS3_dnat-3 "
tcp dport { http, https } dnat to IP_6
}
}
table inet filter {
chain INPUT {
type filter hook input priority 0; policy drop;
#
iif "lo" accept
#
# allow ping
ip protocol icmp icmp type echo-request limit rate 1/second log prefix "PING "
ip protocol icmp icmp type echo-request limit rate 1/second accept
# following is required and must be BEFORE the ct state established otherwise the ping flooding will not be stopped
ip protocol icmp drop
#
ct state established,related accept
ct status dnat accept
#
iifname "ens5" goto INPUT_LOCAL
#
# now we drop the rest
ct state invalid log prefix "INPUT_STATE_INVALID_DROP: "
ct state invalid drop
log prefix "INPUT_FINAL_REJECT: "
reject with icmpx type admin-prohibited
}
chain FILTER {
type filter hook forward priority 50; policy drop;
iif "ens2" goto FILTER_RDS2
iif "ens3" goto FILTER_RDS3
}
chain INPUT_LOCAL {
tcp dport ssh goto INPUT_LOCAL_ssh
}
chain INPUT_LOCAL_ssh {
ip saddr IP_MY_PC accept
}
chain FILTER_RDS2 {
oifname "ens5" ip daddr IP_6 tcp dport { http, https } accept
}
chain FILTER_RDS3 {
oifname "ens5" ip daddr IP_6 tcp dport { http, https } accept
}
}
미리 감사드립니다.
답변1
사실 이 질문은 관련 내용을 잘 살펴보지 않고서는 답하기가 어렵습니다.이전 Q/A초기 설정 해결센토스8. 솔루션은 매우 복잡해집니다. 이를 위해 배치해야 하는 구성 종류를 고려할 때, 특히 가상 환경에 있다는 점을 고려하면 동일한 인터페이스의 모든 IP가 아닌 동일한 LAN에 여러 인터페이스가 있는 인터페이스당 하나의 IP를 갖는 것이 가치가 없을 것입니다. 속도가 빨라지지 않습니다. 구성에 대한 모든 변경 사항은 아래 명령에 모두 반영되어야 하므로 이를 올바르게 관리하기가 어렵습니다.
센토스8라우터
동일 LAN의 다중 인터페이스 문제를 해결하기 위해 추가 라우팅 테이블이 있으므로 이제 이 Q/A에서는센토스8라우터 역할을 하는 경우 기본 테이블에서 추가 라우팅 테이블로 더 많은 경로 항목을 복제해야 합니다.
# ip route add 192.168.1.0/24 dev ens5 table 1001 src 192.168.1.10
# ip route add 192.168.1.0/24 dev ens5 table 1002 src 192.168.1.10
# ip route add 192.168.1.0/24 dev ens5 table 1003 src 192.168.1.10
# ip route add 192.168.1.0/24 dev ens5 table 1004 src 192.168.1.10
그렇지 않은 경우 수신된 모든 패킷ens1,ens2,ens3또는ens4그리고dnat에드를 통해ens5실패할 것이다역방향 경로 필터통과하는 경로가 없기 때문에ens5그 테이블에.
물론 그것만으로는 충분하지 않습니다. 응답 패킷에 정보가 없습니다(예: 다음에서 돌아옴).센토스6) 어떤 인터페이스가 사용되었고 다른 방법으로 재사용되어야 하는지에 대해 설명합니다. 따라서 이 정보는 netfilter의 conntrack을 사용하여 흐름별로 기억되어야 합니다. nftables 규칙에서 전체 ip nat
테이블을 삭제합니다.
# nft delete table ip nat
다음 새 테이블로 바꿉니다 ip markandnat
.
# nft -f - << 'EOF'
table ip markandnat {
map iif2mark {
type iface_index : mark;
elements = {
ens1 : 101,
ens2 : 102,
ens3 : 103,
ens4 : 104
}
}
map mark2daddr {
type mark : ipv4_addr;
elements = {
102 : 192.168.1.2,
103 : 192.168.1.2, # same IP, as per OP's config
104 : 192.168.1.4 # some other VM
}
}
chain premark {
type filter hook prerouting priority -150; policy accept;
meta mark set ct mark meta mark != 0 return
meta mark set iif map @iif2mark meta mark != 0 ct mark set meta mark
}
chain prenat {
type nat hook prerouting priority -100; policy accept;
tcp dport { http, https } dnat to meta mark map @mark2daddr
}
}
EOF
이는 인터페이스 => 마크 => dnat 대상을 매핑하는 동시에 마크를 conntrack의 마크로 저장합니다(마지막에 있는 링크 참조).콘마크용법). 이제 동일한 추가 라우팅 테이블을 가리키도록 아래 규칙을 추가하여 라우팅 스택에서 이 표시를 사용할 수 있고 사용합니다.
# ip rule add pref 11001 fwmark 101 table 1001
# ip rule add pref 11002 fwmark 102 table 1002
# ip rule add pref 11003 fwmark 103 table 1003
# ip rule add pref 11004 fwmark 104 table 1004
하지만 여전히 누락된 부분이 있습니다. 다시 역방향 경로 필터에 대해 설명합니다. 표시가 사용 중일 때 역방향 경로 필터는 표시에 의해 변경된 새 경로를 사용하여 다시 확인하지 않으며 일반적으로 확인에 실패합니다. 실제로는문서화되지 않은 기능, 2009/2010년 커널 2.6.33/2.6.32.8에 추가됨, 이는 느슨한 역방향 경로 모드를 사용할 필요 없이 이 문제를 해결합니다 src_valid_mark
.
# sysctl -w net.ipv4.conf.ens1.src_valid_mark=1
# sysctl -w net.ipv4.conf.ens2.src_valid_mark=1
# sysctl -w net.ipv4.conf.ens3.src_valid_mark=1
# sysctl -w net.ipv4.conf.ens4.src_valid_mark=1
센토스6섬기는 사람
일시적으로 대체 게이트웨이를 사용하려는 경우 다시 복잡성이 추가되고 예상치 못한 미묘한 부작용이 발생하더라도 마크를 사용하면 다시 가능합니다. CentOS 6이기 때문에nftables사용할 수 없으므로iptables사용하게 될 것이다.
나는 그것을 고려할 것이다센토스6VM의 (고유) 인터페이스에 IP 192.168.1.2/24가 있습니다.eth0, 기본값은 gw 192.168.1.1입니다. 대체 게이트웨이 192.168.1.10에 대한 새 라우팅 테이블과 규칙을 추가해 보겠습니다.
# ip route add table 10 default via 192.168.1.10
# ip rule add fwmark 10 lookup 10
넣어iptables규칙(여기서만압착 롤러테이블이 필요합니다):
# iptables-restore << 'EOF'
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -j CONNMARK --restore-mark
-A PREROUTING -m mark ! --mark 0 -j RETURN
-A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j MARK --set-mark 10
-A PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j MARK --set-mark 10
-A PREROUTING -m mark ! --mark 0 -j CONNMARK --save-mark
-A OUTPUT -m connmark ! --mark 0 -j CONNMARK --restore-mark
COMMIT
EOF
이제 포트 80 또는 443에서 수신된 모든 흐름은 수신 패킷과 해당 응답을 표시합니다. 이 표시는 라우팅 스택에서 수신 및 응답을 위해 게이트웨이를 192.168.1.10으로 변경하는 데 사용됩니다(맹글/출력재라우팅 확인을 트리거합니다. 아래 두 번째 링크를 참조하세요.
이 경우에는 사용할 필요가 없는 것처럼 보이지만 src_valid_mark
그냥 설정하거나 rp_filter=2
작동하지 않으면 설정하세요. 이 설정에서는 수신도 허용되지 않습니다.dnat192.168.1.1을 통한 트래픽.
일부 링크:
답변2
의견으로 판단하면 가장 즉각적이고 중요한 누락은 IP 전달이 꺼진 것입니다. 단지:
echo 1 > /proc/sys/net/ipv4/ip_forward
이제 DNATted 패킷이 IP6에 도착하는지 확인합니다.
두 번째 문제는 비대칭 라우팅입니다. DNATted 패킷은 192.168.1.10(IP5)을 통해 IP6으로 전달되며 여기서 수정됩니다(대상 주소가 변경됨). 반환 패킷은 LAN(182.168.1.1)의 기본 게이트웨이를 통과하며 연결 원본으로 가는 경로에서 수정되지 않습니다. RFC1918 주소를 유지하거나 192.168.1.1에서 다른 주소로 SNAT될 가능성이 높으며 대상의 어떤 연결과도 일치하지 않아 삭제될 가능성이 높습니다.
편집하다:
따라서 FORWARD 체인을 해결하기 위해 다음과 같이 다시 작성합니다(훨씬 더 간단한 IMHO).
table inet filter {
:
chain FORWARD {
type filter hook forward priority 0; policy drop;
ct state established,related accept
ct status dnat accept
}
:
}