This is an automated email from the ASF dual-hosted git repository. rohit pushed a commit to branch debian9-systemvmtemplate in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit f494d7dea6535bdbdd109ceed15d90d892b02b44 Author: Rohit Yadav <rohit.ya...@shapeblue.com> AuthorDate: Fri Dec 1 20:58:18 2017 +0530 CLOUDSTACK-10013: Fix ipsec VPN configuration - Fixes strongswan/ipsec, l2tpd and pppd configs - Uses auto=route in ipsec configs - Fixes road-warrior setup - Fixes site-to-site VPN with automatic connection configuration - Fixes vpc_vpn tests Signed-off-by: Rohit Yadav <rohit.ya...@shapeblue.com> --- systemvm/patches/debian/opt/cloud/bin/configure.py | 38 +++++++++++++--------- .../patches/debian/opt/cloud/bin/ipsectunnel.sh | 10 +----- .../debian/opt/cloud/bin/monitor_service.sh | 2 -- systemvm/patches/vpn/etc/ipsec.d/l2tp.conf | 12 +++---- systemvm/patches/vpn/etc/ppp/options.xl2tpd | 2 -- systemvm/patches/vpn/opt/cloud/bin/vpn_l2tp.sh | 18 +++++----- test/integration/smoke/test_vpc_vpn.py | 26 +++++++++++---- 7 files changed, 55 insertions(+), 53 deletions(-) diff --git a/systemvm/patches/debian/opt/cloud/bin/configure.py b/systemvm/patches/debian/opt/cloud/bin/configure.py index 68d1c26..b8a3e02 100755 --- a/systemvm/patches/debian/opt/cloud/bin/configure.py +++ b/systemvm/patches/debian/opt/cloud/bin/configure.py @@ -546,10 +546,6 @@ class CsSite2SiteVpn(CsDataBag): ikepolicy=obj['ike_policy'].replace(';','-') esppolicy=obj['esp_policy'].replace(';','-') - pfs='no' - if 'modp' in esppolicy: - pfs='yes' - if rightpeer in self.confips: self.confips.remove(rightpeer) file = CsFile(vpnconffile) @@ -557,7 +553,6 @@ class CsSite2SiteVpn(CsDataBag): file.search("conn ", "conn vpn-%s" % rightpeer) file.addeq(" left=%s" % leftpeer) file.addeq(" leftsubnet=%s" % obj['local_guest_cidr']) - file.addeq(" leftnexthop=%s" % obj['local_public_gateway']) file.addeq(" right=%s" % rightpeer) file.addeq(" rightsubnet=%s" % peerlist) file.addeq(" type=tunnel") @@ -567,9 +562,8 @@ class CsSite2SiteVpn(CsDataBag): file.addeq(" ikelifetime=%s" % self.convert_sec_to_h(obj['ike_lifetime'])) file.addeq(" esp=%s" % esppolicy) file.addeq(" lifetime=%s" % self.convert_sec_to_h(obj['esp_lifetime'])) - file.addeq(" pfs=%s" % pfs) file.addeq(" keyingtries=2") - file.addeq(" auto=start") + file.addeq(" auto=route") if 'encap' not in obj: obj['encap']=False file.addeq(" forceencaps=%s" % CsHelper.bool_to_yn(obj['encap'])) @@ -585,10 +579,20 @@ class CsSite2SiteVpn(CsDataBag): logging.info("Configured vpn %s %s", leftpeer, rightpeer) CsHelper.execute("ipsec rereadsecrets") - # This will load the new config and start the connection when needed since auto=start in the config + # This will load the new config CsHelper.execute("ipsec reload") os.chmod(vpnsecretsfile, 0400) + for i in xrange(3): + result = CsHelper.execute('ipsec status vpn-%s | grep "%s"' % (rightpeer, peerlist.split(",", 1)[0])) + if len(result) > 0: + break + time.sleep(1) + + # With 'auto=route', connections are established on an attempt to + # communicate over the S2S VPN. This uses ping to initialize the connection. + CsHelper.execute("timeout 5 ping -c 3 %s" % (peerlist.split("/", 1)[0].replace(".0", ".1"))) + def convert_sec_to_h(self, val): hrs = int(val) / 3600 return "%sh" % hrs @@ -658,6 +662,7 @@ class CsRemoteAccessVpn(CsDataBag): self.confips = [] logging.debug(self.dbag) + for public_ip in self.dbag: if public_ip == "id": continue @@ -665,12 +670,13 @@ class CsRemoteAccessVpn(CsDataBag): #Enable remote access vpn if vpnconfig['create']: + shutdownIpsec = False logging.debug("Enabling remote access vpn on "+ public_ip) dev = CsHelper.get_device(public_ip) if dev == "": - logging.error("Request for ipsec to %s not possible because ip is not configured", public_ip) - continue + logging.error("Request for ipsec to %s not possible because ip is not configured", public_ip) + continue CsHelper.start_if_stopped("ipsec") self.configure_l2tpIpsec(public_ip, self.dbag[public_ip]) @@ -682,7 +688,6 @@ class CsRemoteAccessVpn(CsDataBag): CsHelper.execute("ipsec rereadsecrets") else: logging.debug("Disabling remote access vpn .....") - #disable remote access vpn CsHelper.execute("ipsec down L2TP-PSK") CsHelper.execute("systemctl stop xl2tpd") @@ -693,7 +698,6 @@ class CsRemoteAccessVpn(CsDataBag): xl2tpdconffile="/etc/xl2tpd/xl2tpd.conf" xl2tpoptionsfile='/etc/ppp/options.xl2tpd' - file = CsFile(l2tpconffile) localip=obj['local_ip'] localcidr=obj['local_cidr'] publicIface=obj['public_interface'] @@ -701,13 +705,13 @@ class CsRemoteAccessVpn(CsDataBag): psk=obj['preshared_key'] #left - file.addeq(" left=%s" % left) - file.commit() - + l2tpfile = CsFile(l2tpconffile) + l2tpfile.addeq(" left=%s" % left) + l2tpfile.commit() secret = CsFile(vpnsecretfilte) secret.empty() - secret.addeq(": PSK \"%s\"" %psk) + secret.addeq("%s %%any : PSK \"%s\"" % (left, psk)) secret.commit() xl2tpdconf = CsFile(xl2tpdconffile) @@ -730,6 +734,8 @@ class CsRemoteAccessVpn(CsDataBag): self.fw.append(["", "", "-A INPUT -i %s --dst %s -p udp -m udp --dport 1701 -j ACCEPT" % (publicdev, publicip)]) self.fw.append(["", "", "-A INPUT -i %s -p ah -j ACCEPT" % publicdev]) self.fw.append(["", "", "-A INPUT -i %s -p esp -j ACCEPT" % publicdev]) + self.fw.append(["", "", "-A OUTPUT -p ah -j ACCEPT"]) + self.fw.append(["", "", "-A OUTPUT -p esp -j ACCEPT"]) if self.config.is_vpc(): self.fw.append(["", ""," -N VPN_FORWARD"]) diff --git a/systemvm/patches/debian/opt/cloud/bin/ipsectunnel.sh b/systemvm/patches/debian/opt/cloud/bin/ipsectunnel.sh index 20caec5..c42650f 100755 --- a/systemvm/patches/debian/opt/cloud/bin/ipsectunnel.sh +++ b/systemvm/patches/debian/opt/cloud/bin/ipsectunnel.sh @@ -142,7 +142,6 @@ ipsec_tunnel_add() { sudo echo "conn vpn-$rightpeer" > $vpnconffile && sudo echo " left=$leftpeer" >> $vpnconffile && sudo echo " leftsubnet=$leftnet" >> $vpnconffile && - sudo echo " leftnexthop=$leftnexthop" >> $vpnconffile && sudo echo " right=$rightpeer" >> $vpnconffile && sudo echo " rightsubnets={$rightnets}" >> $vpnconffile && sudo echo " type=tunnel" >> $vpnconffile && @@ -152,9 +151,8 @@ ipsec_tunnel_add() { sudo echo " ikelifetime=${ikelifetime}s" >> $vpnconffile && sudo echo " esp=$esppolicy" >> $vpnconffile && sudo echo " salifetime=${esplifetime}s" >> $vpnconffile && - sudo echo " pfs=$pfs" >> $vpnconffile && sudo echo " keyingtries=2" >> $vpnconffile && - sudo echo " auto=start" >> $vpnconffile && + sudo echo " auto=route" >> $vpnconffile && sudo echo "$leftpeer $rightpeer: PSK \"$secret\"" > $vpnsecretsfile && sudo chmod 0400 $vpnsecretsfile @@ -291,12 +289,6 @@ do done < /tmp/iflist rightnets=${rightnets//,/ } -pfs="no" -echo "$esppolicy" | grep "modp" > /dev/null -if [ $? -eq 0 ] -then - pfs="yes" -fi ret=0 #Firewall ports for one-to-one/static NAT diff --git a/systemvm/patches/debian/opt/cloud/bin/monitor_service.sh b/systemvm/patches/debian/opt/cloud/bin/monitor_service.sh index d9d8ec8..e1c7914 100755 --- a/systemvm/patches/debian/opt/cloud/bin/monitor_service.sh +++ b/systemvm/patches/debian/opt/cloud/bin/monitor_service.sh @@ -50,8 +50,6 @@ echo $processname >> $configFile echo $service_name >> $configFile echo $pidfile >> $configFile - - done } diff --git a/systemvm/patches/vpn/etc/ipsec.d/l2tp.conf b/systemvm/patches/vpn/etc/ipsec.d/l2tp.conf index 1cbfe78..2e211e1 100644 --- a/systemvm/patches/vpn/etc/ipsec.d/l2tp.conf +++ b/systemvm/patches/vpn/etc/ipsec.d/l2tp.conf @@ -1,13 +1,9 @@ #ipsec remote access vpn configuration conn L2TP-PSK - authby=psk - pfs=no + authby=secret rekey=no keyingtries=3 - keyexchange=ikev1 - forceencaps=yes leftfirewall=yes - leftnexthop=%defaultroute type=transport # # ---------------------------------------------------------- @@ -19,7 +15,7 @@ conn L2TP-PSK # left=172.26.0.151 # - leftprotoport=17/1701 + leftprotoport=udp/l2tp # If you insist on supporting non-updated Windows clients, # you can use: leftprotoport=17/%any # @@ -31,10 +27,10 @@ conn L2TP-PSK # If you want to allow multiple connections from any IP address, # you can use: right=%any # - rightprotoport=17/%any + rightprotoport=udp/%any # # ---------------------------------------------------------- # Change 'ignore' to 'add' to enable this configuration. # rightsubnetwithin=0.0.0.0/0 - auto=add + auto=route diff --git a/systemvm/patches/vpn/etc/ppp/options.xl2tpd b/systemvm/patches/vpn/etc/ppp/options.xl2tpd index 08c301b..a01687f 100644 --- a/systemvm/patches/vpn/etc/ppp/options.xl2tpd +++ b/systemvm/patches/vpn/etc/ppp/options.xl2tpd @@ -4,11 +4,9 @@ ipcp-accept-remote noccp idle 1800 auth -crtscts mtu 1410 mru 1410 nodefaultroute debug -lock connect-delay 5000 ms-dns 10.1.1.1 diff --git a/systemvm/patches/vpn/opt/cloud/bin/vpn_l2tp.sh b/systemvm/patches/vpn/opt/cloud/bin/vpn_l2tp.sh index 60ee8a6..5928548 100755 --- a/systemvm/patches/vpn/opt/cloud/bin/vpn_l2tp.sh +++ b/systemvm/patches/vpn/opt/cloud/bin/vpn_l2tp.sh @@ -87,15 +87,15 @@ iptables_() { } start_ipsec() { - service ipsec status > /dev/null + systemctl is-active ipsec > /dev/null if [ $? -ne 0 ] then - service ipsec start > /dev/null + systemctl start ipsec > /dev/null #Wait until ipsec started, 5 seconds at most for i in {1..5} do logger -t cloud "$(basename $0): waiting ipsec start..." - service ipsec status > /dev/null + systemctl is-active ipsec > /dev/null result=$? if [ $result -eq 0 ] then @@ -104,7 +104,7 @@ start_ipsec() { sleep 1 done fi - service ipsec status > /dev/null + systemctl is-active ipsec > /dev/null return $? } @@ -112,14 +112,14 @@ ipsec_server() { local op=$1 case $op in "start") start_ipsec - sudo service xl2tpd start + sudo systemctl start xl2tpd ;; - "stop") sudo service xl2tpd stop + "stop") sudo systemctl stop xl2tpd ;; "restart") start_ipsec sudo ipsec auto --rereadall - service xl2tpd stop - service xl2tpd start + systemctl stop xl2tpd + systemctl start xl2tpd ;; esac } @@ -131,7 +131,7 @@ create_l2tp_ipsec_vpn_server() { local local_ip=$4 sed -i -e "s/left=.*$/left=$public_ip/" /etc/ipsec.d/l2tp.conf - echo ": PSK \"$ipsec_psk\"" > /etc/ipsec.d/ipsec.any.secrets + echo "$public_ip %any : PSK \"$ipsec_psk\"" > /etc/ipsec.d/ipsec.any.secrets sed -i -e "s/^ip range = .*$/ip range = $client_range/" /etc/xl2tpd/xl2tpd.conf sed -i -e "s/^local ip = .*$/local ip = $local_ip/" /etc/xl2tpd/xl2tpd.conf diff --git a/test/integration/smoke/test_vpc_vpn.py b/test/integration/smoke/test_vpc_vpn.py index ddf7693..83c244b 100644 --- a/test/integration/smoke/test_vpc_vpn.py +++ b/test/integration/smoke/test_vpc_vpn.py @@ -21,7 +21,8 @@ from marvin.codes import PASS, FAILED from marvin.cloudstackTestCase import cloudstackTestCase from marvin.lib.utils import (validateList, cleanup_resources, - get_process_status) + get_process_status, + wait_until) from marvin.lib.base import (Domain, Account, @@ -184,7 +185,7 @@ class Services: }, "vpn": { "vpn_user": "root", - "vpn_pass": "Md1s#dc", + "vpn_pass": "Md1sdc", "vpn_pass_fail": "abc!123", # too short "iprange": "10.3.2.1-10.3.2.10", "fordisplay": "true" @@ -756,8 +757,19 @@ class TestVpcSite2SiteVpn(cloudstackTestCase): self.apiclient, customer2_response.id, vpn1_response['id']) self.debug("VPN connection created for VPC %s" % vpc1.id) - self.assertEqual( - vpnconn2_response['state'], "Connected", "Failed to connect between VPCs!") + def checkVpnConnected(): + connections = Vpn.listVpnConnection( + self.apiclient, + listall='true', + vpcid=vpc2.id) + if isinstance(connections, list): + return connections[0].state == 'Connected', None + return False, None + + # Wait up to 60 seconds for passive connection to show up as Connected + res, _ = wait_until(2, 30, checkVpnConnected) + if not res: + self.fail("Failed to connect between VPCs, see VPN state as Connected") # acquire an extra ip address to use to ssh into vm2 try: @@ -792,9 +804,9 @@ class TestVpcSite2SiteVpn(cloudstackTestCase): if ssh_client: # run ping test - packet_loss = ssh_client.execute( - "/bin/ping -c 3 -t 10 " + vm1.nic[0].ipaddress + " |grep packet|cut -d ' ' -f 7| cut -f1 -d'%'")[0] - self.assert_(int(packet_loss) == 0, "Ping did not succeed") + packet_loss = ssh_client.execute("/bin/ping -c 3 -t 10 " + vm1.nic[0].ipaddress + " | grep packet | sed 's/.*received, //g' | sed 's/[% ]*packet.*//g'")[0] + # during startup, some packets may not reply due to link/ipsec-route setup + self.assert_(int(packet_loss) < 50, "Ping did not succeed") else: self.fail("Failed to setup ssh connection to %s" % vm2.public_ip) -- To stop receiving notification emails like this one, please contact "commits@cloudstack.apache.org" <commits@cloudstack.apache.org>.