I want to manage UFW firewall rules on a number of remote Ubuntu 18.04 machines using Ansible. If a change to the firewall rules prevents me from re-connecting to the machines via SSH that would be very difficult to fix (go to the data centre in a hurry, type in complicated root passwords one by one, edit firewall config manually). Is there a way to test that a firewall rule change won't prevent me from re-connecting before the change is applied?
Alternatively, is there a way to automatically restore firewall rules if they are applied and I am locked out? (I could make my own back-up and set up a cron job to restore it, then connect again and delete the cron job, but maybe something like this already exists?)
Not built into with the ufw module. And the changes you are making will be enforced at the next reboot or firewall reload.
What you can do is reload the firewall, then test a new connection to the SSH port. If that fails, reset ufw via the persistent connection still open.
I have an implementation of this boringly called ansible-role-ufw. Note in particular the use of
wait_for
, aswait_for_connection
will use the persistent connection and not detect the failure.Beware that this has one shot to work. You still need remote console access for when SSH is broken.
Apply the rules manually, without saving them, but before you do, schedule a reboot or a reset of the current rules after a couple of minutes. So, if the new rule would cause any harm, it'll only be for those couple of minutes.
This is what I ended up with, extending John Mahowald's code:
roles/set_firewall_rules/tasks/main.yml
roles/set_firewall_rules/meta/main.yml
roles/target_ssh_info/tasks/main.yml
Note that
ssh -G
returns the hostname and port even if they are not overridden in .ssh/config, i.e.ssh -G arbitrarystring
just returns "arbitrarystring" as the hostname and 22 as the port.