Page 39 - Chapter 3 - Enable firewalld on db
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:
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.
(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
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:
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:
...
Very strange! I guess something must've gotten stored but not committed/restarted in there :/
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"