Page MenuHomeVyOS Platform

Add CGNAT Carrier-Grade NAT based on nftables
Needs testing, NormalPublicFEATURE REQUEST

Description

Ability to configure CGNAT based on nftables
There is a discussion on the forum

The solution for nftables described in https://debianbrasil.gitlab.io/FiqueEmCasaUseDebian/arquivos/2020-06-03-cgnat-com-nftables.pdf
The script which generates rules for nftables https://github.com/Beiriz/GRCN

#!/usr/sbin/nft -f
flush ruleset
add table ip nat
add chain ip nat PREROUTING { type nat hook prerouting priority -100; policy accept; }
add chain ip nat POSTROUTING { type nat hook postrouting priority 100; policy accept; }
add chain ip nat CGNATOUT
add chain ip nat CGNATIN
add rule ip nat PREROUTING iifname "enp1s0f0" counter jump CGNATIN
add rule ip nat POSTROUTING oifname "enp1s0f0" counter jump CGNATOUT

include "/root/cgnat_nft/cgnat-bng.conf"include "/root/cgnat_nft/cgnat-bng.conf"

cgnat-bng.conf

# GRCN - Gerador de Regras CGNAT em nftables - Beiriz - v4.001 - 27/07/2020 (31/03/2023)
# - blocos 100.64.0.0/21 -> 192.0.2.0/24;
# - /0 de IPs privados / IP público;
# - 8064 portas / IP privado;
# ---------------------------------------- #INDICE 0 / IP PUBLICO 192.0.2.0
add chain ip nat CGNATOUT_0
flush chain ip nat CGNATOUT_0
add rule ip nat CGNATOUT_0 ip protocol tcp ip saddr 100.64.0.0 counter snat to 192.0.2.0:1024-9087
add rule ip nat CGNATOUT_0 ip protocol udp ip saddr 100.64.0.0 counter snat to 192.0.2.0:1024-9087
add rule ip nat CGNATOUT_0 ip protocol tcp ip saddr 100.64.0.1 counter snat to 192.0.2.0:9088-17151
add rule ip nat CGNATOUT_0 ip protocol udp ip saddr 100.64.0.1 counter snat to 192.0.2.0:9088-17151
add rule ip nat CGNATOUT_0 ip protocol tcp ip saddr 100.64.0.2 counter snat to 192.0.2.0:17152-25215
add rule ip nat CGNATOUT_0 ip protocol udp ip saddr 100.64.0.2 counter snat to 192.0.2.0:17152-25215
add rule ip nat CGNATOUT_0 ip protocol tcp ip saddr 100.64.0.3 counter snat to 192.0.2.0:25216-33279
add rule ip nat CGNATOUT_0 ip protocol udp ip saddr 100.64.0.3 counter snat to 192.0.2.0:25216-33279
add rule ip nat CGNATOUT_0 ip protocol tcp ip saddr 100.64.0.4 counter snat to 192.0.2.0:33280-41343
add rule ip nat CGNATOUT_0 ip protocol udp ip saddr 100.64.0.4 counter snat to 192.0.2.0:33280-41343
add rule ip nat CGNATOUT_0 ip protocol tcp ip saddr 100.64.0.5 counter snat to 192.0.2.0:41344-49407
add rule ip nat CGNATOUT_0 ip protocol udp ip saddr 100.64.0.5 counter snat to 192.0.2.0:41344-49407
add rule ip nat CGNATOUT_0 ip protocol tcp ip saddr 100.64.0.6 counter snat to 192.0.2.0:49408-57471
add rule ip nat CGNATOUT_0 ip protocol udp ip saddr 100.64.0.6 counter snat to 192.0.2.0:49408-57471
add rule ip nat CGNATOUT_0 ip protocol tcp ip saddr 100.64.0.7 counter snat to 192.0.2.0:57472-65535
add rule ip nat CGNATOUT_0 ip protocol udp ip saddr 100.64.0.7 counter snat to 192.0.2.0:57472-65535
add rule ip nat CGNATOUT_0 counter snat to 192.0.2.0
add rule ip nat CGNATOUT ip saddr 100.64.0.0/29 counter jump CGNATOUT_0
...

Details

Difficulty level
Unknown (require assessment)
Version
-
Why the issue appeared?
Will be filled on close
Is it a breaking change?
Unspecified (possibly destroys the router)
Issue type
Unspecified (please specify)

Related Objects

Event Timeline

According to nft changelog, this feature is available in 1.0.7 in a much better way:

nft add table ip cgnat
nft add chain ip cgnat nat_chain { type nat hook postrouting priority srcnat \; policy accept \; }
nft add map ip cgnat nat_map { type ipv4_addr: ipv4_addr . inet_service \; flags interval \;}
nft add rule ip cgnat nat_chain ip protocol { tcp, udp } counter snat to ip saddr map @nat_map

nft add element ip cgnat nat_map { 100.64.0.0: 192.0.2.0 . 1024-9087, 100.64.0.1: 192.0.2.1 . 9088-17151 }

This improves performance significantly by reducing the count of rules to one. Therefore, if the feature needs to be implemented, it is better to check it with nftables 1.0.7 and use this version if it works.

Two cents from the fields. It will be nice to see vrf aware cg-nat solution, when subscribers from a number of "inside" vrfs NAT'ed into one outside vrf. Of course if that's possible.

This comment was removed by aserkin.

Proposed CLI:

set nat cgnat pool external <external> range 192.0.2.0/30 seq 1
set nat cgnat pool external <external> range 192.0.2.128-192.0.2.132 seq 2
set nat cgnat pool external <external> per-user-limit port 1024
set nat cgnat pool external <external> global-port-range 1024-65535
set nat cgnat pool internal <internal> range 100.64.1.0/24

set nat cgnat rule 10 source pool internal
set nat cgnat rule 10 translation pool external

Any suggestions?

PoC PR https://github.com/vyos/vyos-1x/pull/3274

set nat cgnat pool external ext1 external-port-range '1024-65535'
set nat cgnat pool external ext1 per-user-limit port '1000'
set nat cgnat pool external ext1 range 192.0.2.222/32
set nat cgnat pool internal int1 range '100.64.0.0/28'
set nat cgnat rule 10 source pool 'int1'
set nat cgnat rule 10 translation pool 'ext1'
Viacheslav changed the task status from Open to Needs testing.Thu, Apr 11, 3:50 PM
Viacheslav removed a project: VyOS 1.4 Sagitta.
Viacheslav lowered the priority of this task from High to Normal.Thu, Apr 18, 6:02 AM