Veeam Hardened Repo: Firewalld security zones

Userlevel 2
Badge +1

Disclaimer: This is only provided as a reference. Make sure you understand what you are doing before executing this in your own setup (eg test in a lab). Since this is modifying the firewall, you might lock yourself out remotely if you are executing the steps incorrectly or you have a slightly different setup

If you are running RHEL or any experimental derivative (in my case Rocky 8.8), you can use firewalld to configure the firewall. Firewalld uses zones in which you can allow ports or services based on the incoming interface or IP sources. By default, all the traffic is “allowed” based on the rules in the public zone (or better the interfaces are by default assigned to the public zone). You can test this with

# What is the default zone
firewall-cmd --get-default-zone

# What are the active zones, by default only the public zone
firewall-cmd --get-active-zones

# List all the rules in the public zone, this is by default ssh cockpit and dhcpv6
firewall-cmd --zone=public --list-all

You can however create a separate zone for Veeam and tell Veeam to respect this . 

So how do you start? Well first you can create a “veeamonly” zone and all the IPs of your Veeam components like VBR and your proxies. 

# create a zone
firewall-cmd --permanent --new-zone=veeamonly

# add vbr, proxies, etc (or all other veeam components that need access)
# eg in this example, ip, and are added
# alternatively, you can do it on a subnet basis
firewall-cmd --permanent --zone=veeamonly --add-source=
firewall-cmd --permanent --zone=veeamonly --add-source=
firewall-cmd --permanent --zone=veeamonly --add-source=

# normally not necessary as the data mover should open port 6160 / 6162
# You can add them manually if you want to survive your firewall reload later
# firewall-cmd --permanent --zone=veeamonly --add-port=6160/tcp --permanent
# firewall-cmd --permanent --zone=veeamonly --add-port=6162/tcp --permanent

Ok now we have made the zone but we have not activated it yet. The way to activate it is by reloading the rules from disk

# reload
firewall-cmd --reload

# verify that both public and veeamonly are active
firewall-cmd --zone=public --list-all
firewall-cmd --zone=veeamonly --list-all

If the new zone is active, we now need to tell veeam that it should add the dynamic rules to this new  “veeamonly” zone. Now the documentation says you need to add it to /etc/VeeamNetConfig but for me it only picked it up on /opt/veeam/transport/VeeamTransportConfig . I have opened a case with our technical writer team to validate that this is because I’m using an existing repository but in any case, you can add to both files just to be sure. Make sure to append, not to overwrite!

echo "FirewalldZones=veeamonly" >> /etc/VeeamNetConfig
echo "FirewalldZones=veeamonly" >> /opt/veeam/transport/VeeamTransportConfig

Now you want to restart the veeam transport and veeam deployment service to readd the dynamic rules. Port 6160 and 6162 will be added to both zones

systemctl restart veeamtransport
systemctl restart veeamdeployment

# verify if 6160 and 6162 are open in both public and veeamonly zone
firewall-cmd --zone=veeamonly --list-all
firewall-cmd --zone=public --list-all

# alternativally, add 6160 and 6162 as described above permanently.
# this will ensure the ports are added when your restart firewalld

What is the result of our action now? Well the data mover ports 2500+ are only added to the “veeamonly” zone during backup. That means that only the Veeam components can talk to them. Yet another layer of security added.

You can also see the effect in the environment service log (the service responsible for opening the dynamic ports):

grep -B12 FirewalldZones /var/log/VeeamBackup/VeeamEnvironmentSvc.log

The result is something like [FirewalldZones]: [veeamonly]

Further down the log you can see only “veeamonly” should be used when a port is opened


Finally, you might want to consider to blocking cockpit and dhcpv6 if you are not using one or both

firewall-cmd --zone=public --remove-service=cockpit --permanent
firewall-cmd --zone=public --remove-service=dhcpv6 --permanent

firewall-cmd --reload
# if you didnt add 6162 and 6160 permanently
# you might need to restart the deployment and transport service

You can also disable SSH. Be very careful as this might impact your current connection

# if you are doing it separately, make sure to also reload
firewall-cmd --zone=public --remove-service=ssh --permanent
firewall-cmd --reload

# to readd
# firewall-cmd --zone=public --add-service=ssh --permanent

Alternatively, you can block SSH in the public zone add SSH as a service to the veeamonly segment. This will only allow SSH from VBR and other Veeam components

firewall-cmd --permanent --zone=veeamonly --add-service=ssh
firewall-cmd --reload

You could probably split up VBR in its own zone so that only this one and only server that can talk to SSH. I haven’t tested it as it probably also requires to change VeeamNetConfig to have both zones. Also, firewalling SSH will not be sufficient. Most of the times I recommend customers to just disable SSH or harden SSH like there is no tomorrow if you absolutely need it.


Userlevel 7
Badge +21

Thanks for providing this Tim.  Always nice to learn more about firewalls in Linux.  😁

Userlevel 7
Badge +17

Fine, I will try this to harden the repo even more… 👍🏼