From 5ec634a3f67b4f20d4025891d55502b3ea68b273 Mon Sep 17 00:00:00 2001 From: Cao Xuan Hoang Date: Fri, 8 Dec 2017 14:20:44 +0700 Subject: [PATCH] [doc] Add testing VPNaaS with devstack This patch adds doc for how to test VPNaaS with devstack in order to help developers, operators and users easy to understand VPNaaS as fast as possible. This patch addresses the gap and improves docs as discussed in Boston summit. The content of this patch is basic inheritted from wiki page [1] [1] https://wiki.openstack.org/wiki/Neutron/VPNaaS/HowToInstall Change-Id: I8465cb90645af0fc3ea8cda554b0477b15f01fbe Related-bug: 1692131 --- devstack/local.conf.sample | 15 + devstack/local_AIO.conf.sample | 18 ++ doc/source/devref/index.rst | 1 + doc/source/devref/testing-with-devstack.rst | 288 ++++++++++++++++++++ tools/test_script.sh | 53 ++++ 5 files changed, 375 insertions(+) create mode 100644 devstack/local.conf.sample create mode 100644 devstack/local_AIO.conf.sample create mode 100644 doc/source/devref/testing-with-devstack.rst create mode 100755 tools/test_script.sh diff --git a/devstack/local.conf.sample b/devstack/local.conf.sample new file mode 100644 index 000000000..e136b7dfa --- /dev/null +++ b/devstack/local.conf.sample @@ -0,0 +1,15 @@ +[[local|localrc]] + +enable_plugin neutron-vpnaas https://git.openstack.org/openstack/neutron-vpnaas + +disable_service n-net +enable_service q-svc +enable_service q-agt +enable_service q-dhcp +enable_service q-l3 +enable_service q-meta +# Optional, to enable tempest configuration as part of devstack +enable_service tempest + +# IPsec driver to use. Optional, defaults to strongswan. +IPSEC_PACKAGE="strongswan" diff --git a/devstack/local_AIO.conf.sample b/devstack/local_AIO.conf.sample new file mode 100644 index 000000000..ac2132e23 --- /dev/null +++ b/devstack/local_AIO.conf.sample @@ -0,0 +1,18 @@ +[[local|localrc]] +disable_service n-net +enable_service q-svc +enable_service q-agent +enable_service q-dhcp +enable_service q-l3 +enable_service q-meta +enable_plugin neutron-vpnaas https://git.openstack.org/openstack/neutron-vpnaas + +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" diff --git a/doc/source/devref/index.rst b/doc/source/devref/index.rst index ef8f91531..ea24b1919 100644 --- a/doc/source/devref/index.rst +++ b/doc/source/devref/index.rst @@ -62,6 +62,7 @@ Testing :maxdepth: 3 devstack + testing-with-devstack .. todo:: diff --git a/doc/source/devref/testing-with-devstack.rst b/doc/source/devref/testing-with-devstack.rst new file mode 100644 index 000000000..6abcd0ff4 --- /dev/null +++ b/doc/source/devref/testing-with-devstack.rst @@ -0,0 +1,288 @@ +============================ +Testing VPNaaS with devstack +============================ + +Installation +------------ + +In order to use Neutron-VPNaaS with `devstack `_ a single node setup, +you'll need the following settings in your local.conf. + +.. literalinclude:: ../../../devstack/local.conf.sample + + +You can find an example at `devstack/local.conf.sample +`_ +in the source tree. + +Quick Test Script +----------------- + +This quick test script creates two sites with a router, a network and a subnet connected +with public network. Then, connect both sites via VPN. + +You can find an example at `tools/test_script.sh +`_ +in the source tree. + +Using Two DevStack Nodes for Testing +------------------------------------ + +You can use two DevStack nodes connected by a common "public" network to test VPNaaS. +The second node can be set up with the same public network as the first node, except +it will use a different gateway IP (and hence router IP). In this example, we'll assume +we have two DevStack nodes (``East`` and ``West``), each running on hardware. + +.. note:: + + - You can do the same thing with multiple VM guests, if desired. + - You can also create similar topology using two virtual routers with one devstack. + +Example Topology +^^^^^^^^^^^^^^^^ + +.. code-block:: none + + (10.1.0.0/24 - DevStack East) + | + | 10.1.0.1 + [Neutron Router] + | 172.24.4.226 + | + | 172.24.4.225 + [Internet GW] + | + | + [Internet GW] + | 172.24.4.232 + | + | 172.24.4.233 + [Neutron Router] + | 10.2.0.1 + | + (10.2.0.0/24 DevStack West) + +DevStack Configuration +^^^^^^^^^^^^^^^^^^^^^^ + +For ``East`` you need to append the following lines to the local.conf, which will give you +a private net of 10.1.0.0/24 and public network of 172.24.4.0/24 + +.. code-block:: none + + PUBLIC_SUBNET_NAME=yoursubnet + PRIVATE_SUBNET_NAME=mysubnet + FIXED_RANGE=10.1.0.0/24 + NETWORK_GATEWAY=10.1.0.1 + PUBLIC_NETWORK_GATEWAY=172.24.4.225 + Q_FLOATING_ALLOCATION_POOL=start=172.24.4.226,end=172.24.4.231 + +For ``West`` you can add the following lines to local.conf to use a different local network, +public GW (and implicitly router) IP. + +.. code-block:: none + + PUBLIC_SUBNET_NAME=yoursubnet + PRIVATE_SUBNET_NAME=mysubnet + FIXED_RANGE=10.2.0.0/24 + NETWORK_GATEWAY=10.2.0.1 + PUBLIC_NETWORK_GATEWAY=172.24.4.232 + Q_FLOATING_ALLOCATION_POOL=start=172.24.4.233,end=172.24.4.238 + +VPNaaS Configuration +^^^^^^^^^^^^^^^^^^^^ + +With DevStack running on ``East`` and ``West`` and connectivity confirmed (make sure +you can ping one router/GW from the other), you can perform these VPNaaS CLI commands. + +On ``East`` + +.. code-block:: none + + neutron vpn-ikepolicy-create ikepolicy1 + neutron vpn-ipsecpolicy-create ipsecpolicy1 + neutron vpn-service-create --name myvpn --description "My vpn service" router1 + neutron vpn-endpoint-group-create --name my-locals --type subnet --value mysubnet + neutron vpn-endpoint-group-create --name my-peers --type cidr --value 10.2.0.0/24 + neutron ipsec-site-connection-create --name vpnconnection1 --vpnservice-id myvpn \ + --ikepolicy-id ikepolicy1 --ipsecpolicy-id ipsecpolicy1 --peer-address 172.24.4.233 \ + --peer-id 172.24.4.233 --local-ep-group my-locals --peer-ep-group my-peers --psk secret + +On ``West`` + +.. code-block:: none + + neutron vpn-ikepolicy-create ikepolicy1 + neutron vpn-ipsecpolicy-create ipsecpolicy1 + neutron vpn-service-create --name myvpn --description "My vpn service" router1 + neutron vpn-endpoint-group-create --name my-locals --type subnet --value mysubnet + neutron vpn-endpoint-group-create --name my-peers --type cidr --value 10.1.0.0/24 + neutron ipsec-site-connection-create --name vpnconnection1 --vpnservice-id myvpn \ + --ikepolicy-id ikepolicy1 --ipsecpolicy-id ipsecpolicy1 --peer-address 172.24.4.226 \ + --peer-id 172.24.4.226 --local-ep-group my-locals --peer-ep-group my-peers --psk secret + +.. note:: + + Make sure setup security group (open icmp for vpn subnet etc) + +Verification +^^^^^^^^^^^^ + +You can spin up VMs on each node, and then from the VM ping to the other one. +With tcpdump running on one of the nodes, you can see that pings appear +as encrypted packets (ESP). Note that BOOTP, IGMP, and the keepalive packets between +the two nodes are not encrypted (nor are pings between the two external IP addresses). + +Once stacked, VMs were created for testing, VPN IPsec commands used to establish connections +between the nodes, and security group rules added to allow ICMP and SSH. + +Using single DevStack and two routers for testing +------------------------------------------------- + +Simple instructions on how to setup a test environment where a VPNaaS IPsec +connection can be established using the reference implementation (StrongSwan). +This example uses VirtualBox running on laptop to provide a VM for running +DevStack. + +The idea here is to have a single OpenStack cloud created using DevStack, +two routers (one created automatically), two private networks (one created automatically) +10.1.0.0/24 and 10.2.0.0/24, a VM in each private network, and establish a VPN connection +between the two private nets, using the public network (172.24.4.0/24). + +Preparation +^^^^^^^^^^^ + +Create a VM (e.g. 4 GB RAM, 2 CPUs) running Ubuntu 16.04, with NAT I/F for +access to the Internet. Clone a DevStack repo with latest. + +DevStack Configuration +^^^^^^^^^^^^^^^^^^^^^^ + +For single DevStack and two routers case, You can find an example at `devstack/local_AIO.conf.sample +`_ +in the source tree. + +Start up the cloud using ``./stack.sh`` and ensure it completes successfully. +Once stacked, you can change ``RECLONE`` option in local.conf to No. + +Cloud Configuration +^^^^^^^^^^^^^^^^^^^ + +Once stacking is completed, you'll have a private network (10.1.0.0/24), and a router (router1). +To prepare for establishing a VPN connection, a second network, subnet, and router needs +to be created, and a VM spun up in each private network. + +.. code-block:: none + + # Create second net, subnet, router + source ~/devstack/openrc admin demo + neutron net-create privateB + neutron subnet-create --name subB privateB 10.2.0.0/24 --gateway 10.2.0.1 + neutron router-create routerB + neutron router-interface-add routerB subB + neutron router-gateway-set routerB public + + # Start up a VM in the privateA subnet. + PRIVATE_NET=`neutron net-list | grep 'private ' | cut -f 2 -d' '` + nova boot --flavor 1 --image cirros-0.3.5-x86_64-uec --nic net-id=$PRIVATE_NET peter + + # Start up a VM in the privateB subnet + PRIVATE_NETB=`neutron net-list | grep privateB | cut -f 2 -d' '` + nova boot --flavor 1 --image cirros-0.3.5-x86_64-uec --nic net-id=$PRIVATE_NETB paul + +At this point, you can verify that you have basic connectivity. + +.. note:: + + DevStack will create a static route that will allow you to ping the private interface IP of + router1 from privateB network. You can remove the route, if desired. + +IPsec Site-to-site Connection Creation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following commands will create the IPsec connection: + +.. code-block:: none + + # Create VPN connections + neutron vpn-ikepolicy-create ikepolicy + neutron vpn-ipsecpolicy-create ipsecpolicy + neutron vpn-service-create --name myvpn --description "My vpn service" router1 + neutron vpn-endpoint-group-create --name my-localsA --type subnet --value privateA + neutron vpn-endpoint-group-create --name my-peersA --type cidr --value 10.2.0.0/24 + neutron ipsec-site-connection-create --name vpnconnection1 --vpnservice-id myvpn \ + --ikepolicy-id ikepolicy --ipsecpolicy-id ipsecpolicy --peer-address 172.24.4.13 \ + --peer-id 172.24.4.13 --local-ep-group my-localsA --peer-ep-group my-peersA --psk secret + + neutron vpn-service-create --name myvpnB --description "My vpn serviceB" routerB + neutron vpn-endpoint-group-create --name my-localsB --type subnet --value subB + neutron vpn-endpoint-group-create --name my-peersB --type cidr --value 10.1.0.0/24 + neutron ipsec-site-connection-create --name vpnconnection2 --vpnservice-id myvpnB \ + --ikepolicy-id ikepolicy --ipsecpolicy-id ipsecpolicy --peer-address 172.24.4.11 \ + --peer-id 172.24.4.11 --local-ep-group my-localsB --peer-ep-group my-peersB --psk secret + +At this point (once the connections become active - which can take up to 30 seconds or so), +you should be able to ping from the VM in the privateA network, to the VM in the privateB +network. You'll see encrypted packets, if you tcpdump using the qg-# interface from one +of the router namespaces. If you delete one of the connections, you'll see that the pings +fail (if all works out correctly :)). + +.. note:: + + Because routerB is created manually, its public IP address may change (172.24.4.13 + in this case). + + +Multiple Local Subnets +^^^^^^^^^^^^^^^^^^^^^^ + +Early in Mitaka, IPsec site-to-site connections will support multiple local subnets, +in addition to the current multiple peer CIDRs. The multiple local subnet feature +is triggered by not specifying a local subnet, when creating a VPN service. +Backwards compatibility is maintained with single local subnets, by providing +the subnet in the VPN service creation. + +To support multiple local subnets, a new capability has been provided (since Liberty), +called "Endpoint Groups". Each endpoint group will define one or more endpoints of +a specific type, and can be used to specify both local and peer endpoints for +IPsec connections. The Endpoint Groups separate the "what gets connected" from +the "how to connect" for a VPN service, and can be used for different flavors +of VPN, in the future. An example: + +.. code-block:: none + + # Create VPN connections + neutron vpn-ikepolicy-create ikepolicy + neutron vpn-ipsecpolicy-create ipsecpolicy + neutron vpn-service-create --name myvpnC --description "My vpn service" router1 + +To prepare for an IPsec site-to-site, one would create an endpoint group for +the local subnets, and an endpoint group for the peer CIDRs, like so: + +.. code-block:: none + + neutron vpn-endpoint-group-create --name my-locals --type subnet --value privateA --value privateA2 + neutron vpn-endpoint-group-create --name my-peers --type cidr --value 10.2.0.0/24 --value 20.2.0.0/24 + +where privateA and privateA2 are two local (private) subnets, and 10.2.0.0/24 and 20.2.0.0/24 +are two CIDRs representing peer (private) subnets that will be used by a connection. +Then, when creating the IPsec site-to-site connection, these endpoint group IDs would +be specified, instead of the peer-cidrs attribute: + +.. code-block:: none + + neutron ipsec-site-connection-create --name vpnconnection3 --vpnservice-id myvpnC \ + --ikepolicy-id ikepolicy --ipsecpolicy-id ipsecpolicy --peer-address 172.24.4.11 \ + --peer-id 172.24.4.11 --local-ep-group my-locals --peer-ep-group my-peers --psk secret + +.. note:: + - The validation logic makes sure that endpoint groups and peer CIDRs are not intermixed. + - Endpoint group types are subnet, cidr, network, router, and vlan. + However, only subnet and cidr are implemented (for IPsec use). + - The endpoints in a group must be of the same type, although It can mix IP versions. + - For IPsec connections, validation currently enforces that the local and peer + endpoints all use the same IP version. + - IPsec connection validation requires that local endpoints are subnets, + and peer endpoints are CIDRs. + - Migration will convert information for any existing VPN services and connections to endpoint groups. + - The original APIs will work for backward compatibility. diff --git a/tools/test_script.sh b/tools/test_script.sh new file mode 100755 index 000000000..305d751c4 --- /dev/null +++ b/tools/test_script.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +EXT_NW_ID=`neutron net-list | awk '/public/{print $2}'` +WEST_SUBNET='192.168.1.0/24' +EAST_SUBNET='192.168.2.0/24' + +function setup_site(){ + local site_name=$1 + local cidr=$2 + neutron net-create net_$site_name + neutron subnet-create --name subnet_$site_name net_$site_name $2 + neutron router-create router_$site_name + neutron router-interface-add router_$site_name subnet_$site_name + neutron router-gateway-set router_$site_name $EXT_NW_ID + neutron vpn-service-create --name vpn_$site_name router_$site_name subnet_$site_name +} + +function get_external_ip(){ + local router_id=`neutron router-show $1 | awk '/ id /{print $4}'` + echo `neutron port-list -c fixed_ips -c device_id -c device_owner|grep router_gateway | awk '/'.$router_id.'/{print $5}' | sed 's/["}]//g'` +} + +function clean_site(){ + local site_name=$1 + neutron ipsec-site-connection-delete conn_$site_name + neutron vpn-service-list | awk '/vpn_'$site_name'/{print "neutron vpn-service-delete " $2}' | bash + neutron router-gateway-clear router_$site_name + neutron router-interface-delete router_$site_name subnet_$site_name + neutron router-list | awk '/router_'$site_name'/{print "neutron router-delete " $2}' | bash + neutron subnet-list | awk '/subnet_'$site_name'/{print "neutron subnet-delete " $2}' | bash + neutron net-list | awk '/net_'$site_name'/{print "neutron net-delete " $2}' | bash +} + +function setup(){ + neutron vpn-ikepolicy-create ikepolicy1 + neutron vpn-ipsecpolicy-create ipsecpolicy1 + setup_site west $WEST_SUBNET + WEST_IP=$(get_external_ip router_west) + setup_site east $EAST_SUBNET + EAST_IP=$(get_external_ip router_east) + neutron ipsec-site-connection-create --name conn_east --vpnservice-id vpn_east --ikepolicy-id ikepolicy1 --ipsecpolicy-id ipsecpolicy1 --peer-address $WEST_IP --peer-id $WEST_IP --peer-cidr $WEST_SUBNET --psk secret + neutron ipsec-site-connection-create --name conn_west --vpnservice-id vpn_west --ikepolicy-id ikepolicy1 --ipsecpolicy-id ipsecpolicy1 --peer-address $EAST_IP --peer-id $EAST_IP --peer-cidr $EAST_SUBNET --psk secret +} + +function cleanup(){ + clean_site west + clean_site east + neutron vpn-ikepolicy-delete ikepolicy1 + neutron vpn-ipsecpolicy-delete ipsecpolicy1 +} + +cleanup +setup