A Bit about Firewall in Linux
Introduction:
netfilter
is a set of hooks inside the Linux kernel that allows kernel modules to register callback functions with the network stack. A registered callback function is then called back for every packet that traverses the respective hook within the network stack.
iptables
is a firewall program used in all Linux flavors. With this program, the user can monitor and take actions on packet transfers to and from the Linux machine.
iptables
is a generic table structure where you define the rulesets. Each rule within an iptable consists of a number of classifiers (iptables matches
— condition) and one connected action (iptables target
— action to be taken).
There are third party tools available that can add rules to iptables and the details can be found in following image.
Terminology:
-
netfilter
: This is a kernel level module that monitors packet transferring. -
iptables
: This can be interchanged between a firewall (command line) program and actual firewall rules table. -
iptables-services
: This is a package name for service that can be installed oncentos 7.X
. The same can be installed oncentos 6.X
andamazon linux ami
withiptables
package name. This uses the same syntax asiptables
(command line program), but it stores its rules in/etc/sysconfig/ip[6]tables
-
firewalld
: This is a firewall program available incentos >= 7
and can be installed onubuntu
anddebian 8
. -
ufw
: This is a firewall program usually found by default indebian
flavors. This program is in sync functionally withiptables
(command line program). -
chain
: Ip packets are divided into chains such as:INPUT
,OUTPUT
,FORWARD
,PREROUTING
,POSTROUTING
. -
INPUT
: This is a chain for allincoming
packets. We can apply rules and policies for this chain and they will be applied to all incoming packets. -
OUTPUT
: This is a chain for alloutgoing
packets. We can apply rules and policies for this chain and they will be applied to all outgoing packets. -
FORWARD
: This is a chain for allFORWARDED
packets. We can apply rules and policies for this chain and they will be applied to allFORWARDED
packets (packets can be forwarded to the same machine on another interface or can be forwarded to another machine). -
policy
: It is usually called default policy and can be eitherACCEPT
orDROP
. It is applied after all rules are checked for matches. When a rule matches the packets, all of the other rules and policies are ignored. -
ACCEPT
: This is one of the default policies we can apply to chains. If set, it allows all packages except rules specified. -
DROP
: This is one of the default policies we can apply to chains. If set, it blocks all packages except rules specified. -
zones
: A zone defines the level of trust for network connections. Zones are applied only on incoming packets. This is a one to many relation, which means that a connection can only be part of one zone, but a zone can be used for many network connections.
There are the following zones available.drop
: Any incoming network packets are dropped and there is no reply. Only outgoing network connections are possible.block
: Any incoming network connections are rejected with an icmp-host-prohibited message for IPv4 and icmp6-adm-prohibited for IPv6. Only network connections initiated within this system are possible.public
: For use in public areas. This works asACCEPT
all by default.external
: For use on external networks with masquerading enabled especially for routers. This works asACCEPT
all by default.dmz
: For computers in your demilitarized zone that are publicly-accessible with limited access to your internal network. This also works asACCEPT
all by default.work
: For use in work areas. This also works asACCEPT
all by default.home
: For use in home areas. This also works asACCEPT
all by default.internal
: For use on internal networks. This also works asACCEPT
all by default.trusted
: All network connections are accepted.
Commands:
iptables:
ip[6]tables -L [INPUT|OUTPUT|FORWARD]
List all rules in the selected chain. If no chain is selected, all chains are listed.
[kishor@localhost ~]$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[kishor@localhost ~]$
ip[6]tables -P {INPUT|OUTPUT|FORWARD} {ACCEPT|DROP}
Set the policy for the chain to the given target
[kishor@localhost ~]$ sudo iptables -P FORWARD DROP
[kishor@localhost ~]$ sudo iptables -L FORWARD
Chain FORWARD (policy DROP)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp- host-prohibited
[kishor@localhost ~]$
ip[6]tables -A {INPUT|OUTPUT|FORWARD} -p {tcp|udp} --dport {22|80|443} -j {ACCEPT|DROP}
Set rule to accept or drop packets for chain on specific port
[kishor@localhost ~]$ sudo iptables -A FORWARD -p tcp --dport 22 -j DROP
[kishor@localhost ~]$ sudo iptables -L FORWARD
Chain FORWARD (policy DROP)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
DROP tcp -- anywhere anywhere tcp dpt:ssh
[kishor@localhost ~]$
sudo iptables -A {INPUT|OUTPUT|FORWARD} -m string --hex-string "|0A|google|03|com" --algo bm -j ACCEPT
Above is rule, when added to iptables will allow packets to and from Google domain.
kishor@localhost:~$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 192.168.0.100 anywhere
ACCEPT icmp -- anywhere anywhere icmp echo-request
ACCEPT all -- anywhere anywhere STRING match "|0a636c6f7564726178616b036e6574|" ALGO name bm TO 65535
kishor@localhost:~$
iptables -A {INPUT|OUTPUT|FORWARD} -p tcp -s XXX.XXX.XXX.XXX -j {ACCEPT|DROP}
ip6tables -A {INPUT|OUTPUT|FORWARD} -p tcp -s XXXX:XXXX:XXXX:XXXX:XXXX:XXXX -j {ACCEPT|DROP}
Set rule to allow or drop connections from specific IPs.
firewalld:
firewall-cmd --get-default-zone
Returns the default(fallback) zone set for all interfaces. Default zone is applied only if active zone is not set for interface. Default zone is permanent by default.
kishor@localhost:~$ firewall-cmd --get-default-zone
public
kishor@localhost:~$
firewall-cmd --set-default-zone
Sets default zone for all interface.
kishor@MWPYT113:~$ firewall-cmd --set-default-zone=trusted
success
kishor@MWPYT113:~$ sudo firewall-cmd --get-default-zone
trusted
kishor@MWPYT113:~$
firewall-cmd --get-active-zones
Returns active zones for each available interfaces. This take precedence over default zone.
kishor@MWPYT113:~$ sudo firewall-cmd --get-active-zones
internal
interfaces: eht0
trusted
interfaces: br0
block
interfaces: virbr0
kishor@MWPYT113:~$
sudo firewall-cmd [--permanent] --zone={trusted|public|dmz|drop|block|internal|home|work|external} --change-interface=<interface-name>
Sets active zone for particular interface. If --permanent is added, result will persist across reboot. To make the permanent changes go into effect, you will have to reload the firewalld as below.
kishor@MWPYT113:~$ sudo firewall-cmd --zone=trusted --change-interface=br0
success
kishor@MWPYT113:~$ sudo firewall-cmd --zone=internal --change-interface=eht0
success
kishor@MWPYT113:~$ sudo firewall-cmd --zone=block --change-interface=virbr0
success
kishor@MWPYT113:~$
firewall-cmd [--permanent] --add-rich-rule="rule family='{ipv4|ipv6}' source address='{192.168.0.11|fe80::dacb:8aff:fe28:298e}' {reject|accept}"
Set rule to accept or reject connection from specific IP address.
kishor@MWPYT113:~$ sudo firewall-cmd --add-rich-rule="rule family='ipv4' source address='192.168.0.11' reject"
success
kishor@MWPYT113:~$
UFW:
The default firewall configuration tool for Ubuntu is ufw. Developed to ease iptables firewall configuration, ufw provides a user friendly way to create an IPv4 or IPv6 host-based firewall.
- Enable UFW
To turn UFW on with the default set of rules:
sudo ufw enable
To check the status of UFW:
sudo ufw status verbose
The output should be like this:
kishor@localhost:~$ sudo ufw status verbose
[sudo] password for kishor:
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing)
New profiles: skip
kishor@localhost:~$
You can also read the rules from /etc/default/ufw
- Disable UFW
To disable ufw use:
sudo ufw disable
- Allow and Deny (specific rules)
sudo ufw allow <port>/<optional: protocol>
example: To allow incoming tcp and udp packet on port 53
sudo ufw allow 53
example: To allow incoming tcp packets on port 53
sudo ufw allow 53/tcp
example: To allow incoming udp packets on port 53
sudo ufw allow 53/udp
* Deny
sudo ufw deny <port>/<optional: protocol>
example: To deny tcp and udp packets on port 53
sudo ufw deny 53
example: To deny incoming tcp packets on port 53
sudo ufw deny 53/tcp
example: To deny incoming udp packets on port 53
sudo ufw deny 53/udp
- Delete Existing Rule
To delete a rule, simply prefix the original rule with delete. For example, if the original rule was:
ufw deny 80/tcp
- Use this to delete it:
sudo ufw delete deny 80/tcp
sudo ufw allow <service name>
example: to allow SSH by name
sudo ufw allow ssh
- Deny by Service Name
sudo ufw deny <service name>
example: to deny SSH by name
sudo ufw deny sshStatus
- To check the status of UFW
sudo ufw status
if UFW was not enabled, the output would be:
sudo ufw status
Status: inactive
To allow port forwarding when UFW is running, follow the below steps:
sudo vim /etc/default/ufw
Set the default forward policy to ACCEPT
, DROP
or REJECT
. Please note that if you change this you will most likely want to adjust your rules
DEFAULT_FORWARD_POLICY="ACCEPT"
.