This PR introduces a couple of new changes to support; 1. Public ipv4: Nat implementation from public to private ipv4. ``` table ip raw { chain prerouting { type filter hook prerouting priority raw; policy accept; ip daddr #{public_ipv4} ip daddr set #{private_ipv4} notrack ip saddr #{private_ipv4} ip daddr != 192.168.0.0/16 ip saddr set #{public_ipv4} notrack } } ``` The above rule means; - If there is a packet coming into public ipv4 address of the VM, we change it to private ip. We use stateless nat here since the number of state objects increasing with the connection count can bring down the whole system to kneel. - If there is a packet coming out of the VM that is targeted to a public system, change the source address of the packet to public ip, if it's destined to private ipv4, leave it as is, which will be handled by ipsec tunnelling work. Explained below. 2. Private ipv4: Using dnsmasq dhcp4 This is handled as simple as adding below line to the dnsmasq.conf ``` dhcp-range=tapvm7m86kv,192.168.0.85,192.168.0.85,32 ``` We also add the proper routing rules to handle the private ipv4 routing in between VM <-> tap* <-> namespace NAT/IPsec Tunnelling 3. Private ipv6: Using dnsmasq slaac This is handled by adding the below rule to the dnsmasq.conf ``` dhcp-range=tapvm7m86kv,fdfe:62d4:efc4:ef3b::2,fdfe:62d4:efc4:ef3b::2,slaac,64,12h ``` Slaac means there will be a router advertisement for the given range and the mask length. After that, the client figures out its own ip address and adds it to its networking stack. For this router advertisement to reach to VM, we had to add the first slice of ipv6 address to the tap* device. Though, the below is also needed; ``` r "ip -n #{q_vm} addr add #{NetAddr.parse_net(net6).nth(1)}/64 dev tap#{q_vm}" ``` 4. Ipsec tunnelling for private ipv6 communication This was already in place but the rule creation and the addresses needed some clean-up. 5. Ipsec tunnelling for private ipv4 communication We added new policy and states to support ipv4 in ipv6 tunnelling. Example end result for 2 VMs to communicate with each other is the following; ``` root@Ubuntu-2204-jammy-amd64-base /vm/vm7m86kv # ip x p src 192.168.0.127/32 dst 192.168.0.85/32 dir fwd priority 0 tmpl src 2a01:4f8:10a:128b:fc0f:: dst 2a01:4f8:242:4f68:3f93:: proto esp spi 0x49f55272 reqid 1 mode tunnel src fdc9:3955:7bf:873c::/64 dst fdfe:62d4:efc4:ef3b::/64 dir fwd priority 0 tmpl src 2a01:4f8:10a:128b:fc0f:: dst 2a01:4f8:242:4f68:3f93:: proto esp spi 0xf567061f reqid 1 mode tunnel src 192.168.0.85/32 dst 192.168.0.127/32 dir out priority 0 tmpl src 2a01:4f8:242:4f68:3f93:: dst 2a01:4f8:10a:128b:fc0f:: proto esp spi 0x562a887b reqid 1 mode tunnel src fdfe:62d4:efc4:ef3b::/64 dst fdc9:3955:7bf:873c::/64 dir out priority 0 tmpl src 2a01:4f8:242:4f68:3f93:: dst 2a01:4f8:10a:128b:fc0f:: proto esp spi 0x2ec0170c reqid 1 mode tunnel root@Ubuntu-2204-jammy-amd64-base /vm/vm7m86kv # ip x s src 2a01:4f8:10a:128b:fc0f:: dst 2a01:4f8:242:4f68:3f93:: proto esp spi 0x49f55272 reqid 1 mode tunnel replay-window 0 aead rfc4106(gcm(aes)) 0xf330d5810712412b64fd3f2c7800c15e689010abceea3b85270aa65a9132f9d736f69d32 128 anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000 sel src 0.0.0.0/0 dst 0.0.0.0/0 src 2a01:4f8:10a:128b:fc0f:: dst 2a01:4f8:242:4f68:3f93:: proto esp spi 0xf567061f reqid 1 mode tunnel replay-window 0 aead rfc4106(gcm(aes)) 0xf330d5810712412b64fd3f2c7800c15e689010abceea3b85270aa65a9132f9d736f69d32 128 anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000 sel src ::/0 dst ::/0 src 2a01:4f8:242:4f68:3f93:: dst 2a01:4f8:10a:128b:fc0f:: proto esp spi 0x562a887b reqid 1 mode tunnel replay-window 0 aead rfc4106(gcm(aes)) 0xc15cd35dbb66ecc5460c9d668c42226ab34ddc1400f4593a539079947f1da9f5b81ed171 128 anti-replay context: seq 0x0, oseq 0xc, bitmap 0x00000000 sel src 0.0.0.0/0 dst 0.0.0.0/0 src 2a01:4f8:242:4f68:3f93:: dst 2a01:4f8:10a:128b:fc0f:: proto esp spi 0x2ec0170c reqid 1 mode tunnel replay-window 0 aead rfc4106(gcm(aes)) 0xc15cd35dbb66ecc5460c9d668c42226ab34ddc1400f4593a539079947f1da9f5b81ed171 128 anti-replay context: seq 0x0, oseq 0x10f, bitmap 0x00000000 sel src ::/0 dst ::/0 ``` The above outputs mean that for both ip4 and ip6 stack, we check the source and destination addresses. If they are from a specific private ip4 to specific private ip6, we use them respectively with public ip6 addresses and setup a tunnel and send an encrypted packet. Both ends know the keys to encrypt/decrypt packets. make tests pass column rename from private_subnet to net6 rubocop private_ipv4 arg is added back This is a temporary measure, will be removed back when the private networking is in place even if there is no public ip4, private ip4 works start using replace instead of add for idempotancy
206 B
206 B