Return-Path: X-Original-To: apmail-cloudstack-commits-archive@www.apache.org Delivered-To: apmail-cloudstack-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id D02EF10382 for ; Wed, 9 Sep 2015 08:00:18 +0000 (UTC) Received: (qmail 45315 invoked by uid 500); 9 Sep 2015 08:00:09 -0000 Delivered-To: apmail-cloudstack-commits-archive@cloudstack.apache.org Received: (qmail 45268 invoked by uid 500); 9 Sep 2015 08:00:09 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 45253 invoked by uid 99); 9 Sep 2015 08:00:09 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 09 Sep 2015 08:00:09 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id EF054E00CC; Wed, 9 Sep 2015 08:00:08 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: ekho@apache.org To: commits@cloudstack.apache.org Date: Wed, 09 Sep 2015 08:00:08 -0000 Message-Id: <8af03ed5cce4457394a4fb2823527057@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [1/3] git commit: updated refs/heads/master to 1bc8b6b Repository: cloudstack Updated Branches: refs/heads/master 33f4f952c -> 1bc8b6b19 CLOUDSTACK-8690:Added remote access vpn and vpn users configuration Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/d3fea571 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/d3fea571 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/d3fea571 Branch: refs/heads/master Commit: d3fea571a5bd9de2883279804678ec3511c641f9 Parents: 4f9aaf3 Author: Jayapal Authored: Wed Sep 2 11:45:53 2015 +0530 Committer: Jayapal Committed: Wed Sep 2 12:03:21 2015 +0530 ---------------------------------------------------------------------- .../debian/config/opt/cloud/bin/configure.py | 176 ++++++++++++++++++- .../debian/config/opt/cloud/bin/cs/CsFile.py | 29 +++ .../debian/config/opt/cloud/bin/cs/CsHelper.py | 4 +- .../config/opt/cloud/bin/cs_remoteaccessvpn.py | 28 +++ .../debian/config/opt/cloud/bin/cs_vpnusers.py | 48 +++++ .../debian/config/opt/cloud/bin/merge.py | 13 ++ .../config/opt/cloud/bin/update_config.py | 2 +- 7 files changed, 294 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d3fea571/systemvm/patches/debian/config/opt/cloud/bin/configure.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/configure.py b/systemvm/patches/debian/config/opt/cloud/bin/configure.py index a591737..3c7e972 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/configure.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/configure.py @@ -28,6 +28,7 @@ import re import time import shutil import os.path +import os from fcntl import flock, LOCK_EX, LOCK_UN from cs.CsDatabag import CsDataBag, CsCmdLine @@ -484,6 +485,170 @@ class CsSite2SiteVpn(CsDataBag): hrs = int(val) / 3600 return "%sh" % hrs +class CsVpnUser(CsDataBag): + PPP_CHAP='/etc/ppp/chap-secrets' + + def process(self): + for user in self.dbag: + if user == 'id': + continue + + userconfig=self.dbag[user] + if userconfig['add']: + self.add_l2tp_ipsec_user(user, userconfig) + else: + self.del_l2tp_ipsec_user(user, userconfig) + + def add_l2tp_ipsec_user(self, user, obj): + userfound = False + password = obj['password'] + + userSearchEntry = "%s \* %s \*"%(user,password) + userAddEntry = "%s * %s *" %(user,password) + logging.debug("Adding vpn user %s" %userSearchEntry) + + file = CsFile(self.PPP_CHAP) + userfound = file.searchString(userSearchEntry, '#') + if not userfound: + logging.debug("User is not there already, so adding user ") + self.del_l2tp_ipsec_user(user, obj) + file.add(userAddEntry) + file.commit() + + + def del_l2tp_ipsec_user(self, user, obj): + userfound = False + password = obj['password'] + userentry = "%s \* %s \*"%(user,password) + + logging.debug("Deleting the user %s " % user) + file = CsFile(self.PPP_CHAP) + file.deleteLine(userentry) + file.commit() + + if not os.path.exists('/var/run/pppd2.tdb'): + return + + logging.debug("kiing the PPPD process for the user %s " % user) + + fileContents = CsHelper.execute("tdbdump /var/run/pppd2.tdb") + print fileContents + + for line in fileContents: + if user in line: + contentlist = line.split(';') + for str in contentlist: + print 'in del_l2tp str = '+ str + pppd = str.split('=')[0] + if pppd == 'PPPD_PID': + pid = str.split('=')[1] + if pid: + logging.debug("killing process %s" %pid) + CsHelper.execute('kill -9 %s' % pid) + + + +class CsRemoteAccessVpn(CsDataBag): + VPNCONFDIR = "/etc/ipsec.d" + + def process(self): + self.confips = [] + + logging.debug(self.dbag) + for public_ip in self.dbag: + if public_ip == "id": + continue + vpnconfig=self.dbag[public_ip] + + #Enable remote access vpn + if vpnconfig['create']: + logging.debug("Enabling remote access vpn on "+ public_ip) + self.configure_l2tpIpsec(public_ip, self.dbag[public_ip]) + logging.debug("Remote accessvpn data bag %s", self.dbag) + self.remoteaccessvpn_iptables(public_ip, self.dbag[public_ip]) + + CsHelper.execute("ipsec auto --rereadall") + CsHelper.execute("service xl2tpd stop") + CsHelper.execute("service xl2tpd start") + CsHelper.execute("ipsec auto --rereadsecrets") + CsHelper.execute("ipsec auto --replace L2TP-PSK") + else: + logging.debug("Disabling remote access vpn .....") + #disable remote access vpn + CsHelper.execute("ipsec auto --down L2TP-PSK") + CsHelper.execute("service xl2tpd stop") + + + def configure_l2tpIpsec(self, left, obj): + vpnconffile="%s/l2tp.conf" % (self.VPNCONFDIR) + vpnsecretfilte="%s/ipsec.any.secrets" % (self.VPNCONFDIR) + xl2tpdconffile="/etc/xl2tpd/xl2tpd.conf" + xl2tpoptionsfile='/etc/ppp/options.xl2tpd' + + file = CsFile(vpnconffile) + localip=obj['local_ip'] + localcidr=obj['local_cidr'] + publicIface=obj['public_interface'] + iprange=obj['ip_range'] + psk=obj['preshared_key'] + + #left + file.addeq(" left=%s" % left) + file.commit() + + + secret = CsFile(vpnsecretfilte) + secret.addeq(": PSK \"%s\"" %psk) + secret.commit() + + xl2tpdconf = CsFile(xl2tpdconffile) + xl2tpdconf.addeq("ip range = %s" %iprange) + xl2tpdconf.addeq("local ip = %s" %localip) + xl2tpdconf.commit() + + xl2tpoptions=CsFile(xl2tpoptionsfile) + xl2tpoptions.search("ms-dns ", "ms-dns %s" %localip) + xl2tpoptions.commit() + + def remoteaccessvpn_iptables(self, publicip, obj): + publicdev=obj['public_interface'] + localcidr=obj['local_cidr'] + local_ip=obj['local_ip'] + + + self.fw.append(["", "", "-A INPUT -i %s --dst %s -p udp -m udp --dport 500 -j ACCEPT" % (publicdev, publicip)]) + self.fw.append(["", "", "-A INPUT -i %s --dst %s -p udp -m udp --dport 4500 -j ACCEPT" % (publicdev, publicip)]) + 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]) + + if self.config.is_vpc(): + self.fw.append(["", ""," -N VPN_FORWARD"]) + self.fw.append(["", "","-I FORWARD -i ppp+ -j VPN_FORWARD"]) + self.fw.append(["", "","-I FORWARD -o ppp+ -j VPN_FORWARD"]) + self.fw.append(["", "","-I FORWARD -o ppp+ -j VPN_FORWARD"]) + self.fw.append(["", "","-A VPN_FORWARD -s %s -j RETURN" %localcidr]) + self.fw.append(["", "","-A VPN_FORWARD -i ppp+ -d %s -j RETURN" %localcidr]) + self.fw.append(["", "","-A VPN_FORWARD -i ppp+ -o ppp+ -j RETURN"]) + else: + self.fw.append(["", "","-A FORWARD -i ppp+ -o ppp+ -j ACCEPT"]) + self.fw.append(["", "","-A FORWARD -s %s -o ppp+ -j ACCEPT" % localcidr]) + self.fw.append(["", "","-A FORWARD -i ppp+ -d %s -j ACCEPT" % localcidr]) + + + self.fw.append(["", "","-A INPUT -i ppp+ -m udp -p udp --dport 53 -j ACCEPT"]) + self.fw.append(["", "","-A INPUT -i ppp+ -m tcp -p tcp --dport 53 -j ACCEPT"]) + self.fw.append(["nat", "","-I PREROUTING -i ppp+ -m tcp --dport 53 -j DNAT --to-destination %s" % local_ip]) + + if self.config.is_vpc(): + return + + self.fw.append(["mangle", "","-N VPN_%s " %publicip]) + self.fw.append(["mangle", "","-I PREROUTING -d %s -j VPN_%s " % (publicip, publicip)]) + self.fw.append(["mangle", "","-A VPN_%s -p ah -j ACCEPT " % publicip]) + self.fw.append(["mangle", "","-A VPN_%s -p esp -j ACCEPT " % publicip]) + self.fw.append(["mangle", "","-A VPN_%s -j RETURN " % publicip]) + class CsForwardingRules(CsDataBag): @@ -672,15 +837,20 @@ def main(argv): fwd = CsForwardingRules("forwardingrules", config) fwd.process() - nf = CsNetfilters() - nf.compare(config.get_fw()) - red = CsRedundant(config) red.set() vpns = CsSite2SiteVpn("site2sitevpn", config) vpns.process() + #remote access vpn + rvpn = CsRemoteAccessVpn("remoteaccessvpn", config) + rvpn.process() + + #remote access vpn users + vpnuser = CsVpnUser("vpnuserlist", config) + vpnuser.process() + dhcp = CsDhcp("dhcpentry", config) dhcp.process() http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d3fea571/systemvm/patches/debian/config/opt/cloud/bin/cs/CsFile.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsFile.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsFile.py index 1cbf971..319b48e 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsFile.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsFile.py @@ -130,5 +130,34 @@ class CsFile: return True return False + + def searchString(self, search, ignoreLinesStartWith): + found = False + logging.debug("Searching for %s string " % search) + + for index, line in enumerate(self.new_config): + print ' line = ' +line + if line.lstrip().startswith(ignoreLinesStartWith): + continue + if re.search(search, line): + found = True + break + + return found + + + def deleteLine(self, search): + found = False + logging.debug("Searching for %s to remove the line " % search) + temp_config = [] + for index, line in enumerate(self.new_config): + if line.lstrip().startswith("#"): + continue + if not re.search(search, line): + temp_config.append(line) + + self.new_config = list(temp_config) + + def compare(self, o): return (isinstance(o, self.__class__) and set(self.config) == set(o.new_config)) http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d3fea571/systemvm/patches/debian/config/opt/cloud/bin/cs/CsHelper.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsHelper.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsHelper.py index 64616fb..6706d4f 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsHelper.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsHelper.py @@ -157,7 +157,7 @@ def get_hostname(): def execute(command): """ Execute command """ - logging.debug("Executing %s" % command) + logging.debug("Executing: %s" % command) p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) result = p.communicate()[0] return result.splitlines() @@ -178,7 +178,7 @@ def save_iptables(command, iptables_file): def execute2(command): """ Execute command """ - logging.debug("Executing %s" % command) + logging.debug("Executing: %s" % command) p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) p.wait() return p http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d3fea571/systemvm/patches/debian/config/opt/cloud/bin/cs_remoteaccessvpn.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs_remoteaccessvpn.py b/systemvm/patches/debian/config/opt/cloud/bin/cs_remoteaccessvpn.py new file mode 100755 index 0000000..4ae79c1 --- /dev/null +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs_remoteaccessvpn.py @@ -0,0 +1,28 @@ +# -- coding: utf-8 -- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from pprint import pprint + + +def merge(dbag, vpn): + key = vpn['vpn_server_ip'] + op = vpn['create'] + if key in dbag.keys() and not op: + del(dbag[key]) + else: + dbag[key] = vpn + return dbag http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d3fea571/systemvm/patches/debian/config/opt/cloud/bin/cs_vpnusers.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs_vpnusers.py b/systemvm/patches/debian/config/opt/cloud/bin/cs_vpnusers.py new file mode 100755 index 0000000..316fabc --- /dev/null +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs_vpnusers.py @@ -0,0 +1,48 @@ +# -- coding: utf-8 -- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from pprint import pprint + +import copy + + +def merge(dbag, data): + dbagc = copy.deepcopy(dbag) + + print dbag + print data + if "vpn_users" not in data: + return dbagc + + # remove previously deleted user from the dict + for user in dbagc.keys(): + if user == 'id': + continue + userrec = dbagc[user] + add = userrec['add'] + if not add: + del(dbagc[user]) + + for user in data['vpn_users']: + username=user['user'] + add=user['add'] + if username not in dbagc.keys(): + dbagc[username] = user + elif username in dbagc.keys() and not add: + dbagc[username] = user + + return dbagc http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d3fea571/systemvm/patches/debian/config/opt/cloud/bin/merge.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/merge.py b/systemvm/patches/debian/config/opt/cloud/bin/merge.py index 2401ef1..cc14d6a 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/merge.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/merge.py @@ -32,6 +32,8 @@ import cs_vmdata import cs_dhcp import cs_forwardingrules import cs_site2sitevpn +import cs_remoteaccessvpn +import cs_vpnusers from pprint import pprint @@ -66,6 +68,7 @@ class DataBag: logging.error("Could not write data bag %s", self.key) else: logging.debug("Writing data bag type %s", self.key) + logging.debug(dbag) jsono = json.dumps(dbag, indent=4, sort_keys=True) handle.write(jsono) @@ -119,6 +122,10 @@ class updateDataBag: dbag = self.processForwardingRules(self.db.getDataBag()) elif self.qFile.type == 'site2sitevpn': dbag = self.process_site2sitevpn(self.db.getDataBag()) + elif self.qFile.type == 'remoteaccessvpn': + dbag = self.process_remoteaccessvpn(self.db.getDataBag()) + elif self.qFile.type == 'vpnuserlist': + dbag = self.process_vpnusers(self.db.getDataBag()) else: logging.error("Error I do not know what to do with file of type %s", self.qFile.type) return @@ -147,6 +154,12 @@ class updateDataBag: def process_site2sitevpn(self, dbag): return cs_site2sitevpn.merge(dbag, self.qFile.data) + def process_remoteaccessvpn(self, dbag): + return cs_remoteaccessvpn.merge(dbag, self.qFile.data) + + def process_vpnusers(self, dbag): + return cs_vpnusers.merge(dbag, self.qFile.data) + def process_network_acl(self, dbag): return cs_network_acl.merge(dbag, self.qFile.data) http://git-wip-us.apache.org/repos/asf/cloudstack/blob/d3fea571/systemvm/patches/debian/config/opt/cloud/bin/update_config.py ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/opt/cloud/bin/update_config.py b/systemvm/patches/debian/config/opt/cloud/bin/update_config.py index 77557f9..35a5cde 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/update_config.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/update_config.py @@ -26,7 +26,7 @@ import os.path import configure import json -logging.basicConfig(filename='/var/log/cloud.log', level=logging.DEBUG, format='%(asctime)s %(message)s') +logging.basicConfig(filename='/var/log/cloud.log', level=logging.DEBUG, format='%(asctime)s %(filename)s %(funcName)s:%(lineno)d %(message)s') # first commandline argument should be the file to process if (len(sys.argv) != 2):