Getting started with 'Iron Skillet' best practices templates

by Community Manager 2 weeks ago - last edited 2 weeks ago (2,990 Views)

The "Iron Skillet, day one configuration templates" are an amazing new tool we've created to help customers deploy new firewalls with the least amount of effort while leveraging best practices. The goal is to make life easy for everyone and improve overall security posture.

 

The templates library contains easy to use snippets that allow for granular configuration add-ons or assembly of full config files that can be used to bootstrap or import onto a firewall or panorama. 

 

 

These are my own first steps creating a fresh Iron Skillet config:

Disclaimer: you may notice me using vi as a text editor, feel free to use nano or any other editor.

 

First I set up my keypair following the GitHub instructions (this had me baffled for a moment as I am a total GitHub noob)

 

MyPuter:~ reaper$ ssh-keygen -t rsa -b 4096 -C "my-email@paloaltonetworks.com" <- generate the keypair
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/reaper/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): <- password prompted here
Enter same passphrase again: 
Your identification has been saved in /Users/reaper/.ssh/id_rsa.
Your public key has been saved in /Users/reaper/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:b65vuXXxxXXxcpc/ImqxxXXxxUcHSeXXxxXXYsS6+qI my-email@paloaltonetworks.com
The key's randomart image is:
+---[RSA 4096]----+
|        .       |
|       .o       |
|       .+.      |
|      ..+..     |
|     o..+..o    |
|  . o .* *. o . |
|    .. Bo ..    |
|    . .oX...    |
|  ..++o . o++.. |
+----[SHA256]-----+
MyPuter:~ reaper$ eval "$(ssh-agent -s)" <- start the ssh-agent in the background
Agent pid 39618
MyPuter:~ reaper$ vi ~/.ssh/config <- automatically add my keypair to the agent
MyPuter:~ reaper$ cat ~/.ssh/config
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_rsa
MyPuter:~ reaper$ ssh-add -K ~/.ssh/id_rsa <- store passphrase in keychain Enter passphrase for /Users/reaper/.ssh/id_rsa: Identity added: /Users/reaper/.ssh/id_rsa (/Users/reaper/.ssh/id_rsa) MyPuter:~ reaper$ pbcopy < ~/.ssh/id_rsa.pub <- this copies the public key to clipboard

 Once I managed to add the key to GitHub, I downloaded the snippets

MyPuter:~ reaper$ git clone git@github.com:PaloAltoNetworks/iron-skillet.git
Cloning into 'iron-skillet'...
remote: Enumerating objects: 208, done.
remote: Counting objects: 100% (208/208), done.
remote: Compressing objects: 100% (150/150), done.
remote: Total 1516 (delta 110), reused 141 (delta 57), pack-reused 1308
Receiving objects: 100% (1516/1516), 588.37 KiB | 1.32 MiB/s, done.
Resolving deltas: 100% (867/867), done.

next, I set up my python virtual environment:

MyPuter:~ reaper$ cd iron-skillet/tools/
MyPuter:tools reaper$ python3.7 -m venv env <- sets up the virtual environment
MyPuter:tools reaper$ source env/bin/activate <- activates the virtual environment
(env) MyPuter:tools reaper$ pip install -r requirements.txt <- installs some required packages
Collecting Jinja2==2.10 (from -r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl (126kB)
    100% |████████████████████████████████| 133kB 2.6MB/s 
Collecting MarkupSafe==1.0 (from -r requirements.txt (line 2))
  Downloading https://files.pythonhosted.org/packages/4d/de/32d741db316d8fdb7680822dd37001ef7a448255de9699ab4bfcbdf4172b/MarkupSafe-1.0.tar.gz
Collecting passlib==1.7.1 (from -r requirements.txt (line 3))
  Downloading https://files.pythonhosted.org/packages/ee/a7/d6d238d927df355d4e4e000670342ca4705a72f0bf694027cf67d9bcf5af/passlib-1.7.1-py2.py3-none-any.whl (498kB)
    100% |████████████████████████████████| 501kB 3.3MB/s 
Installing collected packages: MarkupSafe, Jinja2, passlib
  Running setup.py install for MarkupSafe ... done
Successfully installed Jinja2-2.10 MarkupSafe-1.0 passlib-1.7.1

 

next, I'll edit the my_variables.py to reflect values I want to use in my environment

 

(env) MyPuter:tools reaper$ vi my_variables.py

 

# Copyright (c) 2018, Palo Alto Networks
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

# Author: Scott Shoaf <sshoaf@paloaltonetworks.com>

'''
Palo Alto Networks my_variables.py

Used in tandem with build_my_configs.py to render templates into loadable configurations

Edit the my_variables.py values and then run build_my_configs.py

This software is provided without support, warranty, or guarantee.
Use at your own risk.
'''

xmlvar = {
    # These are sample username and password values to show the variables in the tools script
    # The user will be prompted for the actual user and password when the script is run
    "ADMINISTRATOR_USERNAME": "iron-skillet", <- placeholder for default username
    "ADMINISTRATOR_PASSWORD": "fortheloveofallthingsholychangeme",
    # MY_CONFIGDIR is the prefix to the my_template output folder
    "MYCONFIG_DIR": "reaper_config", <- the folder where the config output will be created
    # MGMT_TYPE values: static, dhcp-cloud, or dhcp-client
    # if static, update the IP, mask, gateway values below
    "MGMT_TYPE": "static", <- the default here is dhcp-client
    # Panorama types are cloud or standard
    # Cloud adds in initcfg bootstrap elements for Panorama
    "PANORAMA_TYPE": "standard",
    # the values below are specific to the firewall deployment environment or default can be used
    # IP addresses are non-routable in the sample config
    "FW_NAME": "Lab-firewall",
    "DEVICE_GROUP": "sample",
    "TEMPLATE": "sample",
    "DNS_1": "1.1.1.1", <- I personally prefer cloudflare, you could add local ISP DNS for best speed
    "DNS_2": "8.8.8.8", <- google as backup
    "NTP_1": "0.pool.ntp.org",
    "NTP_2": "1.pool.ntp.org",
    "SINKHOLE_IPV4": "72.5.65.111",
    "SINKHOLE_IPV6": "2600:5200::1",
    "EMAIL_PROFILE_GATEWAY": "192.168.27.250",
    "EMAIL_PROFILE_FROM": "firewall@yourdomain.com",
    "EMAIL_PROFILE_TO": "admin@yourdomain.com",
    "SYSLOG_SERVER": "192.168.27.253",
    # IP address or hostname for config bundle export <- this is used for panorama config exports
    "CONFIG_EXPORT_IP": "192.0.2.3",
    # configure if management interface type = static
    "MGMT_IP": "192.168.27.254",
    "MGMT_MASK": "255.255.255.0",
    "MGMT_DG": "192.168.27.1",
    # Panorama Management IP Address Info
    # Set CONFIG _PANORAMA_IP to yes to include in config
    # If set to no will not add which may be required for partial config loads
    "CONFIG_PANORAMA_IP": "no",
    "PANORAMA_NAME": "panorama",
    "PANORAMA_IP": "192.168.27.7",
    "PANORAMA_MASK": "255.255.255.0",
    "PANORAMA_DG": "192.168.27.1",

}

 A description of all the variables is available in the Iron Skillet documentation.

 

And now I can run the builder

(env) MyPuter:tools reaper$ python3.7 build_my_configs.py
================================================================================
 
                            Welcome to Iron-Skillet                             
 
================================================================================

datetime used for folder creation: 20181002_165508

Enter the superuser administrator account username: iron-skillet <- here you can choose your initial admin username
This username will be created instead of the default 'admin', so make sure to remember the password
a phash will be created for superuser iron-skillet and added to the config file

Enter the superuser administrator account password: 
Enter password again to verify: 

created new archive folder reaper_config-20181002_165508
created new subdirectories for panos

*** cut for brevity ***

configs have been created and can be found in /Users/reaper/iron-skillet/my_configs/reaper_config-20181002_165508
along with the my_variables.py values used to render the configs

created new subdirectories for panorama

*** cut for brevity ***

configs have been created and can be found in /Users/reaper/iron-skillet/my_configs/reaper_config-20181002_165508
along with the my_variables.py values used to render the configs

 

I can now go find the full config file that was generated:

(env) MyPuter:tools reaper$ pwd
/Users/reaper/iron-skillet/tools
(env) MyPuter:tools reaper$ cd ..
(env) MyPuter:iron-skillet reaper$ ls
CONTRIBUTING.md	LICENSE		README.md	SUPPORT.md	docs		my_configs	templates	tools
(env) MyPuter:iron-skillet reaper$ cd my_configs/
(env) MyPuter:my_configs reaper$ ls
reaper_config-20181002_165508	sample-cloud-Azure		sample-mgmt-dhcp
sample-cloud-AWS		sample-cloud-GCP		sample-mgmt-static
(env) MyPuter:my_configs reaper$ cd reaper_config-20181002_165508/
(env) MyPuter:reaper_config-20181002_165508 reaper$ ls
my_variables.py	panorama	panos
(env) MyPuter:reaper_config-20181002_165508 reaper$ cd panos/
(env) MyPuter:panos reaper$ ls
full		snippets
(env) MyPuter:panos reaper$ cd full/
(env) MyPuter:full reaper$ ls
iron_skillet_day1_template.xml
(env) MyPuter:full reaper$ cat iron_skillet_day1_template.xml 
<config urldb="paloaltonetworks" version="8.0.0">
  <mgt-config>
    <users>
      <entry name="iron-skillet">
        <phash>$1$xZa0NBFG$l.SQncRpP0gRyynn2iOZz0</phash>
        <permissions>
          <role-based>
            <superuser>yes</superuser>
          </role-based>
        </permissions>
      </entry>
    </users>
  </mgt-config>
...

And import it into my firewall (I'd go to Device > Setup > Operations > Import named configuration snapshot)

import config snapshot.png

 

Next, I load the config into the firewall by clicking "Load Named Configuration Snapshot":

load config.pngLoad Named Configuration Snapshot

After reloading the page, browsing through sections of the firewall: several things have been pre-prepared in accordance with my 'my_variables.py' file and best practices. 

 

Iron Skillet security policy.png

 

Several security profiles have been prepared in each section

profiles.png

 

and Inbound, Outbound, Internal, Alert-Only and default Security Profile Groups have been prepared

security profile group.png

Note: a cool little trick here is the use of 'default' as a Security Profile Group. This ensures that any new security rule that's created will automatically be loaded with a set of Security Profiles.

 

 

So what's next?

If I commit this configuration, the management port will assume the IP I configured in my_preferences.py, but there are no interfaces, zones or security policies configured yet. Here's a little checklist to get you rolling:

 

- Create zones, don't forget to add zone protection

- Configure Virtual router (for default gateway)

- Configure interfaces

- Create additional security policies (review the Best Practices for recommendations on identifying whitelist applications)

- Create NAT rules if needed

 

Check out the Iron Skillet page  for instructions on how to add partial config, additional information on individual snippets and keep an eye out for updates and new snippets.

 

 

Additional Information 

Iron Skillet templates documentation

Iron Skillet GitHub repository

Best practices recommendations 

Comments
by cbernstein
Friday

You can skip all of the SSH configuration steps and just grab the repository via HTTPS:

 

git clone https://github.com/PaloAltoNetworks/iron-skillet.git

 

It is publicly available and does not require a GitHub account to download.

Ask Questions Get Answers Join the Live Community