H54AQ

            And it seems to me you lived your life
            Like a candle in the wind..
            Elton John, Goodbye Yellow Brick Road, 1973, 2,0:38

[1] FirewallD
    =========

The firewalld daemon manages groups of rules using entities called "zones". Zones are basically sets of rules dictating what traffic should be allowed depending on the level of trust you have in the networks your computer is connected to. Network interfaces are assigned a zone to dictate the behavior that the firewall should allow.

  drop; block; public; external; internal; dmz; work; home; trusted;

rules can be designated as either permanent or immediate. Most firewall-cmd operations can take the --permanent flag to indicate that the non-ephemeral firewall should be targeted. You can also use the --permanent flag to build out an entire set of rules over time that will all be applied at once when the reload command is issued.

Getting started
...............

Turn the Firewall on:

  # systemctl start firewalld.service

Verify that the service is running:

  $ firewall-cmd --state
  running

Enable firewall to start up at boot.

  # systemctl enable firewalld.service

Which zone is currently selected as the default:

  $ firewall-cmd --get-default-zone
  public

Print out active zone.

  $ firewall-cmd --get-active-zones
  public
    interfaces: eth0 eth1

Since we haven't given firewalld any commands to deviate from the default zone, and none of our interfaces are configured to bind to another zone, that zone will also be the only "active" zone (the zone that is controlling the traffic for our interfaces).

Print out the default zone's configuration:

  $ firewall-cmd --list-all
  public (default, active)
    interfaces: eth0 eth1
    sources:
    services: dhcpv6-client ssh
    ports:
    masquerade: no
    forward-ports:
    icmp-blocks:
    rich rules:

List available zones:

  $ firewall-cmd --get-zones
  block dmz drop external home internal public trusted work

Print out specific configuration associated with a zone:

  $ firewall-cmd --zone=home --list-all
  home
    interfaces:
    sources:
    services: dhcpv6-client ipp-client mdns samba-client ssh
    ports:
    masquerade: no
    forward-ports:
    icmp-blocks:
    rich rules:

Output all of the zone definitions (use | less):

  $ firewall-cmd --list-all-zones

Change zone for current session
...............................

Transition enp0s3 interface to the "home" zone:

  # firewall-cmd --zone=home --change-interface=eth0
  success
  $ firewall-cmd --get-active-zones
  home
    interfaces: eth0
  public
    interfaces: eth1

Make it permanent:

  # cat /etc/sysconfig/network-scripts/ifcfg-eth0 | tail -n 1
  ZONE=home
  # systemctl restart network.service
  # sudo systemctl restart firewalld.service
  $ firewall-cmd --get-active-zones
  home
    interfaces: eth0
  public
    interfaces: eth1

Adjusting the Default Zone
..........................

Let's start with unconfigurated Centos firewall.

Change the default zone:

  # firewall-cmd --set-default-zone=home
  home
    interfaces: eth0 eth1

Setting Rules for your Applications
...................................

Adding a Service to your Zones*

  $ firewall-cmd --get-services
  # firewall-cmd --zone=public --permanent --add-service=http
  # firewall-cmd --zone=public --permanent --add-service=https
  $ firewall-cmd --zone=public --list-services
  dhcpv6-client http ssh

Opening a Port for your Zones
.............................

  # firewall-cmd --zone=public --permanent --add-port=5000/tcp
  # firewall-cmd --zone=public --permanent --add-port=4990-4999/udp
  # firewall-cmd --zone=public --permanent --list-ports
  success
  success
  4990-4999/udp 5000/tcp

Defining a Service
..................

  # cp /usr/lib/firewalld/services/ssh.xml \
       /etc/firewalld/services/example.xml

Services are simply collections of ports with an associated name and description.

  # cat /etc/firewalld/services/example.xml
  <?xml version="1.0" encoding="utf-8"?>
  <service>
    <short>Example Service</short>
    <description>This is just an example service.</description>
    <port protocol="tcp" port="7777"/>
    <port protocol="udp" port="8888"/>
  </service>

  # firewall-cmd --reload
  $ firewall-cmd --get-services
  .. example ..

Creating Your Own Zones
.......................

  # firewall-cmd --permanent --new-zone=publicweb
  # firewall-cmd --permanent --new-zone=privateDNS
  # firewall-cmd --permanent --get-zones
  block dmz drop external home internal privateDNS public publicweb
  trusted work
  # firewall-cmd --reload
  $ firewall-cmd --get-zones
  block dmz drop external home internal privateDNS public publicweb
  trusted work
  # firewall-cmd --zone=publicweb --permanent --add-service=ssh
  # firewall-cmd --zone=publicweb --permanent --add-service=http
  # firewall-cmd --zone=publicweb --permanent --add-service=https
  # firewall-cmd --zone=privateDNS --permanent --add-service=dns
  # cat /etc/sysconfig/network-scripts/ifcfg-eth0 | tail -n 1
  ZONE=publicweb
  # cat /etc/sysconfig/network-scripts/ifcfg-eth1 | tail -n 1
  ZONE=privateDNS
  # systemctl restart network
  # systemctl restart firewalld
  # firewall-cmd --get-active-zones
  privateDNS
    interfaces: eth1
  publicweb
    interfaces: eth0
  # firewall-cmd --zone=publicweb --list-services
  http htpps ssh
  # firewall-cmd --zone=privateDNS --list-services
  dns

To make one of these zones the default for other interfaces:

  # firewall-cmd --set-default-zone=publicweb

------

*) For details see appropriate XML file. For instance, the SSH service is defined like this:

  /usr/lib/firewalld/services/ssh.xml

  <?xml version="1.0" encoding="utf-8"?>
  <service>
    <short>SSH</short>
    <description>Secure Shell (SSH) is a protocol for logging into
      and executing commands on remote machines. It provides secure
      encrypted communications. If you plan on accessing your machine
      remotely via SSH over a firewalled interface, enable this option.
      You need the openssh-server package installed for this option
      to be useful.</description>
    <port protocol="tcp" port="22"/>
  </service>

[2] Introduction to FirewallD on CentOS
    ===================================

Differences compared to directly controlling iptables:

  1. FirewallD uses zones and services instead of chain and rules.
  2. FirewallD  manages rulesets dynamically, allowing updates without breaking existing sessions and connections. iptables breaks all active connections during restart. Restart is necessary after making each change.

Default configuration file is in /usr/lib/FirewallD
Active configuration file is in /etc/firewalld

Firewalld uses two configuration sets: Running and Permanent

Enable or disable the HTTP service:

  # firewall-cmd --zone=public --add-service=http --permanent
  # firewall-cmd --zone=public --remove-service=http --permanent

Allow or disable port/protocol.

  # firewall-cmd --zone=public --add-port=12345/tcp --permanent
  # firewall-cmd --zone=public --remove-port=12345/tcp --permanent

Port Forwarding
...............

  # # 80 to 12345
  # firewall-cmd --zone="public" \
                 --add-forward-port=port=80:proto=tcp:toport=12345

To forward a port to a different server:

  # # Activate masquerade in the desired zone.
  # firewall-cmd --zone=public --add-masquerade
  # firewall-cmd --zone="public" \
    --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=123.456.78.9

To remove the rules, substitute --add with --remove. For example:

Rich rules (examples)
.....................

Allow all IPv4 traffic from host 192.168.0.14.

  # firewall-cmd --zone=public --add-rich-rule \
                 'rule family="ipv4" source address=192.168.0.14 accept'

Deny IPv4 traffic over TCP from host 192.168.1.10 to port 22.

  # firewall-cmd --zone=public --add-rich-rule \
    'rule family="ipv4" source address="192.168.1.10" \
     port port=22 protocol=tcp reject'

Allow IPv4 traffic over TCP from host 10.1.0.3 to port 80, and forward it locally to port 6532.

  # firewall-cmd --zone=public --add-rich-rule \
                 'rule family=ipv4 source address=10.1.0.3 \
                  forward-port port=80 protocol=tcp to-port=6532'

Forward all IPv4 traffic on port 80 to port 8080 on host 172.31.4.2 (masquerade should be active on the zone).

  # firewall-cmd --zone=public --add-rich-rule
                 'rule family=ipv4 forward-port port=80 protocol=tcp
                  to-port=8080 to-addr=172.31.4.2'

List rich rules

  # firewall-cmd --list-rich-rules

iptables Direct Interface
.........................

  firewall-cmd --direct --get-all-chains
  firewall-cmd --direct --get-all-rules

See [6].

[3] Panic mode. Masquerade
    ======================

Panic mode - block any incoming or outgoing connections.

Drop any existing established connection on the system
......................................................

  # firewall-cmd --panic-on
  success
  # firewall-cmd --query-panic
  yes
  # ping google.com -c 1
  ping: google.com: Name or service not known

  # firewall-cmd --panic-off
  success
  # firewall-cmd --query-panic
  no
  # ping google.com -c 1
  PING google.com (172.217.22.174) 56(84) bytes of data.
  64 bytes from arn09s11-in-f14.1e100.net (172.217.22.174): \
  icmp_seq=1 ttl=55 time=14.1 ms

Masquerade also known as Network Address Translation (NAT)..

FAQ.
----

1. How To stop the ping

  sudo nano /etc/sysconfig/network-scripts/ifcfg-eth0
  ZONE=drop

2. Apache install on Centos 7

  # yum clean all
  # yum -y update
  # yum -y install httpd
  # firewall-cmd --permanent --add-port=80/tcp
  # firewall-cmd --permanent --add-port=443/tcp
  # firewall-cmd --reload
  # systemctl start httpd
  # systemctl enable httpd

3. Where are my permanent changes from FAQ::2

  # cat /etc/firewalld/zones/public.xml
  <?xml version="1.0" encoding="utf-8"?>
    <zone>
      <short>Public</short>
    <description>For use in public areas. You do not trust the other
                 computers on networks to not harm your computer.
                 Only selected incoming connections are accepted.
    </description>
    <service name="dhcpv6-client"/>
    <service name="ssh"/>
    <port protocol="tcp" port="443"/>
    <port protocol="tcp" port="80"/>
  </zone>

See also

     /etc/firewalld/firewalld.conf.

However, it's recommended that you don't manually modify this file and instead use firewall-cmd/etc/firewalld/firewalld.conf [4].

4. Can I install a GUI for firewalld?

The graphical tool is firewall-config. It is packaged separate in firewall-applet. Thank you Paranoid Panda for pointing that out [5].

  # yum install firewall-applet
  $ sudo firewall-config

FAQ::2 example.

  Configuration: Permanent
  Zone: Public
    Services  dhcp-v6 client
              ssh
    Ports     443 tcp
              80 tcp
    Protocols
    Source port
    Masquerading
    Port Forwarding
    ICMP Filter
    Rich Rules
    Interfaces
    Sources

Experiments
-----------

Experiment 0. Default Zone
..........................

  # firewall-cmd --get-default-zone
  public
  # firewall-cmd --set-default-zone=home
  success
  # reboot
  # firewall-cmd --get-default-zone
  home

Experiment 1. GUI
.................

  $ sudo firewall-config
  Configuration: Permanent
  Zone: Public
    Ports     443 tcp  [v] Delete in GUI
              80 tcp   [v] Delete in GUI

  Result:

  Changes affected after reboot. Entries

      <port protocol="tcp" port="443"/>
      <port protocol="tcp" port="80"/>

  deleted from /etc/firewalld/zones/public.xml

Experiment 2. Does firewallD masquerade switch kernel ip_forward flag?
......................................................................

Short answer -- sometimes.

There are still chance to get ip_forward 0 after some manipulations with
network.service fitewalld.service and firewall-cmd, but without direct order to remove masquerade. So, setting  net.ipv4.ip_forward=1 in /etc/sysctl.d/ip_forward.conf is still necessary.

  # cat /proc/sys/net/ipv4/ip_forward
  0
  # firewall-cmd --zone=public --query-masquerade
  no
  # firewall-cmd --permanent --zone=public --add-masquerade
  success

  # cat /proc/sys/net/ipv4/ip_forward
  0
  # firewall-cmd --zone=public --add-masquerade
  success
  # cat /proc/sys/net/ipv4/ip_forward
  1
  # reboot
  # cat /proc/sys/net/ipv4/ip_forward
  1
  # cat /etc/firewalld/zones/public.xml | tail -n 2
    <masquerade/>
  </zone>

Experiment 3. Gateway on VirtualBox
...................................

  # dmesg | grep "e1000: enp"
  [    6.555193] e1000: enp0s3 NIC Link is Up 1000 Mbps Full Duplex, ..
  [    6.594367] e1000: enp0s8 NIC Link is Up 1000 Mbps Full Duplex, ..

  # cat /etc/sysconfig/network-scripts/ifcfg-enp0s3
  DEVICE=enp0s3
  BOOTPROTO=dhcp
  ONBOOT=yes
  TYPE=Ethernet
  IPV6INIT=no
  USERCTL=no
  NM_CONTROLLED=no

  # cat /etc/sysconfig/network-scripts/ifcfg-enp0s3
  DEVICE=enp0s8
  BOOTPROTO=static
  ONBOOT=yes
  NM_CONTROLLED=no
  IPADDR="172.16.1.1"
  NETMASK="255.255.255.0"
  DNS1="192.168.1.1"

  # cat /etc/sysctl.d/ip_forward.conf
  net.ipv4.ip_forward=1

  # sysctl -p /etc/sysctl.d/ip_forward.conf
  net.ipv4.ip_forward = 1
  # cat /proc/sys/net/ipv4/ip_forward
  1

  # firewall-cmd --change-interface=enp0s3 --zone=external --permanent
  # firewall-cmd --change-interface=enp0s8 --zone=internal --permanent
  # firewall-cmd --zone=external --add-masquerade --permanent
  # firewall-cmd --permanent --direct --passthrough ipv4 -t nat \
               -I POSTROUTING -o enp0s3 -j MASQUERADE \
               -s 172.16.1.1/24

  # yum install dhcp
  # cat /etc/dhcp/dhcpd.conf
  option domain-name "CBOX";
  option domain-name-servers 192.168.1.1;

  default-lease-time 600;
  max-lease-time 7200;

  # this DHCP server to be declared valid
  authoritative;

  subnet 172.16.1.0 netmask 255.255.255.0 {
    range dynamic-bootp 172.16.1.2 172.16.1.50;
    option broadcast-address 172.16.1.255;
    option routers 172.16.1.1;
  }

  # systemctl start dhcpd
  # systemctl enable dhcpd
  Created symlink from \
  /etc/systemd/system/multi-user.target.wants/dhcpd.service to \
  /usr/lib/systemd/system/dhcpd.service.

  # firewall-cmd --set-default-zone=internal
  # firewall-cmd --complete-reload
  # systemctl restart network
  # systemctl restart firewalld

NOTE: ..be aware that dhcpd listens *only* on interfaces for which it finds subnet declaration in dhcpd.conf. It means that explicitly enumerating interfaces also on command line should not be required in most cases. (source: cat /etc/sysconfig/dhcpd).

So here we have this rare case. Almost immediately. So:

  # $ cp /usr/lib/systemd/system/dhcpd.service /etc/systemd/system/
  # vi /etc/systemd/system/dhcpd.service
  ..
  ExecStart=/usr/sbin/dhcpd -f -cf /etc/dhcp/dhcpd.conf \
                            -user dhcpd -group dhcpd \
                            --no-pid enp0s8
                                     ^^^^^^

  # systemctl restart network
  # systemctl restart firewalld

Result: dhclient works, internet access succeeded on Ubuntu machine connected to internal network.

Links:
------

1. FirewallD intro.

   https://www.digitalocean.com/community/tutorials
         /how-to-set-up-a-firewall-using-firewalld-on-centos-7

2. FirewallD uses zones and services instead of chain and rules.

    https://www.linode.com/docs/security/firewalls
          /introduction-to-firewalld-on-centos

3. Fail2Ban and Panic Mode

    http://www.tecmint.com/firewalld-rules-for-centos-7

4. Using FirewallD to Manage Your Firewall on CentOS 7

    https://www.vultr.com/docs
          /using-firewalld-to-manage-your-firewall-on-centos-7

5. Can I install a GUI for firewalld?

    https://askubuntu.com/questions/707828
          /can-i-install-a-gui-for-firewalld

6. Control Network Traffic with iptables

    https://www.linode.com/docs/networking/firewalls
         /control-network-traffic-with-iptables

7. CentOS 7 as NAT Gateway for Private Network

    http://blog.redbranch.net/2015/07/30
         /centos-7-as-nat-gateway-for-private-network/

8. Configuring firewalld to act as a router

    https://www.centos.org/forums/viewtopic.php?t=53819

9. How To: CentOS 7 Router

    https://ronnybull.com/2015/11/20/how-to-centos-7-router/

10. https://www.cyberciti.biz/faq
          /howto-setting-rhel7-centos-7-static-ip-configuration/


