Proxmox Network Inside Network With Vyos 5
Previously we started working with jinja to template some of our networks. Now we can apply similar bits to creating firewall rules. Lets start by defining what rules we had when we manually entered them in Part 2.
Global-options
set firewall global-options state-policy established action 'accept'
set firewall global-options state-policy invalid action 'drop'
set firewall global-options state-policy related action 'accept'
Network-groups
These are here to define our OUTSIDE HOME/LAN network and INSIDE or DEV/UNTRUSTED network.
set firewall group network-group NET-INSIDE network 10.0.10.0/24
set firewall group network-group NET-OUTSIDE network 192.168.1.0/24
Input Filter
These rules ACCEPT all ssh on port 22 from HOME/LAN network to firewall and all traffic from DEV network to the fierwall.
set firewall ipv4 input filter default-action drop
set firewall ipv4 input filter rule 10 action accept
set firewall ipv4 input filter rule 10 description 'Allow ssh from HOME/NET-OUTSIDE'
set firewall ipv4 input filter rule 10 destination port 22
set firewall ipv4 input filter rule 10 protocol tcp
set firewall ipv4 input filter rule 10 source group network-group 'NET-OUTSIDE'
set firewall ipv4 input filter rule 10 state new
set firewall ipv4 input filter rule 20 action accept
set firewall ipv4 input filter rule 20 description 'Allow NET-INSIDE to firewall'
set firewall ipv4 input filter rule 20 source group network-group NET-INSIDE
set firewall ipv4 input filter rule 20 state new
Forward Filter
These rules ACCEPT all traffic from HOME/LAN to be forwarded to DEV network, DROP any traffic to
HOME/LAN from DEV, ACCEPT the rest of the traffic to be forwarded (Allow DEV to the internet)
set firewall ipv4 forward filter default-action drop
set firewall ipv4 forward filter rule 10 action accept
set firewall ipv4 forward filter rule 10 description 'Allow HOME/NET-OUTSIDE in NET-INSIDE'
set firewall ipv4 forward filter rule 10 destination group network-group NET-INSIDE
set firewall ipv4 forward filter rule 10 source group network-group NET-OUTSIDE
set firewall ipv4 forward filter rule 20 action drop
set firewall ipv4 forward filter rule 20 description 'Drop NET-INSIDE to NET-OUTSIDE'
set firewall ipv4 forward filter rule 20 destination group network-group NET-OUTSIDE
set firewall ipv4 forward filter rule 20 source group network-group NET-INSIDE
set firewall ipv4 forward filter rule 30 action accept
set firewall ipv4 forward filter rule 30 description 'Allow NET-INSIDE out to Internet'
set firewall ipv4 forward filter rule 30 destination address 0.0.0.0/0
set firewall ipv4 forward filter rule 30 source group network-group NET-INSIDE
With these few rules we can copy and paste them easily enough, but as more networks come in, and more
rules you want to add, manually adding rules is a pain. I also wanted to introduce PORT-GROUPS which
we will end up using in a future post.
Port groups
Like network-groups being a group of network CIDRs , port-groups are a collection of ports which we,
can group together to bundle firewall rules up.
Step 1 - New Role
Like last time we created a new role, this time vyos_firewall, we will need the usual handlers,
tasks and template directories and the main.yml files in handlers and tasks. I won’t go through
the same set up agian, you can check my previous posts or can get
this posts role from my Github - blog-5 branch along
with the previous ones.
Step 2 - New Playbook
Agin like last time we created a playbook to run the role
---
- name: Set up VyOS Firewall
  hosts: vyos
  gather_facts: true
  order: inventory
  roles:
    - vyos_firewall
Step 3 - Vars
Since I want to use port-groups lets create a port_groups.yml in our group_vars/all/ directory.
port_groups:
  TCP:
    ports:
      - 22 # ssh
      - 80 # http
      - 443 # https
      - 647 # dhcp-failover
      - 8000 # test webserver
    protocol: tcp
  UDP:
    ports:
      - 67 # dhcp
    protocol: udp
  TCP_UDP:
    ports:
      - 53 # dns
      - 123 # ntp
    protocol: tcp_udp
  WIREGUARD:
    ports:
      - 51820 # wireguard
    protocol: udp
  IPSEC:
    ports:
      - 500
      - 4500
    protocol: udp
We can define all our different port groups and ports and protocol they use.
Step 4 - Templates
The first template we call is firewall.j2 this sets the global-options as well as defining our
network-groups and port-groups before putting in the input and forward filter rules.
{# Global State Policies #}
set firewall global-options state-policy established action accept
set firewall global-options state-policy related action accept
set firewall global-options state-policy invalid action drop
{# Set network-groups #}
{% for addr in networks | dict2items %}
{% if addr.value.firewall is defined %}
set firewall group network-group NET-{{ "INSIDE" if addr.value.firewall.inside else "OUTSIDE" }} network '{{ addr.value.cidr }}'
{% endif %}
{% endfor %}
{# Set port-groups #}
{% for port_group, data in port_groups.items() %}
{% for port in data.ports %}
set firewall group port-group {{ port_group }} port {{ port }}
{% endfor %}
{% endfor %}
{# Set up FORWARD FILTER #}
{% include 'forward-filter.j2' %}
{# Set up INPUT FILTER #}
{% include 'input-filter.j2' %}
So for the network groups we loop through all networks in our networks.yml file and all networks that
have firewall defined. will then set the group network-group NET then if inside: true then it
becomes NET-INSIDE and if not NET-OUTSIDE then puts the network cidr in.
port-groups work similarly and loops throught the port_groups vars and sets the port-grop name
to be the port_group eg. The first item in the port_groups is TCP and the port adds all the ports
in the TCP/ports list 22,80,443,647,8000.
For the forward filter I left the rules simple but will be tweaking in the future. The input filter
is where I put the port-groups as in the future I will be more services on the Vyos router, and
creating port-groups will make allowing access to these easier without blanket ACCEPT rules.
Input filter
{# Set input filters #}
set firewall ipv4 input filter default-action 'drop'
{# Rule 10 - Allow any from home-network #}
set firewall ipv4 input filter rule 10 action 'accept'
set firewall ipv4 input filter rule 10 description 'Allow from home network'
set firewall ipv4 input filter rule 10 source group network-group 'NET-OUTSIDE'
{# Set Rule 20 + - Allow Port groups #}
{% set rule_number = namespace(value=20) %}
{% for port_group , data in port_groups.items() %}
set firewall ipv4 input filter rule {{ rule_number.value }} description 'Allow {{ port_group }} to Firewall'
set firewall ipv4 input filter rule {{ rule_number.value }} destination group port-group {{ port_group }}
set firewall ipv4 input filter rule {{ rule_number.value }} action 'accept'
set firewall ipv4 input filter rule {{ rule_number.value }} protocol '{{ data.protocol }}'
set firewall ipv4 input filter rule {{ rule_number.value }} state new
{% set rule_number.value = rule_number.value + 10 %}
{% endfor %}
So the first rul is hard coded but the next one for port groups, sets up all the port groups, starting
at 20 and for each port_group the rule number increases by +10 we could add an accept or deny
var to our port_groups.yml which could set the action {{ data.action }} as there may be ports, you
want to hard block in our out, as the port-group rules could apply not only to the input filter but
to an output filter or to the forward-filter.
And when we put this all together we should get some configurations like
set firewall global-options state-policy established action 'accept'
set firewall global-options state-policy invalid action 'drop'
set firewall global-options state-policy related action 'accept'
set firewall group network-group NET-INSIDE network '10.0.1.0/24'
set firewall group network-group NET-INSIDE network '10.0.10.0/24'
set firewall group network-group NET-OUTSIDE network '192.168.1.0/24'
set firewall group port-group IPSEC port '500'
set firewall group port-group IPSEC port '4500'
set firewall group port-group WIREGUARD port '51820'
set firewall group port-group TCP port '22'
set firewall group port-group TCP port '80'
set firewall group port-group TCP port '443'
set firewall group port-group TCP port '647'
set firewall group port-group TCP port '8000'
set firewall group port-group TCP_UDP port '53'
set firewall group port-group TCP_UDP port '123'
set firewall group port-group UDP port '67'
set firewall ipv4 forward filter default-action 'drop'
set firewall ipv4 forward filter rule 10 action 'drop'
set firewall ipv4 forward filter rule 10 description 'Drop VXLAN to home-network '
set firewall ipv4 forward filter rule 10 destination group network-group 'NET-OUTSIDE'
set firewall ipv4 forward filter rule 10 source group network-group 'NET-INSIDE'
set firewall ipv4 forward filter rule 20 action 'accept'
set firewall ipv4 forward filter rule 20 description 'Allow home-network into VXLAN'
set firewall ipv4 forward filter rule 20 destination group network-group 'NET-INSIDE'
set firewall ipv4 forward filter rule 20 source group network-group 'NET-OUTSIDE'
set firewall ipv4 forward filter rule 30 action 'accept'
set firewall ipv4 forward filter rule 30 description 'Allow VXLAN Internet'
set firewall ipv4 forward filter rule 30 destination address '0.0.0.0/0'
set firewall ipv4 forward filter rule 30 source group network-group 'NET-INSIDE'
set firewall ipv4 input filter default-action 'drop'
set firewall ipv4 input filter rule 10 action 'accept'
set firewall ipv4 input filter rule 10 description 'Allow from home network'
set firewall ipv4 input filter rule 10 destination port '22'
set firewall ipv4 input filter rule 10 protocol 'tcp'
set firewall ipv4 input filter rule 10 source group network-group 'NET-OUTSIDE'
set firewall ipv4 input filter rule 20 action 'accept'
set firewall ipv4 input filter rule 20 description 'Allow TCP to Firewall'
set firewall ipv4 input filter rule 20 destination group port-group 'TCP'
set firewall ipv4 input filter rule 20 source group network-group NET-INSIDE
set firewall ipv4 input filter rule 20 protocol 'tcp'
set firewall ipv4 input filter rule 20 source group network-group 'NET-INSIDE'
set firewall ipv4 input filter rule 30 action 'accept'
set firewall ipv4 input filter rule 30 description 'Allow UDP to Firewall'
set firewall ipv4 input filter rule 30 destination group port-group 'UDP'
set firewall ipv4 input filter rule 30 protocol 'udp'
set firewall ipv4 input filter rule 30 source group network-group 'NET-INSIDE'
set firewall ipv4 input filter rule 40 action 'accept'
set firewall ipv4 input filter rule 40 description 'Allow TCP_UDP to Firewall'
set firewall ipv4 input filter rule 40 destination group port-group 'TCP_UDP'
set firewall ipv4 input filter rule 40 protocol 'tcp_udp'
set firewall ipv4 input filter rule 40 source group network-group 'NET-INSIDE'
set firewall ipv4 input filter rule 40 state 'new'
set firewall ipv4 input filter rule 50 action 'accept'
set firewall ipv4 input filter rule 50 description 'Allow WIREGUARD to Firewall'
set firewall ipv4 input filter rule 50 destination group port-group 'WIREGUARD'
set firewall ipv4 input filter rule 50 protocol 'udp'
set firewall ipv4 input filter rule 50 state 'new'
set firewall ipv4 input filter rule 60 action 'accept'
set firewall ipv4 input filter rule 60 description 'Allow IPSEC to Firewall'
set firewall ipv4 input filter rule 60 destination group port-group 'IPSEC'
set firewall ipv4 input filter rule 60 protocol 'udp'
set firewall ipv4 input filter rule 60 state 'new'
If you spotted it, well done, we do not have an input filter to allow the DEV/INSIDE network access,
to the firewall. This rule input filter rule 20 got overwritten by our port group templating so,
there is lingering config for that rule.
set firewall ipv4 input filter rule 20 source group network-group NET-INSIDE
Lets fix that by recreating rule 20 to be 999 or something and we have a working network and firewall again.
set firewall ipv4 input filter rule 999 action accept
set firewall ipv4 input filter rule 999 description 'Allow NET-INSIDE to firewall'
set firewall ipv4 input filter rule 999 source group network-group NET-INSIDE
set firewall ipv4 input filter rule 999 state new
Next time in Part 6 - coming soon We can take a look at port forwarding or DNAT, so we can host,
services behind Vyos router/firewall in our DEV environment and be able to reach them from our HOME/LAN
without manually adding a route in our routing table. Or If our Vyos router/firewall was Our HOME/LAN
router and we wanted to access stuff inside our network from the Internet.