.. _design: 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 :ref:`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 :ref:`LMI_FirewalldRule`. Collection of rules associated to :ref:`LMI_FirewalldZone` via :ref:`LMI_FirewalldZoneComponent` represent the zone setting. **Service**, represented by :ref:`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 :ref:`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 ------- .. image:: ../admin/pic/firewalld-schema.svg :alt: UML class diagram of firewalld provider :width: 2800 2 Example class instances ========================= This diagram shows sample configuration where SSH and DHCPv6 services are allowed to pass the firewall. .. image:: ../admin/pic/firewalld-usage-1.svg :alt: 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>.