Manage host firewall with Azure IoT and OSConfig

Important

Version 1.0.3 (published 28 June 2022) includes breaking changes to member names which may impact existing users. For more information, see: Member names transition from PascalCase to camelCase in version 1.0.3

Audience

This article is designed to support people who provision or manage devices with Azure IoT. If that doesn't sound like you, consider taking a look at Audiences for OSConfig documentation.

Firewall overview

When devices have OSConfig installed, you can use Azure IoT services to perform several basic firewall administration tasks. For example:

  • Check whether firewall is active
  • Ensure that certain rules exist (create if not present)
  • Ensure that certain rules do not exist (delete if found)
  • Compare the rules of many deployed devices to a known-good device
  • Set default traffic policies for inbound and outbound traffic

Firewall icon

Tip

If you are here for the object model reference, you can skip over the Use cases examples to the Reference information

Use cases examples

These examples can serve as starting points for you to adapt for your unique environment.

Each example includes steps and screen captures for working in the Azure portal, and for working in bash with Azure CLI.

Each example also includes variations for one device (e.g., a troubleshooting scenario), or for many devices (e.g., a configuration provisioning or reporting scenario).

What to expect:

In the single device instructions, you will read and write reported and desired properties directly in the OSConfig twin for a device. In the at-scale instructions, you will use IoT Hub Configurations (also known as Automatic Device Management or ADM) to push desired properties to many twins, and use IoT Hub Queries (independently, or attached to Configurations as Metrics) to observe the results coming back from devices.

Prerequisites to try the examples on live systems

If you are using this article for reference there are no pre-requisites. You can review the examples, copy property names, etc.

If you want to try the examples on live systems (recommended), follow these steps:

  1. Create a free Azure account or use an existing account

  2. Connect at least one OSConfig-enabled device to an IoT Hub

    Tip

    To easily create an IoT Hub with (virtual) devices attached, see Create an OSConfig (with Azure IoT) lab environment in 5 minutes

  3. Get ready to follow either the Azure portal instruction or the Azure CLI instructions in the examples:

If you prefer to use the Azure portal

  1. Sign in to your Azure portal and access your IoT Hub's Overview page Screenshot showing IoT Hub and devices from the Azure Portal

-OR- If you prefer to use Azure CLI

  1. RECOMMENDED: Use Azure Cloud Shell as your bash environment by signing in to your Azure Portal, then launching Azure Cloud Shell in bash mode Screen capture opening Cloud Shell from Azure Portal
  2. ALTERNATIVE: If you prefer to use your own bash environment rather than Cloud Shell, install the Azure CLI and sign-in
  3. Ensure the Azure IoT extension is ready by running az extension add --name azure-iot

Example A. Is the host firewall active?

The state property under properties.reported.Firewall gives a high level indication of whether the host firewall is active. For example it indicates if the host firewall engine is enabled and at least one rule exists in the FILTER table. For more information about state including possible values, see: Reference information.

  1. From your IoT Hub's portal page, choose Devices in the left hand navigation. If the device has IoT Edge installed in addition to OSConfig, choose IoT Edge instead of Devices.

  2. Click on a device where OSConfig is installed.

  3. Under Module Identities click osconfig.

  4. Click on Module Identity Twin and browse the JSON to properties.reported.Firewall.state. In the following screen capture example, you can see that state: enabled.

    Screen capture that shows how to check firewall state for a specific device using Portal

Example B. Create a firewall rule

This example uses the desiredRules function of the Firewall module. We create a new rule allowing outbound tcp port 443 traffic from the device to subnet 10.9.9.0/24.

For more information about desiredRules (including handling of multiple rules and rule removal) see Firewall desiredRules reference later in this article.

  1. Using Azure Portal, in the osconfig module twin of the device, under properties.desired add or modify a Firewall and desiredRules nodes as follows. Per JSON standards, you may need to add a comma at the end to integrate with other desired properties if present.

    "Firewall": {
       "desiredRules": [
          {
             "desiredState": "present",
             "action": "accept",
             "direction": "out",
             "protocol": "tcp",
             "destinationAddress": "10.9.9.0/24",
             "destinationPort": 443
          }
       ]
    }
    

    Screen capture that shows how to configure a firewall rule for a single device using portal

  2. After approximately 30 seconds, you can verify the change is made successfully from the module twin itself. Refresh the module twin view, then scroll to find properties, then reported, then Firewall then configurationStatus, state and the desiredRules.

    Screen capture that shows how to read the reported properties for firewall configuration for a single device using portal

Example C. Compare firewall state fingerprint of many devices to a known-good device

The fingerprint property enables quick comparisons for checking compliance at scale. You don't need to retrieve all the rules from all the devices and then implement a many-to-many comparison strategy. You can simply check that the fingerprint is the same across devices which are expected to match each other. For example, you can compare between deployed devices and a known-good reference device.

In the single-device examples we will simply retrieve the value, implying that you are performing a comparison out of band. In the at-scale examples, we will use IoT Hub Query's GROUP BY operator to show commonality or divergence across a fleet.

Not applicable, see Azure Portal, at-scale.

Reference information

Object model description

This section describes the twin properties and corresponding behaviors.

Tip

OSConfig reference documentation applies to tools with or without Digital Twin Definition Language (DTDL) enhanced perspectives of the data model. For more information, see: About plain desired/reported views and DTDL enhanced views.

Firewall reported/read-only properties (for reporting and auditing scenarios)
  • Path: properties.reported.Firewall (Firewall component, read-only properties)

  • Description: The state of the host firewall as detected by the Firewall module of OSConfig

  • Members

    Name Type Notes
    configurationStatus enum of strings Represents the failure/success state of reaching desired configuration. Only meaningful if desired configuration properties such as desiredRules or desiredDefaultPolicies have been set. Possible value as of this writing are success, failure, and unknown.
    configurationStatusDetail string Text returned by underlying APIs or tools such as iptables. Meant to provide the first level of insight into bad input parameters, etc. without resorting to combing through diagnostic logs.
    defaultPolicies array of objects (see example payload) Represents the firewall's default handing of packets which don't meet any specific rule. In the the context of iptables this maps to the chain policies for the input and output chains of the filter table. In other firewall engines this would map to firewall engine behavior as needed. For example some firewall engines don't have an explicit policy notion, and inherently drop traffic which doesn't meet any rule.
    fingerprint string • Opaque fingerprint for the list of all firewall rules on the device
    • Used for comparing large numbers of devices to a known-good device
    NOTE: In versions of OSConfig prior to the October 2022 release, this property was known as "firewallFingerprint"
    state enum of strings High level state of the host firewall. Possible values are:
    unknown
    enabled
    disabled
    The logic for enabled is that an active firewall engine was detected and with at least one rule in the FILTER table.
    NOTE: In versions of OSConfig prior to the October 2022 release, this information was presented as "firewallState" (rather than "state") and the values were integers (rather than strings).
  • Example payload (as seen in twin's properties.reported section)

    "Firewall": {
        "configurationStatus": "success",
        "configurationStatusDetail": "",
        "defaultPolicies": [
           {
              "direction": "in",
              "action": "accept"
           },
           {
              "direction": "out",
              "action": "accept"
           }
        ],
        "fingerprint": "c30d8b8bf5327a8a325a686e0c4bbf73b1bd33a72779af88827e8ea256caddb2",
        "state": "enabled"
    }
    
Firewall desiredRules

Caution

As with any firewall administration, take great care when blocking traffic. You have the power to block the device from continuing its connection with IoT Hub or other administrative channels. In such cases local access to the device may be needed to recover.

  • Path: properties.desired.Firewall.desiredRules (Firewall component, desiredRules writable property)

  • Description: An ordered list of rule descriptors. Each rule descriptor in the list can have the following members.

  • Members of each rule descriptor

    Name Type Notes
    desiredState enum of strings Always required. Possible values are present (means that such a rule should be created if a matching rule does not already exist), or absent (means that any existing rule on the device matching this descriptor should be deleted if found. For rule descriptors where desiredState: "present" and where no matching rule already exists on the device, the new rule is added at the top of the list of rules on the device. For context, you can think of this as being analogous to iptables -I as opposed to iptables -A. If multiple desiredState: "present" rule descriptors are present in desiredRules, they are added such that the order is preserved. In other words to top rule in desiredRules will be at the top of the rules list on the device, the next rule in desiredRules will follow that in the list of rules on the device, and so on.
    action enum of strings Always required. Possible values are accept, drop, or reject.
    direction enum of strings Always required. Possible values are in or out.
    protocol enum of strings Always required. Possible values are any, udp, tcp, or icmp. Note that any means any traffic (as opposed to meaning "both tcp and udp, but not other IP protocols). Accordingly, rules where protocol: "any" must not include sourcePort or destinationPort.
    sourceAddress string IP address or CIDR range. If not specified, the resulting rule would match any address
    sourcePort integer Relevant for rules where protocol: tcp or protocol:udp. Must not be included in other rules. Specifies the port number when included in a relevant rule. When not included, indicates a rule that should match any port number.
    destinationAddress string IP address or CIDR range. If not specified, the resulting rule would match any address
    destinationPort integer Relevant for rules where protocol: tcp or protocol:udp. Must not be included in other rules. Specifies the port number when included in a relevant rule. When not included, indicates a rule that should match any port number.

Example payload (as seen in twin's properties.desired section)

The following rules represent the following administrator intentions:

  1. "My on-prem admin subnet is 10.9.9.0/24, so I want devices to allow incoming port 22 (SSH) from there"

  2. "My old admin subnet was 10.24.24.0/24, so if any device still has a rule allowing port 22 (SSH) from there, I want such a rule removed"

  3. NOTE: The administrator might want a third rule here to block SSH from everywhere (with the above exception), but in this example we will use a default drop policy, making such a rule redundant. See the desiredDefaultPolicies example later in this document.

    "Firewall": {
       "desiredRules": [
          {
             "desiredState": "present",
             "action": "accept",
             "direction": "in",
             "protocol": "tcp",
             "sourceAddress": "10.9.9.0/24",
             "destinationPort": 22
          },
          {
             "desiredState": "absent",
             "action": "accept",
             "direction": "in",
             "protocol": "tcp",
             "sourceAddress": "10.24.24.0/24",
             "destinationPort": 22
          }
       ]
    }
    

Note that when an administrative workflow sets properties.desired.Firewall.desiredRules (Firewall component, desiredRules writable property from DTDL perspective), the device acknowledges receipt of the same by adding a desiredRules property to properties.reported.Firewall. The value of that property includes a copy of the original desiredRules payload, along with a version number and status code. IoT Hub based administrative workflows can use this to determine whether the desired state has yet reached the device. This is only an acknowledgement. To determine if the device has succeeded in reaching the desired state, also see configurationStatus and configurationStatusDetail.

Firewall desiredDefaultPolicies

Caution

As with any firewall administration, take great care when blocking traffic. You have the power to block the device from continuing its connection with IoT Hub or other administrative channels. In such cases local access to the device may be needed to recover.

Default policies require especially careful application. On iptables based systems, for example, the policies apply to each packet individually without considering existing connections. In other words, an inbound default policy of drop will (in addition to blocking new inbound connections) block responses from remote systems. This can make it impossible for the device to communicate outbound using protocols (such as TCP) which require bi-directional packet flow. Do not set action to drop on the in or out policies without first ensuring that specific rules exist to enable all required packets in both directions.

  • Path: properties.desired.Firewall.desiredDefaultPolicies (Firewall component, desiredDefaultPolicies writable property)

  • Description: An array with two items, describing the desired default behavior (accept or drop) for inbound traffic and for outbound traffic.

  • Members of each item

    Name Type Notes
    direction enum of strings Possible values are in or out
    action enum of strings Always required. Possible values are accept or drop.

Example payload (as seen in twin's properties.desired section)

"Firewall": {
   "desiredDefaultPolicies": [
      {"direction": "in", "action": "drop"},
      {"direction": "out", "action": "accept"}
   ]
}

Note that when an administrative workflows sets properties.desired.Firewall.desiredDefaultPolicies (Firewall component, desiredDefaultPolicies writable property from DTDL perspective), the device acknowledges receipt of the same by adding a desiredDefaultPolicies property to properties.reported.Firewall. The value of that property includes a copy of the original payload, along with a version number and status code. IoT Hub based administrative workflows can use this to determine whether the desired state has yet reached the device. This is only an acknowledgement of receipt and processing. For more information on success or failure of reaching desired state, see configurationStatus and configurationStatusDetail.

Additional information and FAQs

What about a "replace everything" use case?

In certain cases administrators might want to impose absolute control over device's net list of firewall rules. Imagine an intention such as, "Only rules X, Y, and Z should exist; Any other rules (pre-existing on the device or created over time by other processes) should be periodically removed." At this time the OSConfig Firewall module does not directly provide for this use case. Removal of specific rules can be accomplished through desiredRules and "desiredState": "absent", but there is no explicit replace-all functionality. If you would like to add such a feature, see the extensibility documentation at https://github.com/Azure/azure-osconfig.

Next steps

For an overview of OSConfig scenarios and capabilities, see:

For specific practical examples, see: