User Tools

Site Tools


inbox:doc:iptables_and_firewall

Iptables and firewall

Purpose

Explain to beginners how iptables/firewalling/packet flows works with overviews, examples and comments.

Remarks

- Some knowledge from the internet is used, so could be that the article will be wrong
  (even because the interpretation of a correct source could be wrong)
  plus the knowledge of the contributors themselves could be partial, wrong or outdated
  but this guide, ideally, will be fixed continuously. This is the strength of the wiki.
- a preformatted text is used to speed up the writing, focusing on the content
  an less on the wiki syntax. Like the old good plain text files.
  (feel free to change it anyway, collaborative wikis ftw)

Useful articles on the openwrt wiki

About iptables

About routing

Network interfaces

Physical or logical/virtual interfaces

identifier

Remark: identifier for remote systems, the actual system has different ways to identify (physical or logical) network interfaces.
* IP_address

Iptables

Tables, chains: overview of sequence of evaluation

Conventions:
  - Using a sort of pseudocode

Steps{
  Given: a packet is incoming in an interface (physical or logical).
  
  PREROUTING phase {
    The packet is passing the rules in the table MANGLE chain PREROUTING.
    The packet is passing the rules in the table NAT chain PREROUTING.
  }
  
  Routing phase {
    The a routing decision is made using the routing table.
    Comment {
      In this case the routing rules or routes (shown by the 'route' command)
      are used. In brief routing rules works in this way:
      "according to the destination that the packet wants to reach
      i will send it through a certain (physical or logical) network interface"
      
      With a practical example you have rules like:
      Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
      172.22.0.0      *               255.255.240.0   U     0      0        0 br-wan
      
      The rule says, if the packets wants to reach an ip address contained in the range:
      ( 172.22.0.0, 172.22.15.255 ) [this range is calculated using the destination + genmask]
      then send it through the "br-wan" interface (that is a logical interface that contains one or
      more physical interfaces).
      
      In general, without advanced configuration (ip rules, packet marking and other stuff),
      the routing decision send the packet using the rule (shown in the routing table)
      that has the longest match compared to the packet destination. The match is done
      using the 'destination' in the rule plus the 'genmask'. That is: if the destination IP
      is contained in the range destination+genmask the packet is sent using the rule associated
      to those two values. If more rules matches the packet, then the one will lower metric is chosen,
      if more rules have the same metric then the first rule (in order) is choosen but maybe
      this statement should be checked.
    }
  }
  
  After routing phase {
    There are two possibilities: 
    - processing the packet locally
      (for example let it read by an application on the system or
      applying some "big" modification to the packet)
    - (almost) directly sending it through the (physical or logical) network
      interface
      
    The possibilities are chosen depending on the routing phase {
      In brief packet for local processing are packet routed to
      the system itself. (For example SSH packets, or
      packets pointing to an IP owned by the system)
      Packets with destination different than the system itself,
      (that means: sent towards an IP identifier belonging to a physical or
      logical interface of the system)
      use the second possibility.
    }
  }
  
  processing the packet locally {
    INPUT {
      The packet is passing the rules in the table MANGLE chain INPUT.
      The packet is passing the rules in the table FILTER chain INPUT.
    }
    
    The the packet (in the case) is processed locally by the system
    (for example the ssh request or a packet directed to an IP owned by
    the system)
    OR (that is quite important) is generated by the system itself.
    
    OUTPUT {
      The packet is passing the rules in the table MANGLE chain OUTPUT.
      The packet is passing the rules in the table NAT chain OUTPUT.
      Beware {
        After the NAT OUTPUT the packet could be changed and requires
        a new routing. So routing rules are checked again against the packet.
      }
      The packet is passing the rules in the table FILTER chain OUTPUT.
    }
  }
  sending the packet (almost) directly sending it through the (physical or logical) network interface {
    FORWARD {
      The packet is passing the rules in the table MANGLE chain FORWARD.
      The packet is passing the rules in the table FILTER chain FORWARD.
    }
  }
  
  The packet is sent towards the interface (physical or logical) chosen by the last applied routing decision.
  
  POSTROUTING {
    The packet is passing the rules in the table MANGLE chain FORWARD.
    The packet is passing the rules in the table FILTER chain FORWARD.
  }
  
  The packet is sent out from the interface (physical or logical) chosen by the last applied routing decision.
}

Chains, rules and nested chains: overview of sequence of evaluation and use of targets

Conventions{
  With 'TABLE/CHAIN/OTHERCHAIN' is identified the chain named OTHERCHAIN, that is a nested chain of the main
  chain called CHAIN related to the table TABLE.
}

A chain is an ordered (from first to last) sequence of rules.
A chain could have a default policy of actions (called 'targets'): ACCEPT, DROP, REJECT or RETURN.
A rule is a set of condition to match a packet and, in the case that the conditions are met, then an action is
  performed on the packet (not only the actions written above, an action could also be "marking" the packet").
Main targets or actions {
  ACCEPT: the packet goes through the chain towards the next table/chain pair (or eventually sent out from an
    physical or logical interface).
  DROP: the packet is discarded, without any response to the sender, the packet flow is interrupted.
  REJECT: the packet is discarded but the sender is notified (like "no request"), the packet flow is interrupted.
  RETURN: this action returns from a nested chain to the "previous chain" this action will be more clear later.
  Other: there could be other actions on the packet, like "marking", but they requires way more time to be
    described properly. In the examples some other target is explained.
}
Nested chains {
  A nested chain could be called as "action" on a packet by a rule in the "main" chain.
  A nested chain could be seen as a way to organize rules in a chain. Instead of putting the
    rules all in one chain, rules are grouped somehow in nested chains. Therefore all the rules in
    the nested chains of a chain effectively are rules of the main chain, thus if a rule
    in a nested chain ACCEPT the packet, the main chain is passed for the packet and the flow
    proceeds towards the next table/chain pair.
  Nested chains could be nested in several levels. A rule from the "main" chain FILTER/FORWARD
    can call the nested chain FILTER/FORWARD/forwars_nested1 , and a rule from the chain FILTER/FORWARD/forwars_nested1
    can call the nested chain FILTER/FORWARD/forwars_nested1/forward_nested2 and so on. 
    (If someone knows the limits please contribute here!)
  
  A packet that was checked against all the rules of a nested chain, without matching any on them, 
    is matched against the next rule of the "calling chain", let's say that that rule is called 'R',
    where the previous rule of 'R' is the rule calling the nested chain just left by the packet.
    The RETURN action has mostly the same effect, a rule in a nested chain is matched by the packet,
    and the action RETURN is called, this causes the packet going back to the 'R' rule described above.
}
When a packet was checked against all the rules of a chain, and matched any of them, then the default policy
  is applied on the packet.
Meaning of tables {
  FILTER: default table (for "filtering" packets).
  NAT: checked when packets establishing a new connection is created, used also for changing data in the packet regarding destination
    or source of the packet. Therefore after the nat table normally a routing decision comes.
  MANGLE: altering packets (not only for new connections) in a more general way (therefore routing decisions are needed after
    the mangle table)
}

Examples of iptables rules

Example 1 with analysis and comments

Issuing the command, on the shell, "iptables-save" we can get something like the following,
and comments will be added, with '#' at the start. Remember that rules are listed from the first
to the last.

Remarks {
  Check the useful links mentioned above for understanding some concepts.
}

# Generated by iptables-save v1.4.10 on Thu Dec 18 12:21:31 2014
*nat
 # this is the table "nat"
:PREROUTING ACCEPT [81606:7251503]
  #this is the chain PREROUTING (for the flow, see above) with number of [packets:bytes]
  #went through the chain. The default policy of the rule is ACCEPT.
:INPUT ACCEPT [306:82553]
:OUTPUT ACCEPT [253:19532]
:POSTROUTING ACCEPT [0:0]
:nat_reflection_in - [0:0]
  #this is a nested chains (mostly predefined by the openwrt uci configuration, sometimes without any rule,
  #just ready to receive some), they have different names than the names written above.
  #
  # About the reflection, it will be explained later, analyzing the rules.
  #
  # About nested chains, some of them, created by default, are just empty.
  # They are listed but without containing rules. The drawback is that in the worst
  # case the CPU has to recall those empty chains nevertheless, spending 'not useful' elaboration time
  # while analyzing a packet.
:nat_reflection_out - [0:0]
:postrouting_rule - [0:0]
:prerouting_lan - [0:0]
:prerouting_rule - [0:0]
:prerouting_wan - [0:0]
:zone_lan_nat - [0:0]
:zone_lan_prerouting - [0:0]
:zone_wan_nat - [0:0]
:zone_wan_prerouting - [0:0]
-A PREROUTING -j prerouting_rule 
  # this is a rule for going to a nested chain. It is the first of the chain, therefore means that
  # every packet that is going through the NAT table, chain PREROUTING will go through the
  # nested chain "prerouting_rule"
-A PREROUTING -i br-lan -j zone_lan_prerouting 
  # this means, if a packet going through the table NAT, chain PREROUTING, is coming from
  # the input interface (in this case a logical one) "br-lan", then it has to go
  # the nested chain 'zone_lan_prerouting'
-A PREROUTING -i br-wan -j zone_wan_prerouting 
  # similar to above
-A POSTROUTING -d 192.168.1.0/24 -j MASQUERADE 
  # Now the chain is changed. This rule means: If a packet, after the routing decisions, is going towards an IP in the range
  # [192.168.1.0, 192.168.1.255] (shortened with 192.168.1.0/24 aka BASIC-IP-ADDRESS/NETMASK) then apply the concept of
  # masquerading (and that, for example, is another possible TARGET or action of an iptable rule).
  # Masquerading means "masking the source of a packet", or better, changing the source of a packet.
  # In general it works in this way: a device from a local network communicates with a device in the internet,
  # through a connection like local_device -> router -> device_internet.
  # The device in the internet is not able to see the IP of the local_device, but just the ip of the router.
  # therefore the router has to keep track of the connection, and when a response packet from the internet is coming
  # back, then it has to change the destination of the packet, from the IP of the router to the IP of the local_device.
  # The masquerading target will activate that procedure for every packet between local_devices and devices from the internet
  # (or from other networks)
-A POSTROUTING -d 192.168.0.0/24 -j MASQUERADE 
  # as before.
-A POSTROUTING -j postrouting_rule 
  # jumping to a nested chain.
-A POSTROUTING -o br-lan -j zone_lan_nat 
  # if the output interface is "br-lan" go to the nested chain 'zone_lan_nat'
-A POSTROUTING -o br-wan -j zone_wan_nat 
  # as before, with a different output interface.
-A nat_reflection_in -s 192.168.1.0/24 -d 172.22.13.228/32 -p tcp -m tcp --dport 22 -m comment --comment "wan" -j DNAT --to-destination 192.168.1.1:22 
  # This rule is automatically added when a port is open between two 'zones' or interfaces. It means
  # when some device from the internal network 192.168.1.0/24 (the source) wants to communicate to a device using
  # the 'external' ip '172.22.13.228/32' with TCP protocol on the port 22, recognize that the IP is
  # the IP of the router itself and therefore the device wants to communicate with the system 192.168.1.1 in reality,
  # it is just using an external ip. (maybe needed by the system 192.168.1.1)
-A nat_reflection_in -s 192.168.1.0/24 -d 172.22.13.228/32 -p tcp -m tcp --dport 80 -m comment --comment "wan" -j DNAT --to-destination 192.168.1.1:80 
-A nat_reflection_in -s 192.168.1.0/24 -d 172.22.13.228/32 -p tcp -m tcp --dport 22 -m comment --comment "wan" -j DNAT --to-destination 192.168.0.1:22 
-A nat_reflection_in -s 192.168.1.0/24 -d 172.22.13.228/32 -p tcp -m tcp --dport 80 -m comment --comment "wan" -j DNAT --to-destination 192.168.0.1:80 
-A nat_reflection_out -s 192.168.1.0/24 -d 192.168.1.1/32 -p tcp -m tcp --dport 22 -m comment --comment "wan" -j SNAT --to-source 192.168.1.254 
-A nat_reflection_out -s 192.168.1.0/24 -d 192.168.1.1/32 -p tcp -m tcp --dport 80 -m comment --comment "wan" -j SNAT --to-source 192.168.1.254 
-A nat_reflection_out -s 192.168.1.0/24 -d 192.168.0.1/32 -p tcp -m tcp --dport 22 -m comment --comment "wan" -j SNAT --to-source 192.168.1.254 
-A nat_reflection_out -s 192.168.1.0/24 -d 192.168.0.1/32 -p tcp -m tcp --dport 80 -m comment --comment "wan" -j SNAT --to-source 192.168.1.254 
-A postrouting_rule -j nat_reflection_out 
  # this is a rule in a nested chain that is calling another nested chain.
-A prerouting_rule -j nat_reflection_in 
-A zone_lan_prerouting -j prerouting_lan 
-A zone_wan_nat -j MASQUERADE 
-A zone_wan_prerouting -s 172.22.13.228/32 -p tcp -m tcp --dport 22 -j DNAT --to-destination 192.168.1.1:22 
  # this is a rule for "if the source of the packet match this ip, port and protocol, change the destination
  # and the port of the packet to this"
-A zone_wan_prerouting -s 172.22.13.228/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.1:80 
-A zone_wan_prerouting -s 172.22.13.229/32 -p tcp -m tcp --dport 22 -j DNAT --to-destination 192.168.0.1:22 
-A zone_wan_prerouting -s 172.22.13.229/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.0.1:80 
-A zone_wan_prerouting -j prerouting_wan 
COMMIT

# if we want to assign the rules of nested chains to the real main chain, we would say that (reading the 'calling' rules)
# NAT/PREROUTING contains the rules of the chain prerouting_rule , zone_lan_prerouting , zone_wan_prerouting , nat_reflection_in,
# prerouting_lan , zone_wan_prerouting , prerouting_wan . This means that the "main" table is subdivided a lot.


# Completed on Thu Dec 18 12:21:31 2014
# Generated by iptables-save v1.4.10 on Thu Dec 18 12:21:31 2014
*raw
# This is a type of table not yet covered.
:PREROUTING ACCEPT [87936:7812932]
:OUTPUT ACCEPT [7918:790863]
:zone_lan_notrack - [0:0]
:zone_wan_notrack - [0:0]
-A PREROUTING -i br-lan -j zone_lan_notrack 
-A PREROUTING -i br-wan -j zone_wan_notrack 
COMMIT
# Completed on Thu Dec 18 12:21:31 2014
# Generated by iptables-save v1.4.10 on Thu Dec 18 12:21:31 2014
*mangle
:PREROUTING ACCEPT [87939:7813176]
:INPUT ACCEPT [70710:6268619]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [7921:791107]
:POSTROUTING ACCEPT [7921:791107]
:zone_wan_MSSFIX - [0:0]
-A FORWARD -j zone_wan_MSSFIX 
-A zone_wan_MSSFIX -o br-wan -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu 
  # this is a rule added by default by openwrt
COMMIT
# Completed on Thu Dec 18 12:21:31 2014
# Generated by iptables-save v1.4.10 on Thu Dec 18 12:21:31 2014
*filter
:INPUT ACCEPT [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:forward - [0:0]
:forwarding_lan - [0:0]
:forwarding_rule - [0:0]
:forwarding_wan - [0:0]
:input - [0:0]
:input_lan - [0:0]
:input_rule - [0:0]
:input_wan - [0:0]
:nat_reflection_fwd - [0:0]
:output - [0:0]
:output_rule - [0:0]
:reject - [0:0]
:syn_flood - [0:0]
:zone_lan - [0:0]
:zone_lan_ACCEPT - [0:0]
:zone_lan_DROP - [0:0]
:zone_lan_REJECT - [0:0]
:zone_lan_forward - [0:0]
:zone_wan - [0:0]
:zone_wan_ACCEPT - [0:0]
:zone_wan_DROP - [0:0]
:zone_wan_REJECT - [0:0]
:zone_wan_forward - [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 
  # this means that if the packet is routed towards the router itself
  # and the conenction is tracked, plus the connection type is RELATED,ESTABLISHED
  # the the packet is accepted
-A INPUT -i lo -j ACCEPT 
  # If the packet is coming from the "internal" interface of the router (is created by the
  # router itself), accept it.
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j syn_flood 
-A INPUT -j input_rule 
-A INPUT -j input 
-A FORWARD -s 192.168.0.0/24 -j ACCEPT
  # If the packet is routed not towards the system itself, and has the source
  # in the range 192.168.0.0/24, accept it.
-A FORWARD -d 192.168.0.0/24 -j ACCEPT 
  # The same, but if the destination matches.
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 
-A FORWARD -j forwarding_rule 
-A FORWARD -s 192.168.1.0/24 -j ACCEPT 
-A FORWARD -d 192.168.1.0/24 -j ACCEPT 
-A FORWARD -j forward 
-A FORWARD -j reject 
-A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 
-A OUTPUT -o lo -j ACCEPT 
-A OUTPUT -j output_rule 
-A OUTPUT -j output 
-A forward -i br-lan -j zone_lan_forward 
-A forward -i br-wan -j zone_wan_forward 
-A forwarding_rule -j nat_reflection_fwd 
-A input -i br-lan -j zone_lan 
-A input -i br-wan -j zone_wan 
-A nat_reflection_fwd -s 192.168.1.0/24 -d 192.168.1.1/32 -p tcp -m tcp --dport 22 -m comment --comment "wan" -j ACCEPT 
-A nat_reflection_fwd -s 192.168.1.0/24 -d 192.168.1.1/32 -p tcp -m tcp --dport 80 -m comment --comment "wan" -j ACCEPT 
-A nat_reflection_fwd -s 192.168.1.0/24 -d 192.168.0.1/32 -p tcp -m tcp --dport 22 -m comment --comment "wan" -j ACCEPT 
-A nat_reflection_fwd -s 192.168.1.0/24 -d 192.168.0.1/32 -p tcp -m tcp --dport 80 -m comment --comment "wan" -j ACCEPT 
  # the same "automated rules" for reflection for the forward. This allows the two
  # internal networks to communicate to each other at least if some ip/port/protocol matches.
-A output -j zone_lan_ACCEPT 
-A output -j zone_wan_ACCEPT 
-A reject -p tcp -j REJECT --reject-with tcp-reset 
-A reject -j REJECT --reject-with icmp-port-unreachable 
-A syn_flood -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m limit --limit 25/sec --limit-burst 50 -j RETURN 
-A syn_flood -j DROP 
-A zone_lan -j input_lan 
-A zone_lan -j zone_lan_ACCEPT 
-A zone_lan_ACCEPT -o br-lan -j ACCEPT 
-A zone_lan_ACCEPT -i br-lan -j ACCEPT 
-A zone_lan_DROP -o br-lan -j DROP 
-A zone_lan_DROP -i br-lan -j DROP 
-A zone_lan_REJECT -o br-lan -j reject 
-A zone_lan_REJECT -i br-lan -j reject 
-A zone_lan_forward -j zone_wan_ACCEPT 
-A zone_lan_forward -j forwarding_lan 
-A zone_lan_forward -j zone_lan_REJECT 
-A zone_wan -p udp -m udp --dport 68 -j ACCEPT 
-A zone_wan -p icmp -m icmp --icmp-type 8 -j ACCEPT 
-A zone_wan -p tcp -m tcp --dport 2222 -j ACCEPT 
-A zone_wan -p tcp -m tcp --dport 8080 -j ACCEPT 
-A zone_wan -j input_wan 
-A zone_wan -j zone_wan_REJECT 
-A zone_wan_ACCEPT -o br-wan -j ACCEPT 
-A zone_wan_ACCEPT -i br-wan -j ACCEPT 
-A zone_wan_DROP -o br-wan -j DROP 
-A zone_wan_DROP -i br-wan -j DROP 
-A zone_wan_REJECT -o br-wan -j reject 
-A zone_wan_REJECT -i br-wan -j reject 
-A zone_wan_forward -s 172.22.13.228/32 -d 192.168.1.1/32 -p tcp -m tcp --dport 22 -j ACCEPT 
  # this nested chain belongs to FILTER/FORWARD and the rules states that if a packet
  # comes with source 172.22.13.228/32 and destination 192.168.1.1/32 could be forwarded.
-A zone_wan_forward -s 172.22.13.228/32 -d 192.168.1.1/32 -p tcp -m tcp --dport 80 -j ACCEPT 
-A zone_wan_forward -s 172.22.13.229/32 -d 192.168.0.1/32 -p tcp -m tcp --dport 22 -j ACCEPT 
-A zone_wan_forward -s 172.22.13.229/32 -d 192.168.0.1/32 -p tcp -m tcp --dport 80 -j ACCEPT 
-A zone_wan_forward -j forwarding_wan 
-A zone_wan_forward -j zone_wan_REJECT 
COMMIT
# Completed on Thu Dec 18 12:21:31 2014

Iptables through uci config

See firewall . One interpretation suggest to use as much as possible the uci config (in /etc/config/firewall ) because it will be more readable and clean (moreover with rule reported in the web interface) of raw iptables commands. Moreover, as the example in this page reports, the uci configurations defines additional nested chains to order the rules. If those additional nested chains are unused they creates only additional overhead for the cpu. Therefore would be nice to use them through the uci configurations, plus the 'uci' firewall uses the hotplug feature so if a cable is disconnected the rules are removed/added as needed.

Of course, since the uci configuration is just another way of writing iptables rules, it is obvious that raw iptables rules are more expressive than the uci configurations. Nevertheless to attain the same level of "ordering", through raw iptable commands, it is suggested to use scripts that assemble iptable commands and are more readable/ordered than literal iptable commands.

On the other side, to see the effects of rules in uci configurations, one of the suggested way is analyzing (but it takes time) the raw iptable commands through the "iptables-save" command.

Routing / IPs

Command examples on the terminal with comments

ip

Ip is recommended over ifconfig / route , but is not always available by default.
# ip addr show (the new version of ifconfig)
  Comment {
    shows the ip addresses and other data related
    to physical/virtual network interfaces
  }
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 48:5b:39:e7:eb:3b brd ff:ff:ff:ff:ff:ff
4: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether 48:5b:39:e7:eb:3b brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.254/24 brd 192.168.1.255 scope global br-lan
    inet 192.168.0.254/24 brd 192.168.0.255 scope global br-lan
  # shows that the internet addresses related to the virtual interface br-lan
  # are two, one with IP 192.168.1.254, netmask 24 (255.255.255.0)
5: eth0.0@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-lan state UP
    link/ether 48:5b:39:e7:eb:3b brd ff:ff:ff:ff:ff:ff
6: br-wan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether 00:1e:90:fc:98:3d brd ff:ff:ff:ff:ff:ff
    inet 172.22.13.228/20 brd 172.22.15.255 scope global br-wan
    inet 172.22.13.229/20 brd 172.22.15.255 scope global secondary br-wan
7: eth0.1@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-wan state UP
    link/ether 48:5b:39:e7:eb:3b brd ff:ff:ff:ff:ff:ff

Routing / IPs through uci configs

See network . One interpretation suggest to use as much as possible the uci config (in /etc/config/network ) because it will be more readable and clean (moreover with rule reported in the web interface) of raw ip or ifconfig or route commands. But bear in mind that uci configuration is likely to be less flexible than raw commands.

Effects of combination of routing rules and iptables rules

Through uci config files

Scenario: forwarding packets to an host, behind a router, that has an additional external ip address

Description

### schema:
network <---> router <----> hostA

### Description:
In the network a general request is dispatched to reach a certain Ip address, let's say "192.168.10.119",
in reality the request should be served by the hostA that is behind the router.
The router IP on the side of the network is 192.168.10.118, while the network between the router and the hostA
is 192.168.1.1/24 and the hostA has address 192.168.1.223.

Let's say that the routing in the network for now it is not a problem, the request is dispatched
to every system in the network, so will reach also the router.

One condition is that the router will expose only one IP on the side of the network, that is
192.168.10.118, without exposing also the 192.168.10.119. Of course this condition is not a "must"
in the case that the result cannot be attained.

(for example as an alias in /etc/config/network like (with owrt 12.09):

config interface 'wan'
  option ifname 'ethSomething'
  option type bridge
  option proto static
  option ipaddr 192.168.10.118
  option netmask 255.255.255.0
  option gateway 192.168.10.1

config interface 'wan_alias'
  option ifname 'br-wan'
  option proto static
  option ipaddr 192.168.10.119
  option netmask 255.255.255.0

)

First trial: just with SNAT / DNAT rules

### Configuration
Since the router wants to catch the packets for the ip 192.168.10.119, we start to define
DNAT (destination translation) and SNAT (source translation) [note that SNAT and DNAT are
combined in masquerading, see other articles about firewall in this wiki.
In brief SNAT rewrites the IP source of a packet, DNAT rewrites the IP destination of a packet].
The rules in /etc/config/firewall are like the following.

config redirect 'testing_dnat_icmp'
        option src      wan
        option src_dip  192.168.10.119
        option proto    icmp
        option dest     lan
        option dest_ip  192.168.1.223
        option target   DNAT
        list explanation 'if a icmp packet wants to reach 192.168.10.119 rewrite the destination to 192.168.1.223'
        list explanation 'the source of this packet should be a network in the zone wan and the destination is'
        list explanation 'all the networks in the zone lan'

config redirect 'testing_snat_icmp'
        option src      lan
        option src_ip   192.168.1.223
        option src_dip  192.168.10.119
        option proto    icmp
        option dest     wan
        option dest_ip  '192.168.10.1/24'
        option target   SNAT
        list explanation 'if a icmp packet is coming from 192.168.1.223 rewrite the source to 192.168.10.119'
        list explanation 'the source of this packet should be a network in the zone lan and the destination is'
        list explanation 'all the networks in the zone wan plus in the subnet 192.168.10.1/24'

### Problems

#### Problems about sending the packet to the Ip address.
Until now the experience about networks and openwrt of the contributors of this page
shows that to reach a destination identified by an IPv4 address, the network
structure should know how to reach that ip address.

This knowledge is obtained issuing ARP request to identify the owner (in terms of
MAC address identificator) of the IP address or, in the case that the owner is
not reachable directly, routing rules are used. As explained in this page
and in other pages about routing/firewalling in this wiki, a routing rule
tells the router where to send packets that wants to reach a certain destination (in IP addresses terms).

Often the router does not know directly the destination, therefore the strategy is
"if you want to reach this destination, ask to that other system for it" that other
system is another router that is called gateway, and it is identified by an IP address as well.

#### Why the solution fails
For what we said before, the solution cannot work because
the network does not "see" any owner of the IP address 192.168.10.119,
because the IP address is not exposed (or attached) to the router's IP
addresses. Nor exist a routing rule on the router that is able to
catch the packet and send it to the internal network to reach the hostA.

Therefore we should think about either exposing the Ip address on the router,
and then translate the packets going ot 192.168.10.119 towards the hostA's Ip address
and viceversa (thus applying DNAT and SNAT); or we can route the packets
towards the host A, filtering the unwanted packets (to increase the security),
but then the hostA should be the end point of the packet, therefore having
the IP address 192.168.10.119.

### Result
Failure, due to the problems exposed above.

Second trial: with routing rules and filtering rules

### Configuration
We don't want to give up the condition of not exposing the 192.168.10.119 on the router
wan side. Therefore we try to use routing rules, filtering rules and hostA configuration.

#### Network configuration on the router
We should add a route "to the host" therefore in /etc/config/network we add
config 'route' 'route_to_inside'
        option 'interface' 'lan'
        option 'target' '192.168.10.119'
        option 'netmask' '255.255.255.255'
        option 'gateway' '0.0.0.0'
        
This means: if a packet wants to reach the _exact_ destination (note the netmask) 192.168.10.119
then use the lan interface to send the packet towards no gateway. When the gateway is 0.0.0.0 means everything
or nothing. That is, there is no specific system to ask, just dispatch the packet on that interface.

This is ok because the packet dispatched on the lan interface will reach directly the hostA.
We can even use <option 'gateway' '192.168.1.223'> if we want, it should work the same.

#### Firewall configuration on the router
Since we have a route, this route forwards specific packets directly
from the wan to the lan interface, but the forwarding should be allowed.
Them according to the documentation of the firewall in this wiki, we write in
/etc/config/firewall the following:
config rule 'forward_to_ip_test'
        option src      wan
        option dest     lan
        option dest_ip  192.168.10.119
        option proto    all
        option target   ACCEPT

This will allow us to forward whatever packet (ok it is not so secure for now)
to the destination 192.168.10.119 if the packet is coming from wan and
wants to reach the lan zone.

Don't forget the right masquerading! Always in /etc/config/firewall:
config zone
        option name 'wan'
        option network 'wan'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option masq '1'
        option mtu_fix '1'
        option masq_src '192.168.1.1/24'
        
The masquerading follow the order, so first is subject to masquerading
every connection that has source within the network 192.168.1.1/24
and then is not subject to masquerading connections with source different from
the ones just described. Therefore avoiding to
'destroy' connection due to unwanted SNAT/DNAT.

#### Ip configuration on the hostA
The host should know, since we are not exposing the IP, the IP address
therefore we should add the IP address 192.168.10.119 with netmask 255.255.255.255 to the hostA,
so the hostA will reply as owner of the 192.168.10.119 ip address.

Why do we use a 255.255.255.255 netmask?
Because if the netmask is less strict, then the system
will automatically infer that on the interface where the ip address is assigned
could be possible to reach directly (with an ARP discovery) the Ip addresses of
the network defined by the pair (ip, netmask). Instead with a 'strict' netmask
it is like to say to the system 'you are the only one in this network, don't
think that you can reach directly someone else'.

### Problems

#### When an external system 'thinks' (or better, is programmed to behave) that can reach that hostA 's ip address directly, 
#### then the solution does not work
One problem is when an external system thinks, due to the configuration of its IP addresses/netmask,
that can reach the 192.168.10.119 directly, then the solution does not work due to
the ARP protocol (that allows to discover hosts).

When a system has a certain IP and netmask linked to an interface, if the netmask is _not_ 255.255.255.255,
the system is structured to assume that every other IP addresses in the range of the Ip,netmask
(for example, with ip 192.168.10.19 and netmask 255.255.255.0, the range is 
192.168.10.1-192.168.10.255)
can be directly reachable, this means without additional gateways (unless
an additional route is defined). 

Therefore the system will just issue discovery requests (ARP requests) that are not
routed by routers. So in case of ARP request due to systems that
are configured to reach directly the IP address, this solution is not working.

#### Result
If the system that requires services on the 192.168.10.119 IP address, does
not try to reach it directly (for example because there are routers that instruct it
to ask to gateways. In my case i added the route: 'if you want to reach 192.168.10.119/32 ask 192.168.10.118'
instead of assuming to be able to discover the system immediately), then the solution
works without exposing an IP address on the router.

Scenario: Guest customer network

Overview

Often the customers requires a guest network with internet access, that should not access the local network in terms of customer servers and customer systems with important data.

There are several ways to realize a guest network in a customer network, here we will try to list them.

Solution: Connecting the devices that are in the guest network directly to the main gateways

This solution is often preferred for several reason, for example in the case of wifi accesspoints unable to provide dhcp servers and therefore the dhcp server of a openwrt gateway was used.

The drawback is that one or more physical ports on the gateway must be dedicated to the guest network, leaving less ports free for other work and creating more configuration work on the gateway

Solution: Connecting the devices that are in the guest network to the gateways using the local customer network without major changes (Vlan, direct cable patching, etc...)

The idea is based on the almost universal implementation of routing policies on network devices.

Let's say that the scenario is the following:

  - There is a gateway through which all the traffic to the internet has to pass,
    that also is connected directly (at maximum through switches) to all the customer networks.
    Let's say that those networks are 10.10.10.0/24 ; 10.10.20.0/24; 10.10.30.0/24
    and the gateway ip addresses in those network are, respectively,
    10.10.10.1 ; 10.10.20.1 ; 10.10.30.1
  - Then there are devices able to separate their interfaces in two distinct networks
    (for example router with wireless) that manage some subnetworks for guest clients.
    In our case let's say that we use wifi-routers that create the subnetwork 10.10.50.0/24
    for guest wifi clients, and let us assign another ip for its 'wan'/'external network'
    side.

Now the point is: if we connect the devices that handle the guest subnetworks to the local customer network, but we assign to them ip addresses in the address space of the local customer network, will be possible, for a guest wifi client, to reach a customer system.

For example the device handling the guest subnetwork (from now on, a wifi router) has a wan address of 10.10.30.9 and is serving a wifi client with IP 10.10.50.75 . We cannot control the wifi client, so it can ask to reach the ip 10.10.30.50 (an ip in the local customer network), and this request will be fulfilled because the wifi router, through routing stardards, assumes to be able to reach every address in the network 10.10.30.0/24 without further request to other intermediate systems.

So we should avoid this, a way is the following:

  - defining a guest customer network on the logical level within the local network of the customer,
    for example 10.10.40.0/24 , with the main gateway with an ip in this network, for example 10.10.40.1
  - every device handling guest subnetworks will have the ip on the 'external side'/'wan side' defined in the address space
    10.10.40.0/24 with gateway pointing to the real gateway, that is 10.10.40.1 .

In this way, the wifi-routers that create the guest subnetworks will know that to reach any ip address different from 10.10.40.x/24 (address in the guest customer network) they will have to ask to the gateway with ip 10.10.40.1, and since we (as IT support) define which networks the wifi routers known or not, the wifi client will be powerless to go around our definitions (thanks to routing standards).

On this gateway we can restrict the routing of the packets coming from the guest customer network (that is, it is useful to repeat, 10.10.40.0/24 with eventual subnetworks created by devices connected to this network). We can define, for instance, rules that implement the following condition: "whatever you want to reach a public ip address, you are allowed to, otherwise your request will be rejected".

With Openwrt on the main gateway

With openwrt this solution is quite easy to define, through uci configurations.

First of all the guest customer network will be attached to the main gateway with an alias interface, like

#/etc/config/network
...lines...

config interface lan
  option type bridge
  ...lines...

...lines...

config interface lan_guest
  option ifname 'br-lan'
    #because normally the guest customer network is part of the lan
    #cabling within the customer network.
  option proto static
  option ipaddr 10.10.40.1
  option netmask 255.255.255.0

...lines...

And that is normally enough, due to a subtle detail. Even if the lan side on the openwrt has several IPs in different networks, requests from a network to another won't communicate by default, even if the networks are attached to the same logical interface (in this case br-lan). To let them communicate it is required to forward requests within the same zone (that is defined over the logical interfaces), in this way:

#/etc/config/firewall
# given the zone lan configured over the logical interface lan/br-lan

...lines...

config forwardings
  option src lan
  option dest lan 

...lines...

When the forwarding is necessary for other purposes, then we need to implement reject/drop rules, those will be written here asap.

Through non-uci config files called by uci files

Scenario: approximately limit download bandwidth without using traffic control

Openwrt 12.09. Adding to /etc/firewall.user, called by /etc/config/firewall, the following:

# Because owrt 12.09 firewall does not allow extreme flexibility,
# compared to the possibilities of the tools used.
# Knowing that this file will be executed after all the uci config.

#here we want to limit the incoming packets speed
# _blending_ the usage with the owrt structure.
iptables -N zone_wan_forward_limit
  #chain for limiting the packets going throgh a certain zone
iptables -I zone_wan_forward -j zone_wan_forward_limit
  # first rule (inserted) of the zone_wan_forward chain, made by owrt
iptables -A zone_wan_forward_limit -m limit --limit 1400/s -j RETURN
  # limit the speed to 1400 packets per second, for a maximum bandwidth of ~2Mbyte/s
  # with mtu of 1500 byte.
iptables -A zone_wan_forward_limit -j DROP
  # if packets are not matched by the previous rule, they wil be dropped.
  # reject can cause throuble to the established connections, DROP
  # allows the IP protocols to adapt the speed.

or the alternative (since zone_wan_forward is used mostly with redirects)

# Because owrt 12.09 firewall does not allow extreme flexibility,
# compared to the possibilities of the tools used.
# Knowing that this file will be executed after all the uci config.

# here we want to limit the incoming packets speed
# _blending_ the usage with the owrt structure.
# the problems is to keep track of the interface names.
iptables -N zone_wan_forward_limit
  #chain for limiting the packets going throgh a certain zone
iptables -I FORWARD -i br-wan -o br-lan -j zone_wan_forward_limit
  # first rule (inserted) of the zone_wan_forward chain, made by owrt
iptables -A zone_wan_forward_limit -m limit --limit 1000/s --limit-burst 10000 -j RETURN
#iptables -A zone_wan_forward_limit -m limit --limit 500/s -j RETURN
#iptables -A zone_wan_forward_limit -m limit --limit 500/s -j RETURN
#iptables -A zone_wan_forward_limit -m limit --limit 500/s -j RETURN

  # limits the speed to X packets per second, for a maximum bandwidth of ~(X*512*8)Mbps when
  # packets are 512 byte of average (normally are bigger)
  # Anyway it seems that the checking of rules by iptables
  # with limits has certain limits in 'time' so to 'allow' an average of 1000 pps
  # actually more than one rule in cascade is needed because else packets 'slip'
  # the match and goes to another rule.
  # For example adding 3 consecutive rules with limit 1000/s does not yield to the same
  # bandwidth performance of having one rule with limit 10'000/s, actually the rule with
  # higher limit will have less performance.
  #
  # This is because of the burst. The average seems not computed after one second,
  # or one minute and so on, but it seems computed with smaller fraction of seconds,
  # therefore if packets come too fast they slip away if the burst is too small.
  # To get the wanted speed ( ~ 2Mbyte second ~ 1K packets per second with steady download)
  # fine tuning was necessary and i set the limit of 1000 packets per second
  # on average plus a burst of 5000 packets or a bit more.
  # The burst is used (per matches) when the limit is reached.
  # The burst actually recharges itself like "the limit not used". So if I use all the limit
  # in some time units and then no more for some time unit, the limit goes to change the
  # burst.
  # Therefore one could size the burst like "how many time units without matches
  # would be needed to fill it".

  # with the iperf test, remember that --len somehow affects the size of the packages
  # when under the MTU, should be valid both for usp and tcp even if it is the buffer
  # to receive and send

# testing packet matching and counting
#iptables -N counting_chain
#iptables -A zone_wan_forward_limit -j counting_chain

iptables -A zone_wan_forward_limit -j DROP
  # if packets are not matched by the previous rule, they wil be dropped.

inbox/doc/iptables_and_firewall.txt · Last modified: 2016/10/06 08:32 by pier4r