How do I limit firewalld portforwarding to certain source addresses?
Solution 1:
With the help of Michael Hampton (thanks!) I managed to figure it out and am answering my own question.
What is needed is a separate zone that you define by adding scopes to it:
firewall-cmd --new-zone=special --permanent
firewall-cmd --reload
firewall-cmd --zone=special --add-source=12.34.56.78/32 --permanent
firewall-cmd --zone=special --add-source=12.34.56.88/32 --permanent
firewall-cmd --zone=special --add-source=12.34.99.0/24 --permanent
Then add all the normal services/ports you would have in your public zone to this new zone (basically duplicate its config) and finally add the forwarded port rule to the new zone only with (example http proxy):
firewall-cmd --zone=special --add-forward-port=port=8080:proto=tcp:toaddr=10.0.0.2 --permanent
then issue a final reload to apply:
firewall-cmd --reload
and voila: scopes 12.34.56.78/32 12.34.56.88/32 and 12.34.99.0/24 now have access to the example proxy service, but nobody else.
UPDATE
Critical note: These steps work fine for inbound traffic but getting firewalld to behave as a NAT router including outbound takes more work (which I haven't been able to get working...). If anyone has a more complete solution that allows inbound and outbound to work through a firewalld'ed server I'll happily mark that as accepted answer!
OT: I ended up using IPTables in the end anyway, which I got working for port forwarding and NAT without too much issue once I figured out what I did wrong (I didn't have an outbound rule in the FORWARD chain... >.> <.<) and it allows fine control over the scopes in every rule (with the bonus I can do everything from Webmin :P). Since that is off-topic I'm leaving this answer as-is.