Showing posts with label Python. Show all posts
Showing posts with label Python. Show all posts

Tuesday, April 23, 2019

Uncomplicated Firewall with Python

Uncomplicated Firewall with Python

Uncomplicated Firewall, is an interface to iptables that simplifyies the process of configuring a firewall. Iptables is flexible, it can be difficult for beginners to learn how to use it to properly configure a firewall. 

In the example below is a python program that makes it easy allowing and blocking various services by IP address. 

## Description :
## Generate ip-host binding list for a list of nodes, when internal DNS is missing.
## 1. For existing nodes, allow traffic from new nodes
## 2. For new nodes, allow traffic from all nodes
##
## Sample:
## python ./ufw_allow_ip.py --old_ip_list_file /tmp/old_ip_list --new_ip_list_file /tmp/new_ip_list \
## --ssh_username root --ssh_port 22 --ssh_key_file ~/.ssh/id_rsa
##
##-------------------------------------------------------------------
import os, sys
import paramiko
import argparse
# multiple threading for a list of ssh servers
import Queue
import threading
import logging
log_folder = "%s/log" % (os.path.expanduser('~'))
if os.path.exists(log_folder) is False:
os.makedirs(log_folder)
log_file = "%s/%s.log" % (log_folder, os.path.basename(__file__).rstrip('\.py'))
logging.basicConfig(filename=log_file, level=logging.DEBUG, format='%(asctime)s %(message)s')
logging.getLogger().addHandler(logging.StreamHandler())
def get_list_from_file(fname):
l = []
with open(fname,'r') as f:
for row in f:
row = row.strip()
if row.startswith('#') or row == '':
continue
l.append(row)
return l
def ufw_allow_ip_list(server_ip, ip_list, ssh_connect_args):
if len(ip_list) == 0:
print("Skip run ufw update in %s, since ip_list is empty" % (server_ip))
return("OK", "")
[ssh_username, ssh_port, ssh_key_file, key_passphrase] = ssh_connect_args
ssh_command = ""
# TODO: improve this command, by using a library
for ip in ip_list:
ssh_command = "%s && ufw allow from %s" % (ssh_command, ip)
if ssh_command.startswith(" && "):
ssh_command = ssh_command[len(" && "):]
print("Update ufw in %s. ssh_command: %s" % (server_ip, ssh_command))
output = ""
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
key = paramiko.RSAKey.from_private_key_file(ssh_key_file, password=key_passphrase)
ssh.connect(server_ip, username=ssh_username, port=ssh_port, pkey=key)
stdin, stdout, stderr = ssh.exec_command(ssh_command)
output = "\n".join(stdout.readlines())
output = output.rstrip("\n")
print("Command output in %s: %s" % (server_ip, output))
ssh.close()
except:
return ("ERROR", "Unexpected on server: %s error: %s\n" % (server_ip, sys.exc_info()[0]))
return ("OK", output)
###############################################################
if __name__ == '__main__':
# get parameters from users
parser = argparse.ArgumentParser()
parser.add_argument('--old_ip_list_file', required=True, \
help="IP list of current cluster", type=str)
parser.add_argument('--new_ip_list_file', required=True, \
help="IP list of new nodes", type=str)
parser.add_argument('--ssh_username', required=False, default="root", \
help="Which OS user to ssh", type=str)
parser.add_argument('--ssh_port', required=False, default="22", \
help="Which port to connect sshd", type=int)
parser.add_argument('--ssh_key_file', required=False, default="%s/.ssh/id_rsa" % os.path.expanduser('~'), \
help="ssh key file to connect", type=str)
parser.add_argument('--key_passphrase', required=False, default="", \
help="Which OS user to ssh", type=str)
l = parser.parse_args()
ssh_connect_args = [l.ssh_username, l.ssh_port, l.ssh_key_file, l.key_passphrase]
old_ip_list = get_list_from_file(l.old_ip_list_file)
new_ip_list = get_list_from_file(l.new_ip_list_file)
has_error = False
# TODO: speed up this process by multiple threading
for old_ip in old_ip_list:
(status, output) = ufw_allow_ip_list(old_ip, new_ip_list, ssh_connect_args)
if status != "OK":
has_error = True
print("Error in %s. errmsg: %s" % (old_ip, output))
for new_ip in new_ip_list:
(status, output) = ufw_allow_ip_list(new_ip, new_ip_list + old_ip_list, ssh_connect_args)
if status != "OK":
has_error = True
print("Error in %s. errmsg: %s" % (new_ip, output))
if has_error is True:
sys.exit(1)
#!/usr/bin/python


Monday, February 20, 2017

Application Centric Infrastructure with Python


In application-centric networking, troubleshooting does not mean logging into discrete devices and examining networking state information. If a web application is not performing, you start with the web application. The fact that relevant state information might exist within a router, switch, or even a web server is secondary. You want to gather intelligence on the application itself. That data needs to be collected and correlated. And you aren’t done until the application is up and running as it should.

There are several questions you need to ask: Can you see how applications are talking across your network? For distributed applications, do you have a view of which components are where? Can you see how data is flowing between them?

Here I would like to present a small Python programm that I adapted from the Cisco code repository. 

# Copyright (c) 2015 Cisco Systems #

# All Rights Reserved. 
"""
Simple application that logs on to the APIC and displays all
of the Interfaces.
"""
import sys
import re
import json
import acitoolkit.acitoolkit as aci


def main():
    """
    Main execution routine
    :return: None
    """
    # Take login credentials from the command line if provided
    # Otherwise, take them from your environment variables file ~/.profile
    description = 'Simple application that logs on to the APIC and displays all of the Interfaces.'
    creds = aci.Credentials('apic', description)
    args = creds.get()

    # Login to APIC
    session = aci.Session(args.url, args.login, args.password)
    resp = session.login()
    if not resp.ok:
        print('%% Could not login to APIC')
        sys.exit(0)

    resp = session.get('/api/class/ipv4Addr.json')
    intfs = json.loads(resp.text)['imdata']
    data = {}

    for i in intfs:
        ip = i['ipv4Addr']['attributes']['addr']
        op = i['ipv4Addr']['attributes']['operSt']
        cfg = i['ipv4Addr']['attributes']['operStQual']
        dn = i['ipv4Addr']['attributes']['dn']
        node = dn.split('/')[2]
        intf = re.split(r'\[|\]', dn)[1]
        vrf = re.split(r'/|dom-', dn)[7]
        if vrf not in data.keys():
            data[vrf] = []
        else:
            data[vrf].append((node, intf, ip, cfg, op))

    for k in data.keys():
        header = 'IP Interface Status for VRF "{}"'.format(k)
        print header
        template = "{0:15} {1:10} {2:20} {3:8} {4:10}"
        print(template.format("Node", "Interface", "IP Address ", "Admin Status", "Status"))
        for rec in sorted(data[k]):
            print(template.format(*rec))

if __name__ == '__main__':
main()

With the help of the ACI Toolkit library from Cisco we could define and create many functions and procedures needed to manipulate and programm the ACI Fabric. As an universal data format JSON is used to retrieve data from the APIC controller. The data interested to us are VRFs, IPs, VLANs and so on. In the final function we define a loop that that will search for all of the the values stored inside the dictionary data structure from Python and sort them using a template.


For those wanted to know more about the ACI please checkout the source text from the SDX Central.

Cisco ACI is a tightly coupled policy-driven solution that integrates software and hardware. The hardware for Cisco ACI is based on the Cisco Nexus 9000 family of switches. The software and integration points for ACI include a few components, including Additional Data Center Pod, Data Center Policy Engine, and Non-Directly Attached Virtual and Physical Leaf Switches. While there isn’t an explicit reliance on any specific virtual switch, at this point, policies can only be pushed down to the virtual switches if Cisco’s Application Virtual Switch (AVS) is used, though there has been talk about extending this to Open vSwitch in the near future.

In a leaf-spine ACI fabric, Cisco is provisioning a native Layer 3 IP fabric that supports equal-cost multi-path (ECMP) routing between any two endpoints in the network, but uses overlay protocols, such as virtual extensible local area network (VXLAN) under the covers to allow any workload to exist anywhere in the network. Supporting overlay protocols is what will give the fabric the ability to have machines, either physical or virtual, in the same logical network (Layer 2 domain), even while running Layer 3 routing down to the top of each rack. Cisco ACI supports VLAN, VXLAN, and network virtualization using generic routing encapsulation (NV-GRE), which can be combined and bridged together to create a logical network/domain as needed.

From a management perspective, the central SDN Controller of the ACI solution, the Application Policy Infrastructure Controller (APIC) manages and configures the policy on each of the switches in the ACI fabric. Hardware becomes stateless with Cisco ACI, much like it is with Cisco’s UCS Computing Platform. This means no configuration is tied to the device. The APIC acts as a central repository for all policies and has the ability to rapidly deploy and re-deploy hardware, as needed, by using this stateless computing model.

Feel free to comment.

Tuesday, October 15, 2013

File permissions list in Python

Python script file permissions list


In this small blog I will demonstrate a easy way to show listed file permissions in a Linux Distro environment. This simple script written in Python language, will use the find command under the linux shell and display results with the permissions assigned to a particular file.
Now let us take a look at the code:

<<<CODE>>>
import stat, sys, os, string, commands
#try block with a search pattern 
try:
    #run a 'find' command and assign results to a variable
    pattern = raw_input("Enter the file pattern to search for:\n")
    commandString = "find " + pattern
    commandOutput = commands.getoutput(commandString)
    findResults = string.split(commandOutput, "\n")

    #output find results, along with permissions
    print "Files:"
    print commandOutput
    print "================================"
    for file in findResults:
        mode=stat.S_IMODE(os.lstat(file)[stat.ST_MODE])
        print "\nPermissions for file ", file, ":"
        for level in "USR", "GRP", "OTH":
            for perm in "R", "W", "X":
                if mode & getattr(stat,"S_I"+perm+level):
                    print level, " has ", perm, " permission"
                else:
                    print level, " does NOT have ", perm, " permission"
except:
    print "There was a problem - check the message above"

<<</CODE>>>


Now you can take your favorite Linux text editor and save this code under a "check_F.py" file. I have created three files with different permissions to demonstrate how this script work.


As we can see there are 3 files: test01.txt, test02.tiff and test03.cdr. Now to display the list of file permissions for these file we have to run the check_F.py script. This can be achieved under the shell using the following syntax:  "python check_F.py". Next thing we can do is to type a beginning of the file name with a star sign  "t*". Then we can look at the output.



And we get a fine table output with user, group and everyone permission defined for each file. These files are listed under the current folder, but everyone can choose any other folder using the default find syntax "/etc/t*"

This is all for now. 

Feel free to comment.