[PYTHON] How to hit NAPALM from the Web (NetDevOpsSec reality solution)

Introduction

This article is from December 14, 2016 in NetOpsCoding Advent Calendar 2016.

CLI is often used to operate network devices, but it is difficult to handle with CLI program (-_-;)

To make it easier to programmatically, some engineers around Spotify have created a library called'napalm'. (Paramiko base) https://github.com/napalm-automation/napalm

Actual example

This time, I will try to load the config from the Web with the configuration of Junos + CGI + napalm. If you want to hit a command from the Web (for example, add a firewall policy), prepare the following HTML / CGI.

firewall-policy.html


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<form action="cgi-bin/firewall-policy.py" method="post">
    srcaddress:<input type="text" name="srcaddress">
    srcnetmask:<input type="text" name="srcnetmask">
    destaddress:<input type="text" name="destaddress">
    destnetmask:<input type="text" name="destnetmask">
    applicationname:<input type="text" name="applicationname">
    policy_then:<input type="text" name="policy_then">
    <input type="submit" value="Go">
</form>
</body>
</html>

firewall-policy.py


#!/usr/bin/python


##
(srxipaddr, srxuser, srxpasswd)=('192.168.xx.xx', 'xx', 'xx')
##

import cgi
from napalm import get_network_driver

fs = cgi.FieldStorage()

js={}
for key in fs.keys():
  js[key]=fs[key].value

##
# do import stuff
##
candidate_config_template="""
security policies from-zone untrust to-zone untrust policy automation-policy {{
   match {{
       source-address automation-policy-src;
       destination-address automation-policy-dest;
       application {applicationname};
       }}
       then {{
           {policy_then};
   }}
}}
security zones security-zone untrust address-book {{
   address automation-policy-src {srcaddress}/{srcnetmask};
   address automation-policy-dest {destaddress}/{destnetmask};
}}
"""
candidate_config=candidate_config_template.format(**js)

driver = get_network_driver('junos')
device = driver(srxipaddr, srxuser,  srxpasswd)
device.open()
print (candidate_config)
device.load_merge_candidate(config=candidate_config)
print (device.compare_config())
device.commit_config()
device.close()

As a point

--Convert the argument received from the web form to dict (= JSON = YAML) and then apply it to the config template

I wonder if ...

For more information, see below. http://qiita.com/taijijiji/items/a3f21c8b9e7a0d3afdc6 http://www.slideshare.net/JuniperJapan/interop-tokyo-2016junos-automation

Thanks to the wonderful blogs of the pioneers, it ended easily ... (-o-;)

This is a little lonely because it ends up really lightly, so I'd like to consider a more complicated example (-_-;)

What is the approval flow?

As already written, when performing routine work from the Web, the flow of user instructions (in short, arguments) is shown below.

  1. Applicant (= worker)-> Web application-> napalm

However, in this flow

--A person who operates a browser and describes the work contents (applicant) --People who actually perform the work (workers)

There is a restriction that it can not be used unless they are the same, and this becomes a problem in actual operation.

What this means is that in an Enterprise environment where IT operations are audited. There is a restriction that'applicants (application development vendors, etc.)'cannot directly operate the production environment.

(reference) http://forza.cocolog-nifty.com/blog/2015/02/itdevops-691f.html http://blogs.itmedia.co.jp/infra/2013/09/devops1devops-7abb.html

In this case, the approver approves the content described by the applicant, and then the worker carries out the work. With ITIL-enabled tools (usually this is the focus of audits), this is fixed as a screen and the work is an attachment.

Therefore, the realistic flow in this case is as follows.

  1. Applicant-> Work Instructions (Excel, etc.)-> ITIL Tools-> (Workflow)-> Workers
  2. Worker-> Web App-> napalm

In this case, the applicant writes the work order in as much detail as possible, There is a limit to the information that can be explained in Japanese ... While looking at the Amazon screen, I felt like I would send all orders by email.

――Where and when will you deliver it? ――If you can pick it first, will it be shipped separately? ――What is the payment method?

To be honest, it is difficult to tell accurately in one shot. further,

――How many stocks do you have in the first place?

Etc., including checking the contents that cannot be understood without checking with the system, etc. I think it is desirable for applicants to create an application form based on some kind of web application.

So, I think the ideal flow is as follows.

  1. Applicant-> Web application-> Export input contents as JSON
  2. Applicant-> ITIL Tool (JSON attached)-> (Workflow)-> Worker
  3. Worker-> Web App (Import JSON)-> napalm

If this can be achieved, there are the following merits.

--Applicant (Dev): You can create a request form while checking whether the content can be worked by yourself with a web application, reducing the interaction with workers --Worker (Net, Ops): Work is limited to JSON import, no need to operate the actual machine, less interaction with the applicant --Security personnel (Sec (provisional)): Since it is difficult to approve outside the flow, there is no need to worry about how to leave evidence, how to retain evidence (3 years storage, etc.)

I tried to implement the tool

Regarding the above issues, I tried to implement the following tools while making miso in the foreground. https://github.com/tnaganawa/execjson

The screen image of the tool is as follows. advent-calendar-2016.png

First, the applicant enters the input contents in the Web form for each work to be performed (in the example, adding a firewall policy). Click'export json'when you're done, and the JSON will be exported, which you can pass through the approval flow.

sample.json


{
    "jobapplcode": "", 
    "jobenvcode": "Prod", 
    "joblist": [
        {
            "args": [
                {
                    "applicationname": "junos-vnc", 
                    "destaddress": "192.168.12.11", 
                    "destnetmask": "32", 
                    "policy_then": "permit", 
                    "srcaddress": "192.168.11.11", 
                    "srcnetmask": "32"
                }
            ], 
            "id": "1", 
            "iffail": "stop", 
            "name": "addfirewallpolicy", 
            "time": ""
        }
    ]
}

After that, the worker who received the JSON should import the JSON again with'load'and press'execjson', and this time the process will start to flow.

Summary

I hope the above tools will give you a start on automating user request work. (I can't say anything because it depends on the environment) In fact, the DevOps flow usually stops at security, but with a tool like the one above,

I think it would be better to gradually expand the scope of improvement in the order of.

Recommended Posts

How to hit NAPALM from the Web (NetDevOpsSec reality solution)
How to operate Linux from the console
How to access the Datastore from the outside
How to build an application from the cloud using the Django web framework
How to open a web browser from python
How to operate Linux from the outside Procedure
How to measure line speed from the terminal
How to create an article from the command line
How to instantly launch Jupyter Notebook from the terminal
How to hit the document of Magic Function (Line Magic)
How to post a ticket from the Shogun API
How to use the generator
How to calculate the amount of calculation learned from ABC134-D
How to log in automatically like 1Password from the CLI
How to do the initial setup from Django project creation
How to use the decorator
How to increase the axis
How to start the program
[EC2] How to install and download chromedriver from the command line
How to extract the desired character string from a line 4 commands
How to resolve the error from toimage (from PIL.Image import fromarray as toimage)
How to calculate the autocorrelation coefficient
How to use the zip function
How to use the optparse module
How to use SWIG from waf
How to read the SNLI dataset
[Python] How to import the library
Hit the web API in Python
How to launch Explorer from WSL
How to overwrite the output to the console
How to access wikipedia from python
How to convert from .mgz to .nii.gz
How to use the ConfigParser module
From the introduction of GoogleCloudPlatform Natural Language API to how to use it
How to check local GAE from iPhone browser in the same LAN
Learning record (4th day) #How to get the absolute path from the relative path
Try using the Python web framework Django (1)-From installation to server startup
How to pass values to JavaScript variables directly from the [Django] template tag
How to display the progress bar (tqdm)
How to create a clone from Github
How to use the Spark ML pipeline
How to easily convert format from Markdown
How to check the version of Django
How to solve the bin packing problem
How to set the server time to Japanese time
[TF] How to use Tensorboard from Keras
How to utilize multi-core from multiple languages
[Linux] How to use the echo command
How to use the Linux grep command
How to get colored output to the console
How to access RDS from Lambda (python)
How to create a repository from media
How to use the IPython debugger (ipdb)
[Python] How to save images on the Web at once with Beautiful Soup
[Free] Hit the Clash Royale API from lambda and send it to LINE
[Python Tips] How to retrieve multiple keys with the maximum value from the dictionary
The story of switching the Azure App Service web system from Windows to Linux