ansible-for-devops icon indicating copy to clipboard operation
ansible-for-devops copied to clipboard

Page 39 - Chapter 3 - Enable firewalld on db

Open meleschi opened this issue 3 years ago • 6 comments

Firstly, thank you for such a well written book written for what seems to be people exactly like me!

When I run the commands to enable and configure firewalld, everything seems to run. But when I log into the vagrant db to validate, I see no firewalld rules or iptables rules...

I'm more of iptables guy than a firewalld guy, so maybe my validation is being done improperly. Can you give me a quick sanity check?

Vagrantfile:

~/AnsibleClass2$ cat Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # General Vagrant VM configuration.
  config.vm.box = "geerlingguy/centos8"
  config.ssh.insert_key = false
  config.vm.synced_folder ".", "/vagrant", disabled: true
  config.vm.provider :virtualbox do |v|
    v.memory = 512
    v.linked_clone = true
  end

  # Application server 1.
  config.vm.define "app1" do |app|
    app.vm.hostname = "orc-app1.test"
    app.vm.network :private_network, ip: "192.168.60.4"
  end

  # Application server 2.
  config.vm.define "app2" do |app|
    app.vm.hostname = "orc-app2.test"
    app.vm.network :private_network, ip: "192.168.60.5"
  end

  # Database server.
  config.vm.define "db" do |db|
    db.vm.hostname = "orc-db.test"
    db.vm.network :private_network, ip: "192.168.60.6"
  end
end

Ansible Commands:

ansible db -b -m yum -a "name=firewalld state=present"
ansible db -b -m service -a "name=firewalld state=started enabled=yes"
ansible db -b -m firewalld -a "zone=database state=present permanent=yes"
ansible db -b -m firewalld -a "source=192.168.60.0/24 zone=database state=enabled permanent=yes"
ansible db -b -m firewalld -a "port=3306/tcp zone=database state=enabled permanent=yes"

DB Validation:

meleschi@vm-ansible-02:~/AnsibleClass2$ ansible db -b -a "iptables -L"
192.168.60.6 | CHANGED | rc=0 >>
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

meleschi@vm-ansible-02:~/AnsibleClass2$ ansible db -b -a "firewall-cmd --list-all"
192.168.60.6 | CHANGED | rc=0 >>
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3 enp0s8
  sources:
  services: cockpit dhcpv6-client ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

meleschi avatar Dec 29 '21 22:12 meleschi

firewalld is a bit different—note that the default zone is not the same as the database one we set up (see https://www.redhat.com/sysadmin/firewalld-rules-and-scenarios)

You should try firewall-cmd --list-all --zone=database to see if that shows the new rule.

geerlingguy avatar Dec 29 '21 22:12 geerlingguy

(edited after reading the man page) I tried the option you recommended, here's what I saw:

meleschi@vm-ansible-02:~/AnsibleClass2$ ansible db -b -a "firewall-cmd --list-all --zone=database"
192.168.60.6 | FAILED | rc=112 >>
Error: INVALID_ZONE: databasenon-zero return code

meleschi@vm-ansible-02:~/AnsibleClass2$ vagrant ssh db
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Wed Dec 29 22:39:04 2021 from 192.168.60.1
[vagrant@orc-db ~]$ sudo su -
Last login: Wed Dec 29 22:14:53 UTC 2021 on pts/0
[root@orc-db ~]# firewall-cmd --list-all --zone=database
Error: INVALID_ZONE: database

Might this be an ansible version bug?

meleschi@vm-ansible-02:~/AnsibleClass2$ ansible --version
ansible [core 2.12.1]
  config file = /home/meleschi/AnsibleClass2/ansible.cfg
  configured module search path = ['/home/meleschi/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/meleschi/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.8.10 (default, Nov 26 2021, 20:14:08) [GCC 9.3.0]
  jinja version = 2.10.1
  libyaml = True

meleschi avatar Dec 29 '21 22:12 meleschi

It looks like the zone was not created despite ansible believing that it was:

meleschi@vm-ansible-02:~/AnsibleClass2$ ansible db -b -m firewalld -a "zone=database state=present permanent=yes"

192.168.60.6 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "msg": "Permanent operation"
}
meleschi@vm-ansible-02:~/AnsibleClass2$ vagrant ssh db
sudo su -Activate the web console with: systemctl enable --now cockpit.socket

Last login: Wed Dec 29 22:39:26 2021 from 10.0.2.2
[vagrant@orc-db ~]$ sudo su -
[root@orc-db ~]# firewall-cmd --list-all-zones
block
  target: %%REJECT%%
  icmp-block-inversion: no
  interfaces:
  sources:
  services:
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

dmz
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

drop
  target: DROP
  icmp-block-inversion: no
  interfaces:
  sources:
  services:
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

external
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: ssh
  ports:
  protocols:
  masquerade: yes
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

home
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: cockpit dhcpv6-client mdns samba-client ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

internal
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: cockpit dhcpv6-client mdns samba-client ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

nm-shared
  target: ACCEPT
  icmp-block-inversion: no
  interfaces:
  sources:
  services: dhcp dns ssh
  ports:
  protocols: icmp ipv6-icmp
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
        rule priority="32767" reject

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3 enp0s8
  sources:
  services: cockpit dhcpv6-client ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

trusted
  target: ACCEPT
  icmp-block-inversion: no
  interfaces:
  sources:
  services:
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

work
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: cockpit dhcpv6-client ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

meleschi avatar Dec 29 '21 22:12 meleschi

I rebooted vm-ansible-02, then restarted the vagrant VMs, and now the database zone shows up... I'm unaware of where the initial problem was, but I'll take the small win and move toward... Thank you for the help @geerlingguy!

[root@orc-db ~]# firewall-cmd --list-all-zones
block
  target: %%REJECT%%
  icmp-block-inversion: no
  interfaces:
  sources:
  services:
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

database (active)
  target: default
  icmp-block-inversion: no
  interfaces:
  sources: 192.168.60.0/24
  services:
  ports: 3306/tcp
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
...

meleschi avatar Dec 30 '21 14:12 meleschi

Very strange! I guess something must've gotten stored but not committed/restarted in there :/

geerlingguy avatar Dec 30 '21 15:12 geerlingguy

While reading these docs (https://docs.ansible.com/ansible/latest/collections/ansible/posix/firewalld_module.html) this stood out:

Zone transactions (creating, deleting) can be performed by using only the zone and state parameters “present” or “absent”. Note that zone transactions must explicitly be permanent. This is a limitation in firewalld. This also means that you will have to reload firewalld after adding a zone that you wish to perform immediate actions on. The module will not take care of this for you implicitly because that would undo any previously performed immediate actions which were not permanent. Therefore, if you require immediate access to a newly created zone it is recommended you reload firewalld immediately after the zone creation returns with a changed state and before you perform any other immediate, non-permanent actions on that zone.

I'm reading this as after creating a permanent zone, firewalld must be reloaded for the zone to be useable. I ended up doing a firewalld restart at the end of the firewalld setup to get the database zone active and functioning without having to reboot the vm.

ansible db -b -m yum -a "name=firewalld state=present"
ansible db -b -m service -a "name=firewalld state=started enabled=yes"
ansible db -b -m firewalld -a "zone=database state=present permanent=yes"
ansible db -b -m firewalld -a "source=192.168.60.0/24 zone=database state=enabled permanent=yes"
ansible db -b -m firewalld -a "port=3306/tcp zone=database state=enabled permanent=yes"
ansible db -b -m firewalld -a "zone=database state=present permanent=yes"
ansible db -b -m service -a "name=firewalld state=restarted"
ansible db -b -a "firewall-cmd --get-active-zones"

meleschi avatar Jan 01 '22 18:01 meleschi