1 Model

Model is loosely based on the firewalld API, but altered to provide similar look-and-feel as other OpenLMI models.

1.1 Concepts

Basic concept are shared between the firewalld service and OpenLMI firewalld provider. See firewalld(1) manual page for detailed information about them.

Zone, represented by LMI_FirewalldZone, defines the trust level of the interface used for a connection. There are several pre-defined zones provided by firewalld.

Rule is represented by subclasses of LMI_FirewalldRule. Collection of rules associated to LMI_FirewalldZone via LMI_FirewalldZoneComponent represent the zone setting.

Service, represented by LMI_FirewalldService, can be a list of local ports and destinations and additionally also a list of firewall helper modules automatically loaded if a service is enabled. The use of predefined services makes it easier for the user to enable and disable access to a service.

ICMP Types, represented by LMIFirewalldICMPType. The Internet Control Message Protocol (ICMP) is used to exchange information and also error messages in the Internet Protocol (IP). ICMP types can be used in firewalld to limit the exchange of these messages.

Runtime configuration is the actual active configuration and is not permanent. After reload/restart of the firewalld service or a system reboot, runtime settings will be gone if they haven’t been also in permanent configuration.

Permanent configuration is stored in config files and will be loaded and become new runtime configuration with every machine boot or service reload/restart.

Direct interface is mainly used by services or applications to add specific firewall rules. The rules are not permanent and need to get applied after receiving the start, restart or reload message from firewalld.

1.2 UML

UML class diagram of firewalld provider

2 Example class instances

This diagram shows sample configuration where SSH and DHCPv6 services are allowed to pass the firewall.

Example of firewalld provider class instances

3 Use cases

All the use cases are described using a pseudo language very similar to what the actual LMIShell looks like.

3.1 Basic firewall information

3.1.1 List firewalld zones

ns.LMI_FirewalldZone.instances()

3.1.2 Get default zone

ns.LMI_HostedFirewalldZone.first_instance({'IsDefault': True}).SettingData

3.1.3 Set default zone

zone = ns.LMI_FirewalldZone.first_instance({'Name': 'Zone X'})
service = ns.LMI_FirewalldConfigurationService.first_instance()
service.SetDefaultZone(zone)

3.1.4 List defined services

ns.LMI_FirewalldService.instances()

3.1.5 List port or port ranges assigned to service

service = ns.LMI_FirewalldService.first_instance({'Name': 'Service X'})
for port in service.associators(AssocClass='LMI_FirewalldRuleComponent', ResultClass='LMI_FirewalldPort'):
    protocol = ns.LMI_FirewalldPort.ProtocolValues.ValueName(port.Protocol)
    if port.PortRangeEnd is not None:
        print "Port range: %d-%d/%s" % (port.Port, port.PortRangeEnd, protocol)
    else:
        print "Port: %d/%s" % (port.Port, protocol)

3.1.6 Get target for zone

zone = ns.LMI_FirewalldZone.first_instance({'Name': 'Zone X'})
print ns.LMI_FirewalldZone.TargetValues.ValueName(zone.Target) # One of: default, accept, drop, reject

3.2 Current zone manipulation

3.2.1 Opening port

zone = ns.LMI_FirewalldZone.first_instance({'Name': 'Zone X'})
result = zone.AddPort(Port=5989, Protocol=zone.AddPort.Protocol.TCP, Mode=zone.AddPort.Mode.Both)

3.2.2 Closing port

zone = ns.LMI_FirewalldZone.first_instance({'Name': 'Zone X'})
for component in zone.references(ResultClass='LMI_FirewalldZoneComponent')
    # component.IsPermanent and component.IsCurrent can be used to close
    # port immediately or permanently
    if component.Rule.Port == 5989:
        component.delete()

3.2.3 Opening a range of ports

zone = ns.LMI_FirewalldZone.first_instance({'Name': 'Zone X'})
result, rule, err = zone.AddPort(Port=5989, Protocol=zone.AddPort.Protocol.TCP, Mode=zone.AddPort.Mode.Both)
rule.PortRangeEnd = 5989
rule.push()

3.2.4 Forward port

zone = ns.LMI_FirewalldZone.first_instance({'Name': 'Zone X'})
result, rule, err = zone.AddForwardPort(Port=1234, Protocol=zone.AddForwardPort.Protocol.TCP, Mode=zone.AddPort.Mode.Both)
rule.ToPort = 1235
rule.ToAddress = '1.2.3.4'
rule.push()

3.3 Zone manipulation

3.3.1 Create new zone

service = ns.LMI_FirewalldConfigurationService.first_instance()
result, zone, err = service.CreateZone('Zone X')

3.3.2 Delete zone

zone = ns.LMI_FirewalldZone.first_instance({'Name': 'Zone X'})
zone.delete()

3.3.3 Assign zone to the network device

zone = ns.LMI_FirewalldZone.first_instance({'Name': 'Zone X'})
device = ns.LMI_IPNetworkConnection({'ElementName', 'eth0'})
service = ns.LMI_FirewalldConfigurationService.first_instance()
service.ApplySettingToIPNetworkConnection(device, zone)

4 Additional use cases

If there are any, they will be documented here.

5 Design

Important questions and design decisions will be recorded here, together with a timestamp and version of this document, in which they were made.

Q
Question
A
Answer
D
Decision

5.1 D: Firewalld provider should follow firewalld API closely v1

This decision has been approved on openlmi-devel mailing list <2014-01-30>.