├── .gitignore ├── .gitmodules ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SUPPORT.md ├── docs ├── Makefile ├── conf.py ├── index.rst └── notice.rst ├── loadable_configs ├── sample-cloud-AWS │ ├── panorama │ │ └── iron_skillet_panorama_full.xml │ └── panos │ │ └── iron_skillet_panos_full.xml ├── sample-cloud-Azure │ ├── panorama │ │ └── iron_skillet_panorama_full.xml │ └── panos │ │ └── iron_skillet_panos_full.xml ├── sample-cloud-GCP │ ├── panorama │ │ └── iron_skillet_panorama_full.xml │ └── panos │ │ └── iron_skillet_panos_full.xml ├── sample-mgmt-dhcp │ ├── panorama │ │ └── iron_skillet_panorama_full.xml │ └── panos │ │ └── iron_skillet_panos_full.xml ├── sample-mgmt-static │ ├── panorama │ │ └── iron_skillet_panorama_full.xml │ └── panos │ │ └── iron_skillet_panos_full.xml └── sample-set-commands │ ├── README.md │ ├── panorama │ └── iron_skillet_panorama_full.conf │ └── panos │ └── iron_skillet_panos_full.conf ├── playlists ├── README.md ├── panorama │ ├── panorama_device_hardening.skillet.yaml │ ├── panorama_notshared_dgstack.skillet.yaml │ ├── panorama_notshared_full.skillet.yaml │ ├── panorama_shared_dgtemplate.skillet.yaml │ ├── panorama_shared_full.skillet.yaml │ └── panorama_shared_security_profiles.skillet.yaml └── panos │ ├── panos_alert_only.skillet.yaml │ ├── panos_device_hardening.skillet.yaml │ ├── panos_full.skillet.yaml │ └── panos_security_profiles.skillet.yaml ├── templates ├── README.md ├── panorama │ ├── baseline │ │ └── baseline.xml │ ├── full │ │ ├── .meta-cnc.yaml │ │ └── iron_skillet_panorama_full.xml │ ├── set_commands │ │ ├── .meta-cnc.yaml │ │ ├── iron_skillet_panorama_full.conf │ │ └── iron_skillet_panorama_full.xlsx │ ├── snippets │ │ ├── .meta-cnc.yaml │ │ └── README.md │ ├── snippets_dgstack_notshared │ │ ├── .meta-cnc.yaml │ │ └── README.md │ ├── snippets_dgtemplate_shared │ │ ├── .meta-cnc.yaml │ │ └── README.md │ └── snippets_notshared │ │ ├── .meta-cnc.yaml │ │ └── README.md └── panos │ ├── baseline │ └── baseline.xml │ ├── full │ ├── .meta-cnc.yaml │ └── iron_skillet_panos_full.xml │ ├── set_commands │ ├── .meta-cnc.yaml │ ├── iron_skillet_panos_full.conf │ └── iron_skillet_panos_full.xlsx │ └── snippets │ ├── .meta-cnc.yaml │ └── README.md ├── tools ├── .gitignore ├── README.md ├── archive │ ├── build_all.py │ ├── build_full_templates.py │ ├── create_loadable_configs.py │ ├── create_set_spreadsheet.py │ ├── requirements.txt │ ├── test_full_config.py │ └── test_set_commands.py ├── build_all.sh └── update_submodules.sh └── validations ├── README.md ├── panos ├── IronSkillet_assessment_panos │ ├── .meta-cnc.yaml │ └── report │ │ └── report.yml └── IronSkillet_v10x_update_panos │ ├── .meta-cnc.yaml │ └── report │ └── report.yml └── shared_report ├── is_logo.png └── report.yml /.gitignore: -------------------------------------------------------------------------------- 1 | # Developer testing 2 | changes.yaml 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | git b 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | MANIFEST 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | 53 | # Translations 54 | *.mo 55 | *.pot 56 | 57 | # Django stuff: 58 | *.log 59 | local_settings.py 60 | db.sqlite3 61 | 62 | # Flask stuff: 63 | instance/ 64 | .webassets-cache 65 | 66 | # Scrapy stuff: 67 | .scrapy 68 | 69 | # Sphinx documentation 70 | docs/_build/ 71 | 72 | # PyBuilder 73 | target/ 74 | 75 | # Jupyter Notebook 76 | .ipynb_checkpoints 77 | 78 | # pyenv 79 | .python-version 80 | 81 | # celery beat schedule file 82 | celerybeat-schedule 83 | 84 | # SageMath parsed files 85 | *.sage.py 86 | 87 | # Environments 88 | .env 89 | .venv 90 | env/ 91 | venv/ 92 | ENV/ 93 | env.bak/ 94 | venv.bak/ 95 | 96 | # Spyder project settings 97 | .spyderproject 98 | .spyproject 99 | 100 | # Rope project settings 101 | .ropeproject 102 | 103 | # mkdocs documentation 104 | /site 105 | 106 | # mypy 107 | .mypy_cache 108 | 109 | # Mac crud 110 | .DS_Store 111 | 112 | #rubymine 113 | .idea/ 114 | 115 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "submodules"] 2 | path = submodules 3 | url = git@github.com:PaloAltoNetworks/ironskillet-components.git 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributing 3 | Contributions are welcomed and greatly appreciated! Every little bit helps and credit will always be given. 4 | 5 | You can contribute in many ways: 6 | 7 | Types of Contributions 8 | -- 9 | #### Report Bugs 10 | Report bugs at https://github.com/PaloAltoNetworks/pandevice/issues. 11 | 12 | If you are reporting a bug, please include: 13 | 14 | * The PAN-OS or Panorama version you are running. 15 | * Any details about your local setup that might be helpful in troubleshooting. 16 | * Detailed steps to reproduce the issue. 17 | 18 | #### Fix Bugs 19 | Look through the GitHub issues for bugs. Anything tagged with "bug" 20 | is open to whoever wants to implement it. 21 | 22 | #### Implement Features 23 | Look through the GitHub issues for features. Anything tagged with "enhancement" 24 | is open to whoever wants to implement it. 25 | 26 | #### Write Documentation 27 | The `iron-skillet` project is managed by engineers. As such, it could always use better documentation. Any edits that helps make the documentation clearer and more effective is greatly appreciated. 28 | 29 | #### Submit Feedback 30 | The best way to send feedback is to file an issue at https://github.com/PaloAltoNetworks/iron-skillet/issues. 31 | 32 | If you are proposing a change: 33 | 34 | * Explain in detail why it is needed. 35 | * Keep the scope as narrow as possible, to make it easier to implement. 36 | * Remember that this is a volunteer-driven project and that contributions are welcome :) 37 | 38 | Get Started! 39 | ------------ 40 | 41 | Ready to contribute? Here's how to set up `iron-skillet` for local development. 42 | 43 | 1. Fork the `iron-skillet` repo on GitHub. 44 | 2. Clone your fork locally. 45 | 46 | `$ git clone git@github.com:your_name_here/iron-skillet.git 47 | $ cd iron-skillet` 48 | 49 | 3. Create a branch for local development. 50 | 51 | `$ git checkout -b name-of-your-branch` 52 | 53 | 4. Edit the XML configuration snippets locally. An XML editor is recommended to ensure proper XML structure. 54 | 55 | 5. Import the XML configuration snippet into a non-production NGFW, load it into the candidate configuration, and ensure that the candidate configuration commits without errors. 56 | 57 | 6. Commit your changes and push your branch to GitHub:: 58 | 59 | `$ git add . 60 | $ git commit -m "Your detailed description of your changes." 61 | $ git push origin name-of-your-branch` 62 | 63 | 7. Submit a pull request through the GitHub website. 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Palo Alto Networks 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IronSkillet Day One Configuration Template 2 | 3 | 4 | The purpose of the IronSkillet project is to provide day-one best practice 5 | configuration templates that can be loaded into a Palo Alto Networks 6 | Next-Generation Firewall or Panorama management platform. 7 | 8 | Once loaded, the configuration can be augmented with use case specific 9 | security policies and other deployment requirements including interfaces, 10 | zones, and NAT. 11 | 12 | Detailed information can be found in the 13 | [IronSkillet Documentation](https://iron-skillet.readthedocs.io) 14 | 15 | The docs include a [IronSkillet Visual Guide](https://iron-skillet.readthedocs.io/en/docs_master/viz_guide_panos.html) 16 | for a view of IronSkillet from a GUI perspective. 17 | 18 | ## Quick Start 19 | The templates are provided with a variety of usage options based 20 | on the user operational environment. 21 | 22 | 23 | #### PanHandler Skillet Player 24 | A quick and easy way to play IronSkillet and other skillets is with the panHandler application. 25 | 26 | The [panHandler quick start guide](https://live.paloaltonetworks.com/t5/Skillet-Tools/Install-and-Get-Started-With-Panhandler/ta-p/307916) 27 | in the Skillet District Live community walks you through installation and usage including 28 | how to import the IronSkillet skillets. 29 | 30 | ### SLI 31 | The Skillet Line Interfacing tool is a CLI interface that can also be used to load and work 32 | with skillets. Please refer to the README document found within the following [SLI](https://gitlab.com/panw-gse/as/sli) 33 | repository. This will walk you through the installation and basic usage of SLI in the context of 34 | skillets. 35 | 36 | **SLI Commands to Load Skillet** 37 | ```bash 38 | > sli load 39 | # Above line loads and views all skillets found in the working directory 40 | > sli load -sd {Directory Containing Skillets} 41 | # Above line loads and views all skillets found in the given directory 42 | ``` 43 | 44 | 45 | #### Getting templates from the repo 46 | Users can either grab content file-by-file from the github repo or download all 47 | content to a local drive. 48 | 49 | **TIP:** when copying or getting text files from the repo, users should select 50 | the `Raw` format. This is found as a GUI option when viewing the file. 51 | 52 | Downloading the files is done using a `git clone` command or a direct 53 | download of the repo as a zip file. 54 | 55 | ``` 56 | git clone https://github.com/PaloAltoNetworks/iron-skillet.git 57 | ``` 58 | 59 | 60 | #### Loading configurations using IronSkillet defaults 61 | The `loadable_configs` directory contains a variety of ready-to-go 62 | NGFW and Panorama configurations based on iron-skillet template defaults. 63 | These can be loaded 'as-is' and later updated using the GUI or CLI. 64 | 65 | The two options to load are: 66 | 67 | * ...full.xml: complete xml configuration to import and load 68 | * ...full.conf: complete list of CLI-based set commands 69 | 70 | ###### Full XML configuration file 71 | Loading the full XML file as a candidate configuration: 72 | 73 | ``` 74 | * Log into the GUI 75 | * Go to `Device` > `Setup` > `Operations` 76 | * Choose `Import named configuration snapshot` 77 | * Select the file from a local directory to import 78 | * Choose `Load named configuration snapshot` 79 | * Review the loaded configuration and `commit` to apply changes 80 | ``` 81 | 82 | **WARNING:** this configuration `replaces` the existing configuration and 83 | is not a merge of configurations. Merging configurations requires the 84 | use of `load config partial` referencing select xpaths to be loaded and merged. 85 | 86 | ###### SET commands 87 | Using `set` commands to load in a configuration: 88 | 89 | * Log into the CLI 90 | * Enter `configure` to enter configuration mode 91 | * Copy a cluster of set commands, 30-40 lines recommended as maximum 92 | * Paste into the command line and hit `Enter` to ensure the last line is entered 93 | * Add all set commands in the conf file 94 | * Enter `commit` 95 | 96 | **TIP:** Before entering configure mode, you can use `set cli scripting-mode on` 97 | to paste in a higher volume of lines. This will however remove the option to 98 | use '?' as a command-line helper. If scripting mode is enabled and you wish 99 | to disable, simply return to CLI operation mode with `exit` and enter 100 | 'set cli scripting-mode off'. 101 | 102 | #### Editing Loaded Configurations 103 | The detailed documentation provides a list of variables that can be edited 104 | and instructions for GUI and CLI edits to these values. 105 | 106 | [IronSkillet variables](https://iron-skillet.readthedocs.io/en/docs_master/creating_loadable_configs.html#variables-list-and-descriptions) 107 | 108 | 109 | #### Using the SET Command Spreadsheet to Edit Values 110 | Found in `templates/panorama/set_commands` and `templates/panos/set_commands` 111 | are formula-based Excel files. 112 | 113 | The cells in the `values` worksheet can be edited to create a 114 | localized configuration without the iron-skillet defaults. This updates the 115 | values in the `set commands` worksheet. Using the set command steps above, 116 | the configuration can then be loaded using the CLI. 117 | 118 | **WARNING:** only update the `values` worksheet. Using caution if editing 119 | the worksheets to ensure cell references and formulas are not incorrect. 120 | 121 | ### SLI Tooling Directory 122 | As an alternative, the `Tools` directory within the IronSkillet repository 123 | contains a README.md file going over how to use various SLI commands to help 124 | manage and create loadable configurations among other useful functions. Following 125 | the detailed steps in the README and Using SLI to accomplish these tasks is quick, 126 | efficient and easy. 127 | 128 | ## Recommended Reading for Additional Best Practice Configuration Steps 129 | 130 | Prior to utilizing these configuration templates, it is important to 131 | familiarize yourself with the best practice recommendations for 132 | Internet Gateway, Datacenter, Wildfire, L4-L7 evasions and other use cases. 133 | 134 | [Best Practice Recommendations](https://docs.paloaltonetworks.com/best-practices) 135 | 136 | While useful as suggestions and recommendations, the user is still required 137 | to manually use the GUI or CLI to configure each recommendation. 138 | 139 | 140 | ## Contributing 141 | Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on how you can help contribute to this project. 142 | 143 | ## Support 144 | This is a Palo Alto Networks contributed project. 145 | 146 | ## Authors 147 | 148 | * Scott Shoaf [(@scotchoaf)](https://github.com/scotchoaf) 149 | * Bora Mutluoglu - [(@BoraMutluoglu)](https://github.com/BoraMutluoglu) 150 | 151 | See also the list of [contributors](https://github.com/PaloAltoNetworks/iron-skillet/contributors) who have participated in this project. 152 | 153 | ## License 154 | 155 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details 156 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | 2 | ## SUPPORT 3 | 4 | This project is contributed by Palo Alto Networks and is not formally supported. 5 | Support for the this project is provided on a best-effort basis the Palo Alto Networks user community. 6 | If you encounter any issues you may: 7 | 8 | - Open a [GitHub issue](https://github.com/PaloAltoNetworks/iron-skillet/issues). 9 | - Post a message on the Best Practices discussion forum 10 | 11 | More information on Palo Alto Networks support policies may be found at: 12 | 13 | http://www.paloaltonetworks.com/support 14 | 15 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = iron-skillet 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Configuration file for the Sphinx documentation builder. 4 | # 5 | # This file does only contain a selection of the most common options. For a 6 | # full list see the documentation: 7 | # http://www.sphinx-doc.org/en/master/config 8 | 9 | # -- Path setup -------------------------------------------------------------- 10 | 11 | # If extensions (or modules to document with autodoc) are in another directory, 12 | # add these directories to sys.path here. If the directory is relative to the 13 | # documentation root, use os.path.abspath to make it absolute, like shown here. 14 | # 15 | # import os 16 | # import sys 17 | # sys.path.insert(0, os.path.abspath('.')) 18 | 19 | 20 | # -- Project information ----------------------------------------------------- 21 | 22 | project = u'iron-skillet' 23 | copyright = u'2018, Palo Alto Networks' 24 | author = u'Palo Alto Networks' 25 | 26 | # The short X.Y version 27 | version = u'' 28 | # The full version, including alpha/beta/rc tags 29 | release = u'1.0' 30 | 31 | 32 | # -- General configuration --------------------------------------------------- 33 | 34 | # If your documentation needs a minimal Sphinx version, state it here. 35 | # 36 | # needs_sphinx = '1.0' 37 | 38 | # Add any Sphinx extension module names here, as strings. They can be 39 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 40 | # ones. 41 | extensions = ['sphinx.ext.extlinks' 42 | ] 43 | 44 | # Add any paths that contain templates here, relative to this directory. 45 | templates_path = ['_templates'] 46 | 47 | # The suffix(es) of source filenames. 48 | # You can specify multiple suffix as a list of string: 49 | # 50 | # source_suffix = ['.rst', '.md'] 51 | source_suffix = '.rst' 52 | 53 | # The master toctree document. 54 | master_doc = 'index' 55 | 56 | # The language for content autogenerated by Sphinx. Refer to documentation 57 | # for a list of supported languages. 58 | # 59 | # This is also used if you do content translation via gettext catalogs. 60 | # Usually you set "language" from the command line for these cases. 61 | language = None 62 | 63 | # List of patterns, relative to source directory, that match files and 64 | # directories to ignore when looking for source files. 65 | # This pattern also affects html_static_path and html_extra_path . 66 | exclude_patterns = [u'_build', 'Thumbs.db', '.DS_Store'] 67 | 68 | # The name of the Pygments (syntax highlighting) style to use. 69 | pygments_style = 'sphinx' 70 | 71 | 72 | # -- Options for HTML output ------------------------------------------------- 73 | 74 | # The theme to use for HTML and HTML Help pages. See the documentation for 75 | # a list of builtin themes. 76 | # 77 | html_theme = 'sphinx_rtd_theme' 78 | 79 | # Theme options are theme-specific and customize the look and feel of a theme 80 | # further. For a list of options available for each theme, see the 81 | # documentation. 82 | # 83 | # html_theme_options = {} 84 | 85 | # Add any paths that contain custom static files (such as style sheets) here, 86 | # relative to this directory. They are copied after the builtin static files, 87 | # so a file named "default.css" will overwrite the builtin "default.css". 88 | html_static_path = ['_static'] 89 | 90 | # Custom sidebar templates, must be a dictionary that maps document names 91 | # to template names. 92 | # 93 | # The default sidebars (for documents that don't match any pattern) are 94 | # defined by theme itself. Builtin themes are using these templates by 95 | # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', 96 | # 'searchbox.html']``. 97 | # 98 | # html_sidebars = {} 99 | 100 | 101 | # -- Options for HTMLHelp output --------------------------------------------- 102 | 103 | # Output file base name for HTML help builder. 104 | htmlhelp_basename = 'iron-skilletdoc' 105 | 106 | 107 | # -- Options for LaTeX output ------------------------------------------------ 108 | 109 | latex_elements = { 110 | # The paper size ('letterpaper' or 'a4paper'). 111 | # 112 | # 'papersize': 'letterpaper', 113 | 114 | # The font size ('10pt', '11pt' or '12pt'). 115 | # 116 | # 'pointsize': '10pt', 117 | 118 | # Additional stuff for the LaTeX preamble. 119 | # 120 | # 'preamble': '', 121 | 122 | # Latex figure (float) alignment 123 | # 124 | # 'figure_align': 'htbp', 125 | } 126 | 127 | # Grouping the document tree into LaTeX files. List of tuples 128 | # (source start file, target name, title, 129 | # author, documentclass [howto, manual, or own class]). 130 | latex_documents = [ 131 | (master_doc, 'iron-skillet.tex', u'iron-skillet Documentation', 132 | u'Palo Alto Networks', 'manual'), 133 | ] 134 | 135 | 136 | # -- Options for manual page output ------------------------------------------ 137 | 138 | # One entry per manual page. List of tuples 139 | # (source start file, name, description, authors, manual section). 140 | man_pages = [ 141 | (master_doc, 'iron-skillet', u'iron-skillet Documentation', 142 | [author], 1) 143 | ] 144 | 145 | 146 | # -- Options for Texinfo output ---------------------------------------------- 147 | 148 | # Grouping the document tree into Texinfo files. List of tuples 149 | # (source start file, target name, title, author, 150 | # dir menu entry, description, category) 151 | texinfo_documents = [ 152 | (master_doc, 'iron-skillet', u'iron-skillet Documentation', 153 | author, 'iron-skillet', 'One line description of project.', 154 | 'Miscellaneous'), 155 | ] 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. test_rst documentation master file, created by 2 | sphinx-quickstart on Mon Jul 16 11:03:51 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to Iron Skillet template documentation! 7 | ==================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 1 11 | :caption: Contents: 12 | 13 | notice 14 | -------------------------------------------------------------------------------- /docs/notice.rst: -------------------------------------------------------------------------------- 1 | Documentation change notice 2 | =========================== 3 | 4 | .. Warning:: 5 | Documentation is moving to its own release branch containing all release docs. 6 | The content-by-release elements will be removed in a future release. 7 | 8 | 9 | Documentation for this release can be found at https://iron-skillet.readthedocs.io 10 | -------------------------------------------------------------------------------- /loadable_configs/sample-set-commands/README.md: -------------------------------------------------------------------------------- 1 | # Set-Commands Loadable Configuration 2 | 3 | The set commands loadable config files created within this directory 4 | are initialized with both static and dhcp options by default. It is up to the 5 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 6 | 7 | The set commands loadable config files created within this directory 8 | are initialized with both static and dhcp options by default. It is up to the 9 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 10 | 11 | The set commands loadable config files created within this directory 12 | are initialized with both static and dhcp options by default. It is up to the 13 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 14 | 15 | The set commands loadable config files created within this directory 16 | are initialized with both static and dhcp options by default. It is up to the 17 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 18 | 19 | The set commands loadable config files created within this directory 20 | are initialized with both static and dhcp options by default. It is up to the 21 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 22 | 23 | The set commands loadable config files created within this directory 24 | are initialized with both static and dhcp options by default. It is up to the 25 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 26 | 27 | The set commands loadable config files created within this directory 28 | are initialized with both static and dhcp options by default. It is up to the 29 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 30 | 31 | The set commands loadable config files created within this directory 32 | are initialized with both static and dhcp options by default. It is up to the 33 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 34 | 35 | The set commands loadable config files created within this directory 36 | are initialized with both static and dhcp options by default. It is up to the 37 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 38 | 39 | The set commands loadable config files created within this directory 40 | are initialized with both static and dhcp options by default. It is up to the 41 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 42 | 43 | The set commands loadable config files created within this directory 44 | are initialized with both static and dhcp options by default. It is up to the 45 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 46 | 47 | The set commands loadable config files created within this directory 48 | are initialized with both static and dhcp options by default. It is up to the 49 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 50 | 51 | The set commands loadable config files created within this directory 52 | are initialized with both static and dhcp options by default. It is up to the 53 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 54 | 55 | The set commands loadable config files created within this directory 56 | are initialized with both static and dhcp options by default. It is up to the 57 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 58 | 59 | The set commands loadable config files created within this directory 60 | are initialized with both static and dhcp options by default. It is up to the 61 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 62 | 63 | The set commands loadable config files created within this directory 64 | are initialized with both static and dhcp options by default. It is up to the 65 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 66 | 67 | The set commands loadable config files created within this directory 68 | are initialized with both static and dhcp options by default. It is up to the 69 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 70 | 71 | The set commands loadable config files created within this directory 72 | are initialized with both static and dhcp options by default. It is up to the 73 | user's discretion on which configuration they would like to use.# Set-Commands Loadable Configuration 74 | 75 | The set commands loadable config files created within this directory 76 | are initialized with both static and dhcp options by default. It is up to the 77 | user's discretion on which configuration they would like to use. -------------------------------------------------------------------------------- /playlists/README.md: -------------------------------------------------------------------------------- 1 | # Playlist with Skillet Includes 2 | 3 | Starting with IronSkillet 10.1, skillets are now available in a playlist format. In this new playlist model, it is 4 | possible to reference a set of sub-skillets from a submodule though skillet includes. A git submodule allows content 5 | from one repository to be easily accessed and updated from another repository. For IronSkillet, the 6 | playlists in this directory reference sub-skillets from a submodule called 7 | [ironskillet-components](https://github.com/PaloAltoNetworks/ironskillet-components). In 8 | ironskillet-components, there is a set of panos sub-skillets and a set of panorama sub-skillets that contain the XML 9 | snippets used in IronSkillet. See the panos and panorama template pages for details on what is included in each sub-skillet. 10 | 11 | 12 | Several playlists were created for panos and panorama using the sub-skillets from ironskillet-componenets, which allows 13 | for flexibility in choosing which XML snippets are pushed in a configuration. The playlist model allows for both the full 14 | IronSkillet configuration and more targeted configurations around security policies and device hardening to be created 15 | and updated from the same set of snippets. Each playlist is listed below, along with a short description. 16 | 17 | 18 | **Overview of the panos Playlists** 19 | * `panos_full_skillet`: Traditional full IronSkillet playlist for panos 20 | * `panos_device_hardening`: Contains only device hardening sub-skillets 21 | * subset of the panos_shared_full playlist 22 | * `panos_security_profiles`: Contains only the security profile sub-skillets 23 | * subset of the panos_shared_full playlist 24 | * `panos_alert_only`: Contains only the alert only security profiles from the sub-skillets 25 | * subset of the panos_shared_full playlist 26 | 27 | **Overview of the panorama Playlists** 28 | * `panorama_shared_full`: Traditional full IronSkillet playlist for panorama using shared device-group and template configurations 29 | * used in loadable and full configs 30 | * `panorama_shared_dgtemplate`: Contains only device group and template sub-skillets 31 | * subset of the panorama_shared_full playlist 32 | * used to add shared device-group and baseline template content without Panorama system elements 33 | * `panorama_notshared_full`: Traditional full IronSkillet playlist for panorama with nothing shared 34 | * includes the device-group and stack containing all configuration elements 35 | * `panorama_notshared_dgstack`: Contains only device group and template stack sub-skillets 36 | * subset of the panorama_notshared_full playlist 37 | * used to add additional device-groups and stack, each with full configuration elements 38 | * `panorama_device_hardening`: Contains only device hardening sub-skillets 39 | * subset of the panorama_shared_full playlist 40 | * `panorama_shared_security_profiles`: Contains only the security profile sub-skillets 41 | * subset of the panorama_shared_full playlist 42 | 43 | Users are welcome to create their own playlists to mix and match elements that are not specified above. The 44 | [panos template](https://iron-skillet.readthedocs.io/en/docs_master/panos_template_guide.html) 45 | and [panorama template](https://iron-skillet.readthedocs.io/en/docs_master/panorama_template_guide.html) pages 46 | have an overview of all the sub-skillets available in ironskillet-components to include in a playlist. 47 | 48 | Also, see the [Playlist Includes Tutorial](https://skilletbuilder.readthedocs.io/en/latest/tutorials/tutorial_includes.html) 49 | from SkilletBuilder for more information on playlists, includes, submodules, and how they all work together. The 50 | tutorial shows how to use the playlist model to build configurations for IronSkillet. 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /playlists/panorama/panorama_device_hardening.skillet.yaml: -------------------------------------------------------------------------------- 1 | name: ironskillet_panorama_device_hardening_10_1 2 | label: Panorama Device Hardening IronSkillet 10.1 3 | description: |- 4 | device hardening snippets for ironskillet 10.1 panorama shared configuration 5 | type: panorama 6 | labels: 7 | collection: 8 | - IronSkillet Playlists 9 | 10 | variables: 11 | 12 | 13 | snippets: 14 | # panorama settings 15 | - name: panorama_system_10_1 16 | include: panorama_system_10_1 17 | - name: panorama_setting_10_1 18 | include: panorama_setting_10_1 19 | - name: panorama_mgt_config_pwd_10_1 20 | include: panorama_mgt_config_pwd_10_1 21 | - name: panorama_zone_protection_profile_10_1 22 | include: panorama_zone_protection_profile_10_1 23 | # tag object 24 | - name: panorama_tag_10_1 25 | include: panorama_tag_10_1 26 | include_snippets: 27 | - name: ironskillet_tag_ironskillet_version 28 | # template 29 | - name: panorama_template_10_1 30 | include: panorama_template_10_1 31 | # device settings 32 | - name: panorama_device_system_shared_10_1 33 | include: panorama_device_system_shared_10_1 34 | - name: panorama_device_setting_10_1 35 | include: panorama_device_setting_10_1 36 | - name: panorama_device_mgt_config_10_1 37 | include: panorama_device_mgt_config_10_1 38 | include_snippets: 39 | - name: ironskillet_device_mgt_password_complexity 40 | # template stack 41 | - name: panorama_template_stack_10_1 42 | include: panorama_template_stack_10_1 43 | # device settings pt 2 44 | - name: panorama_device_group_10_1 45 | include: panorama_device_group_10_1 -------------------------------------------------------------------------------- /playlists/panorama/panorama_notshared_dgstack.skillet.yaml: -------------------------------------------------------------------------------- 1 | name: ironskillet_panorama_notshared_dgstack_all_10_1 2 | label: Panorama Notshared DGStack IronSkillet 10.1 3 | description: |- 4 | group of snippets for ironskillet 10.1 panorama notshared dgtemplate configuration 5 | type: panorama 6 | labels: 7 | collection: 8 | - IronSkillet Playlists 9 | 10 | variables: 11 | 12 | - name: STACK 13 | description: Template stack name for Panorama 14 | default: sample_stack 15 | type_hint: text 16 | help_text: creates a sample template stack with IronSkillet configuration elements 17 | - name: DEVICE_GROUP 18 | description: Device-group name for Panorama 19 | default: sample_devicegroup 20 | type_hint: text 21 | help_text: creates a sample device-group with IronSkillet configuration elements 22 | 23 | snippets: 24 | 25 | # template 26 | - name: panorama_template_10_1 27 | include: panorama_template_10_1 28 | - name: panorama_template_stack_10_1 29 | include: panorama_template_stack_10_1 30 | # log settings 31 | - name: panorama_log_settings_10_1 32 | include: panorama_log_settings_10_1 33 | # device settings 34 | - name: panorama_device_system_local_10_1 35 | include: panorama_device_system_local_10_1 36 | - name: panorama_device_system_shared_10_1 37 | include: panorama_device_system_shared_10_1 38 | include_variables: all 39 | include_snippets: 40 | - name: ironskillet_device_system_dynamic_updates 41 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system 42 | - name: ironskillet_device_system_snmp 43 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system 44 | - name: ironskillet_device_system_dns 45 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system 46 | - name: ironskillet_device_system_ntp 47 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system 48 | - name: ironskillet_device_system_login_banner 49 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system 50 | - name: ironskillet_device_system_timezone 51 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system 52 | - name: panorama_device_setting_10_1 53 | include: panorama_device_setting_10_1 54 | include_variables: all 55 | include_snippets: 56 | - name: ironskillet_device_setting_ctd 57 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 58 | - name: ironskillet_device_setting_high_dp_load 59 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 60 | - name: ironskillet_device_setting_max_csv 61 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 62 | - name: ironskillet_device_setting_api_key_lifetime 63 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 64 | - name: ironskillet_device_setting_admin_lockout 65 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 66 | - name: ironskillet_device_setting_idle_timeout 67 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 68 | - name: ironskillet_device_setting_commit_lock 69 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 70 | - name: ironskillet_device_setting_wildfire 71 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 72 | - name: ironskillet_device_setting_config 73 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 74 | - name: ironskillet_device_setting_application 75 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 76 | - name: ironskillet_device_setting_logging 77 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 78 | - name: ironskillet_device_setting_tcp 79 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 80 | - name: ironskillet_device_setting_packet_buffer 81 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 82 | - name: panorama_device_mgt_config_10_1 83 | include: panorama_device_mgt_config_10_1 84 | include_variables: all 85 | include_snippets: 86 | - name: ironskillet_device_mgt_users 87 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/mgt-config 88 | - name: ironskillet_device_mgt_password_complexity 89 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/mgt-config 90 | # shared log settings 91 | - name: panorama_shared_log_settings_10_1 92 | include: panorama_shared_log_settings_10_1 93 | include_variables: all 94 | include_snippets: 95 | - name: ironskillet_shared_log_settings_email_profile 96 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 97 | - name: ironskillet_shared_log_settings_syslog_profile 98 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 99 | - name: ironskillet_shared_log_settings_syslog_forwarding 100 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 101 | - name: ironskillet_shared_log_settings_log_forwarding 102 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 103 | - name: ironskillet_shared_log_settings_userid_forwarding 104 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 105 | - name: ironskillet_shared_log_settings_hip_forwarding 106 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 107 | - name: ironskillet_shared_log_settings_correlation_forwarding 108 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 109 | - name: ironskillet_shared_log_settings_gp_forwarding 110 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 111 | - name: ironskillet_shared_log_settings_ip_tag_forwarding 112 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 113 | # zone protection 114 | - name: panorama_zone_protection_profile_10_1 115 | include: panorama_zone_protection_profile_10_1 116 | include_snippets: 117 | - name: ironskillet_zone_protection 118 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/network/profiles/zone-protection-profile 119 | # device group 120 | - name: panorama_device_group_10_1 121 | include: panorama_device_group_10_1 122 | # tag 123 | - name: panorama_tag_10_1 124 | include: panorama_tag_10_1 125 | include_snippets: 126 | - name: ironskillet_tag_outbound 127 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/tag 128 | - name: ironskillet_tag_inbound 129 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/tag 130 | - name: ironskillet_tag_internal 131 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/tag 132 | - name: ironskillet_tag_ironskillet_version 133 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/tag 134 | # log setting profiles 135 | - name: panorama_log_settings_profiles_10_1 136 | include: panorama_log_settings_profiles_10_1 137 | include_snippets: 138 | - name: ironskillet_log_settings_profiles 139 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/log-settings/profiles 140 | # profiles 141 | - name: panorama_profiles_custom_url_category_10_1 142 | include: panorama_profiles_custom_url_category_10_1 143 | include_snippets: 144 | - name: ironskillet_custom_url_category_block 145 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/custom-url-category 146 | - name: ironskillet_custom_url_category_allow 147 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/custom-url-category 148 | - name: ironskillet_custom_url_category_no_decrypt 149 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/custom-url-category 150 | - name: panorama_profiles_decryption_10_1 151 | include: panorama_profiles_decryption_10_1 152 | include_snippets: 153 | - name: ironskillet_decryption_profile 154 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/decryption 155 | - name: panorama_profiles_virus_10_1 156 | include: panorama_profiles_virus_10_1 157 | include_snippets: 158 | - name: ironskillet_antivirus_alert_all 159 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/virus 160 | - name: ironskillet_antivirus_outbound 161 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/virus 162 | - name: ironskillet_antivirus_inbound 163 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/virus 164 | - name: ironskillet_antivirus_internal 165 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/virus 166 | - name: ironskillet_antivirus_exception 167 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/virus 168 | - name: panorama_profiles_spyware_10_1 169 | include: panorama_profiles_spyware_10_1 170 | include_variables: all 171 | include_snippets: 172 | - name: ironskillet_spyware_outbound 173 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/spyware 174 | - name: ironskillet_spyware_inbound 175 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/spyware 176 | - name: ironskillet_spyware_internal 177 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/spyware 178 | - name: ironskillet_spyware_alert_all 179 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/spyware 180 | - name: ironskillet_spyware_exception 181 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/spyware 182 | - name: panorama_profiles_vulnerability_10_1 183 | include: panorama_profiles_vulnerability_10_1 184 | include_snippets: 185 | - name: ironskillet_vulnerability_outbound 186 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/vulnerability 187 | - name: ironskillet_vulnerability_inbound 188 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/vulnerability 189 | - name: ironskillet_vulnerability_internal 190 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/vulnerability 191 | - name: ironskillet_vulnerability_alert_all 192 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/vulnerability 193 | - name: ironskillet_vulnerability_exception 194 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/vulnerability 195 | - name: panorama_profiles_file_blocking_10_1 196 | include: panorama_profiles_file_blocking_10_1 197 | include_snippets: 198 | - name: ironskillet_file_blocking_outbound 199 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/file-blocking 200 | - name: ironskillet_file_blocking_inbound 201 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/file-blocking 202 | - name: ironskillet_file_blocking_internal 203 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/file-blocking 204 | - name: ironskillet_file_blocking_alert_all 205 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/file-blocking 206 | - name: panorama_profiles_url_filtering_10_1 207 | include: panorama_profiles_url_filtering_10_1 208 | include_snippets: 209 | - name: ironskillet_url_outbound 210 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/url-filtering 211 | - name: ironskillet_url_alert_all 212 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/url-filtering 213 | - name: ironskillet_url_exception 214 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/url-filtering 215 | - name: panorama_profiles_wildfire_analysis_10_1 216 | include: panorama_profiles_wildfire_analysis_10_1 217 | include_snippets: 218 | - name: ironskillet_wildfire_outbound 219 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/wildfire-analysis 220 | - name: ironskillet_wildfire_inbound 221 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/wildfire-analysis 222 | - name: ironskillet_wildfire_internal 223 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/wildfire-analysis 224 | - name: ironskillet_wildfire_alert_all 225 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/wildfire-analysis 226 | - name: panorama_profile_group_10_1 227 | include: panorama_profile_group_10_1 228 | include_snippets: 229 | - name: ironskillet_profile_group_outbound 230 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profile-group 231 | - name: ironskillet_profile_group_inbound 232 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profile-group 233 | - name: ironskillet_profile_group_internal 234 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profile-group 235 | - name: ironskillet_profile_group_alert_all 236 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profile-group 237 | - name: ironskillet_profile_group_default 238 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profile-group 239 | # rulebase 240 | - name: panorama_post_rulebase_default_security_rules_10_1 241 | include: panorama_post_rulebase_default_security_rules_10_1 242 | include_snippets: 243 | - name: ironskillet_post_rulebase_default_security_rules 244 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/post-rulebase/default-security-rules 245 | - name: panorama_pre_rulebase_security_10_1 246 | include: panorama_pre_rulebase_security_10_1 247 | include_variables: all 248 | include_snippets: 249 | - name: ironskillet_pre_rulebase_security 250 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/pre-rulebase 251 | - name: panorama_pre_rulebase_decryption_10_1 252 | include: panorama_pre_rulebase_decryption_10_1 253 | include_snippets: 254 | - name: ironskillet_pre_rulebase_decryption 255 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/pre-rulebase/decryption 256 | # reports and email 257 | - name: panorama_reports_simple_10_1 258 | include: panorama_reports_simple_10_1 259 | - name: panorama_report_group_simple_10_1 260 | include: panorama_report_group_simple_10_1 261 | - name: panorama_email_scheduler_simple_10_1 262 | include: panorama_email_scheduler_simple_10_1 263 | -------------------------------------------------------------------------------- /playlists/panorama/panorama_notshared_full.skillet.yaml: -------------------------------------------------------------------------------- 1 | name: ironskillet_panorama_notshared_10_1 2 | label: Panorama Notshared IronSkillet 10.1 3 | description: |- 4 | group of snippets for ironskillet 10.1 panorama notshared dgtemplate configuration 5 | type: panorama 6 | labels: 7 | collection: 8 | - IronSkillet Playlists 9 | 10 | variables: 11 | - name: config_admin_panorama 12 | description: Configure the Panorama admin user and password 13 | default: 'no' 14 | type_hint: dropdown 15 | help_text: Set to NO if the IronSkillet config is being applied to a Panorama server with an existing admin superuser 16 | dd_list: 17 | - key: 'yes' 18 | value: 'yes' 19 | - key: 'no' 20 | value: 'no' 21 | 22 | - name: config_mgmt_intf_panorama 23 | description: Configure the Panorama management interface IP settings 24 | default: 'no' 25 | type_hint: dropdown 26 | help_text: Set to NO if the IronSkillet config is being applied to a Panorama server with existing management IP settings 27 | dd_list: 28 | - key: 'yes' 29 | value: 'yes' 30 | - key: 'no' 31 | value: 'no' 32 | 33 | - name: STACK 34 | description: Template stack name for Panorama 35 | default: sample_stack 36 | type_hint: text 37 | help_text: creates a sample template stack with IronSkillet configuration elements 38 | - name: DEVICE_GROUP 39 | description: Device-group name for Panorama 40 | default: sample_devicegroup 41 | type_hint: text 42 | help_text: creates a sample device-group with IronSkillet configuration elements 43 | 44 | snippets: 45 | 46 | # panorama settings 47 | - name: panorama_system_mgmt_ip_10_1 48 | include: panorama_system_mgmt_ip_10_1 49 | when: config_mgmt_intf_panorama == 'yes' 50 | - name: panorama_system_10_1 51 | include: panorama_system_10_1 52 | - name: panorama_setting_10_1 53 | include: panorama_setting_10_1 54 | include_variables: all 55 | - name: panorama_mgt_config_users_10_1 56 | include: panorama_mgt_config_users_10_1 57 | when: config_admin_panorama == 'yes' 58 | - name: panorama_log_settings_10_1 59 | include: panorama_log_settings_10_1 60 | - name: panorama_mgt_config_pwd_10_1 61 | include: panorama_mgt_config_pwd_10_1 62 | # log collector/device group 63 | - name: panorama_log_collector_group_10_1 64 | include: panorama_log_collector_group_10_1 65 | - name: panorama_device_group_10_1 66 | include: panorama_device_group_10_1 67 | # template 68 | - name: panorama_template_10_1 69 | include: panorama_template_10_1 70 | - name: panorama_template_stack_10_1 71 | include: panorama_template_stack_10_1 72 | # device settings 73 | - name: panorama_device_system_local_10_1 74 | include: panorama_device_system_local_10_1 75 | - name: panorama_device_system_shared_10_1 76 | include: panorama_device_system_shared_10_1 77 | include_variables: all 78 | include_snippets: 79 | - name: ironskillet_device_system_dynamic_updates 80 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system 81 | - name: ironskillet_device_system_snmp 82 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system 83 | - name: ironskillet_device_system_dns 84 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system 85 | - name: ironskillet_device_system_ntp 86 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system 87 | - name: ironskillet_device_system_login_banner 88 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system 89 | - name: ironskillet_device_system_timezone 90 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system 91 | - name: panorama_device_setting_10_1 92 | include: panorama_device_setting_10_1 93 | include_variables: all 94 | include_snippets: 95 | - name: ironskillet_device_setting_ctd 96 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 97 | - name: ironskillet_device_setting_high_dp_load 98 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 99 | - name: ironskillet_device_setting_max_csv 100 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 101 | - name: ironskillet_device_setting_api_key_lifetime 102 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 103 | - name: ironskillet_device_setting_admin_lockout 104 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 105 | - name: ironskillet_device_setting_idle_timeout 106 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 107 | - name: ironskillet_device_setting_commit_lock 108 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 109 | - name: ironskillet_device_setting_wildfire 110 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 111 | - name: ironskillet_device_setting_config 112 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 113 | - name: ironskillet_device_setting_application 114 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 115 | - name: ironskillet_device_setting_logging 116 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 117 | - name: ironskillet_device_setting_tcp 118 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 119 | - name: ironskillet_device_setting_packet_buffer 120 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/deviceconfig/setting 121 | - name: panorama_device_mgt_config_10_1 122 | include: panorama_device_mgt_config_10_1 123 | include_variables: all 124 | include_snippets: 125 | - name: ironskillet_device_mgt_users 126 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/mgt-config 127 | - name: ironskillet_device_mgt_password_complexity 128 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/mgt-config 129 | # shared log settings 130 | - name: panorama_shared_log_settings_10_1 131 | include: panorama_shared_log_settings_10_1 132 | include_variables: all 133 | include_snippets: 134 | - name: ironskillet_shared_log_settings_email_profile 135 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 136 | - name: ironskillet_shared_log_settings_syslog_profile 137 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 138 | - name: ironskillet_shared_log_settings_syslog_forwarding 139 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 140 | - name: ironskillet_shared_log_settings_log_forwarding 141 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 142 | - name: ironskillet_shared_log_settings_userid_forwarding 143 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 144 | - name: ironskillet_shared_log_settings_hip_forwarding 145 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 146 | - name: ironskillet_shared_log_settings_correlation_forwarding 147 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 148 | - name: ironskillet_shared_log_settings_gp_forwarding 149 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 150 | - name: ironskillet_shared_log_settings_ip_tag_forwarding 151 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/shared/log-settings 152 | # zone protection 153 | - name: panorama_zone_protection_profile_10_1 154 | include: panorama_zone_protection_profile_10_1 155 | include_snippets: 156 | - name: ironskillet_zone_protection 157 | xpath: /config/devices/entry[@name='localhost.localdomain']/template-stack/entry[@name='{{STACK}}']/config/devices/entry[@name='localhost.localdomain']/network/profiles/zone-protection-profile 158 | # tag 159 | - name: panorama_tag_10_1 160 | include: panorama_tag_10_1 161 | include_snippets: 162 | - name: ironskillet_tag_outbound 163 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/tag 164 | - name: ironskillet_tag_inbound 165 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/tag 166 | - name: ironskillet_tag_internal 167 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/tag 168 | - name: ironskillet_tag_ironskillet_version 169 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/tag 170 | # log setting profiles 171 | - name: panorama_log_settings_profiles_10_1 172 | include: panorama_log_settings_profiles_10_1 173 | include_snippets: 174 | - name: ironskillet_log_settings_profiles 175 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/log-settings/profiles 176 | # profiles 177 | - name: panorama_profiles_custom_url_category_10_1 178 | include: panorama_profiles_custom_url_category_10_1 179 | include_snippets: 180 | - name: ironskillet_custom_url_category_block 181 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/custom-url-category 182 | - name: ironskillet_custom_url_category_allow 183 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/custom-url-category 184 | - name: ironskillet_custom_url_category_no_decrypt 185 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/custom-url-category 186 | - name: panorama_profiles_decryption_10_1 187 | include: panorama_profiles_decryption_10_1 188 | include_snippets: 189 | - name: ironskillet_decryption_profile 190 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/decryption 191 | - name: panorama_profiles_virus_10_1 192 | include: panorama_profiles_virus_10_1 193 | include_snippets: 194 | - name: ironskillet_antivirus_alert_all 195 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/virus 196 | - name: ironskillet_antivirus_outbound 197 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/virus 198 | - name: ironskillet_antivirus_inbound 199 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/virus 200 | - name: ironskillet_antivirus_internal 201 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/virus 202 | - name: ironskillet_antivirus_exception 203 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/virus 204 | - name: panorama_profiles_spyware_10_1 205 | include: panorama_profiles_spyware_10_1 206 | include_variables: all 207 | include_snippets: 208 | - name: ironskillet_spyware_outbound 209 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/spyware 210 | - name: ironskillet_spyware_inbound 211 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/spyware 212 | - name: ironskillet_spyware_internal 213 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/spyware 214 | - name: ironskillet_spyware_alert_all 215 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/spyware 216 | - name: ironskillet_spyware_exception 217 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/spyware 218 | - name: panorama_profiles_vulnerability_10_1 219 | include: panorama_profiles_vulnerability_10_1 220 | include_snippets: 221 | - name: ironskillet_vulnerability_outbound 222 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/vulnerability 223 | - name: ironskillet_vulnerability_inbound 224 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/vulnerability 225 | - name: ironskillet_vulnerability_internal 226 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/vulnerability 227 | - name: ironskillet_vulnerability_alert_all 228 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/vulnerability 229 | - name: ironskillet_vulnerability_exception 230 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/vulnerability 231 | - name: panorama_profiles_file_blocking_10_1 232 | include: panorama_profiles_file_blocking_10_1 233 | include_snippets: 234 | - name: ironskillet_file_blocking_outbound 235 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/file-blocking 236 | - name: ironskillet_file_blocking_inbound 237 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/file-blocking 238 | - name: ironskillet_file_blocking_internal 239 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/file-blocking 240 | - name: ironskillet_file_blocking_alert_all 241 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/file-blocking 242 | - name: panorama_profiles_url_filtering_10_1 243 | include: panorama_profiles_url_filtering_10_1 244 | include_snippets: 245 | - name: ironskillet_url_outbound 246 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/url-filtering 247 | - name: ironskillet_url_alert_all 248 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/url-filtering 249 | - name: ironskillet_url_exception 250 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/url-filtering 251 | - name: panorama_profiles_wildfire_analysis_10_1 252 | include: panorama_profiles_wildfire_analysis_10_1 253 | include_snippets: 254 | - name: ironskillet_wildfire_outbound 255 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/wildfire-analysis 256 | - name: ironskillet_wildfire_inbound 257 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/wildfire-analysis 258 | - name: ironskillet_wildfire_internal 259 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/wildfire-analysis 260 | - name: ironskillet_wildfire_alert_all 261 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profiles/wildfire-analysis 262 | - name: panorama_profile_group_10_1 263 | include: panorama_profile_group_10_1 264 | include_snippets: 265 | - name: ironskillet_profile_group_outbound 266 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profile-group 267 | - name: ironskillet_profile_group_inbound 268 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profile-group 269 | - name: ironskillet_profile_group_internal 270 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profile-group 271 | - name: ironskillet_profile_group_alert_all 272 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profile-group 273 | - name: ironskillet_profile_group_default 274 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/profile-group 275 | # rulebase 276 | - name: panorama_post_rulebase_default_security_rules_10_1 277 | include: panorama_post_rulebase_default_security_rules_10_1 278 | include_snippets: 279 | - name: ironskillet_post_rulebase_default_security_rules 280 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/post-rulebase/default-security-rules 281 | - name: panorama_pre_rulebase_security_10_1 282 | include: panorama_pre_rulebase_security_10_1 283 | include_variables: all 284 | include_snippets: 285 | - name: ironskillet_pre_rulebase_security 286 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/pre-rulebase 287 | - name: panorama_pre_rulebase_decryption_10_1 288 | include: panorama_pre_rulebase_decryption_10_1 289 | include_snippets: 290 | - name: ironskillet_pre_rulebase_decryption 291 | xpath: /config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='{{DEVICE_GROUP}}']/pre-rulebase/decryption 292 | # reports and email 293 | - name: panorama_reports_simple_10_1 294 | include: panorama_reports_simple_10_1 295 | - name: panorama_report_group_simple_10_1 296 | include: panorama_report_group_simple_10_1 297 | - name: panorama_email_scheduler_simple_10_1 298 | include: panorama_email_scheduler_simple_10_1 299 | -------------------------------------------------------------------------------- /playlists/panorama/panorama_shared_dgtemplate.skillet.yaml: -------------------------------------------------------------------------------- 1 | name: ironskillet_panorama_shared_dgtemplate_10_1 2 | label: Panorama Shared DGTemplate IronSkillet 10.1 3 | description: |- 4 | group of snippets for ironskillet 10.1 panorama shared dgtemplate configuration 5 | type: panorama 6 | labels: 7 | collection: 8 | - IronSkillet Playlists 9 | 10 | variables: 11 | 12 | 13 | snippets: 14 | # template object 15 | - name: panorama_template_10_1 16 | include: panorama_template_10_1 17 | # device settings 18 | - name: panorama_device_system_shared_10_1 19 | include: panorama_device_system_shared_10_1 20 | - name: panorama_device_setting_10_1 21 | include: panorama_device_setting_10_1 22 | - name: panorama_device_mgt_config_10_1 23 | include: panorama_device_mgt_config_10_1 24 | # shared settings 25 | - name: panorama_shared_log_settings_10_1 26 | include: panorama_shared_log_settings_10_1 27 | # zones 28 | - name: panorama_zone_protection_profile_10_1 29 | include: panorama_zone_protection_profile_10_1 30 | # tag object 31 | - name: panorama_tag_10_1 32 | include: panorama_tag_10_1 33 | # log settings 34 | - name: panorama_log_settings_profiles_10_1 35 | include: panorama_log_settings_profiles_10_1 36 | # profiles 37 | - name: panorama_profiles_custom_url_category_10_1 38 | include: panorama_profiles_custom_url_category_10_1 39 | - name: panorama_profiles_decryption_10_1 40 | include: panorama_profiles_decryption_10_1 41 | - name: panorama_profiles_virus_10_1 42 | include: panorama_profiles_virus_10_1 43 | - name: panorama_profiles_spyware_10_1 44 | include: panorama_profiles_spyware_10_1 45 | - name: panorama_profiles_vulnerability_10_1 46 | include: panorama_profiles_vulnerability_10_1 47 | - name: panorama_profiles_file_blocking_10_1 48 | include: panorama_profiles_file_blocking_10_1 49 | - name: panorama_profiles_url_filtering_10_1 50 | include: panorama_profiles_url_filtering_10_1 51 | - name: panorama_profiles_wildfire_analysis_10_1 52 | include: panorama_profiles_wildfire_analysis_10_1 53 | - name: panorama_profile_group_10_1 54 | include: panorama_profile_group_10_1 55 | # rulebase 56 | - name: panorama_post_rulebase_default_security_rules_10_1 57 | include: panorama_post_rulebase_default_security_rules_10_1 58 | - name: panorama_pre_rulebase_security_10_1 59 | include: panorama_pre_rulebase_security_10_1 60 | - name: panorama_pre_rulebase_decryption_10_1 61 | include: panorama_pre_rulebase_decryption_10_1 -------------------------------------------------------------------------------- /playlists/panorama/panorama_shared_full.skillet.yaml: -------------------------------------------------------------------------------- 1 | name: ironskillet_panorama_shared_10_1 2 | label: Panorama Shared IronSkillet 10.1 3 | description: |- 4 | group of snippets for ironskillet 10.1 panorama shared configuration 5 | type: panorama 6 | labels: 7 | collection: 8 | - IronSkillet Playlists 9 | 10 | variables: 11 | - name: config_admin_panorama 12 | description: Configure the Panorama admin user and password 13 | default: 'no' 14 | type_hint: dropdown 15 | help_text: Set to NO if the IronSkillet config is being applied to a Panorama server with an existing admin superuser 16 | dd_list: 17 | - key: 'yes' 18 | value: 'yes' 19 | - key: 'no' 20 | value: 'no' 21 | 22 | - name: config_mgmt_intf_panorama 23 | description: Configure the Panorama management interface IP settings 24 | default: 'no' 25 | type_hint: dropdown 26 | help_text: Set to NO if the IronSkillet config is being applied to a Panorama server with existing management IP settings 27 | dd_list: 28 | - key: 'yes' 29 | value: 'yes' 30 | - key: 'no' 31 | value: 'no' 32 | 33 | snippets: 34 | # panorama settings 35 | - name: panorama_system_mgmt_ip_10_1 36 | include: panorama_system_mgmt_ip_10_1 37 | when: config_mgmt_intf_panorama == 'yes' 38 | - name: panorama_system_10_1 39 | include: panorama_system_10_1 40 | - name: panorama_setting_10_1 41 | include: panorama_setting_10_1 42 | - name: panorama_mgt_config_users_10_1 43 | include: panorama_mgt_config_users_10_1 44 | when: config_admin_panorama == 'yes' 45 | - name: panorama_mgt_config_pwd_10_1 46 | include: panorama_mgt_config_pwd_10_1 47 | - name: panorama_log_settings_10_1 48 | include: panorama_log_settings_10_1 49 | # log collector group 50 | - name: panorama_log_collector_group_10_1 51 | include: panorama_log_collector_group_10_1 52 | # tag object 53 | - name: panorama_tag_10_1 54 | include: panorama_tag_10_1 55 | # template 56 | - name: panorama_template_10_1 57 | include: panorama_template_10_1 58 | # device settings 59 | - name: panorama_device_system_shared_10_1 60 | include: panorama_device_system_shared_10_1 61 | - name: panorama_device_setting_10_1 62 | include: panorama_device_setting_10_1 63 | - name: panorama_device_mgt_config_10_1 64 | include: panorama_device_mgt_config_10_1 65 | # log settings 66 | - name: panorama_shared_log_settings_10_1 67 | include: panorama_shared_log_settings_10_1 68 | - name: panorama_zone_protection_profile_10_1 69 | include: panorama_zone_protection_profile_10_1 70 | - name: panorama_log_settings_profiles_10_1 71 | include: panorama_log_settings_profiles_10_1 72 | # profiles 73 | - name: panorama_profiles_custom_url_category_10_1 74 | include: panorama_profiles_custom_url_category_10_1 75 | - name: panorama_profiles_decryption_10_1 76 | include: panorama_profiles_decryption_10_1 77 | - name: panorama_profiles_virus_10_1 78 | include: panorama_profiles_virus_10_1 79 | - name: panorama_profiles_spyware_10_1 80 | include: panorama_profiles_spyware_10_1 81 | - name: panorama_profiles_vulnerability_10_1 82 | include: panorama_profiles_vulnerability_10_1 83 | - name: panorama_profiles_file_blocking_10_1 84 | include: panorama_profiles_file_blocking_10_1 85 | - name: panorama_profiles_url_filtering_10_1 86 | include: panorama_profiles_url_filtering_10_1 87 | - name: panorama_profiles_wildfire_analysis_10_1 88 | include: panorama_profiles_wildfire_analysis_10_1 89 | - name: panorama_profile_group_10_1 90 | include: panorama_profile_group_10_1 91 | # rulebase 92 | - name: panorama_post_rulebase_default_security_rules_10_1 93 | include: panorama_post_rulebase_default_security_rules_10_1 94 | - name: panorama_pre_rulebase_security_10_1 95 | include: panorama_pre_rulebase_security_10_1 96 | - name: panorama_pre_rulebase_decryption_10_1 97 | include: panorama_pre_rulebase_decryption_10_1 98 | # template stack 99 | - name: panorama_template_stack_10_1 100 | include: panorama_template_stack_10_1 101 | # device settings pt 2 102 | - name: panorama_device_system_local_10_1 103 | include: panorama_device_system_local_10_1 104 | - name: panorama_device_group_10_1 105 | include: panorama_device_group_10_1 106 | # reports and email 107 | - name: panorama_reports_simple_10_1 108 | include: panorama_reports_simple_10_1 109 | - name: panorama_report_group_simple_10_1 110 | include: panorama_report_group_simple_10_1 111 | - name: panorama_email_scheduler_simple_10_1 112 | include: panorama_email_scheduler_simple_10_1 -------------------------------------------------------------------------------- /playlists/panorama/panorama_shared_security_profiles.skillet.yaml: -------------------------------------------------------------------------------- 1 | name: ironskillet_panorama_shared_security_profiles_10_1 2 | label: Panorama Shared Security Profiles IronSkillet 10.1 3 | description: |- 4 | security profiles for ironskillet 10.1 panorama shared configuration 5 | type: panorama 6 | labels: 7 | collection: 8 | - IronSkillet Playlists 9 | 10 | variables: 11 | 12 | 13 | snippets: 14 | 15 | # tag object 16 | - name: panorama_tag_10_1 17 | include: panorama_tag_10_1 18 | include_snippets: 19 | - name: ironskillet_tag_ironskillet_version 20 | # template 21 | - name: panorama_template_10_1 22 | include: panorama_template_10_1 23 | # profiles 24 | - name: panorama_profiles_custom_url_category_10_1 25 | include: panorama_profiles_custom_url_category_10_1 26 | - name: panorama_profiles_decryption_10_1 27 | include: panorama_profiles_decryption_10_1 28 | - name: panorama_profiles_virus_10_1 29 | include: panorama_profiles_virus_10_1 30 | - name: panorama_profiles_spyware_10_1 31 | include: panorama_profiles_spyware_10_1 32 | - name: panorama_profiles_vulnerability_10_1 33 | include: panorama_profiles_vulnerability_10_1 34 | - name: panorama_profiles_file_blocking_10_1 35 | include: panorama_profiles_file_blocking_10_1 36 | - name: panorama_profiles_url_filtering_10_1 37 | include: panorama_profiles_url_filtering_10_1 38 | - name: panorama_profiles_wildfire_analysis_10_1 39 | include: panorama_profiles_wildfire_analysis_10_1 40 | - name: panorama_profile_group_10_1 41 | include: panorama_profile_group_10_1 42 | # template stack 43 | - name: panorama_template_stack_10_1 44 | include: panorama_template_stack_10_1 45 | # device settings pt 2 46 | - name: panorama_device_group_10_1 47 | include: panorama_device_group_10_1 -------------------------------------------------------------------------------- /playlists/panos/panos_alert_only.skillet.yaml: -------------------------------------------------------------------------------- 1 | name: ironskillet_panos_alert_only_10_1 2 | label: PAN-OS NGFW Alert Only Profiles IronSkillet 10.1 3 | description: |- 4 | alert only profiles for ironskillet 10.1 panos configuration 5 | type: panos 6 | labels: 7 | collection: 8 | - IronSkillet Playlists 9 | 10 | variables: 11 | 12 | 13 | snippets: 14 | 15 | # tag object 16 | - name: panos_ngfw_tag_10_1 17 | include: panos_ngfw_tag_10_1 18 | include_snippets: 19 | - name: ironskillet_tag_ironskillet_version 20 | # security profiles and profile groups 21 | - name: panos_ngfw_profile_custom_urlFiltering_10_1 22 | include: panos_ngfw_profile_custom_urlFiltering_10_1 23 | include_snippets: 24 | - name: ironskillet_custom_url_category_allow 25 | - name: panos_ngfw_profile_decryption_10_1 26 | include: panos_ngfw_profile_decryption_10_1 27 | - name: panos_ngfw_profile_antivirus_10_1 28 | include: panos_ngfw_profile_antivirus_10_1 29 | include_snippets: 30 | - name: ironskillet_antivirus_alert_all 31 | - name: panos_ngfw_profile_spyware_10_1 32 | include: panos_ngfw_profile_spyware_10_1 33 | include_variables: all 34 | include_snippets: 35 | - name: ironskillet_spyware_alert_all 36 | - name: panos_ngfw_profile_vulnerability_10_1 37 | include: panos_ngfw_profile_vulnerability_10_1 38 | include_snippets: 39 | - name: ironskillet_vulnerability_alert_all 40 | - name: panos_ngfw_profile_file-blocking_10_1 41 | include: panos_ngfw_profile_file-blocking_10_1 42 | include_snippets: 43 | - name: ironskillet_file_blocking_alert_all 44 | - name: panos_ngfw_profile_urlFiltering_10_1 45 | include: panos_ngfw_profile_urlFiltering_10_1 46 | include_snippets: 47 | - name: ironskillet_url_alert_all 48 | - name: panos_ngfw_profile_wildfire_analysis_10_1 49 | include: panos_ngfw_profile_wildfire_analysis_10_1 50 | include_snippets: 51 | - name: ironskillet_wildfire_alert_all 52 | - name: panos_ngfw_profile_group_10_1 53 | include: panos_ngfw_profile_group_10_1 54 | include_snippets: 55 | - name: ironskillet_profile_group_alert_all 56 | -------------------------------------------------------------------------------- /playlists/panos/panos_device_hardening.skillet.yaml: -------------------------------------------------------------------------------- 1 | name: ironskillet_panos_device_hardening_10_1 2 | label: PAN-OS NGFW Device Hardening IronSkillet 10.1 3 | description: |- 4 | device hardening for ironskillet 10.1 panos configuration 5 | type: panos 6 | labels: 7 | collection: 8 | - IronSkillet Playlists 9 | 10 | variables: 11 | 12 | 13 | snippets: 14 | 15 | # general device system and setting configs 16 | - name: panos_ngfw_device_system_10_1 17 | include: panos_ngfw_device_system_10_1 18 | - name: panos_ngfw_device_setting_10_1 19 | include: panos_ngfw_device_setting_10_1 20 | - name: panos_ngfw_password_complexity_10_1 21 | include: panos_ngfw_password_complexity_10_1 22 | # zone protection 23 | - name: panos_ngfw_zone_protection_10_1 24 | include: panos_ngfw_zone_protection_10_1 25 | # tag object 26 | - name: panos_ngfw_tag_10_1 27 | include: panos_ngfw_tag_10_1 28 | include_snippets: 29 | - name: ironskillet_tag_ironskillet_version -------------------------------------------------------------------------------- /playlists/panos/panos_full.skillet.yaml: -------------------------------------------------------------------------------- 1 | name: ironskillet_panos_10_1 2 | label: PAN-OS NGFW IronSkillet 10.1 3 | description: |- 4 | group of snippets for ironskillet 10.1 panos configuration 5 | type: panos 6 | labels: 7 | collection: 8 | - IronSkillet Playlists 9 | 10 | variables: 11 | # Need to add "Do we want includes variables" 12 | # Need to add the associated "when's" in the snippets sections 13 | - name: config_mgmt_intf 14 | description: Configure the management interface IP settings 15 | default: 'no' 16 | type_hint: dropdown 17 | help_text: Set to NO if the IronSkillet config is being applied to a device with existing management IP settings 18 | dd_list: 19 | - key: 'yes' 20 | value: 'yes' 21 | - key: 'no' 22 | value: 'no' 23 | 24 | - name: config_admin_user 25 | description: Configure the admin user and password 26 | default: 'no' 27 | type_hint: dropdown 28 | help_text: Set to NO if the IronSkillet config is being applied to a device with an existing admin superuser 29 | dd_list: 30 | - key: 'yes' 31 | value: 'yes' 32 | - key: 'no' 33 | value: 'no' 34 | 35 | - name: config_dns 36 | description: Configure the DNS primary and secondary servers 37 | default: 'no' 38 | type_hint: dropdown 39 | help_text: Set to NO if the IronSkillet config is being applied to a device with an existing DNS configuration 40 | dd_list: 41 | - key: 'yes' 42 | value: 'yes' 43 | - key: 'no' 44 | value: 'no' 45 | 46 | 47 | snippets: 48 | 49 | # IronSkillet baseline 50 | # general device system and setting configs 51 | - name: panos_ngfw_device_system_mgmt_ip_10_1 52 | include: panos_ngfw_device_system_mgmt_ip_10_1 53 | when: config_mgmt_intf == 'yes' 54 | - name: panos_ngfw_device_system_dns_10_1 55 | include: panos_ngfw_device_system_dns_10_1 56 | when: config_dns == 'yes' 57 | - name: panos_ngfw_device_system_10_1 58 | include: panos_ngfw_device_system_10_1 59 | - name: panos_ngfw_device_setting_10_1 60 | include: panos_ngfw_device_setting_10_1 61 | - name: panos_ngfw_mgt_config_users_10_1 62 | include: panos_ngfw_mgt_config_users_10_1 63 | when: config_admin_user == 'yes' 64 | - name: panos_ngfw_password_complexity_10_1 65 | include: panos_ngfw_password_complexity_10_1 66 | # shared log settings and profile 67 | - name: panos_ngfw_shared_log_settings_10_1 68 | include: panos_ngfw_shared_log_settings_10_1 69 | # tag object 70 | - name: panos_ngfw_tag_10_1 71 | include: panos_ngfw_tag_10_1 72 | # log settings 73 | - name: panos_ngfw_log_settings_profiles_10_1 74 | include: panos_ngfw_log_settings_profiles_10_1 75 | # security profiles and profile groups 76 | - name: panos_ngfw_profile_custom_urlFiltering_10_1 77 | include: panos_ngfw_profile_custom_urlFiltering_10_1 78 | - name: panos_ngfw_profile_decryption_10_1 79 | include: panos_ngfw_profile_decryption_10_1 80 | - name: panos_ngfw_profile_antivirus_10_1 81 | include: panos_ngfw_profile_antivirus_10_1 82 | - name: panos_ngfw_profile_spyware_10_1 83 | include: panos_ngfw_profile_spyware_10_1 84 | - name: panos_ngfw_profile_vulnerability_10_1 85 | include: panos_ngfw_profile_vulnerability_10_1 86 | - name: panos_ngfw_profile_file-blocking_10_1 87 | include: panos_ngfw_profile_file-blocking_10_1 88 | - name: panos_ngfw_profile_urlFiltering_10_1 89 | include: panos_ngfw_profile_urlFiltering_10_1 90 | - name: panos_ngfw_profile_wildfire_analysis_10_1 91 | include: panos_ngfw_profile_wildfire_analysis_10_1 92 | - name: panos_ngfw_profile_group_10_1 93 | include: panos_ngfw_profile_group_10_1 94 | # rulebase 95 | - name: panos_ngfw_rulebase_default_security_rules_10_1 96 | include: panos_ngfw_rulebase_default_security_rules_10_1 97 | - name: panos_ngfw_rulebase_security_10_1 98 | include: panos_ngfw_rulebase_security_10_1 99 | - name: panos_ngfw_rulebase_decryption_10_1 100 | include: panos_ngfw_rulebase_decryption_10_1 101 | - name: panos_ngfw_zone_protection_10_1 102 | include: panos_ngfw_zone_protection_10_1 103 | # reports and email 104 | - name: panos_ngfw_reports_simple_10_1 105 | include: panos_ngfw_reports_simple_10_1 106 | - name: panos_ngfw_report_group_simple_10_1 107 | include: panos_ngfw_report_group_simple_10_1 108 | - name: panos_ngfw_email_scheduler_10_1 109 | include: panos_ngfw_email_scheduler_10_1 110 | -------------------------------------------------------------------------------- /playlists/panos/panos_security_profiles.skillet.yaml: -------------------------------------------------------------------------------- 1 | name: ironskillet_panos_security_profiles_10_1 2 | label: PAN-OS NGFW Security Profiles IronSkillet 10.1 3 | description: |- 4 | security profiles for ironskillet 10.1 panos configuration 5 | type: panos 6 | labels: 7 | collection: 8 | - IronSkillet Playlists 9 | 10 | variables: 11 | 12 | 13 | snippets: 14 | 15 | # tag object 16 | - name: panos_ngfw_tag_10_1 17 | include: panos_ngfw_tag_10_1 18 | include_snippets: 19 | - name: ironskillet_tag_ironskillet_version 20 | # security profiles and profile groups 21 | - name: panos_ngfw_profile_custom_urlFiltering_10_1 22 | include: panos_ngfw_profile_custom_urlFiltering_10_1 23 | - name: panos_ngfw_profile_decryption_10_1 24 | include: panos_ngfw_profile_decryption_10_1 25 | - name: panos_ngfw_profile_antivirus_10_1 26 | include: panos_ngfw_profile_antivirus_10_1 27 | - name: panos_ngfw_profile_spyware_10_1 28 | include: panos_ngfw_profile_spyware_10_1 29 | - name: panos_ngfw_profile_vulnerability_10_1 30 | include: panos_ngfw_profile_vulnerability_10_1 31 | - name: panos_ngfw_profile_file-blocking_10_1 32 | include: panos_ngfw_profile_file-blocking_10_1 33 | - name: panos_ngfw_profile_urlFiltering_10_1 34 | include: panos_ngfw_profile_urlFiltering_10_1 35 | - name: panos_ngfw_profile_wildfire_analysis_10_1 36 | include: panos_ngfw_profile_wildfire_analysis_10_1 37 | - name: panos_ngfw_profile_group_10_1 38 | include: panos_ngfw_profile_group_10_1 -------------------------------------------------------------------------------- /templates/README.md: -------------------------------------------------------------------------------- 1 | # Iron-Skillet Templates 2 | 3 | The templates directory houses the jinja-based templates for xml and set 4 | configurations. These are not loadable configurations and require use 5 | of scripting tools or other applications for rendering. 6 | 7 | Also contained are the set commands spreadsheets that use Excel formulas, 8 | allowing users to add in custom values specific to their deployment. 9 | 10 | A complete list of template variables, along with descriptions, can be found 11 | [here](https://iron-skillet.readthedocs.io/en/docs_master/creating_loadable_configs.html#variables-list-and-descriptions) 12 | 13 | 14 | ## Excel set command spreadsheets 15 | The directories `templates/panorama/set_commands` and `templates/panos/set_commands` 16 | each contain an Excel file with two worksheets: 17 | 18 | * values: the list of variables and editable values 19 | * set commands: formula-base set commands for value substitution 20 | 21 | Users can edit the values worksheet based on their local needs. Set commands 22 | can then be pasted to the configuration via CLI. 23 | 24 | ## Text-based set command files 25 | The directories `templates/panorama/set_commands` and `templates/panos/set_commands` 26 | also contain .conf files. These are jinja-based text files that require variable 27 | value substitution. 28 | 29 | **NOTE:** Jinja uses the format `{{ variable name }}` to place variables into 30 | the configuration. Searching for `{{` makes it easy to find the variables 31 | in the file. 32 | 33 | The `create_loadable_configs.py` utility in `tools` is designed to read in 34 | the `config_variables.yaml` file for the substitution. 35 | 36 | For users that elect to do simple substitutions without python utilities, 37 | they can use text-based 'find-and-replace' for each variable value. Searches 38 | for variables can be specific by variable name or a generic search for `{{` 39 | can be used. 40 | 41 | The set_command directory also contains a .meta-cnc.yaml file detailing the 42 | list of variables contained in the .conf file. This is used by external tools 43 | (link???) for application-based value substitution. 44 | 45 | ## XML snippet files and metadata 46 | The `snippets` directories found in `templates/panos` and `templates/panorama` 47 | house sets of xml config files. These are subsets of a main configuration 48 | specific to functional areas of the configuration such as security profiles, 49 | device system configuration, logging, etc. 50 | 51 | Designed primarily for API usage, the snippets are paired with a `.meta-cnc.yaml` 52 | file that includes all variable names/defaults and an ordered list of file names 53 | and their respective xpaths. 54 | 55 | These snippets are also used by `tools/create_loadable_configs.py` to 56 | substitute variable values and output full xml configurations into the 57 | `loadable_configs` directory. 58 | 59 | ## Types of Panorama templates 60 | Panorama has a multi-device management platform has various options for loading 61 | configurations, namely shared and device-specific configurations. This results 62 | in multiple template snippet types: 63 | 64 | * `snippets`: A full Panorama configuration using shared device-group 65 | and template configurations 66 | 67 | * `snippets_dgstack_shared`: used to add additional device-groups 68 | and stacks based on the shared model 69 | 70 | * `snippets_not_shared`: a full Panorama configuration with the device-group 71 | and stack containing all configuration elements. Nothing is shared. 72 | 73 | * `snippets_dgstack_notshared`: used to add additional device-groups 74 | and stack, each with full configuration elements. Nothing is shared. 75 | 76 | 77 | ## Details of template best practices 78 | The details of what's in a template are located in the documentation: 79 | 80 | [Panorama template information](https://iron-skillet.readthedocs.io/en/docs_master/panorama_template_guide.html) 81 | 82 | [PAN-OS template information](https://iron-skillet.readthedocs.io/en/docs_master/panos_template_guide.html) 83 | -------------------------------------------------------------------------------- /templates/panorama/baseline/baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /templates/panorama/full/.meta-cnc.yaml: -------------------------------------------------------------------------------- 1 | # full_panorama is a full configuration file using jinja 2 | # this is a complete Panorama and reference device-group and template stack configuration 3 | # this is based on a 'shared model' with all device-group elements in Shared 4 | # this is based on a 'shared model' with all template elements in the 'iron-skillet' template 5 | 6 | # snippet folder name 7 | name: skillet_full_panorama_v10_1 8 | # label used for menu selection 9 | label: v10.1 Iron-Skillet Full XML Configuration for Panorama (Shared Values) 10 | description: Iron-Skillet day one full XML configuration for Panorama with shared device-group and stack specific values 11 | # type of device configuration 12 | type: template 13 | extends: 14 | 15 | # grouping of like snippets for dynamic menu creation in pan-cnc 16 | labels: 17 | service_type: iron_skillet_full 18 | template_category: panorama_full 19 | collection: 20 | - IronSkillet 21 | - Configure 22 | - Best Practice 23 | 24 | # variables used in the configuration templates 25 | # type_hint defines the form field type in pan-cnc 26 | variables: 27 | - name: PANORAMA_NAME 28 | description: Panorama hostname 29 | default: panorama01 30 | type_hint: text 31 | - name: PANORAMA_TYPE 32 | description: Panorama management IP type 33 | default: static 34 | type_hint: dropdown 35 | help_text: select static unless panorama is cloud deployed and uses DHCP addressing 36 | dd_list: 37 | - key: static 38 | value: static 39 | - key: cloud dhcp 40 | value: cloud 41 | - name: PANORAMA_IP 42 | description: Panorama IP 43 | default: 192.168.55.7 44 | type_hint: ip_address 45 | toggle_hint: 46 | source: PANORAMA_TYPE 47 | value: static 48 | - name: PANORAMA_MASK 49 | description: Panorama netmask 50 | default: 255.255.255.0 51 | type_hint: ip_address 52 | toggle_hint: 53 | source: PANORAMA_TYPE 54 | value: static 55 | - name: PANORAMA_DG 56 | description: Panorama default gateway 57 | default: 192.168.55.2 58 | type_hint: ip_address 59 | toggle_hint: 60 | source: PANORAMA_TYPE 61 | value: static 62 | - name: CONFIG_EXPORT_IP 63 | description: IP address for scheduled config exports 64 | default: 192.0.2.3 65 | type_hint: text 66 | - name: STACK 67 | description: Template stack name for Panorama 68 | default: sample_stack 69 | type_hint: text 70 | help_text: creates a sample template stack with IronSkillet configuration elements 71 | - name: DEVICE_GROUP 72 | description: Device-group name for Panorama 73 | default: sample_devicegroup 74 | type_hint: text 75 | help_text: creates a sample device-group with IronSkillet configuration elements 76 | - name: FW_NAME 77 | description: Device Name for NGFW 78 | default: sample 79 | type_hint: text 80 | - name: MGMT_TYPE 81 | description: firewall management IP type 82 | default: dhcp-client 83 | type_hint: dropdown 84 | dd_list: 85 | - key: dhcp-client 86 | value: dhcp-client 87 | - key: static 88 | value: static 89 | - name: MGMT_IP 90 | description: NGFW management IP 91 | default: 192.0.2.6 92 | type_hint: ip_address 93 | toggle_hint: 94 | source: MGMT_TYPE 95 | value: static 96 | - name: MGMT_MASK 97 | description: NGFW management netmask 98 | type_hint: ip_address 99 | default: 255.255.255.0 100 | toggle_hint: 101 | source: MGMT_TYPE 102 | value: static 103 | - name: MGMT_DG 104 | description: NGFW management default gateway 105 | default: 192.0.2.7 106 | type_hint: ip_address 107 | toggle_hint: 108 | source: MGMT_TYPE 109 | value: static 110 | - name: NTP_1 111 | description: primary NTP server 112 | default: 0.pool.ntp.org 113 | type_hint: text 114 | - name: NTP_2 115 | description: secondary NTP server 116 | default: 1.pool.ntp.org 117 | type_hint: text 118 | - name: ADMINISTRATOR_USERNAME 119 | description: admin username 120 | default: adminuser 121 | type_hint: text 122 | - name: ADMINISTRATOR_PASSWORD 123 | description: admin password 124 | default: adminuser 125 | type_hint: password 126 | - name: DNS_1 127 | description: primary dns server 128 | default: 8.8.8.8 129 | type_hint: ip_address 130 | - name: DNS_2 131 | description: secondary dns server 132 | default: 8.8.4.4 133 | type_hint: ip_address 134 | - name: SINKHOLE_IPV4 135 | description: sinkhole FQDN IPv4 136 | default: sinkhole.paloaltonetworks.com 137 | type_hint: text 138 | help_text: FQDN value for the IPV4 sinkhole address used in the anti-spyware security profile 139 | - name: SINKHOLE_IPV6 140 | description: sinkhole address IPv6 141 | default: 2600:5200::1 142 | type_hint: ip_address 143 | help_text: IP address for the IPv6 sinkhole used in the anti-spyware security profile 144 | - name: EMAIL_PROFILE_GATEWAY 145 | description: email gateway address for critical alerts 146 | default: 192.0.2.1 147 | type_hint: text 148 | help_text: email server profile configuration under Device --> Server Profiles 149 | - name: EMAIL_PROFILE_FROM 150 | description: from address in email alerts 151 | default: sentfrom@yourdomain.com 152 | type_hint: text 153 | help_text: email server profile configuration under Device --> Server Profiles 154 | - name: EMAIL_PROFILE_TO 155 | description: to address in email alerts 156 | default: sendto@yourdomain.com 157 | type_hint: text 158 | help_text: email server profile configuration under Device --> Server Profiles 159 | - name: SYSLOG_SERVER 160 | description: syslog server ip address 161 | default: 192.0.2.2 162 | type_hint: text 163 | - name: API_KEY_LIFETIME 164 | description: lifetime for the api key in minutes 165 | default: 525600 166 | type_hint: text 167 | help_text: sets the expiration period for generated API keys 168 | # option built into the templates to ignore the panw published external dynamic lists security rules 169 | # should ONLY be excluded based on licensing limitations outside of best practices 170 | # when 'yes' (default) will include the EDL rule 171 | - name: INCLUDE_PAN_EDL 172 | description: include the predefined Palo Alto Networks external lists security rules 173 | default: 'no' 174 | type_hint: dropdown 175 | help_text: a valid threat license and content updates are required to access the panw external-lists used in the rules 176 | dd_list: 177 | - key: 'yes' 178 | value: 'yes' 179 | - key: 'no' 180 | value: 'no' 181 | 182 | snippets: 183 | - name: panorama-full 184 | file: iron_skillet_panorama_full.xml 185 | 186 | -------------------------------------------------------------------------------- /templates/panorama/set_commands/.meta-cnc.yaml: -------------------------------------------------------------------------------- 1 | # snippets_panorama_dgstack_notshared is used to load a full Panorama configuration 2 | # this is a complete Panorama and reference device-group and template stack configuration 3 | # all values are contained in the device-groups and template stacks; nothing shared 4 | 5 | # snippet name 6 | name: skillet_setcommand_panorama_v10_1 7 | # label used for menu selection 8 | label: v10.1 Iron-Skillet set commands for Panorama 9 | description: Set command configuration for Panorama 10 | # type of device configuration 11 | type: template 12 | extends: 13 | 14 | # grouping of like snippets for dynamic menu creation in pan-cnc 15 | labels: 16 | service_type: iron_skillet_set 17 | collection: 18 | - IronSkillet 19 | - Configure 20 | - Best Practice 21 | 22 | # variables used in the configuration templates 23 | # type_hint defines the form field type in pan-cnc 24 | variables: 25 | - name: PANORAMA_NAME 26 | description: Panorama hostname 27 | default: panorama01 28 | type_hint: text 29 | - name: PANORAMA_TYPE 30 | description: Panorama management IP type 31 | default: static 32 | type_hint: dropdown 33 | help_text: select static unless panorama is cloud deployed and uses DHCP addressing 34 | dd_list: 35 | - key: static 36 | value: static 37 | - key: cloud dhcp 38 | value: cloud 39 | - name: PANORAMA_IP 40 | description: Panorama IP 41 | default: 192.168.55.7 42 | type_hint: ip_address 43 | toggle_hint: 44 | source: PANORAMA_TYPE 45 | value: static 46 | - name: PANORAMA_MASK 47 | description: Panorama netmask 48 | default: 255.255.255.0 49 | type_hint: ip_address 50 | toggle_hint: 51 | source: PANORAMA_TYPE 52 | value: static 53 | - name: PANORAMA_DG 54 | description: Panorama default gateway 55 | default: 192.168.55.2 56 | type_hint: ip_address 57 | toggle_hint: 58 | source: PANORAMA_TYPE 59 | value: static 60 | - name: CONFIG_EXPORT_IP 61 | description: IP address for scheduled config exports 62 | default: 192.0.2.3 63 | type_hint: text 64 | - name: STACK 65 | description: Template stack name for Panorama 66 | default: sample_stack 67 | type_hint: text 68 | help_text: creates a sample template stack with IronSkillet configuration elements 69 | - name: DEVICE_GROUP 70 | description: Device-group name for Panorama 71 | default: sample_devicegroup 72 | type_hint: text 73 | help_text: creates a sample device-group with IronSkillet configuration elements 74 | - name: FW_NAME 75 | description: Device Name for NGFW 76 | default: sample 77 | type_hint: text 78 | - name: MGMT_TYPE 79 | description: firewall management IP type 80 | default: dhcp-client 81 | type_hint: dropdown 82 | dd_list: 83 | - key: dhcp-client 84 | value: dhcp-client 85 | - key: static 86 | value: static 87 | - name: MGMT_IP 88 | description: NGFW management IP 89 | default: 192.0.2.6 90 | type_hint: ip_address 91 | toggle_hint: 92 | source: MGMT_TYPE 93 | value: static 94 | - name: MGMT_MASK 95 | description: NGFW management netmask 96 | type_hint: ip_address 97 | default: 255.255.255.0 98 | toggle_hint: 99 | source: MGMT_TYPE 100 | value: static 101 | - name: MGMT_DG 102 | description: NGFW management default gateway 103 | default: 192.0.2.7 104 | type_hint: ip_address 105 | toggle_hint: 106 | source: MGMT_TYPE 107 | value: static 108 | - name: NTP_1 109 | description: primary NTP server 110 | default: 0.pool.ntp.org 111 | type_hint: text 112 | - name: NTP_2 113 | description: secondary NTP server 114 | default: 1.pool.ntp.org 115 | type_hint: text 116 | - name: ADMINISTRATOR_USERNAME 117 | description: admin username 118 | default: adminuser 119 | type_hint: text 120 | - name: DNS_1 121 | description: primary dns server 122 | default: 8.8.8.8 123 | type_hint: ip_address 124 | - name: DNS_2 125 | description: secondary dns server 126 | default: 8.8.4.4 127 | type_hint: ip_address 128 | - name: SINKHOLE_IPV4 129 | description: sinkhole FQDN IPv4 130 | default: sinkhole.paloaltonetworks.com 131 | type_hint: text 132 | help_text: FQDN value for the IPV4 sinkhole address used in the anti-spyware security profile 133 | - name: SINKHOLE_IPV6 134 | description: sinkhole address IPv6 135 | default: 2600:5200::1 136 | type_hint: ip_address 137 | help_text: IP address for the IPv6 sinkhole used in the anti-spyware security profile 138 | - name: EMAIL_PROFILE_GATEWAY 139 | description: email gateway address for critical alerts 140 | default: 192.0.2.1 141 | type_hint: text 142 | help_text: email server profile configuration under Device --> Server Profiles 143 | - name: EMAIL_PROFILE_FROM 144 | description: from address in email alerts 145 | default: sentfrom@yourdomain.com 146 | type_hint: text 147 | help_text: email server profile configuration under Device --> Server Profiles 148 | - name: EMAIL_PROFILE_TO 149 | description: to address in email alerts 150 | default: sendto@yourdomain.com 151 | type_hint: text 152 | help_text: email server profile configuration under Device --> Server Profiles 153 | - name: SYSLOG_SERVER 154 | description: syslog server ip address 155 | default: 192.0.2.2 156 | type_hint: text 157 | - name: API_KEY_LIFETIME 158 | description: lifetime for the api key in minutes 159 | default: 525600 160 | type_hint: text 161 | help_text: sets the expiration period for generated API keys 162 | 163 | snippets: 164 | - name: iron_skillet_panorama_full.conf 165 | file: iron_skillet_panorama_full.conf -------------------------------------------------------------------------------- /templates/panorama/set_commands/iron_skillet_panorama_full.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaloAltoNetworks/iron-skillet/98333734ab43f889507572413b63aafbcb351f5e/templates/panorama/set_commands/iron_skillet_panorama_full.xlsx -------------------------------------------------------------------------------- /templates/panorama/snippets/README.md: -------------------------------------------------------------------------------- 1 | # Migrating from legacy skillets to the next-gen model 2 | 3 | Prior versions of IronSkillet used the legacy skillet model with the . 4 | meta-cnc.yaml file plus external xml element files. The yaml file snippets 5 | included both the xpath and external snippet file name. 6 | 7 | The newer model embeds the xml elements inside the yaml file as a single file 8 | package. Functionally everything else is the same. 9 | 10 | The latest skillet model also adds the use of playlists and 'include' 11 | statements 12 | to reference skillets 13 | and snippets by name to mix and match configuration elements. As this model 14 | matures, the classic hardcoded method used in this snippet directory will be 15 | deprecated. 16 | 17 | 18 | -------------------------------------------------------------------------------- /templates/panorama/snippets_dgstack_notshared/README.md: -------------------------------------------------------------------------------- 1 | # Migrating from legacy skillets to the next-gen model 2 | 3 | Prior versions of IronSkillet used the legacy skillet model with the . 4 | meta-cnc.yaml file plus external xml element files. The yaml file snippets 5 | included both the xpath and external snippet file name. 6 | 7 | The newer model embeds the xml elements inside the yaml file as a single file 8 | package. Functionally everything else is the same. 9 | 10 | The latest skillet model also adds the use of playlists and 'include' 11 | statements 12 | to reference skillets 13 | and snippets by name to mix and match configuration elements. As this model 14 | matures, the classic hardcoded method used in this snippet directory will be 15 | deprecated. -------------------------------------------------------------------------------- /templates/panorama/snippets_dgtemplate_shared/README.md: -------------------------------------------------------------------------------- 1 | # Migrating from legacy skillets to the next-gen model 2 | 3 | Prior versions of IronSkillet used the legacy skillet model with the . 4 | meta-cnc.yaml file plus external xml element files. The yaml file snippets 5 | included both the xpath and external snippet file name. 6 | 7 | The newer model embeds the xml elements inside the yaml file as a single file 8 | package. Functionally everything else is the same. 9 | 10 | The latest skillet model also adds the use of playlists and 'include' 11 | statements 12 | to reference skillets 13 | and snippets by name to mix and match configuration elements. As this model 14 | matures, the classic hardcoded method used in this snippet directory will be 15 | deprecated. -------------------------------------------------------------------------------- /templates/panorama/snippets_notshared/README.md: -------------------------------------------------------------------------------- 1 | # Migrating from legacy skillets to the next-gen model 2 | 3 | Prior versions of IronSkillet used the legacy skillet model with the . 4 | meta-cnc.yaml file plus external xml element files. The yaml file snippets 5 | included both the xpath and external snippet file name. 6 | 7 | The newer model embeds the xml elements inside the yaml file as a single file 8 | package. Functionally everything else is the same. 9 | 10 | The latest skillet model also adds the use of playlists and 'include' 11 | statements 12 | to reference skillets 13 | and snippets by name to mix and match configuration elements. As this model 14 | matures, the classic hardcoded method used in this snippet directory will be 15 | deprecated. -------------------------------------------------------------------------------- /templates/panos/baseline/baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 3 15 | 5 16 | wait-recover 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | aes-128-cbc 26 | 3des 27 | 28 | 29 | sha1 30 | 31 | 32 | group2 33 | 34 | 35 | 8 36 | 37 | 38 | 39 | 40 | aes-128-cbc 41 | 42 | 43 | sha256 44 | 45 | 46 | group19 47 | 48 | 49 | 8 50 | 51 | 52 | 53 | 54 | aes-256-cbc 55 | 56 | 57 | sha384 58 | 59 | 60 | group20 61 | 62 | 63 | 8 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | aes-128-cbc 72 | 3des 73 | 74 | 75 | sha1 76 | 77 | 78 | group2 79 | 80 | 1 81 | 82 | 83 | 84 | 85 | 86 | aes-128-gcm 87 | 88 | 89 | none 90 | 91 | 92 | group19 93 | 94 | 1 95 | 96 | 97 | 98 | 99 | 100 | aes-256-gcm 101 | 102 | 103 | none 104 | 105 | 106 | group20 107 | 108 | 1 109 | 110 | 111 | 112 | 113 | 114 | 115 | aes-128-cbc 116 | 117 | 118 | sha1 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | real-time 130 | 131 | 132 | high 133 | 134 | 135 | high 136 | 137 | 138 | medium 139 | 140 | 141 | medium 142 | 143 | 144 | low 145 | 146 | 147 | low 148 | 149 | 150 | low 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | no 161 | 162 | 163 | 1.25 164 | 0.5 165 | 900 166 | 300 167 | 900 168 | yes 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /templates/panos/full/.meta-cnc.yaml: -------------------------------------------------------------------------------- 1 | # full_panos is used to load a full NGFW configuration 2 | 3 | # snippet folder name 4 | name: skillet_full_panos_v10_1 5 | # label used for menu selection 6 | label: v10.1 Iron-Skillet Full XML Configuration for NGFW 7 | description: Iron-Skillet day one configuration for a firewall 8 | dependency: 9 | # type of device configuration 10 | type: template 11 | extends: 12 | 13 | # grouping of like snippets for dynamic menu creation in pan-cnc 14 | labels: 15 | service_type: iron_skillet_full 16 | template_category: panos_full 17 | collection: 18 | - IronSkillet 19 | - Configure 20 | - Best Practice 21 | 22 | # variables used in the configuration templates 23 | # type_hint defines the form field type in pan-cnc 24 | variables: 25 | - name: FW_NAME 26 | description: Firewall hostname 27 | default: panos-01 28 | type_hint: text 29 | - name: MGMT_TYPE 30 | description: firewall management IP type 31 | default: dhcp-client 32 | type_hint: dropdown 33 | help_text: select if the management interface will use DHCP or static configuration 34 | dd_list: 35 | - key: dhcp-client 36 | value: dhcp-client 37 | - key: static 38 | value: static 39 | - name: MGMT_IP 40 | description: NGFW management IP 41 | default: 192.0.2.6 42 | type_hint: ip_address 43 | toggle_hint: 44 | source: MGMT_TYPE 45 | value: static 46 | - name: MGMT_MASK 47 | description: NGFW management netmask 48 | type_hint: ip_address 49 | default: 255.255.255.0 50 | toggle_hint: 51 | source: MGMT_TYPE 52 | value: static 53 | - name: MGMT_DG 54 | description: NGFW management default gateway 55 | default: 192.0.2.7 56 | type_hint: ip_address 57 | toggle_hint: 58 | source: MGMT_TYPE 59 | value: static 60 | - name: NTP_1 61 | description: primary NTP server 62 | default: 0.pool.ntp.org 63 | type_hint: text 64 | - name: NTP_2 65 | description: secondary NTP server 66 | default: 1.pool.ntp.org 67 | type_hint: text 68 | - name: ADMINISTRATOR_USERNAME 69 | description: admin username 70 | default: adminuser 71 | type_hint: text 72 | - name: ADMINISTRATOR_PASSWORD 73 | description: admin password 74 | default: adminuser 75 | type_hint: password 76 | - name: DNS_1 77 | description: primary dns server 78 | default: 8.8.8.8 79 | type_hint: ip_address 80 | - name: DNS_2 81 | description: secondary dns server 82 | default: 8.8.4.4 83 | type_hint: ip_address 84 | - name: SINKHOLE_IPV4 85 | description: sinkhole FQDN IPv4 86 | default: sinkhole.paloaltonetworks.com 87 | type_hint: text 88 | help_text: FQDN value for the IPV4 sinkhole address used in the anti-spyware security profile 89 | - name: SINKHOLE_IPV6 90 | description: sinkhole address IPv6 91 | default: 2600:5200::1 92 | type_hint: ip_address 93 | help_text: IP address for the IPv6 sinkhole used in the anti-spyware security profile 94 | - name: EMAIL_PROFILE_GATEWAY 95 | description: email gateway address for critical alerts 96 | default: 192.0.2.1 97 | type_hint: text 98 | help_text: email server profile configuration under Device --> Server Profiles 99 | - name: EMAIL_PROFILE_FROM 100 | description: from address in email alerts 101 | default: sentfrom@yourdomain.com 102 | type_hint: text 103 | help_text: email server profile configuration under Device --> Server Profiles 104 | - name: EMAIL_PROFILE_TO 105 | description: to address in email alerts 106 | default: sendto@yourdomain.com 107 | type_hint: text 108 | help_text: email server profile configuration under Device --> Server Profiles 109 | - name: SYSLOG_SERVER 110 | description: syslog server ip address 111 | default: 192.0.2.2 112 | type_hint: text 113 | - name: API_KEY_LIFETIME 114 | description: lifetime for the api key in minutes 115 | default: 525600 116 | type_hint: text 117 | help_text: sets the expiration period for generated API keys 118 | # option built into the templates to ignore the panw published external dynamic lists security rules 119 | # should ONLY be excluded based on licensing limitations outside of best practices 120 | # when 'yes' (default) will include the EDL rule 121 | - name: INCLUDE_PAN_EDL 122 | description: include the predefined Palo Alto Networks external lists security rules 123 | default: 'no' 124 | type_hint: dropdown 125 | help_text: a valid threat license and content updates are required to access the panw external-lists used in the rules 126 | dd_list: 127 | - key: 'yes' 128 | value: 'yes' 129 | - key: 'no' 130 | value: 'no' 131 | 132 | snippets: 133 | - name: panos-full 134 | file: iron_skillet_panos_full.xml -------------------------------------------------------------------------------- /templates/panos/set_commands/.meta-cnc.yaml: -------------------------------------------------------------------------------- 1 | # set_commands is used to load a full NGFW configuration 2 | 3 | # snippet folder name 4 | name: skillet_set_command_panos_v10_1 5 | # label used for menu selection 6 | label: v10.1 Iron-Skillet set commands for NGFW 7 | description: Iron-Skillet baseline configuration for a firewall 8 | dependency: 9 | # type of device configuration 10 | type: template 11 | extends: 12 | 13 | # grouping of like snippets for dynamic menu creation in pan-cnc 14 | labels: 15 | service_type: iron_skillet_set 16 | collection: 17 | - IronSkillet 18 | - Configure 19 | - Best Practice 20 | 21 | # variables used in the configuration templates 22 | # type_hint defines the form field type in pan-cnc 23 | variables: 24 | - name: FW_NAME 25 | description: Firewall hostname 26 | default: panos-01 27 | type_hint: text 28 | - name: MGMT_TYPE 29 | description: firewall management IP type 30 | default: dhcp-client 31 | type_hint: dropdown 32 | help_text: select if the management interface will use DHCP or static configuration 33 | dd_list: 34 | - key: dhcp-client 35 | value: dhcp-client 36 | - key: static 37 | value: static 38 | - name: MGMT_IP 39 | description: NGFW management IP 40 | default: 192.0.2.6 41 | type_hint: ip_address 42 | toggle_hint: 43 | source: MGMT_TYPE 44 | value: static 45 | - name: MGMT_MASK 46 | description: NGFW management netmask 47 | type_hint: ip_address 48 | default: 255.255.255.0 49 | toggle_hint: 50 | source: MGMT_TYPE 51 | value: static 52 | - name: MGMT_DG 53 | description: NGFW management default gateway 54 | default: 192.0.2.7 55 | type_hint: ip_address 56 | toggle_hint: 57 | source: MGMT_TYPE 58 | value: static 59 | - name: NTP_1 60 | description: primary NTP server 61 | default: 0.pool.ntp.org 62 | type_hint: text 63 | - name: NTP_2 64 | description: secondary NTP server 65 | default: 1.pool.ntp.org 66 | type_hint: text 67 | - name: ADMINISTRATOR_USERNAME 68 | description: admin username 69 | default: adminuser 70 | type_hint: text 71 | - name: DNS_1 72 | description: primary dns server 73 | default: 8.8.8.8 74 | type_hint: ip_address 75 | - name: DNS_2 76 | description: secondary dns server 77 | default: 8.8.4.4 78 | type_hint: ip_address 79 | - name: SINKHOLE_IPV4 80 | description: sinkhole FQDN IPv4 81 | default: sinkhole.paloaltonetworks.com 82 | type_hint: text 83 | help_text: FQDN value for the IPV4 sinkhole address used in the anti-spyware security profile 84 | - name: SINKHOLE_IPV6 85 | description: sinkhole address IPv6 86 | default: 2600:5200::1 87 | type_hint: ip_address 88 | help_text: IP address for the IPv6 sinkhole used in the anti-spyware security profile 89 | - name: EMAIL_PROFILE_GATEWAY 90 | description: email gateway address for critical alerts 91 | default: 192.0.2.1 92 | type_hint: text 93 | help_text: email server profile configuration under Device --> Server Profiles 94 | - name: EMAIL_PROFILE_FROM 95 | description: from address in email alerts 96 | default: sentfrom@yourdomain.com 97 | type_hint: text 98 | help_text: email server profile configuration under Device --> Server Profiles 99 | - name: EMAIL_PROFILE_TO 100 | description: to address in email alerts 101 | default: sendto@yourdomain.com 102 | type_hint: text 103 | help_text: email server profile configuration under Device --> Server Profiles 104 | - name: SYSLOG_SERVER 105 | description: syslog server ip address 106 | default: 192.0.2.2 107 | type_hint: text 108 | - name: API_KEY_LIFETIME 109 | description: lifetime for the api key in minutes 110 | default: 525600 111 | type_hint: text 112 | help_text: sets the expiration period for generated API keys 113 | 114 | snippets: 115 | - name: iron_skillet_panos_full.conf 116 | file: iron_skillet_panos_full.conf -------------------------------------------------------------------------------- /templates/panos/set_commands/iron_skillet_panos_full.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaloAltoNetworks/iron-skillet/98333734ab43f889507572413b63aafbcb351f5e/templates/panos/set_commands/iron_skillet_panos_full.xlsx -------------------------------------------------------------------------------- /templates/panos/snippets/README.md: -------------------------------------------------------------------------------- 1 | # Migrating from legacy skillets to the next-gen model 2 | 3 | Prior versions of IronSkillet used the legacy skillet model with the . 4 | meta-cnc.yaml file plus external xml element files. The yaml file snippets 5 | included both the xpath and external snippet file name. 6 | 7 | The newer model embeds the xml elements inside the yaml file as a single file 8 | package. Functionally everything else is the same. 9 | 10 | The latest skillet model also adds the use of playlists and 'include' 11 | statements 12 | to reference skillets 13 | and snippets by name to mix and match configuration elements. As this model 14 | matures, the classic hardcoded method used in this snippet directory will be 15 | deprecated. -------------------------------------------------------------------------------- /tools/.gitignore: -------------------------------------------------------------------------------- 1 | # python venv 2 | env/ 3 | venv/ -------------------------------------------------------------------------------- /tools/README.md: -------------------------------------------------------------------------------- 1 | # SLI Tooling 2 | Documentation showing how to install/use SLI in the CLI 3 | and run the relevant tooling commands. SLI allows for the user 4 | to run a type panos or panorama skillet against a config file 5 | without the need to communicate to a live device. 6 | 7 | **Quick overview of the SLI tooling capabilities** 8 | * `sli spreadsheet`: Read the panorama and panos template set commands .yaml 9 | file and output a formula-based Excel file. 10 | 11 | * `sli preview`: Variable substitutions for xml/set commands to create 12 | loadable output files archived in the given directory 13 | 14 | * `sli load_config`: Load a candidate config into the NGFW 15 | from an xml file 16 | 17 | * `sli load_set`: Load a candidate config from a file containing 18 | set commands 19 | 20 | * `sli rollup_skillet`: Take in a .skillet.yaml file and performs a 21 | rollup on it resulting in an output .skillet.yaml file with full 22 | XML snippets within. 23 | 24 | * `sli rollup_playlist`: takes a playlist and turns it into a 25 | standard skillet file. 26 | 27 | * `sli template`: Render an xml or set command template and save it to a file. 28 | Templates will be created named as they are named in the skillet. 29 | 30 | * `sli create_template`: Input a skillet and baseline.xml file to 31 | Output a full XML Jinja file with default variables. 32 | 33 | 34 | ## Quick Start with PanHandler 35 | PanHandler is one of the recommended tools to use as a skillet player. 36 | See the [quick start guide for panHandler](https://live.paloaltonetworks.com/t5/Skillet-Tools/Install-and-Get-Started-With-Panhandler/ta-p/307916) 37 | in Live. 38 | 39 | 40 | ## Quick Start with SLI 41 | The SLI tool can also be used to run end user and template admin tools 42 | quickly and efficiently. 43 | 44 | **SLI Setup Steps** 45 | ```bash 46 | > mkdir (choose a directory name) 47 | > cd (into directory from above) 48 | > python3 -m venv ./venv (create the venv) 49 | > source ./venv/bin/activate (activate the venv) 50 | > pip intall sli (install sli) 51 | ``` 52 | 53 | Once SLI has been installed it can be tested by running `sli` or 54 | `sli --help` to see available commands. Visit the [SLI repository](https://gitlab.com/panw-gse/as/sli) 55 | for more information. 56 | 57 | 58 | ## Using SLI to Create a SpreadSheet 59 | SLI can be used to read a yaml file and render it to load into a spreadsheet. 60 | To do this we can utilize the `sli spreadsheet` command. The command takes in 61 | a template type yaml file that creates set commands, if a yaml file is 62 | passed in that *doesn't* create set commands the `sli spreadsheet` command will error out. 63 | 64 | The expected result is an output spreadsheet containing all the variable names, default values 65 | and all loadable set commands with default variable values passed in. 66 | 67 | **SLI Spreadsheet Command** 68 | ```bash 69 | > sli spreadsheet -n {Template Skillet Name} -o {Output Directory} 70 | Example usage 71 | > sli spreadsheet -n skillet_set_command_panos_v10_1 -o /Users/bmutluoglu/Desktop/ 72 | ``` 73 | Note: Make sure you are in the correct directory to access the template 74 | skillet. 75 | 76 | The -n flag takes in the name of the set command template skillet to be used. 77 | The -o flag takes in a directory to store the output spreadsheet. 78 | 79 | 80 | ## Using SLI to Create a Loadable Config File 81 | The user can use the `sli template` command to create a loadable config file. 82 | with rendered Jinja variables. Running `sli template` allows the user to make 83 | changes and gives the user a template of what the config file would look like. 84 | this command modifies the configuration of the device but as opposed to 85 | modifying it on your device it saves the config file to your specified directory. 86 | 87 | **SLI Template Command** 88 | ```bash 89 | > sli template -n {Panos or Panorama Skillet Name} {Output Directory Ending in File Name} 90 | Example usage: 91 | > sli template -sd ../ -ad -n skillet_full_panos_v10_1 ../loadable_configs/sample-cloud-AWS/panos 92 | ``` 93 | 94 | The `-sd` flag specifies a directory to load all skillets from. The `-n` flag takes 95 | in a panos/panorama skillet. The `-ad` flag accepts all the default values for 96 | skillet variables. 97 | 98 | 99 | ## Using SLI to Load a Config into the NGFW 100 | The user can also load a config saved in an xml or txt file to the NGFW. 101 | In order to load an xml config into the NGFW the user would use the 102 | command `sli load_config`. In order to load a set command config into the 103 | NGFW the user would use the command `sli load_set`. you can run these load 104 | config commands, specify the config file, and it will load the file into 105 | the device as the candidate config. 106 | 107 | **SLI Load Commands** 108 | ```bash 109 | > sli load_config -uc {Directory Containing File} 110 | > sli load_set -uc {Directory Containing File} 111 | Example usage: 112 | > sli load_config -uc /Users/bmutluoglu/Desktop/testing.xml 113 | > sli load_set -uc /Users/bmutluoglu/Desktop/testing.txt 114 | ``` 115 | 116 | The `-uc` flag uses the NGFW information previously stored in the SLI context. 117 | You can check what is stored in your context by doing `sli show_context`. If you 118 | have no NGFW stored in your context you can run the command without the -uc flag 119 | and enter in the information manually. Be sure to give the correct 120 | path to the required xml/txt file when running this command. 121 | 122 | 123 | ## Using SLI to Rollup a Panos Skillet 124 | The user can use SLI to create a full config file from an existing file. 125 | The `sli rollup_skillet` command takes in a baseline skillet yaml file 126 | that performs a rollup on all the snippets within as is with no Jinja 127 | variable rendering and then returns out a yaml skillet file containing 128 | the full XML snippets. The output file will appear in the current 129 | working directory. 130 | 131 | 2 arguments, use the -n flag to get the playlist, specify the output file 132 | make sure it exists, take the header data from it, copy everything over 133 | and then override it. 134 | 135 | **SLI Rollup Skillet Command** 136 | ```bash 137 | > sli rollup_skillet {Input File Name} {Output File Name} 138 | Example Usage: 139 | > sli rollup_skillet skillet_full_panos_v10_1.meta-cnc.yaml out.skillet.yaml 140 | ``` 141 | 142 | The user passes in a skillet yaml filename in their current working 143 | directory into the `Input File Name` section. The user can pass in 144 | any file name they want as long as it ends with .skillet.yaml into the 145 | `Output File Name` section. 146 | 147 | 148 | ## Using SLI to Transform a Playlist to a Skillet 149 | The function sli `rollup_playlist` takes a playlist and turns it into a 150 | standard skillet file. This function gets rid of all includes statements 151 | and expands them to be in the newly generated skillet file. The variables 152 | section would capture all of the playlist variables. The snippets section 153 | would contain all of the playlist snippets swapping the includes statements 154 | with XML Xpaths and XML element information. 155 | 156 | **SLI Rollup Playlist Command** 157 | ```bash 158 | > sli rollup_playlist -n {Input Skillet Name} {Output File Name} 159 | Example Usage: 160 | > sli rollup_playlist -n skillet_full_panos_v10_1.meta-cnc.yaml out.skillet.yaml 161 | ``` 162 | 163 | 164 | ## Using SLI to Output a Full XML Jinja Template 165 | The user can use SLI to create a full XML Jinja Template configuration 166 | through use of the `sli create_template` command. Running this command 167 | with the proper inputs results in a large XML template file with all 168 | the Jinja variables unrendered. This allows the user to load this 169 | new output file as a jinja template, render it and have it be a valid 170 | XML that works for a PANW device. 171 | 172 | **SLI Create Template Command** 173 | ```bash 174 | > sli create_template -n {Input Full Skillet Name} {Baseline XML File} {Output XML File Name} 175 | Example Usage: 176 | > sli create_template -n ironskillet_panos_10_1 templates/panos/baseline/baseline.xml out.xml 177 | ``` 178 | 179 | The create template sli command takes 3 arguments. First it takes the 180 | full skillet in the `Input Full Skillet Name` section which includes 181 | many other skillets each of which reference other XML Jinja templates. 182 | It also takes the baseline XML file in the `Baseline XML File` section 183 | and the users choice of output file in the `Output XML File Name` section. 184 | 185 | 186 | ## Build_all.sh Bash Script 187 | Used by the IronSkillet administrator to generate the full config skillets, 188 | loadable configs and spreadsheets. Simply run the bash script to populate 189 | and update all templates/playlists/config directories. 190 | 191 | 192 | ## Variables used by iron-skillet 193 | For information about the variables used in iron-skillet can be found at: 194 | 195 | [iron-skillet variables](https://iron-skillet.readthedocs.io/en/docs_master/creating_loadable_configs.html#variables-list-and-descriptions) -------------------------------------------------------------------------------- /tools/archive/build_all.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018, Palo Alto Networks 2 | # 3 | # Permission to use, copy, modify, and/or distribute this software for any 4 | # purpose with or without fee is hereby granted, provided that the above 5 | # copyright notice and this permission notice appear in all copies. 6 | # 7 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | # Author: Scott Shoaf 16 | 17 | ''' 18 | Palo Alto Networks create_batch.py 19 | 20 | creates a roll-up of loadable configs in the repo for the various 21 | options: mgmt dhcp/static and public cloud flavors 22 | 23 | Edit the config_variables.yaml values and then run the script 24 | 25 | This software is provided without support, warranty, or guarantee. 26 | Use at your own risk. 27 | ''' 28 | 29 | import os 30 | import sys 31 | import oyaml 32 | 33 | from jinja2 import Environment, FileSystemLoader 34 | from passlib.hash import md5_crypt 35 | from build_full_templates import build_xpath, generate_full_config_template 36 | from create_set_spreadsheet import create_spreadsheet 37 | 38 | defined_filters = ['md5_hash'] 39 | 40 | 41 | def myconfig_newdir(myconfigdir_name): 42 | ''' 43 | create a new main loadable_configs folder if required then new subdirectories for configs 44 | :param myconfigdir_name: prefix folder name from the my_variables.py file 45 | :param foldertime: datetime when script run; to be used as suffix of folder name 46 | :return: the myconfigdir full path name 47 | ''' 48 | 49 | # get the full path to the config directory we want (panos / panorama) 50 | myconfigpath = os.path.abspath(os.path.join('..', 'loadable_configs')) 51 | if os.path.isdir(myconfigpath) is False: 52 | os.mkdir(myconfigpath, mode=0o755) 53 | print('created new loadable config directory') 54 | 55 | # check that configs folder exists and if not create a new one 56 | # then create snippets and full sub-directories 57 | myconfigdir = '{0}/{1}'.format(myconfigpath, myconfigdir_name) 58 | if os.path.isdir(myconfigdir) is False: 59 | os.mkdir(myconfigdir, mode=0o755) 60 | print('\ncreated new archive folder {0}'.format(myconfigdir_name)) 61 | 62 | if os.path.isdir('{0}/{1}'.format(myconfigdir, config_type)) is False: 63 | os.mkdir('{0}/{1}'.format(myconfigdir, config_type)) 64 | print('created new subdirectories for {0}'.format(config_type)) 65 | 66 | return myconfigdir 67 | 68 | 69 | def create_context(config_var_file): 70 | # read the metafile to get variables and values 71 | try: 72 | with open(config_var_file, 'r') as var_metadata: 73 | variables = oyaml.safe_load(var_metadata.read()) 74 | 75 | except IOError as ioe: 76 | print(f'Could not open metadata file {config_var_file}') 77 | print(ioe) 78 | sys.exit() 79 | 80 | # grab the metadata values and convert to key-based dictionary 81 | jinja_context = dict() 82 | 83 | for snippet_var in variables['variables']: 84 | jinja_context[snippet_var['name']] = snippet_var['value'] 85 | 86 | return jinja_context 87 | 88 | 89 | def yaml2dict(config_var_file): 90 | # read the metafile to get variables and values 91 | try: 92 | with open(config_var_file, 'r') as var_metadata: 93 | variables = oyaml.safe_load(var_metadata.read()) 94 | 95 | except IOError as ioe: 96 | print(f'Could not open metadata file {config_var_file}') 97 | print(ioe) 98 | sys.exit() 99 | 100 | return variables 101 | 102 | 103 | def template_render(filename, template_path, render_type, context): 104 | ''' 105 | render the jinja template using the context value from config_variables.yaml 106 | :param filename: name of the template file 107 | :param template_path: path for the template file 108 | :param render_type: type if full or set commands; aligns with folder name 109 | :param context: dict of variables to render 110 | :return: return the rendered xml file and set conf file 111 | ''' 112 | 113 | print('..creating template for {0}'.format(filename)) 114 | 115 | env = Environment(loader=FileSystemLoader('{0}/{1}'.format(template_path, render_type))) 116 | 117 | # load our custom jinja filters here, see the function defs below for reference 118 | env.filters['md5_hash'] = md5_hash 119 | 120 | template = env.get_template(filename) 121 | rendered_template = template.render(context) 122 | 123 | return rendered_template 124 | 125 | 126 | def template_save(snippet_name, myconfigdir, config_type, element): 127 | ''' 128 | after rendering the template save to the myconfig directory 129 | each run saves with a unique prefix name + datetime 130 | :param snippet_name: name of the output file 131 | :param myconfigdir: path to the my_config directory 132 | :param config_type: based on initial run list; eg. panos or panorama 133 | :param element: xml element rendered based on input variables; used as folder name 134 | :param render_type: type eg. if full or snippets; aligns with folder name 135 | :return: no value returned (future could be success code) 136 | ''' 137 | 138 | print('..saving template for {0}'.format(snippet_name)) 139 | 140 | filename = snippet_name 141 | 142 | with open('{0}/{1}/{2}'.format(myconfigdir, config_type, filename), 'w') as configfile: 143 | configfile.write(element) 144 | 145 | return 146 | 147 | 148 | # define functions for custom jinja filters 149 | def md5_hash(txt): 150 | ''' 151 | Returns the MD5 Hashed secret for use as a password hash in the PanOS configuration 152 | :param txt: text to be hashed 153 | :return: password hash of the string with salt and configuration information. Suitable to place in the phash field 154 | in the configurations 155 | ''' 156 | return md5_crypt.hash(txt) 157 | 158 | 159 | def replace_variables(config_type, render_type, input_var): 160 | ''' 161 | get the input variables and render the output configs with jinja2 162 | inputs are read from the template directory and output to my_config 163 | :param config_type: panos or panorama to read/write to the respective directories 164 | :param archivetime: datetimestamp used for the output my_config folder naming 165 | ''' 166 | 167 | config_variables = 'config_variables.yaml' 168 | 169 | # create dict of values for the jinja template render 170 | context = create_context(config_variables) 171 | 172 | # update context dict with variables from user input 173 | for snippet_var in input_var: 174 | context[snippet_var] = input_var[snippet_var] 175 | 176 | # get the full path to the output directory we want (panos / panorama) 177 | template_path = os.path.abspath(os.path.join('..', 178 | 'templates', config_type)) 179 | 180 | # append to the sys path for module lookup 181 | sys.path.append(template_path) 182 | 183 | # output subdir located in loadable_configs dir 184 | myconfig_path = myconfig_newdir(input_var['output_dir']) 185 | 186 | # render full and set conf files 187 | print('\nworking with {0} config template'.format(render_type)) 188 | if render_type == 'full': 189 | filename = 'iron_skillet_{0}_full.xml'.format(config_type) 190 | if render_type == 'set_commands': 191 | filename = 'iron_skillet_{0}_full.conf'.format(config_type) 192 | 193 | element = template_render(filename, template_path, render_type, context) 194 | template_save(filename, myconfig_path, config_type, element) 195 | 196 | print('\nconfigs have been created and can be found in {0}'.format(myconfig_path)) 197 | print('along with the metadata values used to render the configs\n') 198 | 199 | return 200 | 201 | 202 | if __name__ == '__main__': 203 | # Use the timestamp to create a unique folder name 204 | 205 | print('=' * 80) 206 | print(' ') 207 | print('Welcome to Iron-Skillet batch create loadable configs'.center(80)) 208 | print(' ') 209 | print('=' * 80) 210 | 211 | # build full config from snippets 212 | print('Building full configs...') 213 | for config_type in ['panos', 'panorama']: 214 | generate_full_config_template(config_type) 215 | 216 | # create sample loadable configs as part of core repo 217 | # uses full config template so updated after new full config build 218 | input_var = {} 219 | # get batch variables define loadable_config types and values 220 | loadable_types = yaml2dict('loadable_config_vars/batch_variables.yaml') 221 | 222 | for loadable in loadable_types['variables']: 223 | 224 | # this prompts for the prefix name of the output directory 225 | input_var['output_dir'] = loadable['name'] 226 | input_var['MGMT_TYPE'] = loadable['MGMT_TYPE'] 227 | input_var['PANORAMA_TYPE'] = loadable['PANORAMA_TYPE'] 228 | 229 | # loop through all config types that have their respective template folders 230 | for config_type in ['panos', 'panorama']: 231 | for render_type in ['full', 'set_commands']: 232 | replace_variables(config_type, render_type, input_var) 233 | 234 | # create set command spreadsheet based on set command text file 235 | for config_type in ['panos', 'panorama']: 236 | create_spreadsheet(config_type) 237 | -------------------------------------------------------------------------------- /tools/archive/build_full_templates.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018, Palo Alto Networks 2 | # 3 | # Permission to use, copy, modify, and/or distribute this software for any 4 | # purpose with or without fee is hereby granted, provided that the above 5 | # copyright notice and this permission notice appear in all copies. 6 | # 7 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | # Author: Nathan Embery 16 | 17 | ''' 18 | Palo Alto Networks Iron-Skillet build_full_templates 19 | 20 | This tool combines the iron-skillet configuration snippets into a full configuration template. 21 | This template can then be customized and applied to a new out-of-the-box PanOS NGFW or Panorama 22 | 23 | This software is provided without support, warranty, or guarantee. 24 | Use at your own risk. 25 | ''' 26 | 27 | 28 | import os 29 | import re 30 | import sys 31 | import oyaml 32 | 33 | from xml.etree import ElementTree 34 | #from lxml.etree import ElementTree 35 | 36 | 37 | def build_xpath(parent_doc, xpath, new_element_contents): 38 | """ 39 | attaches a new Element to the document at the specified xpath with the specified contents 40 | if the xpath is something like '/config/xyz/abc' then create an element 'abc' and attach it as a 41 | subelement of 'xyz'. 42 | :param parent_doc: XML document to modify 43 | :param xpath: where to attach the new element 44 | :param new_element_contents: contents of the element 45 | :return: None. parent_doc is modified in place 46 | """ 47 | 48 | # viewing the current xpath of interest 49 | print('working with this xpath:') 50 | print(xpath) 51 | # first of all, we need to fix the xpath to be relative (replace config with '.') 52 | modified_xpath = re.sub('^/config', '.', xpath) 53 | print(f'Checking xpath {modified_xpath}') 54 | # let's check if the xpath exists as is first of all 55 | # is exists later will do merge of children instead of add full element 56 | is_present = parent_doc.find(modified_xpath) 57 | 58 | # get a list of the tree elements that make up the xpath 59 | split_path = modified_xpath.split('/') 60 | # keep a list of things we'll need to manually construct 61 | path_to_build = [] 62 | orig_tail = split_path[-1] 63 | # begin infinite loop 64 | while True: 65 | # grab the last part of the xpath and start there 66 | # we will work backwards 'up' the tree until we find something that exists and build all the parts we 67 | # need back 'down' the tree 68 | tail = split_path[-1] 69 | print(f'tail is {tail}') 70 | # put the path back together minus the 'tail' (last node) 71 | parent_path = "/".join(split_path[:-1]) 72 | print(f'parent_path is {parent_path}') 73 | # does this one exist? 74 | parent_element = parent_doc.find(parent_path) 75 | print(f'parent_element is {parent_element}') 76 | # go ahead and keep this around even if it exists or not 77 | print(f'appending {tail} to path_to_build') 78 | path_to_build.append(tail) 79 | if parent_element is not None: 80 | print('found a parent element') 81 | print(parent_element) 82 | # found a node that exists so we can break out of the loop here 83 | break 84 | else: 85 | # pop tail from the path we're searching and try again 86 | split_path.pop() 87 | 88 | # we now have a path that exists and list of items we need to build 89 | # flesh out the tree if the path we need to build is larger than one, i.e. the leaf node needs to attach 90 | # to another node that doesn't yet exist, go ahead and build them all the up 91 | while len(path_to_build) > 1: 92 | p = path_to_build.pop() 93 | print('appending {} to parent_element'.format(p)) 94 | parent_element = ElementTree.SubElement(parent_element, p) 95 | 96 | # we should now have a document that has the tree fully built out to the xpath we want 97 | # wrap up the new_element_contents in the leaf node and attach it to the last known parent_element 98 | leaf_node = path_to_build[0] 99 | # use if merging into an existing xpath 100 | # instead of wrap with tail and merge will load each child of the tail node 101 | if is_present is not None: 102 | print('tail exists so merging element') 103 | # only temp wrap to create a parent and then append each child 104 | # WARNING: ensure no jinja conditionals are outside the child tags 105 | wrapped_snippet = f"<{leaf_node}>{new_element_contents}" 106 | #print(wrapped_snippet) 107 | snippet_xml = ElementTree.fromstring(wrapped_snippet) 108 | for item in snippet_xml: 109 | print(item) 110 | print('merging to parent_element') 111 | parent_element = parent_doc.find(modified_xpath) 112 | parent_element.append(item) 113 | # print it out if needed 114 | #print(ElementTree.tostring(parent_element)) 115 | else: 116 | # wrap to create new leaf element and insert 117 | wrapped_snippet = f"<{leaf_node}>{new_element_contents}" 118 | #print(wrapped_snippet) 119 | snippet_xml = ElementTree.fromstring(wrapped_snippet) 120 | print('appending to parent_element') 121 | parent_element.append(snippet_xml) 122 | # print it out if needed 123 | #print(ElementTree.tostring(parent_element)) 124 | # returning parent_doc to use as the new baseline config 125 | return(parent_doc) 126 | 127 | def generate_full_config_template(config_type): 128 | """ 129 | Generates the full configuration template for a given configuration type (panos or panorama). 130 | This will use the load order 131 | :param config_type: currently supported: 'panos' or 'panorama' 132 | :return: will print full configs to STDOUT and also overwrite the full/iron_skillet__full.xml 133 | """ 134 | # get the path to the full baseline config for this config type 135 | full_config_file_path = os.path.abspath(os.path.join('..', 'templates', config_type, 'baseline', 'baseline.xml')) 136 | output_file_path = os.path.abspath(os.path.join('..', 137 | 'templates', config_type, 'full'.format(config_type), 138 | 'iron_skillet_{0}_full.xml'.format(config_type))) 139 | metadata_file = os.path.abspath(os.path.join('..', 'templates', config_type, 'snippets'.format(config_type), '.meta-cnc.yaml')) 140 | 141 | # open the file and read it in 142 | with open(full_config_file_path, 'r') as full_config_obj: 143 | full_config_string = full_config_obj.read() 144 | 145 | # debugging 146 | # print(full_config_string) 147 | 148 | # Begin XML manipulation. Grab the full config and parse into a DOM 149 | full_config_element = ElementTree.fromstring(full_config_string) 150 | 151 | full_config = ElementTree.ElementTree(full_config_element) 152 | 153 | # get the full path to the config directory we want (panos / panorama) 154 | config_path = os.path.abspath(os.path.join('..', 'templates', config_type)) 155 | 156 | # append to the sys path for module lookup 157 | sys.path.append(config_path) 158 | 159 | # read the metafile to get xpaths and load order 160 | try: 161 | with open(metadata_file, 'r') as snippet_metadata: 162 | service_config = oyaml.safe_load(snippet_metadata.read()) 163 | 164 | except IOError as ioe: 165 | print(f'Could not open metadata file {metadata_file}') 166 | print(ioe) 167 | sys.exit() 168 | 169 | # iterate through the metadata snippets load order 170 | # parse the snippets into XML objects 171 | # attach to the current full_config dom 172 | for xml_snippet in service_config['snippets']: 173 | # xml_snippet is a set of attributes in the .meta-cnc.yaml file 174 | # that includes the xpaths and files listed in the proper load order 175 | snippet_name = xml_snippet['file'] 176 | xpath = xml_snippet['xpath'] 177 | snippet_path = os.path.join(config_path, 'snippets'.format(config_type), snippet_name) 178 | 179 | # skip snippets that aren't actually there for some reason 180 | if not os.path.exists(snippet_path): 181 | print(snippet_path) 182 | print('this snippet does not actually exist!') 183 | sys.exit() 184 | 185 | # read them in 186 | with open(snippet_path, 'r') as snippet_obj: 187 | snippet_string = snippet_obj.read() 188 | 189 | # verify this snippet has an xpath associated and if so, let's attach to the document 190 | #if xml_snippet in xpaths_configtype: 191 | 192 | # magic happens here 193 | # update the document in place to attach the snippet string in the correct place according to it's xpath 194 | updated_config = build_xpath(full_config, xpath, snippet_string) 195 | # create a new baseline full config after above element added 196 | full_config = updated_config 197 | 198 | print('=' * 80) 199 | raw_xml = str(ElementTree.tostring(full_config.getroot(), encoding='unicode')) 200 | #print(raw_xml) 201 | # open the output file for writing 202 | with open(output_file_path, 'w') as output_config_obj: 203 | output_config_obj.write(raw_xml) 204 | print('=' * 80) 205 | 206 | if __name__ == '__main__': 207 | for config_type in ['panos', 'panorama']: 208 | generate_full_config_template(config_type) 209 | -------------------------------------------------------------------------------- /tools/archive/create_loadable_configs.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018, Palo Alto Networks 2 | # 3 | # Permission to use, copy, modify, and/or distribute this software for any 4 | # purpose with or without fee is hereby granted, provided that the above 5 | # copyright notice and this permission notice appear in all copies. 6 | # 7 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | # Author: Scott Shoaf 16 | 17 | ''' 18 | Palo Alto Networks create_loadable_configs.py 19 | 20 | Provides rendering of configuration templates with user defined values 21 | Output is a set of loadable full configurations and set commands for Panos and Panorama 22 | 23 | Edit the config_variables.yaml values and then run the script 24 | 25 | This software is provided without support, warranty, or guarantee. 26 | Use at your own risk. 27 | ''' 28 | 29 | import datetime 30 | import os 31 | import shutil 32 | import sys 33 | import time 34 | import getpass 35 | import oyaml 36 | 37 | from jinja2 import Environment, FileSystemLoader 38 | from passlib.hash import des_crypt 39 | from passlib.hash import md5_crypt 40 | from passlib.hash import sha256_crypt 41 | from passlib.hash import sha512_crypt 42 | 43 | defined_filters = ['md5_hash', 'des_hash', 'sha512_hash'] 44 | 45 | 46 | def myconfig_newdir(myconfigdir_name, foldertime): 47 | ''' 48 | create a new main loadable_configs folder if required then new subdirectories for configs 49 | :param myconfigdir_name: prefix folder name from the my_variables.py file 50 | :param foldertime: datetime when script run; to be used as suffix of folder name 51 | :return: the myconfigdir full path name 52 | ''' 53 | 54 | # get the full path to the config directory we want (panos / panorama) 55 | myconfigpath = os.path.abspath(os.path.join('..', 'loadable_configs')) 56 | if os.path.isdir(myconfigpath) is False: 57 | os.mkdir(myconfigpath, mode=0o755) 58 | print('created new loadable config directory') 59 | 60 | # check that configs folder exists and if not create a new one 61 | # then create snippets and full sub-directories 62 | myconfigdir = '{0}/{1}-{2}'.format(myconfigpath, myconfigdir_name, foldertime) 63 | if os.path.isdir(myconfigdir) is False: 64 | os.mkdir(myconfigdir, mode=0o755) 65 | print('\ncreated new archive folder {0}-{1}'.format(myconfigdir_name, foldertime)) 66 | 67 | if os.path.isdir('{0}/{1}'.format(myconfigdir, config_type)) is False: 68 | os.mkdir('{0}/{1}'.format(myconfigdir, config_type)) 69 | print('created new subdirectories for {0}'.format(config_type)) 70 | 71 | return myconfigdir 72 | 73 | 74 | def create_context(config_var_file): 75 | # read the metafile to get variables and values 76 | try: 77 | with open(config_var_file, 'r') as var_metadata: 78 | variables = oyaml.safe_load(var_metadata.read()) 79 | 80 | except IOError as ioe: 81 | print(f'Could not open metadata file {config_var_file}') 82 | print(ioe) 83 | sys.exit() 84 | 85 | # grab the metadata values and convert to key-based dictionary 86 | jinja_context = dict() 87 | 88 | for snippet_var in variables['variables']: 89 | jinja_context[snippet_var['name']] = snippet_var['value'] 90 | 91 | return jinja_context 92 | 93 | 94 | def template_render(filename, template_path, render_type, context): 95 | ''' 96 | render the jinja template using the context value from config_variables.yaml 97 | :param filename: name of the template file 98 | :param template_path: path for the template file 99 | :param render_type: type if full or set commands; aligns with folder name 100 | :param context: dict of variables to render 101 | :return: return the rendered xml file and set conf file 102 | ''' 103 | 104 | print('..creating template for {0}'.format(filename)) 105 | 106 | env = Environment(loader=FileSystemLoader('{0}/{1}'.format(template_path, render_type))) 107 | 108 | # load our custom jinja filters here, see the function defs below for reference 109 | env.filters['md5_hash'] = md5_hash 110 | env.filters['des_hash'] = des_hash 111 | env.filters['sha512_hash'] = sha512_hash 112 | 113 | template = env.get_template(filename) 114 | rendered_template = template.render(context) 115 | 116 | return rendered_template 117 | 118 | 119 | def template_save(snippet_name, myconfigdir, config_type, element): 120 | ''' 121 | after rendering the template save to the myconfig directory 122 | each run saves with a unique prefix name + datetime 123 | :param snippet_name: name of the output file 124 | :param myconfigdir: path to the my_config directory 125 | :param config_type: based on initial run list; eg. panos or panorama 126 | :param element: xml element rendered based on input variables; used as folder name 127 | :param render_type: type eg. if full or snippets; aligns with folder name 128 | :return: no value returned (future could be success code) 129 | ''' 130 | 131 | print('..saving template for {0}'.format(snippet_name)) 132 | 133 | filename = snippet_name 134 | 135 | with open('{0}/{1}/{2}'.format(myconfigdir, config_type, filename), 'w') as configfile: 136 | configfile.write(element) 137 | 138 | # copy the variables file used for the render into the my_template folder 139 | var_file = 'loadable_config_vars/config_variables.yaml' 140 | if os.path.isfile('{0}/{1}'.format(myconfigdir, var_file)) is False: 141 | vfilesrc = var_file 142 | vfiledst = '{0}/{1}'.format(myconfigdir, var_file) 143 | shutil.copy(vfilesrc, vfiledst) 144 | 145 | return 146 | 147 | 148 | # define functions for custom jinja filters 149 | def md5_hash(txt): 150 | ''' 151 | Returns the MD5 Hashed secret for use as a password hash in the PanOS configuration 152 | :param txt: text to be hashed 153 | :return: password hash of the string with salt and configuration information. Suitable to place in the phash field 154 | in the configurations 155 | ''' 156 | return md5_crypt.hash(txt) 157 | 158 | 159 | def des_hash(txt): 160 | ''' 161 | Returns the DES Hashed secret for use as a password hash in the PanOS configuration 162 | :param txt: text to be hashed 163 | :return: password hash of the string with salt and configuration information. Suitable to place in the phash field 164 | in the configurations 165 | ''' 166 | return des_crypt.hash(txt) 167 | 168 | 169 | def sha256_hash(txt): 170 | ''' 171 | Returns the SHA256 Hashed secret for use as a password hash in the PanOS configuration 172 | :param txt: text to be hashed 173 | :return: password hash of the string with salt and configuration information. Suitable to place in the 174 | phash field in the configurations 175 | ''' 176 | return sha256_crypt.hash(txt) 177 | 178 | 179 | def sha512_hash(txt): 180 | ''' 181 | Returns the SHA512 Hashed secret for use as a password hash in the PanOS configuration 182 | :param txt: text to be hashed 183 | :return: password hash of the string with salt and configuration information. Suitable to place in the 184 | phash field in the configurations 185 | ''' 186 | return sha512_crypt.hash(txt) 187 | 188 | 189 | def replace_variables(config_type, render_type, input_var): 190 | ''' 191 | get the input variables and render the output configs with jinja2 192 | inputs are read from the template directory and output to my_config 193 | :param config_type: panos or panorama to read/write to the respective directories 194 | :param archivetime: datetimestamp used for the output my_config folder naming 195 | ''' 196 | 197 | config_variables = 'config_variables.yaml' 198 | 199 | # create dict of values for the jinja template render 200 | context = create_context(config_variables) 201 | 202 | # update context dict with variables from user input 203 | for snippet_var in input_var: 204 | context[snippet_var] = input_var[snippet_var] 205 | 206 | # get the full path to the output directory we want (panos / panorama) 207 | template_path = os.path.abspath(os.path.join('..', 208 | 'templates', config_type)) 209 | 210 | # append to the sys path for module lookup 211 | sys.path.append(template_path) 212 | 213 | # output subdir located in loadable_configs dir 214 | myconfig_path = myconfig_newdir(input_var['output_dir'], input_var['archive_time']) 215 | 216 | # render full and set conf files 217 | print('\nworking with {0} config template'.format(render_type)) 218 | if render_type == 'full': 219 | filename = 'iron_skillet_{0}_full.xml'.format(config_type) 220 | if render_type == 'set_commands': 221 | filename = 'iron_skillet_{0}_full.conf'.format(config_type) 222 | 223 | element = template_render(filename, template_path, render_type, context) 224 | template_save(filename, myconfig_path, config_type, element) 225 | 226 | print('\nconfigs have been created and can be found in {0}'.format(myconfig_path)) 227 | print('along with the metadata values used to render the configs\n') 228 | 229 | return 230 | 231 | 232 | if __name__ == '__main__': 233 | # Use the timestamp to create a unique folder name 234 | 235 | print('=' * 80) 236 | print(' ') 237 | print('Welcome to Iron-Skillet'.center(80)) 238 | print(' ') 239 | print('=' * 80) 240 | 241 | input_var = {} 242 | # archive_time used as part of the my_config directory name 243 | input_var['archive_time'] = datetime.datetime.fromtimestamp(time.time()).strftime('%Y%m%d_%H%M%S') 244 | print('\ndatetime used for folder creation: {0}\n'.format(input_var['archive_time'])) 245 | 246 | # this prompts for the prefix name of the output directory 247 | input_var['output_dir'] = input('Enter the name of the output directory: ') 248 | 249 | # this prompts for the superuser username to be added into the configuration; no default admin/admin used 250 | input_var['ADMINISTRATOR_USERNAME'] = input('Enter the superuser administrator account username: ') 251 | 252 | print('\na phash will be created for superuser {0} and added to the config file\n'.format( 253 | input_var['ADMINISTRATOR_USERNAME'])) 254 | passwordmatch = False 255 | 256 | # prompt for the superuser password to create a phash and store in the my_config files; no default admin/admin 257 | while passwordmatch is False: 258 | password1 = getpass.getpass("Enter the superuser administrator account password: ") 259 | password2 = getpass.getpass("Enter password again to verify: ") 260 | if password1 == password2: 261 | input_var['ADMINISTRATOR_PASSWORD'] = password1 262 | passwordmatch = True 263 | else: 264 | print('\nPasswords do not match. Please try again.\n') 265 | 266 | # loop through all config types that have their respective template folders 267 | for config_type in ['panos', 'panorama']: 268 | for render_type in ['full', 'set_commands']: 269 | replace_variables(config_type, render_type, input_var) -------------------------------------------------------------------------------- /tools/archive/create_set_spreadsheet.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018, Palo Alto Networks 2 | # 3 | # Permission to use, copy, modify, and/or distribute this software for any 4 | # purpose with or without fee is hereby granted, provided that the above 5 | # copyright notice and this permission notice appear in all copies. 6 | # 7 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | # Author: Nathan Embery 16 | 17 | ''' 18 | Palo Alto Networks Iron-Skillet create_set_spreadsheet 19 | 20 | This tool turns the set-based template file into a formula-based spreadsheet 21 | This template can then be customized and applied to a new out-of-the-box PanOS NGFW or Panorama 22 | 23 | This software is provided without support, warranty, or guarantee. 24 | Use at your own risk. 25 | ''' 26 | 27 | 28 | import os 29 | import sys 30 | import oyaml 31 | import xlsxwriter 32 | 33 | from jinja2 import Environment, meta 34 | 35 | 36 | def create_spreadsheet(config_type): 37 | """ 38 | Generates the full configuration template for a given configuration type (panos or panorama). 39 | This will use the load order 40 | :param config_type: currently supported: 'panos' or 'panorama' 41 | :return: will print full configs to STDOUT and also overwrite the full/iron_skillet_full.xml 42 | """ 43 | # get the path to the full baseline config for this config type 44 | 45 | 46 | # get the full path to the config directory we want (panos / panorama) 47 | set_path = os.path.abspath(os.path.join('..', 'templates', config_type, 'set_commands')) 48 | 49 | # append to the sys path for module lookup 50 | sys.path.append(set_path) 51 | 52 | set_file = '{0}/iron_skillet_{1}_full.conf'.format(set_path, config_type) 53 | config_variables = '{0}/.meta-cnc.yaml'.format(set_path) 54 | 55 | print('creating workbook based on {0}'.format(set_file)) 56 | # Create a workbook and add worksheets. 57 | workbook = xlsxwriter.Workbook('{0}/iron_skillet_{1}_full.xlsx'.format(set_path, config_type)) 58 | 59 | # add columns and format width 60 | worksheet_values = workbook.add_worksheet('values') 61 | worksheet_values.set_column(0, 0, 30) 62 | worksheet_values.set_column(1, 1, 30) 63 | worksheet_set = workbook.add_worksheet('set commands') 64 | 65 | # Add a bold format to use to highlight cells. 66 | bold = workbook.add_format({'bold': 1}) 67 | 68 | # read the metafile to get variables and values 69 | try: 70 | with open(config_variables, 'r') as set_metadata: 71 | set_variables = oyaml.safe_load(set_metadata.read()) 72 | 73 | except IOError as ioe: 74 | print(f'Could not open metadata file {config_variables}') 75 | print(ioe) 76 | sys.exit() 77 | 78 | row = 1 79 | 80 | # positional list to map variables into formula 81 | # padded since variables start at row 2 with zero offset 82 | variable_list = ['first row', 'second row'] 83 | 84 | worksheet_values.write(0, 0, 'Variable Name', bold) 85 | worksheet_values.write(0, 1, 'Variable Value', bold) 86 | worksheet_values.write(0, 2, 'Description', bold) 87 | 88 | # iterate through each variable in the yaml file and 89 | # add to variable worksheet including defaults 90 | for variable in set_variables['variables']: 91 | print('working with variable: {0}'.format(variable)) 92 | worksheet_values.write(row, 0, variable['name']) 93 | worksheet_values.write(row, 1, variable['default']) 94 | worksheet_values.write(row, 2, variable['description']) 95 | variable_list.append(variable['name']) 96 | 97 | row += 1 98 | 99 | row = 1 100 | 101 | try: 102 | with open(set_file, 'r') as set_commands: 103 | set_list = set_commands.readlines() 104 | 105 | except IOError as ioe: 106 | print(f'Could not open metadata file {set_file}') 107 | print(ioe) 108 | sys.exit() 109 | 110 | for line in set_list: 111 | 112 | # read the line and create a variable set 113 | env = Environment() 114 | var_set = sorted(meta.find_undeclared_variables(env.parse(line))) 115 | 116 | # check if line has a single variable 117 | if len(var_set) == 1: 118 | # replace quote with 2xquotes to be excel friendly 119 | line = line.replace('"', '""').strip() 120 | var_name = var_set[0] 121 | jinja_var = '{{ ' + var_name + ' }}' 122 | cell_pos = variable_list.index(var_name) 123 | 124 | # formula format = =SUBSTITUTE("set deviceconfig system dns-setting servers primary {0}", "{0}", '0-Config Values'!B21) 125 | form_line = '=SUBSTITUTE("{0}", "{1}", \'values\'!B{2})'.format(line, jinja_var, cell_pos) 126 | # print(form_line) 127 | worksheet_set.write(row, 0, form_line) 128 | 129 | # check if line has 2 variables when requires nested SUBSTITUTEs 130 | elif len(var_set) == 2: 131 | # replace quote with 2xquotes to be excel friendly 132 | line = line.replace('"', '""').strip() 133 | var_name_0 = var_set[0] 134 | jinja_var_0 = '{{ ' + var_name_0 + ' }}' 135 | cell_pos_0 = variable_list.index(var_name_0) 136 | 137 | var_name_1 = var_set[1] 138 | jinja_var_1 = '{{ ' + var_name_1 + ' }}' 139 | cell_pos_1 = variable_list.index(var_name_1) 140 | 141 | # inner is first substitute and all is nested substitute for excel 142 | form_line_inner = 'SUBSTITUTE("{0}", "{1}", \'values\'!B{2})'.format(line, jinja_var_0, cell_pos_0) 143 | form_line_all = '=SUBSTITUTE({0}, "{1}", \'values\'!B{2})'.format(form_line_inner, jinja_var_1, cell_pos_1) 144 | worksheet_set.write(row, 0, form_line_all) 145 | 146 | else: 147 | # replace quotes and also remove hidden quotes for standard non-formula cells 148 | line = line.replace('"', '""').strip() 149 | worksheet_set.write(row, 0, line) 150 | 151 | row += 1 152 | 153 | workbook.close() 154 | print('...done') 155 | 156 | if __name__ == '__main__': 157 | 158 | print('=' * 80) 159 | print(' ') 160 | print('Welcome to Iron-Skillet spreadsheet creator'.center(80)) 161 | print(' ') 162 | print('=' * 80) 163 | 164 | for config_type in ['panos', 'panorama']: 165 | create_spreadsheet(config_type) 166 | -------------------------------------------------------------------------------- /tools/archive/requirements.txt: -------------------------------------------------------------------------------- 1 | Jinja2>=2.10.1 2 | MarkupSafe==1.0 3 | oyaml==0.7 4 | passlib==1.7.1 5 | PyYAML==5.4 6 | XlsxWriter==1.1.2 7 | requests==2.22.0 8 | pexpect==4.7.0 9 | pan-python==0.14.0 -------------------------------------------------------------------------------- /tools/archive/test_full_config.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018, Palo Alto Networks 2 | # 3 | # Permission to use, copy, modify, and/or distribute this software for any 4 | # purpose with or without fee is hereby granted, provided that the above 5 | # copyright notice and this permission notice appear in all copies. 6 | # 7 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | # Author: Scott Shoaf 16 | 17 | ''' 18 | Palo Alto Networks test_set_commands.py 19 | 20 | configures the firewall using set commands 21 | simple expect script model 22 | has a start_row parameter to skip various sections in the conf file 23 | 24 | This software is provided without support, warranty, or guarantee. 25 | Use at your own risk. 26 | ''' 27 | 28 | import argparse 29 | import sys 30 | import time 31 | import requests 32 | import pan.xapi 33 | 34 | def get_job_id(s): 35 | ''' 36 | extract job-id from pan-python string xml response 37 | regex parse due to pan-python output join breaking xml rules 38 | :param s is the input string 39 | :return: simple string with job id 40 | ''' 41 | 42 | return s.split('')[1].split('')[0] 43 | 44 | def get_job_status(s): 45 | ''' 46 | extract status and progress % from pan-python string xml response 47 | regex parse due to pan-python output join breaking xml rules 48 | :param s is the input string 49 | :return: status text and progress % 50 | ''' 51 | 52 | status = s.split('')[1].split('')[0] 53 | progress = s.split('')[1].split('')[0] 54 | result = s.split('')[1].split('')[0] 55 | details = '' 56 | if '
' in s: 57 | details = s.split('
')[1].split('
')[0] 58 | return status, progress, result, details 59 | 60 | def check_job_status(fw, results): 61 | ''' 62 | periodically check job status in the firewall 63 | :param fw is fw object being queried 64 | :param results is the xml-string results returned for job status 65 | ''' 66 | 67 | # initialize to null status 68 | status = '' 69 | 70 | job_id = get_job_id(results) 71 | #print('checking status of job id {0}...'.format(job_id)) 72 | 73 | # check job id status and progress 74 | while status != 'FIN': 75 | 76 | fw.op(cmd='{0}'.format(job_id)) 77 | status, progress, result, details = get_job_status(fw.xml_result()) 78 | if status != 'FIN': 79 | print('job {0} in progress [ {1}% complete ]'.format(job_id, progress), end='\r', flush=True) 80 | time.sleep(5) 81 | 82 | print('\njob {0} is complete as {1}'.format(job_id, result)) 83 | print(details) 84 | 85 | if result == 'FAIL': 86 | print(details) 87 | 88 | 89 | def commit(device): 90 | ''' 91 | commit to device after config is complete 92 | :param device: device object being configured 93 | :return: 94 | ''' 95 | 96 | # commit changes to the device to look for errors 97 | cmd = '' 98 | print('commit config') 99 | device.commit(cmd=cmd) 100 | results = device.xml_result() 101 | 102 | if '' in results: 103 | check_job_status(device, results) 104 | 105 | def import_conf(ip_addr, api_key, filename, file_dir): 106 | ''' 107 | import local config file to device 108 | :param ip_addr: ip address of configured device 109 | :param api_key: api key for the device 110 | :param filename: filename to import 111 | :param file_dir: name of directory for the file 112 | :return: 113 | ''' 114 | 115 | import_file = '{0}/{1}'.format(file_dir, filename) 116 | print('importing {0} to device'.format(import_file)) 117 | 118 | url = "https://{0}/api".format(ip_addr) 119 | params = { 120 | "type": "import", 121 | "category": "configuration", 122 | "key": api_key 123 | } 124 | 125 | with open(import_file, 'rb') as f: 126 | files = {'file': f} 127 | r = requests.post(url, 128 | params=params, 129 | verify=False, 130 | files=files) 131 | 132 | print(r.text) 133 | 134 | def load_conf(device, filename): 135 | ''' 136 | load file in device as candidate config 137 | :param device: configuration device object (fw or panorama) 138 | :param filename: name of configuration file imported to the device 139 | :return: 140 | ''' 141 | 142 | print('loading {0} as candidate config'.format(filename)) 143 | device.op(cmd='{0}'.format(filename)) 144 | results = device.xml_result() 145 | print(results) 146 | 147 | if __name__ == '__main__': 148 | 149 | print('=' * 80) 150 | print(' ') 151 | print('Welcome to Iron-Skillet full xml config test'.center(80)) 152 | print(' ') 153 | print('=' * 80) 154 | 155 | parser = argparse.ArgumentParser() 156 | parser.add_argument("-ip", "--ip_address", help="IP address of the device", type=str) 157 | parser.add_argument("-u", "--username", help="Firewall Username", type=str) 158 | parser.add_argument("-p", "--password", help="Firewall Password", type=str) 159 | parser.add_argument("-t", "--type", help="panorama or panos", type=str) 160 | args = parser.parse_args() 161 | 162 | if len(sys.argv) < 2: 163 | parser.print_help() 164 | parser.exit() 165 | exit(1) 166 | 167 | ip_addr = args.ip_address 168 | username = args.username 169 | password = args.password 170 | dev_type = args.type 171 | 172 | filename = 'iron_skillet_{0}_full.xml'.format(dev_type) 173 | file_dir = '../loadable_configs/sample-mgmt-dhcp/{0}/'.format(dev_type) 174 | 175 | # create panorama object using pan-python class 176 | device = pan.xapi.PanXapi(api_username=username, api_password=password, hostname=ip_addr) 177 | # get panorama api key 178 | api_key = device.keygen() 179 | 180 | # import config 181 | import_conf(ip_addr, api_key, filename, file_dir) 182 | 183 | # load config 184 | load_conf(device, filename) 185 | 186 | # commit config 187 | commit(device) -------------------------------------------------------------------------------- /tools/archive/test_set_commands.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018, Palo Alto Networks 2 | # 3 | # Permission to use, copy, modify, and/or distribute this software for any 4 | # purpose with or without fee is hereby granted, provided that the above 5 | # copyright notice and this permission notice appear in all copies. 6 | # 7 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | # Author: Scott Shoaf 16 | 17 | ''' 18 | Palo Alto Networks test_set_commands.py 19 | 20 | configures the firewall using set commands 21 | simple expect script model 22 | has a start_row parameter to skip various sections in the conf file 23 | 24 | This software is provided without support, warranty, or guarantee. 25 | Use at your own risk. 26 | ''' 27 | 28 | import argparse 29 | import sys 30 | import time 31 | import pexpect 32 | import pan.xapi 33 | 34 | def get_job_id(s): 35 | ''' 36 | extract job-id from pan-python string xml response 37 | regex parse due to pan-python output join breaking xml rules 38 | :param s is the input string 39 | :return: simple string with job id 40 | ''' 41 | 42 | return s.split('')[1].split('')[0] 43 | 44 | def get_job_status(s): 45 | ''' 46 | extract status and progress % from pan-python string xml response 47 | regex parse due to pan-python output join breaking xml rules 48 | :param s is the input string 49 | :return: status text and progress % 50 | ''' 51 | 52 | status = s.split('')[1].split('')[0] 53 | progress = s.split('')[1].split('')[0] 54 | result = s.split('')[1].split('')[0] 55 | details = '' 56 | if '
' in s: 57 | details = s.split('
')[1].split('
')[0] 58 | return status, progress, result, details 59 | 60 | def check_job_status(fw, results): 61 | ''' 62 | periodically check job status in the firewall 63 | :param fw is fw object being queried 64 | :param results is the xml-string results returned for job status 65 | ''' 66 | 67 | # initialize to null status 68 | status = '' 69 | 70 | job_id = get_job_id(results) 71 | #print('checking status of job id {0}...'.format(job_id)) 72 | 73 | # check job id status and progress 74 | while status != 'FIN': 75 | 76 | fw.op(cmd='{0}'.format(job_id)) 77 | status, progress, result, details = get_job_status(fw.xml_result()) 78 | if status != 'FIN': 79 | print('job {0} in progress [ {1}% complete ]'.format(job_id, progress), end='\r', flush=True) 80 | time.sleep(5) 81 | 82 | print('\njob {0} is complete as {1}'.format(job_id, result)) 83 | print(details) 84 | 85 | if result == 'FAIL': 86 | print(details) 87 | 88 | 89 | def commit(device): 90 | ''' 91 | commit to device after config is complete 92 | :param device: device object being configured 93 | :return: 94 | ''' 95 | 96 | # commit changes to the device to look for errors 97 | cmd = '' 98 | print('commit config') 99 | device.commit(cmd=cmd) 100 | results = device.xml_result() 101 | 102 | if '' in results: 103 | check_job_status(device, results) 104 | 105 | def test_set(ip_addr, user, mypassword, dev_type, start_row, stop_row): 106 | ''' 107 | expect style scripts to login and send set commands 108 | :param ip_addr: device ip address 109 | :param user: login username 110 | :param mypassword: login password 111 | ''' 112 | 113 | # create fw object for pexpect scripting 114 | fw = pexpect.spawn('ssh {0}@{1}'.format(user, ip_addr), encoding='utf-8') 115 | fw.logfile = sys.stdout 116 | # see password and log in 117 | fw.expect('Password:') 118 | fw.sendline(mypassword) 119 | fw.expect('>') 120 | # turn off paging in the event of multi-line response 121 | fw.sendline('set cli pager off') 122 | fw.expect('>') 123 | fw.expect('\n') 124 | fw.expect('>') 125 | # go into configure mode 126 | fw.sendline('configure') 127 | fw.expect('#') 128 | 129 | # read in conf file and do line by line configuration looking for errors 130 | # start_row bypasses interface and admin configuration items to avoid errors 131 | read_file = '../loadable_configs/sample-mgmt-dhcp/{0}/iron_skillet_{0}_full.conf'.format(dev_type) 132 | #start_row = 'set mgt-config password-complexity enabled yes\n' 133 | 134 | start = False 135 | 136 | 137 | with open(read_file) as config_file: 138 | 139 | for counter, line in enumerate(config_file, start=1): 140 | # use of start_row to start with a conf file line and skip others 141 | # until end of file or last line encountered 142 | if counter == start_row: 143 | start = True 144 | print('start set command sequence') 145 | 146 | # ignore conf file comments and start config at start_row line 147 | if not line.startswith('#') and start is True: 148 | #print(counter, line) 149 | fw.sendline(line) 150 | # not sure why pexpect needs this combo but works to get response 151 | fw.expect('#') 152 | fw.expect('\n') 153 | fw.expect('#') 154 | # pexpect before grabs last response from the device 155 | fw_response = fw.before 156 | 157 | # if starts with [edit] then no errors returned 158 | # otherwise stop the config showing CLI error message 159 | if not fw_response.strip().startswith('[edit]'): 160 | print('error found in configuration') 161 | print(line) 162 | print(fw_response) 163 | break 164 | 165 | if counter == stop_row: 166 | print('end set command sequence') 167 | exit() 168 | 169 | if __name__ == '__main__': 170 | 171 | print('=' * 80) 172 | print(' ') 173 | print('Welcome to Iron-Skillet set command test'.center(80)) 174 | print(' ') 175 | print('=' * 80) 176 | 177 | parser = argparse.ArgumentParser() 178 | parser.add_argument("-ip", "--ip_address", help="IP address of the device", type=str) 179 | parser.add_argument("-u", "--username", help="Firewall Username", type=str, default='admin') 180 | parser.add_argument("-p", "--password", help="Firewall Password", type=str, default='Paloalto1') 181 | parser.add_argument("-t", "--type", help="panorama or panos", type=str, default='panos') 182 | parser.add_argument("-start", "--start_row", help='start row number from input file', type=int, default=1) 183 | parser.add_argument("-stop", "--stop_row", help='stop row number from input file', type=int, default=10000) 184 | args = parser.parse_args() 185 | 186 | if len(sys.argv) < 2: 187 | parser.print_help() 188 | parser.exit() 189 | exit(1) 190 | 191 | ip_addr = args.ip_address 192 | username = args.username 193 | password = args.password 194 | dev_type = args.type 195 | start_row = args.start_row 196 | stop_row = args.stop_row 197 | 198 | # this is the real work with device login and configuration 199 | test_set(ip_addr, username, password, dev_type, start_row, stop_row) 200 | 201 | print('\n') 202 | print('=' * 80) 203 | print('set commands loaded') 204 | 205 | # create panorama object using pan-python class 206 | #device = pan.xapi.PanXapi(api_username=username, api_password=password, hostname=ip_addr) 207 | # get panorama api key and commit 208 | #api_key = device.keygen() 209 | #commit(device) -------------------------------------------------------------------------------- /tools/build_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This is a bash script to run all SLI Tooling commands. This script 3 | # is meant to replace the build_all.py python script which ran all 4 | # The .py functions found within the IronSkillet Tooling directory. 5 | # This bash script is still a work in progress. 6 | #MGM Cloud is default 7 | MGMT_STATIC="MGMT_TYPE=static" 8 | MGMT_DHCP="MGMT_TYPE=dhcp" 9 | #Panorama Static is default 10 | PANORAMA_CLD="PANORAMA_TYPE=cloud" 11 | CONFIG_ALL_PANOS="config_mgmt_intf=yes config_dns=yes config_admin_user=yes" 12 | CONFIG_ALL_PANORAMA="config_admin_panorama=yes config_mgmt_intf_panorama=yes" 13 | 14 | echo "Checking if a Venv already exists in given directory" 15 | if [ ! -d "./venv" ] 16 | then 17 | echo "Directory ./venv DOES NOT exist." 18 | echo "Creating the venv" 19 | python3 -m venv ./venv 20 | echo "Activate the venv" 21 | source ./venv/bin/activate 22 | echo "Install Sli in venv" 23 | pip install sli 24 | else 25 | echo "Directory ./venv exists" 26 | echo "Activate the venv" 27 | source ./venv/bin/activate 28 | echo "Upgrade SLI to the latest" 29 | pip install sli --upgrade 30 | fi 31 | echo "Run SLI" 32 | sli 33 | echo "Perform SLI Load to load all skillets" 34 | cd .. 35 | sli load 36 | cd tools 37 | 38 | echo "Create loadable_config directories" 39 | cd .. 40 | mkdir loadable_configs 41 | cd loadable_configs 42 | mkdir sample-cloud-AWS 43 | cd sample-cloud-AWS 44 | mkdir panorama 45 | mkdir panos 46 | cd .. 47 | mkdir sample-cloud-Azure 48 | cd sample-cloud-Azure 49 | mkdir panorama 50 | mkdir panos 51 | cd .. 52 | mkdir sample-cloud-GCP 53 | cd sample-cloud-GCP 54 | mkdir panorama 55 | mkdir panos 56 | cd .. 57 | mkdir sample-mgmt-dhcp 58 | cd sample-mgmt-dhcp 59 | mkdir panorama 60 | mkdir panos 61 | cd .. 62 | mkdir sample-mgmt-static 63 | cd sample-mgmt-static 64 | mkdir panorama 65 | mkdir panos 66 | cd .. 67 | mkdir sample-set-commands 68 | cd sample-set-commands 69 | mkdir panorama 70 | mkdir panos 71 | if [ ! -d "./README.md" ] 72 | then 73 | echo "Creating README.md for directory" 74 | touch README.md 75 | printf "# Set-Commands Loadable Configuration\n\n" >> README.md 76 | printf "The set commands loadable config files created within this directory\n" >> README.md 77 | printf "are initialized with both static and dhcp options by default. It is up to the\n" >> README.md 78 | printf "user's discretion on which configuration they would like to use." >> README.md 79 | else 80 | echo "README.md file already exists, moving forward" 81 | fi 82 | cd .. 83 | 84 | # Below block of commands rolls up all skillets from the playlists directories 85 | echo "Rollup all skillets in the playlists/panos/ directory" 86 | sli -sd ../../ rollup_playlist -n ironskillet_panos_10_1 ../templates/panos/snippets/.meta-cnc.yaml 87 | 88 | # swap out skillet preamble text after rollup 89 | # temp fix until features added to SLI for value options 90 | cd ../templates/panos/snippets 91 | sed -i '' 's/ironskillet_panos_10_1_rollup/skillet_panos_v10_1/' .meta-cnc.yaml 92 | sed -i '' 's/PAN-OS NGFW IronSkillet 10.1/v10.1 Iron-Skillet for NGFW/' .meta-cnc.yaml 93 | sed -i '' 's/IronSkillet Playlists/IronSkillet/' .meta-cnc.yaml 94 | cd ../../../tools 95 | 96 | echo "Rollup all skillets in the playlists/panorama/ directory" 97 | sli -sd ../../ rollup_playlist -n ironskillet_panorama_notshared_dgstack_all_10_1 ../templates/panorama/snippets_dgstack_notshared/.meta-cnc.yaml 98 | sli -sd ../../ rollup_playlist -n ironskillet_panorama_notshared_10_1 ../templates/panorama/snippets_notshared/.meta-cnc.yaml 99 | sli -sd ../../ rollup_playlist -n ironskillet_panorama_shared_dgtemplate_10_1 ../templates/panorama/snippets_dgtemplate_shared/.meta-cnc.yaml 100 | sli -sd ../../ rollup_playlist -n ironskillet_panorama_shared_10_1 ../templates/panorama/snippets/.meta-cnc.yaml 101 | 102 | # swap out skillet preamble text after rollup 103 | # temp fix until features added to SLI for value options 104 | # shared snippets 105 | cd ../templates/panorama/snippets 106 | sed -i '' 's/ironskillet_panorama_shared_10_1_rollup/skillet_panorama_v10_1/' .meta-cnc.yaml 107 | sed -i '' 's/Panorama Shared IronSkillet 10.1/v10.1 Iron-Skillet for Panorama (Shared Values)/' .meta-cnc.yaml 108 | sed -i '' 's/IronSkillet Playlists/IronSkillet/' .meta-cnc.yaml 109 | # dgstack_notshared 110 | cd ../snippets_dgstack_notshared 111 | sed -i '' 's/ironskillet_panorama_notshared_dgstack_all_10_1_rollup/skillet_panorama_dgstack_notshared_v10_1/' .meta-cnc.yaml 112 | sed -i '' 's/Panorama Notshared DGTemplate IronSkillet 10.1/v10.1 Iron-Skillet for Panorama with Device-Group and Stack only (No Shared Values)/' .meta-cnc.yaml 113 | sed -i '' 's/IronSkillet Playlists/IronSkillet/' .meta-cnc.yaml 114 | # dgtemplate_shared 115 | cd ../snippets_dgtemplate_shared 116 | sed -i '' 's/ironskillet_panorama_shared_dgtemplate_10_1_rollup/skillet_panorama_dgtemplate_shared_v10_1/' .meta-cnc.yaml 117 | sed -i '' 's/Panorama Shared IronSkillet 10.1/v10.1 Iron-Skillet for Panorama with Device-Group and Template only (no Panorama system config)/' .meta-cnc.yaml 118 | sed -i '' 's/IronSkillet Playlists/IronSkillet/' .meta-cnc.yaml 119 | # snippets_notshared 120 | cd ../snippets_notshared 121 | sed -i '' 's/ironskillet_panorama_notshared_10_1_rollup/skillet_panorama_notshared_v10_1/' .meta-cnc.yaml 122 | sed -i '' 's/Panorama Notshared IronSkillet 10.1/v10.1 Iron-Skillet for Panorama (No Shared Values)/' .meta-cnc.yaml 123 | sed -i '' 's/IronSkillet Playlists/IronSkillet/' .meta-cnc.yaml 124 | cd ../../../tools 125 | 126 | 127 | 128 | # Below block of commands creates the full template configurations for Panos 129 | # This template is an XML version of the panos_full.skillet.yaml in the playlists/panos directory 130 | # but leaves Jinja unrendered and results are outputted in templates/panos/full/ directory. 131 | echo "Creating a full XML Jinja Template configuration for Panos" 132 | cd .. 133 | sli create_template $CONFIG_ALL_PANOS -n ironskillet_panos_10_1 templates/panos/baseline/baseline.xml templates/panos/full/iron_skillet_panos_full.xml 134 | cd tools 135 | 136 | echo "Creating a full XML Jinja Template configuration for Panorama" 137 | cd .. 138 | sli create_template $CONFIG_ALL_PANORAMA -n ironskillet_panorama_shared_10_1 templates/panorama/baseline/baseline.xml templates/panorama/full/iron_skillet_panorama_full.xml 139 | cd tools 140 | 141 | 142 | # Create all loadable config XML and set command files with rendered jinja for panos and 143 | # Panorama Using full panos file from playlists/panos/panos_full outputting in respective 144 | # Loadable config folders 145 | echo "using sli template to create the loadable config xml with rendered jinja for panos" 146 | sli template -sd ../ -ad -n skillet_full_panos_v10_1 -o ../loadable_configs/sample-cloud-AWS/panos/iron_skillet_panos_full.xml 147 | sli template -sd ../ -ad -n skillet_full_panos_v10_1 -o ../loadable_configs/sample-cloud-Azure/panos/iron_skillet_panos_full.xml 148 | sli template -sd ../ -ad -n skillet_full_panos_v10_1 -o ../loadable_configs/sample-cloud-GCP/panos/iron_skillet_panos_full.xml 149 | sli template -sd ../ -ad -n skillet_full_panos_v10_1 -o ../loadable_configs/sample-mgmt-dhcp/panos/iron_skillet_panos_full.xml 150 | sli template -sd ../ -ad $MGMT_STATIC -n skillet_full_panos_v10_1 -o ../loadable_configs/sample-mgmt-static/panos/iron_skillet_panos_full.xml 151 | 152 | echo "Using sli template to create the loadable config set commands with rendered jinja for panos" 153 | sli template -sd ../ -ad -n skillet_set_command_panos_v10_1 -o ../loadable_configs/sample-set-commands/panos/iron_skillet_panos_full.conf 154 | 155 | echo "using sli template to create the loadable config xml with rendered jinja for panorama" 156 | sli template -sd ../ -ad $PANORAMA_CLD -n skillet_full_panorama_v10_1 -o ../loadable_configs/sample-cloud-AWS/panorama/iron_skillet_panorama_full.xml 157 | sli template -sd ../ -ad $PANORAMA_CLD -n skillet_full_panorama_v10_1 -o ../loadable_configs/sample-cloud-Azure/panorama/iron_skillet_panorama_full.xml 158 | sli template -sd ../ -ad $PANORAMA_CLD -n skillet_full_panorama_v10_1 -o ../loadable_configs/sample-cloud-GCP/panorama/iron_skillet_panorama_full.xml 159 | sli template -sd ../ -ad -n skillet_full_panorama_v10_1 -o ../loadable_configs/sample-mgmt-dhcp/panorama/iron_skillet_panorama_full.xml 160 | sli template -sd ../ -ad $MGMT_STATIC -n skillet_full_panorama_v10_1 -o ../loadable_configs/sample-mgmt-static/panorama/iron_skillet_panorama_full.xml 161 | 162 | echo "Using sli template to create the loadable config set commands with rendered jinja for panorama" 163 | sli template -sd ../ -ad -n skillet_setcommand_panorama_v10_1 -o ../loadable_configs/sample-set-commands/panorama/iron_skillet_panorama_full.conf 164 | 165 | 166 | # Below block of commands creates the spreadsheet files for both Panorama and Panos set commands 167 | echo "Creating Panos spreadsheet to be output in /templates/panos/set_commands/" 168 | sli spreadsheet -sd ../templates/panos/set_commands -n skillet_set_command_panos_v10_1 -o ../templates/panos/set_commands/ 169 | echo "Creating Panorama spreadsheet to be output in /templates/panorama/set_commands/" 170 | sli spreadsheet -sd ../templates/panorama/set_commands -n skillet_setcommand_panorama_v10_1 -o ../templates/panorama/set_commands/ -------------------------------------------------------------------------------- /tools/update_submodules.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This is a bash script to update the current version of the submodules 3 | # folder to point at the latest commit/changes made. 4 | 5 | cd .. 6 | echo "The current submodules version is:" 7 | git submodule 8 | echo "Heading into submodules directory" 9 | cd submodules 10 | echo "Updating the submodules folder to latest commit" 11 | git pull 12 | echo "Moving back into main directory" 13 | cd .. 14 | echo "Updated submodules version is:" 15 | git submodule 16 | echo "" 17 | echo "Changes are not commited by this script." 18 | echo "Please be sure to commit changes to git manually." 19 | echo "" -------------------------------------------------------------------------------- /validations/README.md: -------------------------------------------------------------------------------- 1 | # IronSkillet Validations 2 | 3 | Validation skillets allow the user to map configuration files against 4 | a set of validation rules. 5 | 6 | Key use cases are missing configuration elements based on best practices, 7 | missing configuration elements for later stage config dependencies, or 8 | potential merge conflicts of same-named rules and objects. 9 | 10 | ### Full IronSkillet configuration assessment 11 | 12 | This validation skillet provides a comprehensive analysis of a NGFW configuration 13 | compared to IronSkillet. This includes device hardening, security profiles, 14 | and other recommended day one practices. 15 | 16 | The documentation links map to the visual guide allowing the user to manually 17 | remediate any 'fail' state config items. 18 | 19 | ### Upgrade to 10.1 Missing Elements 20 | 21 | This is a partial validation that only looks at new items added between 22 | PAN-OS 9.1 and 10.1. Users can opt to manually remediate missing 23 | elements using links to the visual guide. 24 | 25 | -------------------------------------------------------------------------------- /validations/panos/IronSkillet_assessment_panos/report/report.yml: -------------------------------------------------------------------------------- 1 | --- 2 | import: ../../../shared_report 3 | 4 | report: 5 | subtitle: PAN-OS 10.1 -------------------------------------------------------------------------------- /validations/panos/IronSkillet_v10x_update_panos/.meta-cnc.yaml: -------------------------------------------------------------------------------- 1 | name: validate-IronSkillet-v10_1-panos-bae945bc-c667-4e56-a3fc-73bbb5afbe0g 2 | label: IronSkillet - check NGFW config for updated v10.1 elements 3 | 4 | description: | 5 | Check NGFW for new items updated in IronSkillet v10.1 skillet 6 | 7 | type: pan_validation 8 | labels: 9 | collection: 10 | - IronSkillet 11 | - Validation 12 | 13 | variables: 14 | 15 | snippets: 16 | 17 | - name: rules 18 | cmd: parse 19 | variable: config 20 | outputs: 21 | # used to check WF update interval 22 | - name: wf_update 23 | capture_object: /config/devices/entry[@name='localhost.localdomain']/deviceconfig/system/update-schedule/wildfire 24 | - name: as_profiles_outbound_dns 25 | capture_object: /config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/profiles/spyware/entry[@name='Outbound-AS']/botnet-domains/lists 26 | 27 | # check if Outbound-URL profile exists 28 | - name: url_outbound 29 | capture_list: |- 30 | /config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/profiles/url-filtering 31 | /entry[@name='Outbound-URL']/@name 32 | # check that dynamic class is part of url filtering config 33 | - name: url_dynclass_entries 34 | capture_list: |- 35 | /config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/profiles/url-filtering 36 | /entry[@name='Outbound-URL']/mlav-engine-urlbased-enabled/entry/@name 37 | # list of dynamic classification options set to block 38 | - name: url_dynclass_block 39 | capture_list: |- 40 | /config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/profiles/url-filtering 41 | /entry[@name='Outbound-URL']/mlav-engine-urlbased-enabled/entry/mlav-policy-action[text()='block']/../@name 42 | # list of dynamic classification options not set to block 43 | - name: url_dynclass_not_block 44 | capture_list: |- 45 | /config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/profiles/url-filtering 46 | /entry[@name='Outbound-URL']/mlav-engine-urlbased-enabled/entry/@name 47 | filter_items: item not in url_dynclass_block 48 | # list with the profile name if hacking is alert 49 | - name: url_profiles_alert_hacking 50 | capture_list: |- 51 | /config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/profiles/url-filtering/entry[@name='Outbound-URL'] 52 | /alert/member[text()='hacking']/../../@name 53 | 54 | # list looking for the Outbound-AV profile 55 | - name: av_outbound 56 | capture_list: |- 57 | /config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/profiles/virus/ 58 | entry[@name='Outbound-AV']/@name 59 | # list with the dynamic classification action as reset-both 60 | - name: av_decoder_dynclass_resetboth 61 | capture_list: |- 62 | /config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/profiles/virus/ 63 | entry[@name='Outbound-AV']/decoder/entry/mlav-action[text()='reset-both']/../@name 64 | # list with the dynamic classification action not reset-both 65 | - name: av_decoder_dynclass_not_resetboth 66 | capture_list: |- 67 | /config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/profiles/virus/ 68 | entry[@name='Outbound-AV']/decoder/entry/@name 69 | filter_items: item not in av_decoder_dynclass_resetboth 70 | 71 | # check dynamic classification engine found in the configuration 72 | - name: av_engine_entries 73 | capture_list: |- 74 | /config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/profiles/virus/ 75 | entry[@name='Outbound-AV']/mlav-engine-filebased-enabled/entry/@name 76 | # list with the dynamic classification engine action = enable 77 | - name: av_engine_dynclass_enable 78 | capture_list: |- 79 | /config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/profiles/virus/ 80 | entry[@name='Outbound-AV']/mlav-engine-filebased-enabled/entry/mlav-policy-action[text()='enable']/../@name 81 | # list with the dynamic classification engine action != enable 82 | - name: av_engine_dynclass_not_enable 83 | capture_list: |- 84 | /config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/profiles/virus/ 85 | entry[@name='Outbound-AV']/mlav-engine-filebased-enabled/entry/@name 86 | filter_items: item not in av_engine_dynclass_enable 87 | 88 | # use list to check for configuration of Recommended_Decryption_Profile 89 | - name: IS_decrypt_profile 90 | capture_list: |- 91 | /config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/profiles/decryption/ 92 | entry[@name="Recommended_Decryption_Profile"]/@name 93 | # check max version in the recommended decrypt profile 94 | - name: profile_decryption_max_version 95 | capture_value: |- 96 | /config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/profiles/decryption/ 97 | entry[@name="Recommended_Decryption_Profile"]/ssl-protocol-settings/max-version/text() 98 | 99 | #----------------- 100 | # tests 101 | 102 | - name: wf_realtime_update 103 | label: Wildfire dynamic update schedule set to real-time 104 | test: wf_update | tag_present('recurring.real-time') 105 | severity: medium 106 | fail_message: Wildfire should be configured to use real-time updates 107 | documentation_link: https://iron-skillet.readthedocs.io/en/docs_master/viz_guide_panos.html#ironskillet-security-policies 108 | 109 | - name: url_dynclass 110 | label: URL Filtering Outbound dynamic classification set to block 111 | test: url_dynclass_not_block | length == 0 and 'Outbound-URL' in url_outbound and url_dynclass_entries | length 112 | severity: high 113 | fail_message: | 114 | {%- if 'Outbound-URL' not in url_outbound %}URL-filtering profile Outbound-URL not in configuration 115 | {%- elif url_dynclass_entries | length == 0 %}Dynamic classification options not found in configuration; may be unsupported version 116 | {%- else %}Dynamic classification for all options should be set to block; {{ url_dynclass_not_block }} not blocking 117 | {%- endif %} 118 | documentation_link: https://iron-skillet.readthedocs.io/en/docs_master/viz_guide_panos.html#ironskillet-security-policies 119 | 120 | - name: url_hacking 121 | label: Outbound-URL hacking category moved from block to alert 122 | test: url_profiles_alert_hacking | length and 'Outbound-URL' in url_outbound 123 | fail_message: | 124 | {%- if 'Outbound-URL' not in url_outbound %}URL-filtering profile Outbound-URL not in configuration 125 | {%- else %}Hacking is set as alert in IronSkillet; No transfer of malicious content, only how to be malicious 126 | {%- endif %} 127 | documentation_link: https://iron-skillet.readthedocs.io/en/docs_master/viz_guide_panos.html#ironskillet-security-policies 128 | 129 | - name: av_dynclass_decoder_action 130 | label: Outbound Dynamic Classification set to reset-both for all decoders 131 | test: av_decoder_dynclass_not_resetboth | length == 0 and 'Outbound-AV' in av_outbound 132 | severity: high 133 | fail_message: | 134 | {%- if 'Outbound-AV' not in av_outbound %}Antivirus profile Outbound-AV not in configuration 135 | {%- else %}Dynamic classification should be set to reset-both; {{ av_decoder_dynclass_not_resetboth}} set to another value 136 | {%- endif %} 137 | documentation_link: https://iron-skillet.readthedocs.io/en/docs_master/viz_guide_panos.html#anti-spyware 138 | 139 | - name: av_dynclass_engines_action 140 | label: Outbound Dynamic Classification set to enable for all engines 141 | test: av_engine_dynclass_not_enable | length == 0 and 'Outbound-AV' in av_outbound and av_engine_entries | length 142 | severity: high 143 | fail_message: | 144 | {%- if 'Outbound-AV' not in av_outbound %}Antivirus profile Outbound-AV not in configuration 145 | {%- elif av_engine_entries | length == 0 %}No AV engine configuration found in configuration; may be unsupported version 146 | {%- else %}Dynamic classification should be set to enable for all engines; {{ av_engine_dynclass_not_enable }} set to another value 147 | {%- endif %} 148 | documentation_link: https://iron-skillet.readthedocs.io/en/docs_master/viz_guide_panos.html#anti-spyware 149 | 150 | - name: decrypt_profile_tls13 151 | label: Recommended_Decryption_Profile protocol settings max version is TLS 1.3 or max 152 | test: (profile_decryption_max_version == 'tls1-3' or profile_decryption_max_version == 'max') and 'Recommended_Decryption_Profile' in IS_decrypt_profile 153 | severity: medium 154 | fail_message: | 155 | {%- if 'Recommended_Decryption_Profile' not in IS_decrypt_profile %}Recommended_Decryption_Profile not in configuration 156 | {%- elif profile_decryption_max_version | length == 0 %}The max version in the profile setting should be configured as v1.3 or max 157 | {%- else %}The max version in the profile setting should be v1.3 or max instead of {{ profile_decryption_max_version }} 158 | {%- endif %} 159 | documentation_link: https://iron-skillet.readthedocs.io/en/docs_master/viz_guide_panos.html#decryption-profile 160 | -------------------------------------------------------------------------------- /validations/panos/IronSkillet_v10x_update_panos/report/report.yml: -------------------------------------------------------------------------------- 1 | --- 2 | import: ../../../shared_report 3 | 4 | report: 5 | subtitle: PAN-OS 10.1 -------------------------------------------------------------------------------- /validations/shared_report/is_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaloAltoNetworks/iron-skillet/98333734ab43f889507572413b63aafbcb351f5e/validations/shared_report/is_logo.png -------------------------------------------------------------------------------- /validations/shared_report/report.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # Report template for Iron Skillet 4 | 5 | # Not to be called directly, but imported into Iron Skillet 6 | # versions for different PAN-OS versions 7 | 8 | report: 9 | 10 | title: Iron Skillet full validation 11 | subtitle: Automated Solutions 12 | second_logo: is_logo 13 | second_logo_style: 14 | height: 125px 15 | width: 125px 16 | footer_links: 17 | - name: Palo Alto Networks 18 | url: https://paloaltonetworks.com 19 | - name: Iron Skillet 20 | url: https://github.com/PaloAltoNetworks/iron-skillet/ 21 | 22 | sections: 23 | 24 | - name: Validation Statistics 25 | content: 26 | - type: stats_block 27 | key: stats 28 | data: 29 | 30 | - title: Total Checks 31 | key: total 32 | 33 | - title: Checks Passed 34 | key: pass 35 | icon: checkmark 36 | 37 | - title: Checks Failed 38 | key: fail 39 | icon: alert 40 | 41 | - name: Iron Skillet validation results 42 | content: 43 | - type: table 44 | key: checks 45 | columns: 46 | 47 | - title: Validation Check 48 | key: documentation_link 49 | type: url 50 | display_key: label 51 | 52 | - title: Result 53 | key: icon 54 | type: icon 55 | style: 56 | width: 30px 57 | tooltip: 58 | key: output_message 59 | style: 60 | left: -300px 61 | 62 | pre_processing: |- 63 | {% set output = {'checks': [], 'stats': {'total':0, 'pass':0, 'fail':0}} %} 64 | {% for check in data.keys() %} 65 | {% set c = data[check] %} 66 | {% if c.results %} 67 | {% set _= c.__setitem__('icon', 'checkmark') %} 68 | {% set _= output.stats.__setitem__('pass', output.stats.pass + 1) %} 69 | {% else %} 70 | {% set _= c.__setitem__('icon', 'alert') %} 71 | {% set _= output.stats.__setitem__('fail', output.stats.fail + 1) %} 72 | {% endif %} 73 | {% set _= output['checks'].append(c) %} 74 | {% set _= output.stats.__setitem__('total', output.stats.total + 1) %} 75 | {% endfor %} 76 | {{ output | tojson }} 77 | --------------------------------------------------------------------------------