Improving the RaspIDS Autoconfig Script

Now that I’ve finished my last exam of my degree and waiting for my marks to find out if I’ve passed or not I decided to revisit the auto-configuration bash script that I wrote for the individual major project I for the degree where I create an inline IDS device based on the Raspberry Pi device. The problem with the original auto-configuration script was that it just configured the device into one state all the time on boot, so if a interface/device is missing at the time of the boot the bash script would just could executing anyways. I decided I wanted a script which would configure the device at boot based on what devices/interfaces were connected, though the original script I wrote was fine for the purpose of my major project. The below bash script was the original auto-configuration script for the project.

#!/bin/bash
# Configures the virtual bridge between the two physical interfaces.
ifconfig eth0 0.0.0.0
ifconfig eth1 0.0.0.0
brctl addbr bridge0
brctl addif bridge0 eth0
brctl addif bridge0 eth1
ifconfig bridge0 up
# Configures Snort and TCPdump tools to begin listen and inspecting
# the network traffic that travels through the bridge interface.
TCPdump -i bridge0 -w /root/IDS-log/networkdump/network-traffic-$(date +%y%m%d).cap &;
Snort -i bridge0 -v |tee /root/IDS-log/snortdump/Snort-dump-$(date +%y%m%d) &;

So now that I’ve decided I wanted to create a better auto-configuration script which will configure the device based on the what the peripheral devices are connected to the Raspberry Pi board at the boot time I need to make a list of what I want this script to achieve. In which I came up with the following list which will become the new project scope for the auto-configuration script:

  1. If interface “eth1”  is plugged into board at the time of boot, configure both eth0 and eth1 to have IP address of 0.0.0.0. And then create a bridge interface and add both eth0 and eth1 interfaces to the bridge configuration.
  2. If interface wlan0 is detected during the boot process, have the device scan for wireless networks and if the Olympus network is detected, connect to the network and request a DHCP IP address from a DHCP server from the network.
  3. If configuring of the interfaces into states outlined above is successful, then I want the script to initialise the IDS functionality:
    • Check to see if logfile directories exist in the operating system, if found in defined location, if not create the logfile directories.
    • Check to see if the logfile within the directories are archived to save space but still have a record of the logs, if not archived then archive the logs into single archives, if archive exists then delete the logfile.
    • Start tcpdump and snort listening on the bridge interface create in point 1.
  4. If interfaces eth0 and wlan0 are detect but not eth1 then scan for the wireless network called Olympus and connect, once connected to the network then request a IP address via DHCP on the wireless interface.
  5. If Unable to connect to the Olympus network and the interface eth1 was not detected, then the devices request an IP address for eth0 via DHCP.

So with my new scope defined I decided that I would write this new auto-configuration script in the Python programming language.

#!/usr/bin/python
import os
import sys
import subprocess
import string
import fnmatch

#######################################################################
### CHECK SCRIPT FOR "# Hardcoded!" lines before going live!!!		###
### Python script to configure Raspberry Pi as an inline-IDS device	###
#######################################################################

# Detects if interface is connected to device.
eth0, eth1, wlan0, ws0 = ([] for i in range(4))
eth0 = str.split(subprocess.Popen("ifconfig |grep eth0", stdout=subprocess.PIPE, shell=True).stdout.read())
eth1 = str.split(subprocess.Popen("ifconfig |grep eth1", stdout=subprocess.PIPE, shell=True).stdout.read())
wlan0 = str.split(subprocess.Popen("ifconfig |grep wlan0", stdout=subprocess.PIPE, shell=True).stdout.read())

# IF Statement that configures the device's networking interfaces.
if (eth0[0] == 'eth0') & (eth1[0] == 'eth1') & (wlan0[0] == 'wlan0'):
 # Code that sets the two ethernet interfaces if found to accept any incoming traffic from both interfaces and
 # then bridges the two interfaces together to forward the traffic from one to the other.
 print("Setting the Ethernet Interfaces to passive mode.")
 subprocess.Popen("ifconfig eth0 0.0.0.0", stdout=subprocess.PIPE, shell=True).stdout.read()
 subprocess.Popen("ifconfig eth1 0.0.0.0", stdout=subprocess.PIPE, shell=True).stdout.read()
 print("eth0 & eth1 have been configured with IP address 0.0.0.0!")
 print("Now configuring the interface bridge for eth0 and eth1.")
 subprocess.Popen("brctl addbr bridge0", stdout=subprocess.PIPE, shell=True).stdout.read()
 subprocess.Popen("brctl addif eth0", stdout=subprocess.PIPE, shell=True).stdout.read()
 subprocess.Popen("brctl addif eth1", stdout=subprocess.PIPE, shell=True).stdout.read()
 subprocess.Popen("ifconfig bridge0 up", stdout=subprocess.PIPE, shell=True).stdout.read()

 # Code scans for wireless networks on wireless interface, if hardcoded wireless network (SSID/ESSID) is found in
 # ws0 variable then connect to that network using hardcoded credentials and request DHCP IP address.
 print('Bringing up wireless interface')
 subprocess.Popen('ifconfig wlan0 up', stdout=subprocess.PIPE, shell=True).stdout.read()
 print('Scanning for wireless networks')
 ws0 = str.split(subprocess.Popen('iwlist wlan0 scan', stdout=subprocess.PIPE, shell=True).stdout.read())
 if 'ESSID:"Olympus"' in ws0:
  print('Olympus network was found!')
  print('Now trying to connect to the Olympus network!')
  subprocess.Popen("echo 'auto wlan0' >> /etc/network/interfaces", stdout=subprocess.PIPE, shell=True).stdout.read()				# Hardcoded!
  subprocess.Popen("echo 'iface wlan0 inet dhcp' >> /etc/network/interfaces", stdout=subprocess.PIPE, shell=True).stdout.read()		# Hardcoded!
  subprocess.Popen("echo ' wpa-ssid Olympus' >> /etc/network/interfaces", stdout=subprocess.PIPE, shell=True).stdout.read()			# Hardcoded!
  subprocess.Popen("echo ' wpa-psk "pre-shared key"' >> /etc/network/interfaces", stdout=subprocess.PIPE, shell=True).stdout.read()	# Hardcoded!
  print("Restarting network daemon...")
  subprocess.Popen("service networking restart", stdout=subprocess.PIPE, shell=True).stdout.read()
  print("Restarting SSH daemon...")
  subprocess.Popen("service ssh restart", stdout=subprocess.PIPE, shell=True).stdout.read()

 # Function that sets the IDS applications up.
 # IF statement that checks to see if logfile directories exists on system, if false creates the directories.
 if (os.path.exists("/tmp/tcpdump_dump/") & os.path.exists("/tmp/snort_dump/") == False):
  subprocess.Popen('mkdir -p /tmp/tcpdump_dump/', stdout=subprocess.PIPE, shell=True).stdout.read()
  subprocess.Popen('mkdir -p /tmp/snort_dump/', stdout=subprocess.PIPE, shell=True).stdout.read()

 # Checks to see if there is currently any files in the logfile directories and if there is and they aren't .tar.gz archives to archive the
 # file and then delete the archived file.
 dirname = string.split("/tmp/tcpdump_dump/ /tmp/snort_dump/")
 for path_to_dir in dirname:
  print("Now checking dir: " + path_to_dir)
  files_in_dir = os.listdir(path_to_dir)
  for file in files_in_dir:
   if file == "":
    print("No files found!")

   if fnmatch.fnmatch(file, "*.tar.gz"):
    print("These archive already exist for: " + file)
   else:
    print("Attempting to archive: " + file)
    subprocess.Popen("tar cvzfP " + (path_to_dir + file) + ".tar.gz "  + path_to_dir + file + " --remove-files", stdout=subprocess.PIPE, shell=True).stdout.read()

 # Initialises the IDS applications.
 print("Starting tcpdump now!")
 subprocess.Popen('tcpdump -i bridge0 -vv >> /tmp/tcpdump_dump/network_traffic_`date +%y%m%d`.cap &', stdout=subprocess.PIPE, shell=True).stdout.read()
 print("Restarting the snort daemon...")
 subprocess.Popen('service snort restart', stdout=subprocess.PIPE, shell=True).stdout.read()
 print("Starting snort now!")
 subprocess.Popen('snort -i bridge0 -v >> /tmp/snort_dump/snort_dump_`date +%y%m%d` &', stdout=subprocess.PIPE, shell=True).stdout.read()
 print("RaspIDS is ready and listening for traffic...")

# If no eth1 interface is not detected!
elif (eth0[0] == 'eth0') & (eth1[0] != 'eth1'):

 # If eth1 interface is not detected but wlan0 is, then configures the wireless interface to connect to 'Olympus' network.
 if (wlan0[0] == 'wlan0'):
  # Code scans for wireless networks on wireless interface, if hardcoded wireless network (SSID/ESSID) is found in
  # ws0 variable then connect to that network using hardcoded credentials and request DHCP IP address.
  print('Bringing up wireless interface')
  subprocess.Popen('ifconfig wlan0 up', stdout=subprocess.PIPE, shell=True).stdout.read()
  print('Scanning for wireless networks')
  ws0 = str.split(subprocess.Popen('iwlist wlan0 scan', stdout=subprocess.PIPE, shell=True).stdout.read())
  if 'ESSID:"Olympus"' in ws0:
   print('Olympus network was found!')
   print('Now trying to connect to the Olympus network!')
   subprocess.Popen("echo 'auto wlan0' >> /etc/network/interfaces", stdout=subprocess.PIPE, shell=True).stdout.read()				# Hardcoded!
   subprocess.Popen("echo 'iface wlan0 inet dhcp' >> /etc/network/interfaces", stdout=subprocess.PIPE, shell=True).stdout.read()	# Hardcoded!
   subprocess.Popen("echo ' wpa-ssid Olympus' >> /etc/network/interfaces", stdout=subprocess.PIPE, shell=True).stdout.read()		# Hardcoded!
   subprocess.Popen("echo ' wpa-psk "pre-shared key"' >> /etc/network/interfaces", stdout=subprocess.PIPE, shell=True).stdout.read()	# Hardcoded!
   subprocess.Popen("service networking restart", stdout=subprocess.PIPE, shell=True).stdout.read()
   subprocess.Popen("service ssh restart", stdout=subprocess.PIPE, shell=True).stdout.read()

  # If can't connect to the hardcoded wireless network the else statement attempts to get an IP address via DHCP for eth0 interface.
  else:
   subprocess.Popen("dhclient eth0", stdout=subprocess.PIPE, shell=True).stdout.read()
 else:
  subprocess.Popen("dhclient eth0", stdout=subprocess.PIPE, shell=True).stdout.read()

# If no eth1 or wlan0 interfaces detected then DHCP on eth0 interface.
else:
 subprocess.Popen("dhclient eth0", stdout=subprocess.PIPE, shell=True).stdout.read()

Once I had the script written and tested all that was left to do was to setup the auto-configuration portion, I simply just used the same technique as I did in the major project initially.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s