Trying out the ML2 port-security extension
Intro
In the kilo cycle, support for the Neutron port security extension was added to the ML2 driver. This allows administrators to create VMs that route traffic and/or provide DHCP services by disabling certain anti-spoofing firewall rules that Neutron would otherwise automatically create.
The purpose of this post is to just run through the configuration and commands necessary to use this extension, not to actually do anything useful with it. Perhaps that will come in a later post.
Setting up devstack
To enable the port-security extension in ML2, the extension driver must be enabled in ml2_conf.ini. To do this in devstack, add the following to local.conf:
[[post-config|/$Q_PLUGIN_CONF_FILE]]
[ml2]
extension_drivers=port_security
My complete local.conf:
[[local|localrc]] disable_service n-net enable_service q-svc enable_service q-agt enable_service q-dhcp enable_service q-l3 enable_service q-meta enable_service neutron enable_service q-vpn FIXED_RANGE=10.1.0.0/24 FIXED_NETWORK_SIZE=256 NETWORK_GATEWAY=10.1.0.1 PRIVATE_SUBNET_NAME=privateA PUBLIC_SUBNET_NAME=public-subnet FLOATING_RANGE=172.24.4.0/24 PUBLIC_NETWORK_GATEWAY=172.24.4.10 Q_FLOATING_ALLOCATION_POOL="start=172.24.4.11,end=172.24.4.29" SCREEN_LOGDIR=/opt/stack/screen-logs ADMIN_PASSWORD=password MYSQL_PASSWORD=password RABBIT_PASSWORD=password SERVICE_PASSWORD=password SERVICE_TOKEN=tokentoken Q_USE_DEBUG_COMMAND=True [[post-config|/$Q_PLUGIN_CONF_FILE]] [ml2] extension_drivers=port_security
Launching a VM on a port with security disabled
Start devstack
Start devstack normally with
./stack.sh
and set the appropriate environment variables with
./openrc admin
Create a new network
neutron net-create testnet
Created a new network +---------------------------+--------------------------------------+ | Field | Value | +---------------------------+--------------------------------------+ | admin_state_up | True | | id | 0a752dc8-ff8b-4927-9a5f-6e922fa3f1d1 | | mtu | 0 | | name | testnet | | port_security_enabled | True | | provider:network_type | vxlan | | provider:physical_network | | | provider:segmentation_id | 1004 | | router:external | False | | shared | False | | status | ACTIVE | | subnets | | | tenant_id | 7bd48f0667974a948382e60a65330353 | +---------------------------+--------------------------------------+
Create a subnet
It isn’t strictly required to disable DHCP, I did so that I could test running a DHCP server on a VM.
neutron subnet-create testnet 10.10.0.0/24 --enable-dhcp=False --name testsubnet
Created a new subnet: +-------------------+----------------------------------------------+ | Field | Value | +-------------------+----------------------------------------------+ | allocation_pools | {"start": "10.10.0.2", "end": "10.10.0.254"} | | cidr | 10.10.0.0/24 | | dns_nameservers | | | enable_dhcp | False | | gateway_ip | 10.10.0.1 | | host_routes | | | id | 436258d1-f67e-441a-8522-4cdcbcbaa05b | | ip_version | 4 | | ipv6_address_mode | | | ipv6_ra_mode | | | name | testsubnet | | network_id | 0a752dc8-ff8b-4927-9a5f-6e922fa3f1d1 | | subnetpool_id | | | tenant_id | 7bd48f0667974a948382e60a65330353 | +-------------------+----------------------------------------------+
Creating a port-security disabled port
neutron port-create testnet --port-security-enabled=False --name rawport
Created a new port: +-----------------------+----------------------------------------------------------------------------------+ | Field | Value | +-----------------------+----------------------------------------------------------------------------------+ | admin_state_up | True | | allowed_address_pairs | | | binding:host_id | | | binding:profile | {} | | binding:vif_details | {} | | binding:vif_type | unbound | | binding:vnic_type | normal | | device_id | | | device_owner | | | fixed_ips | {"subnet_id": "436258d1-f67e-441a-8522-4cdcbcbaa05b", "ip_address": "10.10.0.2"} | | id | 56f7ae5a-a646-4ce6-a160-f51a435ba6d2 | | mac_address | fa:16:3e:d4:95:a1 | | name | rawport | | network_id | 0a752dc8-ff8b-4927-9a5f-6e922fa3f1d1 | | port_security_enabled | False | | security_groups | | | status | DOWN | | tenant_id | 7bd48f0667974a948382e60a65330353 | +-----------------------+----------------------------------------------------------------------------------+
Note that port_security_enabled is False.
Launching a VM using the port-security disabled port
To do anything useful, like run your own DHCP server on the VM, you’ll want to use a more featureful image than the cirros images, but since configuring the service VM is outside of the scope of this post:
nova boot --flavor=1 --image=cirros-0.3.2-x86_64-uec --nic port-id=$(neutron port-show -f value -F id rawport) testvm
+--------------------------------------+----------------------------------------------------------------+ | Property | Value | +--------------------------------------+----------------------------------------------------------------+ | OS-DCF:diskConfig | MANUAL | | OS-EXT-AZ:availability_zone | nova | | OS-EXT-SRV-ATTR:host | - | | OS-EXT-SRV-ATTR:hypervisor_hostname | - | | OS-EXT-SRV-ATTR:instance_name | instance-00000002 | | OS-EXT-STS:power_state | 0 | | OS-EXT-STS:task_state | scheduling | | OS-EXT-STS:vm_state | building | | OS-SRV-USG:launched_at | - | | OS-SRV-USG:terminated_at | - | | accessIPv4 | | | accessIPv6 | | | adminPass | bHFoc2GArP5Q | | config_drive | | | created | 2015-04-01T18:42:25Z | | flavor | m1.tiny (1) | | hostId | | | id | 02b068cf-8180-43cb-99b4-82911363e1bf | | image | cirros-0.3.2-x86_64-uec (152babef-d826-4317-8559-9bbee32edcab) | | key_name | - | | metadata | {} | | name | testvm | | os-extended-volumes:volumes_attached | [] | | progress | 0 | | security_groups | default | | status | BUILD | | tenant_id | 7bd48f0667974a948382e60a65330353 | | updated | 2015-04-01T18:42:25Z | | user_id | c622e5b49a844fb9b76f466210384955 | +--------------------------------------+----------------------------------------------------------------+
Next steps
The VM should boot and after becoming active can be configued via the console/horizon. It will not have a DHCP address and will need to be configured manually.