-- Leo's gemini proxy
-- Connecting to gemini.splashgel.net:1965...
-- Connected
-- Sending request
-- Meta line: 20 text/gemini
Suppose you want to run a service on a Linux VM via vmd, and want it accessible to the world. The process is slightly less straightforward than you might think, and less simple than if you're using IPv4. As an example, let’s say we're setting up nginx to run on Alpine Linux.
This goes page through the steps in detail to get things working, but to ‘skip-to-the end’ go to:
There are a number of different ways of setting up networking on a vmm guest. The easiest way is a local interface with NAT (option 2 in the FAQ).
What the FAQ doesn’t mention is that by adding 'local inet6' at the top of 'vm.conf' you'll also get a unique-local routable subnet allocated. To be able to access the internet via the IPv4 side you need to add the NAT rules as specified in the FAQ to your pf.conf
match out on egress from 100.64.0.0/10 to any nat-to (egress) pass in proto { udp tcp } from 100.64.0.0/10 to any port domain \ rdr-to $dns_server port domain
Now create a disk with 'vmctl create -s 4G /mnt/data/alpine.img' or something similar. Then start the machine with 'vmctl start -c -L -m 1G -r alpine-virt.iso -d /mnt/data/alpine.img alpine' then install Alpine to the disk; to avoid creating a pointless swap partition cancel when it asks you about the disk setup then run 'setup-disk -s 0'. After installation you can create a vm.conf file as below so that the VM is saved.
local inet6 vm "alpine" { memory 1G disk /mnt/data/alpine.img local interface }
auto eth0 iface eth0 inet dhcp iface eth0 inet6 auto
If you look at the tap0 device on OpenBSD you will find it gives you an unpredictable address prefix, and so if you start running a server on it, you won’t know what address it will be on. This is explained on the OpenBSD mailing list.
The answer, therefore, is to go for option 3 in the FAQ, and set-up a bridge and a virtual switch. The FAQ shows how to set up an IPv4 subnet, but this needs to be tweaked by adding an IPv6 prefix. To generate your own local non-routable address block go here:
Now your /etc/hostname.vether0 should look something like this:
inet 10.0.0.1 255.255.255.0 inet6 fdxx:xxxx:xxxx:xxxx::/64
Change the lines in pf.conf an vm.conf so that you have:
match out on egress from vether0:network to any nat-to (egress)
switch "my_switch" { interface bridge0 } vm "alpine" { ... interface { switch "my_switch" } }
remove the 'local interface' and 'local inet6' lines from vm.conf.
Change /etc/network/interfaces to
iface eth0 inet static address 10.0.0.100 netmask 255.255.255.0 gateway 10.0.0.1 iface eth0 inet6 static address fdxx:xxxx:xxxx:xxxx::xxxx/64 scope site gateway fdxx:xxxx:xxxx:xxxx::1
Note that the addresses should match those in the vether0 setup in OpenBSD. 'scope site' is ignored in Alpine 3.17 but is correct. There is more information about setting up networking in Alpine at the wiki:
You have a VM with a predictable IPv6 address, but this can’t be reached by the global internet. Let’s pretend nginx is already set up on Alpine, there is a tutorial for doing this on the wiki:
Suppose the external address we want our server to be on is 2001:db8:100::99 then we have to add this to the external (i.e. egress) adapter’s addresses.
ifconfig fxp0 inet6 2001:db8:100::99
This can be made permanent by appending it to hostname.fxp0 (or whatever the adapter name is).
echo 'inet6 2001:db8:100::99' >>/etc/hostname.fxp0
You might think you can set pf up with 'rdr-to' so that packets can be redirected to this internal address, but you can’t. The answer now is to use relayd, which would be set up like this:
relay "alpinevm_nginx" { listen on 2001:db8:100::99 port 80 forward to fdxx:xxxx:xxxx:xxxx:xxxx port 80 }
-- Response ended
-- Page fetched on Sat May 18 23:40:56 2024