MonPi
-an admin's favorite portable tool
by Ernest Stratoberdha
High-level
- Get resource usage:
- CPU
- Memory
- Bandwidth
- Visualize them using graphs
Pi setup
- Raspbian OS
- Static IP address
- VNC server
- Flask framework
Pi setup
- Python packages
- psutil
- matplotlib
- numpy
- Network tools
- tshark
Remote management
Home
- SSH tunneling for VNC
- Configurations on the network
- Port-forwarding
- OpenVPN on the router
Remote management
Networking Lab
- Port mirroring for Cisco switch 2960
- Public-facing
- Fail2ban
Home environment
Lab environment
2960 Cisco switch config
monitor session 1 source interface Gi0/24
monitor session 1 destination interface Gi0/12 ingress untagged vlan 99
Graphing
- tshark to capture packets
- psutils lib to get system usage
- flask to run web app
- matplotlib to build graphs
Graphing

Code
import os
import subprocess
import sys
import threading
from flask import Flask
from flask import render_template, abort
app = Flask(__name__)
app.debug = True
# function to call netcap.py script to capture traffic
def run_script():
theproc = subprocess.Popen(['python', 'netcap.py'])
theproc.communicate()
@app.route('/')
def index():
return render_template('index.html')
@app.route('/basics')
def basics():
return render_template('basics.html')
@app.route('/about')
def about():
return render_template('about.html')
@app.route('/generate')
def generate():
threading.Thread(target=lambda: run_script()).start()
return render_template('processing.html')
@app.route('/is_done')
def is_done():
hfile = "templates\itworked.html"
if os.path.isfile(hfile):
return render_template('itworked.html')
else:
abort(404)
if __name__ == "__main__":
app.run()
app.py
Code
import subprocess
import sys
import os.path
import psutil
print "Monitoring broadcast packets on the network..."
# loop range set arbitrarily for testing
for x in range(0, 10):
subprocess.call(['sudo tshark -i eth0 -a duration:2 -w /root/capfile'], shell=True)
# moving file to different location to avoid root permission problem
subprocess.call(['sudo mv /root/capfile /home/nestig/monpi/capfile'], shell=True)
# next 3 lines are calls to process output formatting of packets captured
pcap = subprocess.Popen(["sudo", "capinfos", "-yu", "/home/nestig/monpi/capfile"], stdout=subprocess.PIPE)
lrow = subprocess.Popen(["awk", "NR==3"], stdin=pcap.stdout, stdout=subprocess.PIPE)
dbrate = subprocess.Popen (["cut", "-c22-25"], stdin=lrow.stdout, stdout=subprocess.PIPE)
pcap.stdout.close() # close output stream
lrow.stdout.close() # close output stream
stdout, stderr = dbrate.communicate() # connects PIPE
sys.stdout.write(stdout) # no newline bullshit
infile = "/home/nestig/monpi/logs/network.txt" # path to the input file to be modified
openfile = open(infile, 'a')
space = " "
y = x * 5 # holds approximate intervals
# write the formatted data to file
openfile.write(str(y))
openfile.write(space)
openfile.write(stdout)
openfile.close()
# call psutils.py to get memory and cpu stats
subprocess.call(['python /home/nestig/monpi/psutils.py'], shell=True)
netcap.py
Code
psutils.py
# import the libraries needed
import sys
import subprocess
import psutil as ps
# demonstrate psutil for memory and cpu usages
print "Collecting info on RAM and CPU: "
for x in range(0, 10):
cpu = ps.cpu_percent(interval=2)
mem = ps.virtual_memory()
m = mem.used >> 20
mfile = "/home/nestig/monpi/logs/memory.txt"
cfile = "/home/nestig/monpi/logs/cpu.txt"
space = " "
newline = '\n'
y = x * 5 # arbitrarily set loop variable to get samples
# open memory log file
openfile = open(mfile, 'a')
openfile.write(str(y))
openfile.write(space)
openfile.write(str(m))
openfile.write('\n')
openfile.close()
# open cpu log file
openfile = open(cfile, 'a')
openfile.write(str(y))
openfile.write(space)
openfile.write(str(cpu))
openfile.write('\n')
openfile.close()
# call filedata_graph.py to plot
subprocess.call(['python /home/nestig/monpi/filedata_graph.py'], shell=True)
subprocess.call(['cat /dev/null > /home/nestig/monpi/logs/network.txt'], shell=True)
subprocess.call(['cat /dev/null > /home/nestig/monpi/logs/memory.txt'], shell=True)
subprocess.call(['cat /dev/null > /home/nestig/monpi/logs/cpu.txt'], shell=True)
Future
Add storage monitoring.
Add report features.
Improve front-end of MonPi.
Website
MonPi.net is alive!
Questions
?
MonPi
By Ernest Stratoberdha
MonPi
Senior Project
- 821