In the I.T. world, security has always been important. Although the concept of something being “secure” can be defined in many different ways, one thing is usually fairly consistent – if you don’t want a device or service on your network to communicate with another device or service on your network, there needs to be a system in place to prevent that communication.
In today’s article we’ll discuss some high-level aspects of Nutanix Flow and how we as developers can automate the provisioning of network security policies via REST API.
Introduction
Let’s take a quick look at how Nutanix Flow is described on the main Nutanix Flow product page:
Security starts with a “Zero Trust” philosophy. Nutanix AHV with Flow delivers advanced networking, application-centric visibility and enterprise-grade microsegmentation for protection from network threats.
https://www.nutanix.com/products/flow
Although network security best practices are beyond the scope of this article, we can use the concept of “zero trust” as the basis of today’s automation discussion.
Environment Configuration
The following base configuration has been deployed in our development environment.
Application Servers
Nutanix Calm has been used to deploy a standard LAMP stack, that is, Linux/Apache/MySQL and PHP (including an HAProxy server, used to distribute requests amongst the Apache web servers). The complete component list is as follows:
- 1x MySQL Server, IP address 10.42.250.80
- 1x HAProxy Server, IP address 10.42.250.86
- 2x Apache web servers, IP addresses 10.42.250.75 and 10.42.250.96
In the default configuration, each server in the list can communicate with any other server in the list. All devices are on the same /24 subnet and there are no software-based firewalls (e.g. firewalld
or iptables
) that could block communication between the servers.
For today’s tests, we will use two different types of communication:
- Basic ICMP PING from the MySQL Server to the HAProxy Server
- Using
wget
, an HTTP request on port 80 from the MySQL Server to the HAProxy Server
Prism Central Categories
Nutanix Flow policies are configured based on Prism Central categories. In the official Prism Central documentation, categories are described as follows:
A category is a grouping of entities into a key value pair. Typically, new entities are assigned to a category based on some criteria. Policies can then be tied to those entities that are assigned (grouped by) a specific category value.
https://portal.nutanix.com/page/documents/details?targetId=Prism-Central-Guide-Prism-v6_0:ssp-ssp-categories-manage-pc-c.html
Nutanix Calm creates default categories when deploying apps, but for this demo a number of dedicated categories have been created. The categories are as follows:
Category Name | Category Value | Entities |
LAMPAppServices | Apache_Servers | 2x Apache Web Servers |
LAMPAppServices | HAProxy_Servers | 1x HAProxy Server |
LAMPAppServices | MySQL_Servers | 1x MySQL Server |
Nutanix Flow Policy (UI)
For this demo, the desired rule is quite simple: block the MySQL Server from communicating with the HAProxy. In point of fact, there’s really no reason for that to ever happen in an application like this anyway. The HAProxy server needs to communicate with the web servers only and doesn’t run a copy of our PHP web application itself. In other words, there’s no reason for the HAProxy server to make requests to the MySQL database. Conversely, there’s also no reason for the MySQL server to communicate with the HAProxy server, either.
Within Nutanix Flow, we can create rules with two different modes:
- Monitor mode – create the security policy but don’t apply it, yet. This allows us to create and test a rule before it is enforced, thereby greatly reducing the chance of an incorrectly configured rule blocking required traffic.
- Enforce mode – create the security policy and immediately enforce its rules. For this example, all traffic between the MySQL and HAProxy servers will be blocked.
Security Policy – Monitor Mode
To further demonstrate this, examining the Security Policy shows traffic matching both tests has been detected. Remember that the rule is currently in “Monitor” mode, so the traffic is still being allowed.
As of right now, traffic between the HAProxy and MySQL servers isn’t blocked – we can both complete an ICMP PING and a wget
request, as shown below. Please note the HTTP 403 response is expected, but still shows there is connectivity between the two servers.
Security Policy – Enforce Mode
Lastly, here are the same requests but with the Security Policy set to “Enforce” mode. In this test, the wget
command has been altered slightly, since a failed request won’t contain the text “HTTP” like a successful test does.
Security Policy Management via REST API
As with many entity types in Prism Central, network security rules can be created, read, updated and deleted via the Prism Central v3 REST APIs. To continue with our demo, let’s first get some information about the existing Security Policy.
List Network Security Rules
The request below can be used to list our existing network security rules. Note that there will always be two additional rules that were created by the system and both listed as “Quarantine” rules. These must not be deleted or changed so please don’t attempt to do so.
- HTTP method: POST
- URL:
<strong>https://{{prism_central_ip}}:9440/api/nutanix/v3/network_security_rules/list</strong>
- JSON payload: (shown below)
{
"kind":"network_security_rule"
}
From this request we’ll get a reasonably long response, providing information about how many network security rules there are and how each one is configured. The parts we’re interested in are shown below (note this isn’t valid JSON anymore, since adding “content cut here” annotations).
{
"api_version": "3.1",
"metadata": {
"total_matches": 3,
"kind": "network_security_rule",
"length": 3,
"offset": 0
},
"entities": [
{ content cut here },
{ content cut here },
{
"status": {
content cut here
},
"spec": {
"description": "Microsegmentation Isolation rule created via UI",
"resources": {
"is_policy_hitlog_enabled": false,
"isolation_rule": {
"action": "APPLY",
"first_entity_filter": {
"params": {
"LAMPAppServices": [
"HAProxy_Servers"
]
},
"kind_list": [
"vm"
],
"type": "CATEGORIES_MATCH_ALL"
},
"second_entity_filter": {
"params": {
"LAMPAppServices": [
"MySQL_Servers"
]
},
"kind_list": [
"vm"
],
"type": "CATEGORIES_MATCH_ALL"
}
}
},
"name": "isolation_ui"
},
"metadata": {
content cut here
"kind": "network_security_rule",
"uuid": "8394e11d-3154-4dc1-955b-49fdcd935d20",
}
}
]
}
As you can see, the rule examined earlier has the following partial configuration.
- Name: isolation_ui
- UUID: 8394e11d-3154-4dc1-955b-49fdcd935d20
- Matched categories: LAMPAppServices:HAProxy_Servers and LAMPAppServices:MySQL_Servers
- Hitlog enabled: false (don’t log the traffic)
Create Network Security Rule
At this point it’s easy to see how we would start building the JSON payload for creating the same request, but via the Prism Central v3 REST APIs.
Important note: When sending a JSON payload to create a network security rule, the payload must be complete and contain all required fields. Submitting a JSON payload that specifies a name, description and mode but without specifying the entity filters can result in an incomplete network security rule that prevents the Flow UI from successfully listing all rules. Nutanix Enginering is aware of this issue and will resolve it in due course.
For our demo security policy/network security rule set to be created in “Monitor” mode, the JSON payload can be built as shown below. We’re specifying the name, description, mode, entity filters, entity type and hitlog status.
Using an API mocking and test application such as Postman, we can submit this JSON payload as part of an API request:
- HTTP method: POST
- URL:
<strong>https://{{prism_central_ip}}:9440/api/nutanix/v3/network_security_rules</strong>
- JSON payload: (shown below)
{
"spec": {
"name": "isolation_api",
"description": "Microsegmentation Isolation rule created via API",
"resources": {
"is_policy_hitlog_enabled": false,
"isolation_rule": {
"action": "MONITOR",
"first_entity_filter": {
"params": {
"LAMPAppServices": [
"HAProxy_Servers"
]
},
"kind_list": [
"vm"
],
"type": "CATEGORIES_MATCH_ALL"
},
"second_entity_filter": {
"params": {
"LAMPAppServices": [
"MySQL_Servers"
]
},
"kind_list": [
"vm"
],
"type": "CATEGORIES_MATCH_ALL"
}
}
}
},
"metadata": {
"kind": "network_security_rule"
}
}
If we wanted to immediately enforce the rule when it is created, the “action” parameter would be changed as follows:
"action": "APPLY"
The relevant part of the JSON response is shown below, indicating the policy creation is pending, along with a task UUID that we can use via the tasks
API.
{
"status": {
"state": "PENDING",
"execution_context": {
"task_uuid": "76c927bb-4a69-4ad3-80aa-2adbdb203e61"
}
},
Checking the Nutanix Flow UI now shows our new Security Policy named “isolation_api” has been created and is monitoring traffic.
Update Network Security Rule
The demo above creates our network security rule, but sets it to “Monitor” mode. As outlined earlier, this will monitor the traffic between matching categorised entities but will not enforce those rules.
Using the Prism Central v3 REST APIs, I’ve already requested information about the new network security rule, as follows:
- UUID: 8ba9850e-811c-45d8-bf52-3863a3678125
- spec_version: 0
spec_version is an important value to note here. So that we don’t run into entity configuration mismatches, the current version of the rule must be submitted along with the update’s PUT request. This ensures the rule hasn’t been updated since we requested info about its current state.
With this information available, we can send the PUT request along with an appropriate JSON payload. This will instruct Prism Central to immediately set the rule to “Enforce” mode.
This request will be sent as follows – note the rule’s UUID has been appended as the last part of the URL.
- HTTP method: PUT
- URL:
https://{{prism_central_ip}}:9440/api/nutanix/v3/{{uuid}}
- Payload: (shown below)
{
"spec": {
"name": "isolation_api",
"description": "Microsegmentation Isolation rule created via API (Updated)",
"resources": {
"is_policy_hitlog_enabled": false,
"isolation_rule": {
"action": "APPLY",
"first_entity_filter": {
"params": {
"LAMPAppServices": [
"HAProxy_Servers"
]
},
"kind_list": [
"vm"
],
"type": "CATEGORIES_MATCH_ALL"
},
"second_entity_filter": {
"params": {
"LAMPAppServices": [
"MySQL_Servers"
]
},
"kind_list": [
"vm"
],
"type": "CATEGORIES_MATCH_ALL"
}
}
}
},
"metadata": {
"kind": "network_security_rule",
"spec_version": 0
}
}
As soon as this change takes effect, usually within seconds, our ICMP PING that has been left running from the earlier tests, will immediately begin to fail.
Delete Network Security Rule
The last action we’ll take during today’s article is to clean up after ourselves by deleting the rules that have been created. This is a simple case of sending a final API request, as follows:
- HTTP method: DELETE
- URL:
<strong>https://{{pc_ip}}:9440/api/nutanix/v3/network_security_rules/{{uuid}}</strong>
As expected, the deletion of this network security rule will immediately re-establish communication between the MySQL and HAProxy servers.
Related Resources
If you found this information useful, we also have a number of other resources available to you:
Wrapping Up
As you can see, creating, reading, updating and deleting network security rules can be accomplished easily and quickly with the Nutanix Prism Central v3 REST APIs. Using these approaches, automation of these processes could be easily integrated into a larger automation workflow via script, custom application or any other process capable of sending HTTP requests.
Hopefully this article has been useful and informative. Thanks for reading and have a great day! 🙂