Category: openstack

Managing Port Level Security in OpenStack

The OpenStack platform, specifically (the networking component) Neutron uses the concepts of Ports in order to connect the various Cloud instances to different networks and the corresponding Virtual Networking devices like Neutron Routers, Firewalls etc.

The default security on these ports is quite restrictive and rightly so since the platform is supposed to be an autonomous, mostly independent system hosting multiple cloud tenants (customers,) or different cloud instances with varying security requirements. To get a better feel on Ports look at the diagram below.

Network Topology view in OpenStack

What you see above is a simple Network Topology in OpenStack. It comprises of 1 Router: RTR1TNT80CL3, connected to two networks (PubNetCL3, PriNetTNT81CL3) and 1 VM: vm1. In the pop-up you see two IP addresses (, assigned to two Interfaces on the router. These are two ports connecting the router to the two networks.

In certain advanced use cases (as you will see below) we might need to change the restrictive security settings on ports to allow for further customization of the environment.

Thankfully, OpenStack allows us to manage security on the individual port level in an environment. By default the following rules apply:

  • All incoming and outgoing traffic is blocked for ports connected to virtual machine instances. (Unless a ‘Security Group’ has been applied.)
  • Only traffic originating from the IP / MAC address pair known to OpenStack for a particular port, will be allowed on the network.
  • By default pass through and promiscuous mode will be blocked.

Reading Level: Intermediate
Environment: OpenStack (Liberty) on Redhat Enterprise Linux

Allowing Additional Addresses

In certain instances we would need to allow traffic from multiple IP address/MAC pairs to pass through a port, or for multiple ports to share a MAC address or IP address. One such requirement would be for clustering instances. In order to do this we need to add these IP address / MAC pairs on the port.

Step 1 – In order to obtain a list of all ports run the following command:

$ neutron port-list 
| id                                   | name | mac_address       | fixed_ips                     
| 0240a7c8-f892-4596-8420-af5e3295a535 |      | fa:16:3e:3f:dc:18 | {"subnet_id": "8071b06a-bd05-49da-a710-ec85c8df5efb", "ip_address": ""} |
| 064e8473-9bd6-4225-9cf3-13f855cd805f |      | fa:16:3e:2c:75:42 | {"subnet_id": "8071b06a-bd05-49da-a710-ec85c8df5efb", "ip_address": ""}  |
| 0c86a8c6-c415-41be-958d-867ae110b995 |      | fa:16:3e:cb:cc:a3 | {"subnet_id": "3608806e-0991-4c81-91a5-11f9f097be64", "ip_address": ""} |
| 0cb383b8-dadd-4b89-b863-d595a2173685 |      | fa:16:3e:7f:4a:78 | {"subnet_id": "8071b06a-bd05-49da-a710-ec85c8df5efb", "ip_address": ""}  |

The above output list all the ports in the environment. The first column gives the port ID e.g “0240a7c8-f892-4596-8420-af5e3295a535” and the last column provides the IP address e.g “” The IP address is usually a good way of identifying the port.

Step 2 – Once you have identified the port, use the following command to list the port details:

# neutron port-show ee976fc9-882d-46d4-80ef-c352090b8089
| Field                 | Value                    
| admin_state_up        | True
| allowed_address_pairs |
| binding:host_id       |
| binding:profile       | {}
| binding:vif_details   | {"port_filter": true, "ovs_hybri
| binding:vif_type      | ovs
| binding:vnic_type     | normal
| device_id             | dhcpdab444c7-710d-580a-b097-950c
| device_owner          | network:dhcp
| dns_assignment        | {"hostname": "host-10-101-12-2",
| dns_name              |
| extra_dhcp_opts       |
| fixed_ips             | {"subnet_id": "9bce8971-2e28-40b
| id                    | ee976fc9-882d-46d4-80ef-c352090b
| mac_address           | fa:16:3e:56:35:c4
| name                  |
| network_id            | fc2a69df-cf8c-45ac-8c0f-2dd8911a
| port_security_enabled | True
| security_groups       |
| status                | ACTIVE
| tenant_id             | b56cc570621243ca8fd9d53056279238

The above output gives you the details of the port. Note that ee976fc9-882d-46d4-80ef-c352090b8089 is the ID of the port you are interested in. The first attribute that we are interested in is allowed_address_pairs. This is blank for now, meaning it will only allow traffic for the IP/MAC pair that is already assigned to the port by neutron.

Default Port settings

In order to allow more than one IP/MAC pair to pass through a  particular port you would need to add the additional IPs to allowed_address_pairs. Use the following commands to manage this attribute:

Step 3.a – To add an IP address:

# neutron port-update b7d1d8bd-6ca7-4c35-9855-ba0dc2573fdc --allowed_address_pairs list=true type=dict ip_address=
Port settings allowing additional IP address

Step 3.b – To add multiple IP addresses and an additional MAC address:

# neutron port-update b7d1d8bd-6ca7-4c35-9855-ba0dc2573fdc --allowed_address_pairs list=true type=dict mac_address=ce:9e:5d:ad:6d:80,ip_address= ip_address=
Port settings allowing additional IP address and an additional IP/MAC pair

Step 3.c – To add an IP subnet:

# neutron port-update b7d1d8bd-6ca7-4c35-9855-ba0dc2573fdc --allowed_address_pairs list=true type=dict ip_address=
Port settings allowing an IP subnet

Note: If you do not provide the MAC address, Neutron defaults to the MAC address of the port known to OpenStack. This means that you cannot provide an IP / range of IP(s) without a MAC address. This is effective when you want to add more than one IP address on the same virtual machine instance. However this will not work if you want to create a virtual machine to allow traffic to pass through, for example a virtual machine representing a router or a firewall.

Disabling Port Security

In certain situations you might need to allow traffic to pass through the virtual machine instance in OpenStack. For example, if this virtual machine represents a networking device, like a router or a firewall. In this situation it is not possible to provide all the possible IP / MAC address combinations in allowed_address_pairs to cover all the possible machines that might send traffic via this networking instance. A better option in this case is to disable the port level security. Before disabling the port level security please note the following:

  • Port level security cannot be disabled if:
    • A security group is assigned to the instance
    • Allowed address pairs are set for the instamce
  • Once port level security is disabled, all traffic (Ingress and Egress) will be allowed on this interface.
  • Make sure that the security is being managed by the virtual machine instance (e.g. firewall rules) to compensate for the disabled security at the OpenStack level.

As seen above you will need to remove any existing security groups from the instance. This can be easily done from the Horizon GUI. I will not dwell into the details of how to do this, since this is very rudimentary.

Also you will need to disable the allowed address pairs. As of date I was unable to find, the OpenStack command-line option to set the allowed address pairs to blank once it has been set. In order to do this we use the OpenStack API.

Use the following command to get an authentication token from keystone in order to access the OpenStack API:

# curl -d '{"auth":{"passwordCredentials":{"username": "admin","password": "pass"},"tenantName": "tenant1"}}' -H "Content-Type: application/json"

Note that we need to provide the username and password for a valid OpenStack user that has access to the given tenant (tenant1 above,) and also note the IP address ’’ which represents the server where keystone resides. The output for this command will be as follows:

{"access": {"token": {"issued_at": "2016-06-05T01:49:36.477765", "expires": "2016-06-05T02:49:36Z", "id": "f3e704d837cf4074a0eb965d9de58c40", "tenant": {"description": "RDP Service UAT (TNT11_CL1)", "enabled": true, "id": "4dedb7b7ffe740c181d35a930809b22b", "name": "rdp_srv_uat"}, "audit_ids": ["H5JfGB-6QISRBlWObwAyRg"]}, "serviceCatalog": [{"endpoints": [{"adminURL": "", "region": "RegionOne", "internalURL": "", "id": "78655fc75ce2432986e1469c0703d32c", "publicURL": ….

I have trimmed the above output for readability. The only item of interest for us is the session token ID that is highlighted in yellow above. We will use this in the next command:

# curl -i -X PUT -H "X-Auth-Token: 4dedb7b7ffe740c181d35a930809b22b" -H "Content-Type: application/json" -H "Accept: application/json" -H "User-Agent: python-neutronclient" -d '{"port": {"allowed_address_pairs": []}}'

The Token is highlighted in yellow above. This is the same token we obtained from the previous command. Also note the number highlighted in orange. This is the ID of the port for which we need to set allowed_address_pairs to blank. The last section of the command “”port”: {“allowed_address_pairs”: []” (highlighted in blue) sets the allowed address pairs to blank.

Now that we have removed the security group and set allowed address pairs to blank we can disable the port level security. Run the following command to achieve this:

# neutron port-update ccbd0ed6-3dfd-4431-af29-4a2d921abb38 --port_security_enabled=False

In the above command the port ID is highlighted in orange. This command will disable port security on the particular port and allow all traffic to pass through without neutron dropping it as depicted below.

Port setting with all port security disabled

Thank you for reading. If you have any questions/comments please feel free to share below in the comments section so everyone from different sources can benefit from the discussion.

For my latest posts please visit WhatCloud.


Private project network

If you choose Network Option 2, you can also create a private virtual network for the project that connects to the physical network infrastructure via routing and NAT. This network includes a DHCP server that provides IP addresses to instances. An instance of this network can automatically access external networks such as the Internet. However, access to an instance of this network from an external network such as the Internet requires a floating IP address . Continue reading

Openstack Networking for Scalability and Multi-tenancy with VlanManager

In a previous post I explained the basic mode of network operation for OpenStack, namely FlatManager and its extension, FlatDHCPManager. In this post, I’ll talk about VlanManager. While flat managers are designed for simple, small scale deployments, VlanManager is a good choice for large scale internal clouds and public clouds. As its name implies, VlanManager relies on the use of vlans (“virtual LANs”). The purpose of vlans is to partition a physical network into distinct broadcast domains (so that host groups belonging to different vlans can’t see each other). VlanManager tries to address two main flaws of flat managers, those being: Continue reading

Configuring Floating IP addresses for Networking in OpenStack Public and Private Clouds

Recently I outlined how VlanManager works and how it ensures network scalability and tenant isolation. Up to this point, however, I’ve only dealt with fixed IP networks of different tenants. While fixed IPs are what instances are given by default, they do not ensure that the instance is immediately reachable from the outside world (or from the rest of the data center). Imagine the following scenario: Continue reading