Score:0

Limit connections to private network with firewalld and wireguard in point to site

in flag

I am trying to limit VPN access to a private network running in Openstack. The wireguard server is inside the private network and the traffic is routed to its private ip address from Openstack. Inside the private network is a Dns Server all clients need to reach and for each client a specific server. The clients should only reach their specific server and the dns server. Administrators should also access the private network via wireguard without limitation using a different wireguard interface.

Network

Wireguard Server(Ubuntu 22.04):

  • net.ipv4.ip_forward=1 set in /etc/sysctl.conf
  • ens3: 10.10.10.107
  • wg_admin: 10.42.43.1 / Port 51821
  • wg_clients: 10.42.42.1 / Port 51820

Servers inside the private Network:

  • DNS Server: 10.10.10.203
  • Client1 Server: 10.10.10.133
  • Client2 Server: 10.10.10.209

Connecting clients/admins:

  • Client1: 10.42.42.3
  • Client2: 10.42.42.2
  • Admin1: 10.42.43.2

Wireguard Server Config

I am using two zones: public: Handling the incoming traffic

$ firewall-cmd --zone=public --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens3
  sources: 
  services: dhcpv6-client ssh ssh-custom
  ports: 51821/udp 51820/udp
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

wireguard: Handling the wireguard traffic; limiting which traffic forwarding

$ firewall-cmd --zone=wireguard --list-all
wireguard (active)
  target: default
  icmp-block-inversion: no
  interfaces: wg_admin wg_clients
  sources: 
  services: 
  ports: 
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
        rule family="ipv4" source address="10.42.42.2" destination address="10.10.10.209" masquerade
        rule family="ipv4" source address="10.42.42.2" destination address="10.10.10.203" masquerade
        rule family="ipv4" source address="10.42.42.3" destination address="10.10.10.203" masquerade
        rule family="ipv4" source address="10.42.43.0/24" masquerade log prefix="wg_admin_masq" level="warning"
        rule family="ipv4" source address="10.42.42.3" destination address="10.10.10.133" masquerade

Problem

With the current firewalld setup i would assume that packets coming in on the wiregurad interfaces are handled in the wireguard zone. When a rich rule is matching the source ip should be changed to the wireguard server ip 10.10.10.107 and then simply routed to the client. But unfortunately this is not working like this.

When checking the kernel messages I see:

[Thu Jun  8 13:32:18 2023] "filter_FWD_wireguard_REJECT: "IN=wg_admin OUT=ens3 MAC= SRC=10.42.43.2 DST=10.10.10.203 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=31157 DF PROTO=TCP SPT=44920 DPT=53 WINDOW=64860 RES=0x00 SYN URGP=0 
[Thu Jun  8 13:32:20 2023] "filter_FWD_wireguard_REJECT: "IN=wg_clients OUT=ens3 MAC= SRC=10.42.42.2 DST=10.10.10.203 LEN=82 TOS=0x00 PREC=0x00 TTL=63 ID=9462 PROTO=UDP SPT=36905 DPT=53 LEN=62 
[Thu Jun  8 13:32:23 2023] "filter_FWD_wireguard_REJECT: "IN=wg_admin OUT=ens3 MAC= SRC=10.42.43.2 DST=10.10.10.203 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=50271 DF PROTO=TCP SPT=55930 DPT=53 WINDOW=64860 RES=0x00 SYN URGP=0 
[Thu Jun  8 13:32:41 2023] "filter_FWD_wireguard_REJECT: "IN=wg_clients OUT=ens3 MAC= SRC=10.42.42.2 DST=10.10.10.203 LEN=92 TOS=0x00 PREC=0x00 TTL=63 ID=2910 PROTO=UDP SPT=45837 DPT=53 LEN=72 
[Thu Jun  8 13:32:41 2023] "filter_FWD_wireguard_REJECT: "IN=wg_clients OUT=ens3 MAC= SRC=10.42.42.2 DST=10.10.10.203 LEN=92 TOS=0x00 PREC=0x00 TTL=63 ID=58612 PROTO=UDP SPT=53142 DPT=53 LEN=72 

My custom log prefix is not shown so I assume my rich rules are ignored. When I try to ping the dns server:

$ ping 10.10.10.203
PING 10.10.10.203 (10.10.10.203) 56(84) bytes of data.
From 10.42.43.1 icmp_seq=1 Packet filtered

When I try to ping the wireguard server:

$ ping 10.10.10.107
PING 10.10.10.107 (10.10.10.107) 56(84) bytes of data.
64 bytes from 10.10.10.107: icmp_seq=1 ttl=64 time=26.7 ms
$ ping 10.42.42.1  
PING 10.42.42.1 (10.42.42.1) 56(84) bytes of data.
64 bytes from 10.42.42.1: icmp_seq=1 ttl=64 time=28.5 ms

What am I doing wrong?

Score:0
in flag

Finally I found the answer my self. The feature allowing routing and filtering with firewalld is called policies and was introduced later. This great post from Pro Custodibus also explains different scenarios using wireguard and firewalld.

With policies it is possible to route traffic from one zone to another and to set a specific rule set for the traffic passing through.

To archive the separation between my wireguard interfaces/connections for admins/clients and routing into the private network the wireguard server we:

  • split up the wireguard interfaces into separate zones
  • added a zone were the traffic is forwared
  • added two policies which connecting the wireguard zones with the forward zone
  • added rules to the policies to filter the wireguard traffic

Zones:

$ firewall-cmd --info=zone=wg_clients
wg_clients (active)
  target: DROP
  icmp-block-inversion: no
  interfaces: wg_clients
  sources: 
  services: 
  ports: 
  protocols: 
  forward: no
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules:

$ firewall-cmd --info=zone=wg_admins
wg_admins (active)
  target: DROP
  icmp-block-inversion: no
  interfaces: wg_admins
  sources: 
  services: 
  ports: 
  protocols: 
  forward: no
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules:

$ firewall-cmd --info=zone=forward
forward (active)
  target: ACCEPT
  icmp-block-inversion: no
  interfaces: 
  sources: 10.10.10.0/24
  services: 
  ports: 
  protocols: 
  forward: no
  masquerade: yes
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

Policies:

$ firewall-cmd --info-policy=wg_clients2forward
wg_clients2forward (active)
  priority: -1
  target: REJECT
  ingress-zones: wg_clients
  egress-zones: forward
  services: 
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
        rule family="ipv4" destination address="10.10.10.203" service name="dns" accept
        rule family="ipv4" source address="10.42.42.3/32" destination address="10.10.10.133" service name="https" accept
        rule family="ipv4" source address="10.42.42.2/32" destination address="10.10.10.209" service name="https" accept

$ firewall-cmd --info-policy=wg_admins2forward
wg_admins2forward (active)
  priority: -1
  target: REJECT
  ingress-zones: wg_admins
  egress-zones: forward
  services: 
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
        rule family="ipv4" destination address="10.10.10.0/24" accept
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.