mirror of
				https://github.com/vyos/vyos-documentation.git
				synced 2025-11-04 00:02:05 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			380 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			380 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
.. _examples-zone-policy:
 | 
						||
 | 
						||
Zone-Policy example
 | 
						||
-------------------
 | 
						||
 | 
						||
Native IPv4 and IPv6
 | 
						||
^^^^^^^^^^^^^^^^^^^^
 | 
						||
 | 
						||
We have three networks.
 | 
						||
 | 
						||
.. code-block:: sh
 | 
						||
 | 
						||
  WAN - 172.16.10.0/24, 2001:0DB8:0:9999::0/64
 | 
						||
  LAN - 192.168.100.0/24, 2001:0DB8:0:AAAA::0/64
 | 
						||
  DMZ - 192.168.200.0/24, 2001:0DB8:0:BBBB::0/64
 | 
						||
 | 
						||
 | 
						||
This specific example is for a router on a stick, but is very easily adapted
 | 
						||
for however many NICs you have.
 | 
						||
 | 
						||
[http://imgur.com/Alz1J.png Topology Image]
 | 
						||
 | 
						||
The VyOS interface is assigned the .1/:1 address of their respective networks.
 | 
						||
WAN is on VLAN 10, LAN on VLAN 20, and DMZ on VLAN 30.
 | 
						||
 | 
						||
It will look something like this:
 | 
						||
 | 
						||
.. code-block:: sh
 | 
						||
 | 
						||
  interfaces {
 | 
						||
      ethernet eth0 {
 | 
						||
          duplex auto
 | 
						||
          hw-id 00:0c:29:6e:2a:92
 | 
						||
          smp_affinity auto
 | 
						||
          speed auto
 | 
						||
          vif 10 {
 | 
						||
              address 172.16.10.1/24
 | 
						||
              address 2001:db8:0:9999::1/64
 | 
						||
          }
 | 
						||
          vif 20 {
 | 
						||
              address 192.168.100.1/24
 | 
						||
              address 2001:db8:0:AAAA::1/64
 | 
						||
          }
 | 
						||
          vif 30 {
 | 
						||
              address 192.168.200.1/24
 | 
						||
              address 2001:db8:0:BBBB::1/64
 | 
						||
          }
 | 
						||
      }
 | 
						||
      loopback lo {
 | 
						||
      }
 | 
						||
  }
 | 
						||
 | 
						||
 | 
						||
Zones Basics
 | 
						||
^^^^^^^^^^^^
 | 
						||
 | 
						||
Each interface is assigned to a zone. The interface can be physical or virtual
 | 
						||
such as tunnels (VPN, pptp, gre, etc) and are treated exactly the same.
 | 
						||
 | 
						||
Traffic flows from zone A to zone B. That flow is what I refer to as a
 | 
						||
zone-pair-direction. eg. A->B and B->A are two zone-pair-destinations.
 | 
						||
 | 
						||
Ruleset are created per zone-pair-direction.
 | 
						||
 | 
						||
I name rule sets to indicate which zone-pair-direction they represent. eg.
 | 
						||
ZoneA-ZoneB or ZoneB-ZoneA. LAN-DMZ, DMZ-LAN.
 | 
						||
 | 
						||
In VyOS, you have to have unique Ruleset names. In the event of overlap, I
 | 
						||
add a "-6" to the end of v6 rulesets. eg. LAN-DMZ, LAN-DMZ-6. This allows for
 | 
						||
each auto-completion and uniqueness.
 | 
						||
 | 
						||
In this example we have 4 zones. LAN, WAN, DMZ, Local. The local zone is the
 | 
						||
firewall itself.
 | 
						||
 | 
						||
If your computer is on the LAN and you need to SSH into your VyOS box, you
 | 
						||
would need a rule to allow it in the LAN-Local ruleset. If you want to access
 | 
						||
a webpage from your VyOS box, you need a rule to allow it in the Local-LAN
 | 
						||
ruleset.
 | 
						||
 | 
						||
In rules, it is good to keep them named consistently. As the number of rules
 | 
						||
you have grows, the more consistency you have, the easier your life will be.
 | 
						||
 | 
						||
.. code-block:: sh
 | 
						||
 | 
						||
  Rule 1 - State Established, Related
 | 
						||
  Rule 2 - State Invalid
 | 
						||
  Rule 100 - ICMP
 | 
						||
  Rule 200 - Web
 | 
						||
  Rule 300 - FTP
 | 
						||
  Rule 400 - NTP
 | 
						||
  Rule 500 - SMTP
 | 
						||
  Rule 600 - DNS
 | 
						||
  Rule 700 - DHCP
 | 
						||
  Rule 800 - SSH
 | 
						||
  Rule 900 - IMAPS
 | 
						||
 | 
						||
The first two rules are to deal with the idiosyncrasies of VyOS and iptables.
 | 
						||
 | 
						||
Zones and Rulesets both have a default action statement. When using
 | 
						||
Zone-Policies, the default action is set by the zone-policy statement and is
 | 
						||
represented by rule 10000.
 | 
						||
 | 
						||
It is good practice to log both accepted and denied traffic. It can save you
 | 
						||
significant headaches when trying to troubleshoot a connectivity issue.
 | 
						||
 | 
						||
To add logging to the default rule, do:
 | 
						||
 | 
						||
.. code-block:: sh
 | 
						||
 | 
						||
  set firewall name <ruleSet> enable-default-log
 | 
						||
 | 
						||
 | 
						||
By default, iptables does not allow traffic for established session to return,
 | 
						||
so you must explicitly allow this. I do this by adding two rules to every
 | 
						||
ruleset. 1 allows established and related state packets through and rule 2
 | 
						||
drops and logs invalid state packets. We place the established/related rule at
 | 
						||
the top because the vast majority of traffic on a network is established and
 | 
						||
the invalid rule to prevent invalid state packets from mistakenly being matched
 | 
						||
against other rules. Having the most matched rule listed first reduces CPU load
 | 
						||
in high volume environments. Note: I have filed a bug to have this added as a
 | 
						||
default action as well.
 | 
						||
 | 
						||
''It is important to note, that you do not want to add logging to the
 | 
						||
established state rule as you will be logging both the inbound and outbound
 | 
						||
packets for each session instead of just the initiation of the session.
 | 
						||
Your logs will be massive in a very short period of time.''
 | 
						||
 | 
						||
In VyOS you must have the interfaces created before you can apply it to the
 | 
						||
zone and the rulesets must be created prior to applying it to a zone-policy.
 | 
						||
 | 
						||
I create/configure the interfaces first. Build out the rulesets for each
 | 
						||
zone-pair-direction which includes at least the three state rules. Then I setup
 | 
						||
the zone-policies.
 | 
						||
 | 
						||
Zones do not allow for a default action of accept; either drop or reject.
 | 
						||
It is important to remember this because if you apply an interface to a zone
 | 
						||
and commit, any active connections will be dropped. Specifically, if you are
 | 
						||
SSH’d into VyOS and add local or the interface you are connecting through to a
 | 
						||
zone and do not have rulesets in place to allow SSH and established sessions,
 | 
						||
you will not be able to connect.
 | 
						||
 | 
						||
The following are the rules that were created for this example
 | 
						||
(may not be complete), both in IPv4 and IPv6. If there is no IP specified,
 | 
						||
then the source/destination address is not explicit.
 | 
						||
 | 
						||
.. code-block:: sh
 | 
						||
 | 
						||
  WAN – DMZ:192.168.200.200 – tcp/80
 | 
						||
  WAN – DMZ:192.168.200.200 – tcp/443
 | 
						||
  WAN – DMZ:192.168.200.200 – tcp/25
 | 
						||
  WAN – DMZ:192.168.200.200 – tcp/53
 | 
						||
  WAN – DMZ:2001:0DB8:0:BBBB::200 – tcp/80
 | 
						||
  WAN – DMZ:2001:0DB8:0:BBBB::200 – tcp/443
 | 
						||
  WAN – DMZ:2001:0DB8:0:BBBB::200 – tcp/25
 | 
						||
  WAN – DMZ:2001:0DB8:0:BBBB::200 – tcp/53
 | 
						||
 | 
						||
  DMZ - Local - tcp/53
 | 
						||
  DMZ - Local - tcp/123
 | 
						||
  DMZ - Local - tcp/67,68
 | 
						||
 | 
						||
  LAN - Local - tcp/53
 | 
						||
  LAN - Local - tcp/123
 | 
						||
  LAN - Local - tcp/67,68
 | 
						||
  LAN:192.168.100.10 - Local - tcp/22
 | 
						||
  LAN:2001:0DB8:0:AAAA::10 - Local - tcp/22
 | 
						||
 | 
						||
  LAN - WAN - tcp/80
 | 
						||
  LAN - WAN - tcp/443
 | 
						||
  LAN - WAN - tcp/22
 | 
						||
  LAN - WAN - tcp/20,21
 | 
						||
 | 
						||
  DMZ - WAN - tcp/80
 | 
						||
  DMZ - WAN - tcp/443
 | 
						||
  DMZ - WAN - tcp/22
 | 
						||
  DMZ - WAN - tcp/20,21
 | 
						||
  DMZ - WAN - tcp/53
 | 
						||
  DMZ - WAN - udp/53
 | 
						||
 | 
						||
  Local - WAN - tcp/80
 | 
						||
  Local - WAN - tcp/443
 | 
						||
  Local - WAN - tcp/20,21
 | 
						||
 | 
						||
  Local - DMZ - tcp/25
 | 
						||
  Local - DMZ - tcp/67,68
 | 
						||
  Local - DMZ - tcp/53
 | 
						||
  Local - DMZ - udp/53
 | 
						||
 | 
						||
  Local - LAN - tcp/67,68
 | 
						||
 | 
						||
  LAN - DMZ - tcp/80
 | 
						||
  LAN - DMZ - tcp/443
 | 
						||
  LAN - DMZ - tcp/993
 | 
						||
  LAN:2001:0DB8:0:AAAA::10 - DMZ:2001:0DB8:0:BBBB::200 - tcp/22
 | 
						||
  LAN:192.168.100.10 - DMZ:192.168.200.200 - tcp/22
 | 
						||
 | 
						||
Since we have 4 zones, we need to setup the following rulesets.
 | 
						||
 | 
						||
.. code-block:: sh
 | 
						||
 | 
						||
  Lan-wan
 | 
						||
  Lan-local
 | 
						||
  Lan-dmz
 | 
						||
  Wan-lan
 | 
						||
  Wan-local
 | 
						||
  Wan-dmz
 | 
						||
  Local-lan
 | 
						||
  Local-wan
 | 
						||
  Local-dmz
 | 
						||
  Dmz-lan
 | 
						||
  Dmz-wan
 | 
						||
  Dmz-local
 | 
						||
 | 
						||
Even if the two zones will never communicate, it is a good idea to create the
 | 
						||
zone-pair-direction rulesets and set enable-default-log. This will allow you to
 | 
						||
log attempts to access the networks. Without it, you will never see the
 | 
						||
connection attempts.
 | 
						||
 | 
						||
This is an example of the three base rules.
 | 
						||
 | 
						||
.. code-block:: sh
 | 
						||
 | 
						||
  name wan-lan {
 | 
						||
    default-action drop
 | 
						||
    enable-default-log
 | 
						||
    rule 1 {
 | 
						||
      action accept
 | 
						||
      state {
 | 
						||
        established enable
 | 
						||
        related enable
 | 
						||
      }
 | 
						||
    }
 | 
						||
    rule 2 {
 | 
						||
      action drop
 | 
						||
      log enable
 | 
						||
      state {
 | 
						||
        invalid enable
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
 | 
						||
Here is an example of an IPv6 DMZ-WAN ruleset.
 | 
						||
 | 
						||
.. code-block:: sh
 | 
						||
 | 
						||
  ipv6-name dmz-wan-6 {
 | 
						||
    default-action drop
 | 
						||
    enable-default-log
 | 
						||
    rule 1 {
 | 
						||
      action accept
 | 
						||
      state {
 | 
						||
        established enable
 | 
						||
        related enable
 | 
						||
      }
 | 
						||
    }
 | 
						||
    rule 2 {
 | 
						||
      action drop
 | 
						||
      log enable
 | 
						||
      state {
 | 
						||
        invalid enable
 | 
						||
    }
 | 
						||
    rule 100 {
 | 
						||
      action accept
 | 
						||
      log enable
 | 
						||
      protocol ipv6-icmp
 | 
						||
    }
 | 
						||
    rule 200 {
 | 
						||
      action accept
 | 
						||
      destination {
 | 
						||
        port 80,443
 | 
						||
      }
 | 
						||
      log enable
 | 
						||
      protocol tcp
 | 
						||
    }
 | 
						||
    rule 300 {
 | 
						||
      action accept
 | 
						||
      destination {
 | 
						||
        port 20,21
 | 
						||
      }
 | 
						||
      log enable
 | 
						||
      protocol tcp
 | 
						||
    }
 | 
						||
    rule 500 {
 | 
						||
      action accept
 | 
						||
      destination {
 | 
						||
        port 25
 | 
						||
      }
 | 
						||
      log enable
 | 
						||
      protocol tcp
 | 
						||
      source {
 | 
						||
        address 2001:db8:0:BBBB::200
 | 
						||
      }
 | 
						||
    }
 | 
						||
    rule 600 {
 | 
						||
      action accept
 | 
						||
      destination {
 | 
						||
        port 53
 | 
						||
      }
 | 
						||
      log enable
 | 
						||
      protocol tcp_udp
 | 
						||
      source {
 | 
						||
        address 2001:db8:0:BBBB::200
 | 
						||
      }
 | 
						||
    }
 | 
						||
    rule 800 {
 | 
						||
      action accept
 | 
						||
      destination {
 | 
						||
      port 22
 | 
						||
      }
 | 
						||
      log enable
 | 
						||
      protocol tcp
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
Once you have all of your rulesets built, then you need to create your
 | 
						||
zone-policy.
 | 
						||
 | 
						||
Start by setting the interface and default action for each zone.
 | 
						||
 | 
						||
.. code-block:: sh
 | 
						||
 | 
						||
  set zone-policy zone dmz default-action drop
 | 
						||
  set zone-policy zone dmz interface eth0.30
 | 
						||
 | 
						||
In this case, we are setting the v6 ruleset that represents traffic sourced
 | 
						||
from the LAN, destined for the DMZ.
 | 
						||
Because the zone-policy firewall syntax is a little awkward, I keep it straight
 | 
						||
by thinking of it backwards.
 | 
						||
 | 
						||
 set zone-policy zone dmz from lan firewall ipv6-name lan-dmz-6
 | 
						||
 | 
						||
dmz-lan policy is lan-dmz. You can get a rhythm to it when you build out a bunch at one time.
 | 
						||
 | 
						||
In the end, you will end up with something like this config. I took out everything but the Firewall, Interfaces, and zone-policy sections. It is long enough as is.
 | 
						||
== IPv6 Tunnel ==
 | 
						||
 | 
						||
If you are using a IPv6 tunnel from HE.net or someone else, the basis is the same except you have two WAN interface. One for v4 and one for v6.
 | 
						||
 | 
						||
You would have 5 zones instead of just 4 and you would configure your v6 ruleset between your tunnel interface and your LAN/DMZ zones instead of to the WAN.
 | 
						||
 | 
						||
LAN, WAN, DMZ, local and TUN (tunnel)
 | 
						||
 | 
						||
v6 pairs would be:
 | 
						||
 | 
						||
.. code-block:: sh
 | 
						||
 | 
						||
  lan-tun
 | 
						||
  lan-local
 | 
						||
  lan-dmz
 | 
						||
  tun-lan
 | 
						||
  tun-local
 | 
						||
  tun-dmz
 | 
						||
  local-lan
 | 
						||
  local-tun
 | 
						||
  local-dmz
 | 
						||
  dmz-lan
 | 
						||
  dmz-tun
 | 
						||
  dmz-local
 | 
						||
 | 
						||
Notice, none go to WAN since WAN wouldn't have a v6 address on it.
 | 
						||
 | 
						||
You would have to add a couple of rules on your wan-local ruleset to allow protocol 41 in.
 | 
						||
 | 
						||
Something like:
 | 
						||
 | 
						||
.. code-block:: sh
 | 
						||
 | 
						||
  rule 400 {
 | 
						||
    action accept
 | 
						||
    destination {
 | 
						||
      address 172.16.10.1
 | 
						||
    }
 | 
						||
    log enable
 | 
						||
    protocol 41
 | 
						||
    source {
 | 
						||
      address ip.of.tunnel.broker
 | 
						||
    }
 | 
						||
  }
 | 
						||
 |