Automating Cloud Passage firewall management

Halo, by Cloud Passage, is a great tool to ensure compliance across a hybrid infrastructure.
When it comes to security, some organizations have made incredible strides to streamline and
automate. But for those organizations who may not employ fully automated security, there are
often issues managing user access within services outside of LDAP (Lightweight Directory
Access Protocol). Manually configuring firewalls is tedious, not to mention inefficient. Thankfully,
CloudPassage has an API that alleviates this issue within our Python SDK.

The Python SDK allows you to easily write a script and bake Halo right into the plumbing of your
automation system. Essentially this makes it possible to do almost anything you need to do with
Halo, without having to use your browser. And as as we mentioned before, it’s such a pain to
manually configure firewall rules.

That being said, leaving things open to the world, and trusting SSH or RDP to not let the bad
guys in isn’t an option. We need firewall orchestration, but no one wants to give themselves
carpal tunnel spending day after day configuring their workloads. Time is money, right?
With Halo you have the capability to dynamically authorize specific users based on their IP to
connect to your servers through GhostPorts, and that’s a great way to enable granular security compliance and auditing.
Let me explain. Each policy under which these rules are defined and can have a GhostPorts
user added, which is a user that when registered under your account, can have access to
specific ports on workloads secured by multi-factor authentication.
I wanted to create a tool that allows me to create these firewall policies, with GhostPorts users,
using only the Halo API. This was made easier with the use of the Python SDK, which allows us
to write logic against Halo functionality without dealing with the minutia of remembering URLs or
handling authentication with Halo.

THE NITTY GRITTY
One of the main design ideas behind the Halo Python SDK is to have a single object that holds
everything the SDK needs to know in order to interact with Halo, and pass it into different parts
of the SDK. An analogy would be using a car key to unlock doors, open trunk, open glove box,
or start the car.
This script enables you to add a number of users to various groups of matching policies. Each
enabled group with these rules is looped through each specified user name and then looped
through each matching service name that is verified as an existing service and applied. This
allows multiple users that need to be added to multiple policies with multiple services to be
added quickly and securely (rules can be added as inactive by default on a per group basis or
for all groups) on a large scale, and can also be set to inactive and removed from all policies as well.

SCRIPT CONFIGURATION
The purpose of the script is to have a number of users be added to various “groups” of matching policies. A user like “bill@example.com” can be added to every policy that has the word “qa” in it, or that exactly match “qa” by setting the wildcard setting to true or false with any number of specified services. Settings are loaded via a groups.yaml in the same path as the script, although this could fairly easily be modified to be a command line argument instead to load whatever given yaml file location is specified. Each enabled group with these rules is looped through for each specified user name and then loops through each matching service name that is verified as an existing service and applied. This allows multiple users that need to be added to multiple policies with multiple services able to be added quickly and safely (rules can be set to be added as inactive by default on a per group basis or for all groups) on a large scale, and can also be set to inactive and removed from all policies as well. Below you’ll see an example of the yaml file output that contains these values, and after I’ll give a brief overview the script style and common classes used after these parameters are passed to the script:


groups:
  enabled: group1
  comment:
  usernames: foo@bar.com, bar@foo.com
  # How many to subtract from the last position
  subtractfromlastrule:

group1:
  name: Prod content hosts
  chain: INPUT
  active: False
  source: None
  destination: None
  states:
  action: ACCEPT
  services: ssh, https
  log: False
  log_prefix:
  comment:
  username:
  wildcard: False
  position:
  subtractfromlastrule:

group2:
  name: foo
  chain: INPUT
  active: False
  source:
  destination:
  states: NEW, ESTABLISHED
  services: cp-ssh
  action: ACCEPT
  log: false
  log_prefix:
  comment:
  username:
  wildcard: True
  position:
  subtractfromlastrule:

WE MUST GO DEEPER: CODE EXPLORATION

There are a few classes to take note of, specifically within firewally_policy.py[5] and http_helper.py[6]. These classes, “FirewallPolicy,” “FirewallRule,” and “HttpHelper,” are all called through the HaloSession instantiation that grabs the required token grabbed by passing along your API key and secret, ideally within its own class function that can be called for use later on. HttpHelper is needed in order to parse the v2 users api as mentioned in the API Guide, and is not currently included within the SDK due to being subject to change.

Everything within the halo portal has an id associated with it, from users to services to policies to rules, and can be obtained through the “list_all” function. It mostly just boils down to a standard fizzbuzz problem, as in create lists of filtered rules and policies based on names, if rule url is in policy then create a dictionary list with policy rules, etc. etc.

With all this in mind, eventually you’ll have a dictionary of policy ids and required json values to pass along that looks something like this:


for pol, pos in self.pol_positions.iteritems():
    for service in self.list_of_services:
        if service["name"] == self.service:
            policy_json = {
            'firewall_rule': {'chain': self.chain, 'firewall_source': {'id': self.user_id, 'type': 'User'},
            'active': self.active, 'firewall_service': service["id"],
            'connection_states': self.states, 'action': self.action, 'log': self.log,
            'log_prefix': self.log_prefix, 'comment': self.comment, 'position': pos}}

and be ready to start updating firewall policies through python! To learn more about this process, and to use it in your own environment, visit the GitHub page. All in all, the Python SDK makes managing firewalls within Halo a breeze. While your script runs, you can feel free to go about your business managing workload issues while not being slowed down with manual configuration.

Posted in General

Leave a Reply

Your email address will not be published. Required fields are marked *

*