Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions azurelinuxagent/common/osutil/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,13 @@ def is_atapiix_mod_loaded(self, max_retry=1):
time.sleep(1)
return False

def is_mod_available(self, mod_name):
"""
Checks if the given module is available.
"""
ret = shellutil.run("modinfo {0}".format(mod_name), chk_err=False)
return ret == 0

def mount(self, device, mount_point, option=None, chk_err=True):
if not option:
option = []
Expand Down
12 changes: 12 additions & 0 deletions azurelinuxagent/ga/firewall_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from azurelinuxagent.common import event
from azurelinuxagent.common.event import WALAEventOperation
from azurelinuxagent.common.utils import shellutil
from azurelinuxagent.common.osutil import get_osutil

from azurelinuxagent.common.future import ustr
from azurelinuxagent.common.utils.flexible_version import FlexibleVersion
Expand Down Expand Up @@ -77,6 +78,7 @@ class FirewallManager(object):
def __init__(self, wire_server_address):
self._wire_server_address = wire_server_address
self._verbose = False
self._osutil = get_osutil()

# Friendly names for the firewall rules
ACCEPT_DNS = "ACCEPT DNS"
Expand Down Expand Up @@ -308,6 +310,8 @@ def __init__(self, wire_server_address):
#
# Get the version of iptables and check whether we can use the wait option ("-w"), which was introduced in iptables 1.4.21.
#
if not self._osutil.is_mod_available("xt_owner") or not self._osutil.is_mod_available("xt_conntrack"):
raise FirewallManagerNotAvailableError("iptables is not available")
try:
output = shellutil.run_command(["iptables", "--version"])
#
Expand Down Expand Up @@ -446,6 +450,14 @@ class FirewallCmd(_FirewallManagerIndividualRules):
def __init__(self, wire_server_address):
super(FirewallCmd, self).__init__(wire_server_address)

#
# Check for required kernel modules. FirewallCmd uses iptables passthrough rules that require
# xt_owner (for the ACCEPT rule with -m owner) and xt_conntrack (for the DROP rule with -m conntrack).
# If these modules are not available, the firewall-cmd rules will fail.
#
if not self._osutil.is_mod_available("xt_owner") or not self._osutil.is_mod_available("xt_conntrack"):
raise FirewallManagerNotAvailableError("Required kernel modules (xt_owner, xt_conntrack) are not available for firewall-cmd")

try:
self._version = shellutil.run_command(["firewall-cmd", "--version"]).strip()
except Exception as exception:
Expand Down
12 changes: 10 additions & 2 deletions azurelinuxagent/ga/persist_firewall_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from azurelinuxagent.common import logger
from azurelinuxagent.common import event
from azurelinuxagent.common.event import add_event, WALAEventOperation
from azurelinuxagent.ga.firewall_manager import FirewallCmd, FirewallStateError
from azurelinuxagent.ga.firewall_manager import FirewallCmd, FirewallStateError, FirewallManagerNotAvailableError
from azurelinuxagent.common.future import ustr
from azurelinuxagent.common.osutil import get_osutil, systemd
from azurelinuxagent.common.utils import shellutil, fileutil, textutil
Expand Down Expand Up @@ -132,7 +132,15 @@ def setup(self):
# In case of a failure, this would throw. In such a case, we don't need to try to setup our custom service
# because on system reboot, all iptables rules are reset by firewalld.service, so it would be a no-op.
# setup permanent firewalld rules
firewall_manager = FirewallCmd(self._dst_ip)
try:
firewall_manager = FirewallCmd(self._dst_ip)
except FirewallManagerNotAvailableError as e:
# If required kernel modules (xt_owner, xt_conntrack) are not available, firewall-cmd cannot set up
# the required rules. Fall back to the custom network-setup service which may handle this better.
event.warn(WALAEventOperation.PersistFirewallRules, "Cannot use firewall-cmd for persistent rules: {0}. Falling back to custom network-setup service.", ustr(e))
self._setup_network_setup_service()
return

event.info(WALAEventOperation.Firewall, "Using firewall-cmd [version {0}] to manage the persistent firewall rules", firewall_manager.version)

try:
Expand Down