diff --git a/model-based-aaa/.DS_Store b/model-based-aaa/.DS_Store new file mode 100644 index 0000000..7729e64 Binary files /dev/null and b/model-based-aaa/.DS_Store differ diff --git a/model-based-aaa/README.md b/model-based-aaa/README.md new file mode 100644 index 0000000..d2d3d1b --- /dev/null +++ b/model-based-aaa/README.md @@ -0,0 +1,13 @@ +# Model Based AAA + +The NETCONF and RESTCONF are industry standard protocols uses YANG data models for managing network devices. These protocols do not provide any mechanism for authorizing a user with different privilege levels. Every NETCONF or RESTCONF user is a super user with privilege level 15. + +NETCONF Access Control Model is a form of role-based access control (RBAC) specified in RFC 6536 can provide rules for privilege levels. A user can be authorized with aaa new-model and the privilege level is determined for that user, in the absence of aaa new-model configuration the locally configured privilege level is used. Using NACM you can set rules to that privilege level to control what to access for that user. It is a group-based authorization scheme for data and operations modeled in YANG. + +These are examples scripts for the Model Based AAA to retrieve, edit and delete the rules for a privilege level by using ietf-netconf-acm.yang data model. There are also examples for configuring and deleting users in a group. + +## requirements + +-- ncclient +-- IOS-XE running >/= 16.8 also enabled for NETCONF + diff --git a/model-based-aaa/delete-config_user.py b/model-based-aaa/delete-config_user.py new file mode 100644 index 0000000..5a8b33b --- /dev/null +++ b/model-based-aaa/delete-config_user.py @@ -0,0 +1,85 @@ +""" +#!/usr/bin/env python +# +# Copyright (c) 2017 Krishna Kotha +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This script retrieves entire configuration from a network element via NETCONF +# prints it out in a "pretty" XML tree.) +# +# Installing python dependencies: +# > pip install lxml ncclient +# +# Running script: (save as example.py) +# > python example.py -a 172.26.198.63 -u cisco -p cisco --port 830 +""" + +import lxml.etree as ET +from argparse import ArgumentParser +from ncclient import manager +from ncclient.operations import RPCError + +payload = """ + + + + priv04-group + + + +""" + +if __name__ == '__main__': + + parser = ArgumentParser(description='Usage:') + + # script arguments + parser.add_argument('-a', '--host', type=str, required=True, + help="Device IP address or Hostname") + parser.add_argument('-u', '--username', type=str, required=True, + help="Device Username (netconf agent username)") + parser.add_argument('-p', '--password', type=str, required=True, + help="Device Password (netconf agent password)") + parser.add_argument('--port', type=int, default=830, + help="Netconf agent port") + args = parser.parse_args() + + # connect to netconf agent + with manager.connect(host=args.host, + port=args.port, + username=args.username, + password=args.password, + timeout=90, + hostkey_verify=False, + device_params={'name': 'csr'}) as m: + + # execute netconf operation + try: + response = m.edit_config(target='running', config=payload).xml + data = ET.fromstring(response) + except RPCError as e: + data = e._raw + + # beautify output + print(ET.tostring(data, pretty_print=True)) \ No newline at end of file diff --git a/model-based-aaa/edit-config-permit-native.py b/model-based-aaa/edit-config-permit-native.py new file mode 100755 index 0000000..6a69cc8 --- /dev/null +++ b/model-based-aaa/edit-config-permit-native.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# +# Copyright (c) 2017 Krishna Kotha +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This script retrieves entire configuration from a network element via NETCONF +# prints it out in a "pretty" XML tree.) +# +# Installing python dependencies: +# > pip install lxml ncclient +# +# Running script: (save as example.py) +# > python example.py --host 172.26.198.63 -u cisco -p cisco + +import sys +from argparse import ArgumentParser +from ncclient import manager +import xml.dom.minidom + +data = ''' + + + + priv04-group + PRIV04 + + permit-read-native + Cisco-IOS-XE-native + read + permit + + + + +''' + +if __name__ == '__main__': + parser = ArgumentParser(description='Select options.') + # Input parameters + parser.add_argument('--host', type=str, required=True, + help="The device IP or DN") + parser.add_argument('-u', '--username', type=str, default='cisco', + help="Go on, guess!") + parser.add_argument('-p', '--password', type=str, default='cisco', + help="Yep, this one too! ;-)") + parser.add_argument('--port', type=int, default=830, + help="Specify this if you want a non-default port") + args = parser.parse_args() + m = manager.connect(host=args.host, + port=args.port, + username=args.username, + password=args.password, + device_params={'name':"csr"}) + # Pretty print the XML reply + xmlDom = xml.dom.minidom.parseString( str( m.edit_config(data, target='running') ) ) + print xmlDom.toprettyxml( indent = " " ) \ No newline at end of file diff --git a/model-based-aaa/edit-config-permit-netconf-native.py b/model-based-aaa/edit-config-permit-netconf-native.py new file mode 100755 index 0000000..f285fd1 --- /dev/null +++ b/model-based-aaa/edit-config-permit-netconf-native.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# +# Copyright (c) 2017 Krishna Kotha +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This script retrieves entire configuration from a network element via NETCONF +# prints it out in a "pretty" XML tree.) +# +# Installing python dependencies: +# > pip install lxml ncclient +# +# Running script: (save as example.py) +# > python example.py --host 172.26.198.63 -u cisco -p cisco + +import sys +from argparse import ArgumentParser +from ncclient import manager +import xml.dom.minidom + +data = ''' + + + + priv04-group + PRIV04 + + permit-netconf-rpc + ietf-netcon + exec + permit + + + permit-read-native + Cisco-IOS-XE-native + read + permit + + + + +''' + +if __name__ == '__main__': + parser = ArgumentParser(description='Select options.') + # Input parameters + parser.add_argument('--host', type=str, required=True, + help="The device IP or DN") + parser.add_argument('-u', '--username', type=str, default='cisco', + help="Go on, guess!") + parser.add_argument('-p', '--password', type=str, default='cisco', + help="Yep, this one too! ;-)") + parser.add_argument('--port', type=int, default=830, + help="Specify this if you want a non-default port") + args = parser.parse_args() + m = manager.connect(host=args.host, + port=args.port, + username=args.username, + password=args.password, + device_params={'name':"csr"}) + # Pretty print the XML reply + xmlDom = xml.dom.minidom.parseString( str( m.edit_config(data, target='running') ) ) + print xmlDom.toprettyxml( indent = " " ) \ No newline at end of file diff --git a/model-based-aaa/edit-config-permit-netconf.py b/model-based-aaa/edit-config-permit-netconf.py new file mode 100755 index 0000000..3d81d0e --- /dev/null +++ b/model-based-aaa/edit-config-permit-netconf.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# +# Copyright (c) 2017 Krishna Kotha +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This script retrieves entire configuration from a network element via NETCONF +# prints it out in a "pretty" XML tree.) +# +# Installing python dependencies: +# > pip install lxml ncclient +# +# Running script: (save as example.py) +# > python example.py --host 172.26.198.63 -u cisco -p cisco + +import sys +from argparse import ArgumentParser +from ncclient import manager +import xml.dom.minidom + +data = ''' + + + + priv04-group + PRIV04 + + permit-netconf-rpc + ietf-netconf + exec + permit + + + + +''' + +if __name__ == '__main__': + parser = ArgumentParser(description='Select options.') + # Input parameters + parser.add_argument('--host', type=str, required=True, + help="The device IP or DN") + parser.add_argument('-u', '--username', type=str, default='cisco', + help="Go on, guess!") + parser.add_argument('-p', '--password', type=str, default='cisco', + help="Yep, this one too! ;-)") + parser.add_argument('--port', type=int, default=830, + help="Specify this if you want a non-default port") + args = parser.parse_args() + m = manager.connect(host=args.host, + port=args.port, + username=args.username, + password=args.password, + device_params={'name':"csr"}) + # Pretty print the XML reply + xmlDom = xml.dom.minidom.parseString( str( m.edit_config(data, target='running') ) ) + print xmlDom.toprettyxml( indent = " " ) diff --git a/model-based-aaa/edit-config-user-groups.py b/model-based-aaa/edit-config-user-groups.py new file mode 100644 index 0000000..e8164a3 --- /dev/null +++ b/model-based-aaa/edit-config-user-groups.py @@ -0,0 +1,90 @@ +""" +#!/usr/bin/env python +# +# Copyright (c) 2017 Krishna Kotha +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This script retrieves entire configuration from a network element via NETCONF +# prints it out in a "pretty" XML tree.) +# +# Installing python dependencies: +# > pip install lxml ncclient +# +# Running script: (save as example.py) +# > python example.py -a 172.26.198.63 -u cisco -p cisco --port 830 +""" + +import lxml.etree as ET +from argparse import ArgumentParser +from ncclient import manager +from ncclient.operations import RPCError + +payload = """ + + + + + users + user1 + user2 + user3 + + + + +""" + +if __name__ == '__main__': + + parser = ArgumentParser(description='Usage:') + + # script arguments + parser.add_argument('-a', '--host', type=str, required=True, + help="Device IP address or Hostname") + parser.add_argument('-u', '--username', type=str, required=True, + help="Device Username (netconf agent username)") + parser.add_argument('-p', '--password', type=str, required=True, + help="Device Password (netconf agent password)") + parser.add_argument('--port', type=int, default=830, + help="Netconf agent port") + args = parser.parse_args() + + # connect to netconf agent + with manager.connect(host=args.host, + port=args.port, + username=args.username, + password=args.password, + timeout=90, + hostkey_verify=False, + device_params={'name': 'csr'}) as m: + + # execute netconf operation + try: + response = m.edit_config(target='running', config=payload).xml + data = ET.fromstring(response) + except RPCError as e: + data = e._raw + + # beautify output + print(ET.tostring(data, pretty_print=True)) \ No newline at end of file diff --git a/model-based-aaa/get-config-nacm.py b/model-based-aaa/get-config-nacm.py new file mode 100755 index 0000000..c8ec2ff --- /dev/null +++ b/model-based-aaa/get-config-nacm.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# +# Copyright (c) 2017 Krishna Kotha +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This script retrieves entire configuration from a network element via NETCONF +# prints it out in a "pretty" XML tree.) +# +# Installing python dependencies: +# > pip install lxml ncclient +# +# Running script: (save as example.py) +# > python example.py --host 172.26.198.63 -u cisco -p cisco + +import sys +from argparse import ArgumentParser +from ncclient import manager +import xml.dom.minidom + +if __name__ == '__main__': + parser = ArgumentParser(description='Select options.') + # Input parameters + parser.add_argument('--host', type=str, required=True, + help="The device IP or DN") + parser.add_argument('-u', '--username', type=str, default='cisco', + help="Go on, guess!") + parser.add_argument('-p', '--password', type=str, default='cisco', + help="Yep, this one too! ;-)") + parser.add_argument('--port', type=int, default=830, + help="Specify this if you want a non-default port") + args = parser.parse_args() + + m = manager.connect(host=args.host, + port=args.port, + username=args.username, + password=args.password, + device_params={'name':"csr"}) + + hostname_filter = ''' + + + + ''' + + # Pretty print the XML reply + xmlDom = xml.dom.minidom.parseString( str( m.get_config('running', hostname_filter))) + print(xmlDom.toprettyxml( indent = " " )) \ No newline at end of file diff --git a/model-based-aaa/update-config-hostname.py b/model-based-aaa/update-config-hostname.py new file mode 100755 index 0000000..993c961 --- /dev/null +++ b/model-based-aaa/update-config-hostname.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# +# Copyright (c) 2017 Krishna Kotha +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This script retrieves entire configuration from a network element via NETCONF +# prints it out in a "pretty" XML tree.) +# +# Installing python dependencies: +# > pip install lxml ncclient +# +# Running script: (save as example.py) +# > python example.py --host 172.26.198.63 -u cisco -p cisco + + +import sys +from argparse import ArgumentParser +from ncclient import manager +import xml.dom.minidom + +data = ''' + + + + priv04-group + PRIV04 + + permit-hostname + /native/hostname + update + permit + + + + +""" +''' + +if __name__ == '__main__': + parser = ArgumentParser(description='Select options.') + # Input parameters + parser.add_argument('--host', type=str, required=True, + help="The device IP or DN") + parser.add_argument('-u', '--username', type=str, default='cisco', + help="Go on, guess!") + parser.add_argument('-p', '--password', type=str, default='cisco', + help="Yep, this one too! ;-)") + parser.add_argument('--port', type=int, default=830, + help="Specify this if you want a non-default port") + args = parser.parse_args() + m = manager.connect(host=args.host, + port=args.port, + username=args.username, + password=args.password, + device_params={'name':"csr"}) + # Pretty print the XML reply + xmlDom = xml.dom.minidom.parseString( str( m.edit_config(data, target='running') ) ) + print xmlDom.toprettyxml( indent = " " ) \ No newline at end of file