To install Linux without the need of a CD/DVD/USB-stick, I now use PXE-booting ("pixie"-booting) on our local home network. I could not find good instructions and had to try out things before it started working, but the process itself is fairly simple. Here are the steps:
TFTP Server: 192.168.1.1 (internal network address of the pfsense router)
Check "Enables network booting"
Next Server: 192.168.1.1
Default BIOS file name, UEFI 32 bit file name and UEFI 64 bit file name: pxelinux.0
[...]
CLIENT IP: 192.168.1.86 MASK: 255.255.255.0 DHCP IP: 192.168.1.1
GATEWAY IP: 192.168.1.1
PXE-E32. TFTP open timeout
PXE-M0F: Exiting Intel Boot Agent
First, I thought that a firewall was blocking the access to port 69, but that was not the case. However, it was difficult to sort these things out since the pfsense reports only "port filtered" when the port is scanned:
nmap -p 69 192.168.1.1
Starting Nmap 7.60 ( https://nmap.org ) at 2019-11-02 10:39 EET
Nmap scan report for pfsense.localdomain (192.168.1.1)
Host is up (0.00033s latency).
PORT STATE SERVICE
69/tcp filtered tftp
Nmap done: 1 IP address (1 host up) scanned in 0.26 seconds
[...]
Failed to load ldlinux.c32
Boot failed: press a key to retry, or wait for reset...
This appears to be a bug with the location of the file in the Ubuntu network booting directory structure. You just need to copy the file ldlinux.c32 from /tftpboot/ubuntu-installer/amd64/boot-screens/ldlinux.c32 to /tftpboot/ldlinux.c32Failed to load COM32 file ubuntu-installer/amd64/boot-screens/vesamenu.c32
After fixing this, I was finally able to start the network installer.