pf: Make nat-to and rdr-to work properly both on in and out rules
New-style address translation is done by nat-to and rdr-to actions on normal match and pass rules. Those rules, when used without address translation, can be specified without direction. But that allows users to specify pre-routing nat and post-routing rdr. This case is not handled properly and causes pre-routing nat to modify destination address, as if it was a rdr rule, and post-routing rdr to modify source address, as if it was a nat rule. Ensure that nat-to action modifies source address and rdr-to destination address no matter in which direction the rule is applied. The man page for pf.conf already specifies that nat-to and rdr-to rules should be limited to respective directions. PR: 288577 Reviewed by: kp MFC after: 3 days Sponsored by: InnoGames GmbH Differential Revision: https://reviews.freebsd.org/D53216
This commit is contained in:
+14
-2
@@ -974,6 +974,7 @@ pf_get_transaddr(struct pf_test_ctx *ctx, struct pf_krule *r,
|
|||||||
{
|
{
|
||||||
struct pf_pdesc *pd = ctx->pd;
|
struct pf_pdesc *pd = ctx->pd;
|
||||||
struct pf_addr *naddr;
|
struct pf_addr *naddr;
|
||||||
|
int idx;
|
||||||
uint16_t *nportp;
|
uint16_t *nportp;
|
||||||
uint16_t low, high;
|
uint16_t low, high;
|
||||||
u_short reason;
|
u_short reason;
|
||||||
@@ -988,8 +989,19 @@ pf_get_transaddr(struct pf_test_ctx *ctx, struct pf_krule *r,
|
|||||||
return (PFRES_MEMORY);
|
return (PFRES_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
naddr = &ctx->nk->addr[1];
|
switch (nat_action) {
|
||||||
nportp = &ctx->nk->port[1];
|
case PF_NAT:
|
||||||
|
idx = pd->sidx;
|
||||||
|
break;
|
||||||
|
case PF_BINAT:
|
||||||
|
idx = 1;
|
||||||
|
break;
|
||||||
|
case PF_RDR:
|
||||||
|
idx = pd->didx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
naddr = &ctx->nk->addr[idx];
|
||||||
|
nportp = &ctx->nk->port[idx];
|
||||||
|
|
||||||
switch (nat_action) {
|
switch (nat_action) {
|
||||||
case PF_NAT:
|
case PF_NAT:
|
||||||
|
|||||||
@@ -477,15 +477,49 @@ no_addrs_random_cleanup()
|
|||||||
pft_cleanup
|
pft_cleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
atf_test_case "nat_pass" "cleanup"
|
atf_test_case "nat_pass_in" "cleanup"
|
||||||
nat_pass_head()
|
nat_pass_in_head()
|
||||||
{
|
{
|
||||||
atf_set descr 'IPv4 NAT on pass rule'
|
atf_set descr 'IPv4 NAT on inbound pass rule'
|
||||||
atf_set require.user root
|
atf_set require.user root
|
||||||
atf_set require.progs scapy
|
atf_set require.progs scapy
|
||||||
}
|
}
|
||||||
|
|
||||||
nat_pass_body()
|
nat_pass_in_body()
|
||||||
|
{
|
||||||
|
setup_router_server_ipv4
|
||||||
|
# Delete the route back to make sure that the traffic has been NAT-ed
|
||||||
|
jexec server route del -net ${net_tester} ${net_server_host_router}
|
||||||
|
# Provide routing back to the NAT address
|
||||||
|
jexec server route add 203.0.113.0/24 ${net_server_host_router}
|
||||||
|
jexec router route add 203.0.113.0/24 -iface ${epair_tester}b
|
||||||
|
|
||||||
|
pft_set_rules router \
|
||||||
|
"block" \
|
||||||
|
"pass in on ${epair_tester}b inet proto tcp nat-to 203.0.113.0 keep state" \
|
||||||
|
"pass out on ${epair_server}a inet proto tcp keep state"
|
||||||
|
|
||||||
|
ping_server_check_reply exit:0 --ping-type=tcp3way --send-sport=4201
|
||||||
|
|
||||||
|
jexec router pfctl -qvvsr
|
||||||
|
jexec router pfctl -qvvss
|
||||||
|
jexec router ifconfig
|
||||||
|
jexec router netstat -rn
|
||||||
|
}
|
||||||
|
|
||||||
|
nat_pass_in_cleanup()
|
||||||
|
{
|
||||||
|
pft_cleanup
|
||||||
|
}
|
||||||
|
|
||||||
|
nat_pass_out_head()
|
||||||
|
{
|
||||||
|
atf_set descr 'IPv4 NAT on outbound pass rule'
|
||||||
|
atf_set require.user root
|
||||||
|
atf_set require.progs scapy
|
||||||
|
}
|
||||||
|
|
||||||
|
nat_pass_out_body()
|
||||||
{
|
{
|
||||||
setup_router_server_ipv4
|
setup_router_server_ipv4
|
||||||
# Delete the route back to make sure that the traffic has been NAT-ed
|
# Delete the route back to make sure that the traffic has been NAT-ed
|
||||||
@@ -504,7 +538,7 @@ nat_pass_body()
|
|||||||
jexec router netstat -rn
|
jexec router netstat -rn
|
||||||
}
|
}
|
||||||
|
|
||||||
nat_pass_cleanup()
|
nat_pass_out_cleanup()
|
||||||
{
|
{
|
||||||
pft_cleanup
|
pft_cleanup
|
||||||
}
|
}
|
||||||
@@ -874,7 +908,8 @@ atf_init_test_cases()
|
|||||||
atf_add_test_case "no_addrs_random"
|
atf_add_test_case "no_addrs_random"
|
||||||
atf_add_test_case "map_e_compat"
|
atf_add_test_case "map_e_compat"
|
||||||
atf_add_test_case "map_e_pass"
|
atf_add_test_case "map_e_pass"
|
||||||
atf_add_test_case "nat_pass"
|
atf_add_test_case "nat_pass_in"
|
||||||
|
atf_add_test_case "nat_pass_out"
|
||||||
atf_add_test_case "nat_match"
|
atf_add_test_case "nat_match"
|
||||||
atf_add_test_case "binat_compat"
|
atf_add_test_case "binat_compat"
|
||||||
atf_add_test_case "binat_match"
|
atf_add_test_case "binat_match"
|
||||||
|
|||||||
Reference in New Issue
Block a user