Creating an Access Point using bookworm

Back when Buster was current, I was able to make router / access point / pihole using a Pi4. It used hostapd on wlan0 (the internal chipset) to create the access point LAN, and wpa_supplicant on wlan1 (a realtek USB adapter) to connect to local coffee shop wifi for the WAN. PIHOLE_INTERFACE was set to wlan0 in setupVars.conf, with a static IP of 192.168.4.1 created wtih dhcpcd. The pihole was also set to create the DHCP server.

Routing was done with iptables, and once that was all setup, I could connect a laptop or tablet to the access point using 192.168.4.1 for DNS, and the pihole worked flawlessly.

I'm now trying to recreate that on bookworm using NetworkManager. It seems creating an access point is much easier now, and I can get that up and running with nmcli. Works great. But as soon as I install the pihole, I lose internet access from the WAN. I am disabling the NetworkManager instance of dnsmasq with port=0 in /etc/NetworkManager/dnsmasq-shared.d/disable-dns.conf, and at times I am able to arm wrestle the pihole-FTL into listening on port 53, but still, no internet access on the LAN. Strangely, if I set PIHOLE_INTERFACE to wlan1, I get internet access on the pi, but not through to devices on the LAN. ss shows 4 instances of port 53 bound to pihole-FTL, but no ads are blocked, and nothing show up with pihole -t.

When PIHOLE_INTERFACE=wlan0, and I try to turn on the DHCP server in the web UI, I get a PHP error: Unable to connect to 127.0.0.1:4711

When PIHOLE_INTERFACE=wlan1, and the the DHCP server off, the error goes away, and no clients can connect to the access point, with an "Incorrect Password" error.

Foundering, I know. Can anyone throw me a bone?

How do you know dnsmasq is booted up by NM as a stub resolver/caching nameserver?
NM can boot up a couple of stub resolvers depending distro:

$ man NetworkManager.conf
[..]
       dns
           Set the DNS processing mode.

           If the key is unspecified, default is used, unless
           /etc/resolv.conf is a symlink to
           /run/systemd/resolve/stub-resolv.conf,
           /run/systemd/resolve/resolv.conf,
           /lib/systemd/resolv.conf or /usr/lib/systemd/resolv.conf.
           In that case, systemd-resolved is chosen automatically.

           default: NetworkManager will update /etc/resolv.conf to
           reflect the nameservers provided by currently active
           connections. The rc-manager setting (below) controls how
           this is done.

           dnsmasq: NetworkManager will run dnsmasq as a local
           caching nameserver, using "Conditional Forwarding" if you
           are connected to a VPN, and then update resolv.conf to
           point to the local nameserver. It is possible to pass
           custom options to the dnsmasq instance by adding them to
           files in the "/etc/NetworkManager/dnsmasq.d/" directory.
           Note that when multiple upstream servers are available,
           dnsmasq will initially contact them in parallel and then
           use the fastest to respond, probing again other servers
           after some time. This behavior can be modified passing
           the 'all-servers' or 'strict-order' options to dnsmasq
           (see the manual page for more details).

           systemd-resolved: NetworkManager will push the DNS
           configuration to systemd-resolved

           none: NetworkManager will not modify resolv.conf. This
           implies rc-manager unmanaged

           Note that the plugins dnsmasq and systemd-resolved are
           caching local nameservers. Hence, when NetworkManager
           writes /run/NetworkManager/resolv.conf and
           /etc/resolv.conf (according to rc-manager setting below),
           the name server there will be localhost only.
           NetworkManager also writes a file
           /run/NetworkManager/no-stub-resolv.conf that contains the
           original name servers pushed to the DNS plugin.

           When using dnsmasq and systemd-resolved per-connection
           added dns servers will always be queried using the device
           the connection has been activated on.

Mine is the default profile from above:

$ cat /etc/NetworkManager/NetworkManager.conf
[main]
plugins=ifupdown,keyfile

[ifupdown]
managed=false
$ rgrep . /etc/NetworkManager/conf.d/
$

You can check which stub resolver is occupying port 53 with below:

sudo ss -nltup sport = 53

20241211 UPDATE:

Once I hardwired the WAN gateway and DNS to static IP's using nmcli, and rebooting a couple of times, everything's finally working. In the end, vastly easier than geting dnsmasq, dhcpcd, hostapd and wpa_supplicant all working in concert on earlier versions of the OS.

deHakkelaar, how did I know dnsmasq was booted up by NetworkManager?

Because I never installed it.