iptables Management with a Microservicer

This tutorial explains how to design a new Microservice that provides simple firewall functionalities such as IP and port-based network filtering.

Getting the sources

Prerequisite

You need a managed Linux device on your MSActivator. Check the guide Simple Managed Security Service with a Linux Firewall to learn how to activate a Linux device on the MSActivator.

Make sure that your Linux instance allows SSH connection as root and that the iptables service is started.

Build the Microservice

To perform firewall management on Linux we are going to use iptables.

Use Case Overview

The end customer or MSSP (Managed Security Service Provider) needs to be able 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 MSActivator will use the two parameters: IP and port, to automatically configure the firewalls selected by the user.

Firewall Implementation on Linux

  • Based on Linux iptables
  • Takes an IP and a port as parameters

Below are some example of iptable used 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

These are the steps to follow to build the Microservice. These steps are usually the generic steps to design and develop Microservices with 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

You can learn how to use the repository with this guide: Repository Management.

Create a new Microservice simple_firewall.xml for the device type Linux/Generic

Image

Provide some information related to this new Microservice such as a display name, a category, etc. These can be modified at any later time during the design phase.

Image

Save and close the Microservice editor and attach the Microservice to the device that will be used for the design and test work.

To edit the Microservice you can use the Microservice console on the device "config" tab, right click on the Microservice from the list on the left and choose "Edit definition"

Image

Step 2: Implement the CREATE command

The creation of a filtering rule using iptable can be implemented with the CLI command below:

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 take 2 parameters, a port and an 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 check that 2 new variables were created. The Microservice engine detects the pattern {$params.XXX} and automatically creates the variable XXX.

You can adjust the display name of the variable as well as the type:

Image

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

For the last step, add the mandatory variable object_id and set its type to "Auto Increment"

Image

You can reorder the variable by 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 point the Microservice is ready for a first test. Make sure that you have an SSH access to you device to test. 

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

Image

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

During the design and test phase, it's recommended to:

  • have access to the MSActivator 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 MSActivator 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 MSActivator 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 3 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 operations 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 some "grep" commands to remove the lines that starts with "Chain" and "target".

Note

The use of grep here is a straightforward way, specific to this use case, to have a simple and easy to parse output. The same result could also be achieved by adding a parser instruction to ignore the first 2 lines starting with "Chain" and "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 it you can copy the rules to parse in the section EXAMPLE.

Image

Then use the button "Test Parser" in the section IMPORT.

Image

Step 5: Test and check the Linux vFW via the command line interface

The Microservice is ready to be tested. 

Make sure that you can add and delete a policy rule, that it's reflected on the Linux firewall, and that the parameters are also properly synchronised after a call to CREATE or DELETE.

You can also add some iptables rules manually on the Linux CLI and run a configuration synchronisation to make sure that your manual changes are properly imported.