While I don’t run an ISP (unless you consider my hosting company Fourplex an “ISP”), one project I’ve wanted to try in my homelab is implementing Carrier Grade NAT with Port Block Allocation.
Yes, we all know Carrier Grade NAT sucks. It makes it hard to host services and use console gaming and such. And yes, I haven’t daily driven FreeBSD in years. But FreeBSD is still a good network appliance even if it’s no longer my desktop.
Note: I won’t describe other parts of the network, like rc.conf IP assignments, IPv6 and routing protocols.
Ranting aside, first off you need this in /etc/rc.conf:
gateway_enable="YES"
pf_enable="YES"
Subsequently, you need something like this in /etc/pf.conf:
nat on $ext_if from 100.64.0.0 to any -> 1.2.3.4 port 1000:2999
nat on $ext_if from 100.64.0.1 to any -> 1.2.3.4 port 3000:5999
What do these lines mean? I’ll explain:
- $ext_if is the external interface, which has the public IPs CGNAT will use.
- 100.64.0.X is the CGNAT IPv4 which will be allocated to a client.
- 1.2.3.4 is the public IPv4 used by CGNAT.
- After the port is the start and end IPv4 port ranges respectively, separated by :. For instance, 1000:2999 will assign a start port of 1000 and end port of 2999 to a client.
You will need a nat line for each CGNAT customer, and can use multiple public IPv4s for different clients.
What about automating generation?
I should do it eventually. But since I’m not running a broadband ISP (only a VPS/VPN host) it’s not a priority to script it.
Yes, I’d love to be an ISP. But only if the FCC would actually mandate “line sharing” rules neither party wants. Or NYC builds an “open access” fiber network which they won’t. I won’t do a WISP for various reasons.
You could also use VyOS for CGNAT instead of FreeBSD which has CGNAT syntax.
Leave a Reply