Design a Simple Firewall Microservice on Linux

Overview

This tutorial will illustrate how to compose a new Microservice on a Linux system that will provide a simple firewall function for IP and port based network filtering.

getting the sources

Prerequisite

A managed Linux system defined in OpenMSA.

Building the Microservice

To do firewall management on Linux, will we use iptables.

Use Case Overview

End-customer or Managed Security Service Provider (MSSP) needs to the ability to:

  • Use a simple, multi-vendor, automated tool
  • Implement basic network security policies

High-Level Requirements

  • The operator should have the option to protect IT resources (e.g. public or corporate servers, like ticketing systems, web servers, etc.) with a firewall
  • The firewalls should not be limited to a single vendor
  • The operator should benefit from a single management panel for all operations, from policy provisioning to monitoring and reporting
  • Configuring the firewall should be as simple as possible

Specifications for a Simple Firewall

  • The user (operator or end-customer) must be able to specify an IP address and a service (network port number) on the OpenMSA console
  • The user must be able to select a group of firewalls to configure
  • The OpenMSA will use two parameters: IP and port to automatically configure the firewalls selected by the user

Firewall Implementation on Linux

  • Based on Linux iptables
  • Consumes IP and a port as parameters

Below are few examples of using iptable to perform IP/port based filtering

Create a rule
sudo iptables -A INPUT -p tcp --dport <PORT TO BLOCK> -s <IP TO BLOCK> -j DROP
sudo iptables -A FORWARD -p tcp --dport <PORT TO BLOCK> -s <IP TO BLOCK> -j DROP
Get the list of rules
iptables -L INPUT -n | grep -v Chain | grep -v target

Returns

DROP       tcp  --  92.103.182.20        0.0.0.0/0           tcp dpt:
DROP       tcp  --  92.103.182.20        0.0.0.0/0           tcp dpt:80

Implementation steps

The following procedures are generic steps in designing and developing microservices. I can be applied for other vendors and services.

Step 1: Create a new Microservice in the repository

Step 2: Implement the CREATE command

Step 3: Implement the DELETE command

Step 4: Implement the IMPORT command

Step 5: Test and check the Linux vFW via the Command Line Interface

Step 1:Create a new Microservice in the repository

* To learn more about the Microservice repository, visit the Repository Management guide.

Go to Microservice > MSA > LINUX > Generic >Tutorial directory tree and create a new Microservice file named "simple_firewall.xml"

Image

Provide information related to the new Microservice (e.g., display name, description, Microservice category, etc.) . These can me modified at anytime during during the design phase.

Image

Save and close the Microservice editor and attach the Microservice to the managed device used for this use case.

To edit the Microservice, use the microservice console by choosing the "Config" tab for the target Linux device. Right click on the Microservice newly created from the list located on the left side pane and choose "Edit definition"

Image

Step 2: Implement the CREATE command

The creation of a filtering rule with iptable can be implemented utilizing the following CLI command:

sudo iptables -A INPUT -p tcp --dport <PORT TO BLOCK> -s <IP TO BLOCK> -j DROP
sudo iptables -A FORWARD -p tcp --dport <PORT TO BLOCK> -s <IP TO BLOCK> -j DROP

These commands will take two parameters, the port and the IP address.

Add a CREATE function to your Microservice and copy the implementation below:

sudo iptables -A INPUT -p tcp --dport {$params.dst_port} -s {$params.src_ip} -j DROP
sudo iptables -A FORWARD -p tcp --dport {$params.dst_port} -s {$params.src_ip} -j DROP
Image

On the vertical tabs, select "VARIABLES" and verify that the two new variables were created. The Microservice engine detects the pattern {$params.XXX} and automatically creates the variable XXX.

You can also define the display name of the variable and type:

Image

Selecting a type will enforce some UI control over the value entered by an end-user.

Last step, add the mandatory variable object_id and set the type to "Auto Increment".

Image

You can also reorder the variables using the up/down arrows or by dragging them up or down.

Since the type of the object_id is Auto Increment, we can set it to be a mandatory, read-only variable:

Image

At this stage, the Microservice is ready for its first test. Ensure you have SSH access to Linux firewall to test the Microservice.

Save and Close, select the Microservice on the device "config" tab and click on the Icon to open the Microservice creation dialog.

Image

Enter an IP and a port number, save and click on "Apply configuration".

During the design and test phase, it is recommended to:

  • have an access to the OpenMSA Linux console
  • enable the debug mode on the configuration engine (CLI command: tstsms SETLOGLEVEL 255 255) 
  • have a tail on the configuration engine logs: tail -F /opt/sms/logs/smsd.log

Check that the iptable rule has been configured by entering the CLI command 

iptables -L INPUT -n

on the SSH terminal of the Linux firewall.

[root@LINUX-FW ~]# iptables -L INPUT -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       tcp  --  192.168.1.2          0.0.0.0/0           tcp dpt:80 
[root@LINUX-FW ~]# 

Step 3: Implement the DELETE command

The deletion of the iptables INPUT and FORWARD rules is executed with the CLI command below:

sudo iptables -D INPUT -p tcp --dport <PORT TO BLOCK>  -s <IP TO BLOCK>  -j DROP 
sudo iptables -D FORWARD -p tcp --dport <PORT TO BLOCK>  -s <IP TO BLOCK>  -j DROP 

This will be written as 

sudo iptables -D INPUT -p tcp --dport {$simple_firewall.$object_id.dst_port} -s {$simple_firewall.$object_id.src_ip} -j DROP
sudo iptables -D FORWARD -p tcp --dport {$simple_firewall.$object_id.dst_port} -s {$simple_firewall.$object_id.src_ip} -j DROP
Image

Note

The syntax {$simple_firewall.$object_id.dst_port} provides a way to access the Microservice variable values in the OpenMSA configuration database. 

The convention is as follow:

{$<MICROSERVICE NAME>.$object_id.<VARIABLE NAME>}

In our case:

MICROSERVICE NAME => simple_firewall 
VARIABLE NAME => dst_port

MICROSERVICE NAME is the name of the Microservice file without the .xml extension.

ex: simple_firewall.xml => simple_firewall

Step 4: Implement the IMPORT command

The role of the IMPORT command is to import the current device configuration into the OpenMSA database.

The implementation of the IMPORT is based on a set of regular expressions that build a parser that will extract the values of the Microservice variables.

The IMPORT is made of three parts:

  1. The command to run on the device (for CLI command based device)
  2. The configuration parser, implemented with a set of regular expressions. Only the Microservice identifier extractor is mandatory
  3. A set of port import operation implemented in Smarty language (https://www.smarty.net/)
Image
Command to run on the device

To list the iptables rules the CLI command to use is 

[root@LINUX-FW ~]# iptables -L INPUT -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       tcp  --  192.168.1.2          0.0.0.0/0           tcp dpt:80 
DROP       tcp  --  192.168.1.4          0.0.0.0/0           tcp dpt:443  

We can add a grep CLI command to remove the line that starts with "Chain" and the "target"

[root@LINUX-FW ~]# iptables --line-numbers -L INPUT -n | grep -v Chain | grep -v num
1    DROP       tcp  --  192.168.1.2          0.0.0.0/0           tcp dpt:80 
2    DROP       tcp  --  192.168.1.4          0.0.0.0/0           tcp dpt:443 

Identifier extractor

The identifier extractor will parse each line and assign the rule ID to the Microservice variable object_id.
Since the rule contains the other variables on the same line, the identifier extractor will also extract the source IP and the destination port.

The regular expression below will extract the object_id, the src_ip and the dst_port

@(?<object_id>\d+)    DROP       tcp  --  (?<src_ip>([0-9]{1,3}\.){3}[0-9]{1,3})[^:]+:(?<dst_port>\d+)@

To test this, copy the rules to parse in the EXAMPLE section.

Image

Then use the button "Test Parser" in the IMPORTsection.

Image

Step 5: Test and check the Linux vFW via the Command Line Interface

The Microservice is ready to be tested. 

Ensure that you can add and delete a policy rule and treflected on the Linux firewall. Verify the parameters are also properly synchronized after the call-out to CREATE or DELETE.

You can also add other iptable rules manually on the Linux CLI and run the configuration synchronization to confirm the manual changes were properly imported.