Commit 4847070d authored by Olav Kvittem's avatar Olav Kvittem

Merge branch 'microdep' into 'master'

Microdep

See merge request iou/microdep!1
parents cd2bc612 b887b8ff
Package: microdep
Priority: extra
Section: uninett
Architecture: all
Depends: rude, crude, traceroute, perl-base, cron, libstatistics-linefit-perl, libjson-xs-perl, libdatetime-perl
Maintainer:olav.kvittem@uninett.no
Version: {VERSION}
Provides: microdep
Replaces: microdep
Description: Software for measuring network using rude/crude and traceroute.
#! /bin/sh
echo microdep 'ALL=(ALL) NOPASSWD: /usr/local/sbin/get-icmp.sh' > /etc/sudoers.d/microdep
cp /home/microdep/microdep/bin/get-icmp.sh /usr/local/sbin/
find /home/microdep -not -user microdep -exec chown microdep.microdep \{} \;
if test -e /usr/bin/crude -a ! -e /home/microdep/microdep/bin/crude ; then
sudo -u microdep ln -s /usr/bin/rude /home/microdep/microdep/bin/
sudo -u microdep ln -s /usr/bin/crude /home/microdep/microdep/bin/
fi
mkdir -p /var/log/mp-rude
chown microdep.microdep /var/log/mp-rude
sudo -u microdep /home/microdep/microdep/bin/update-config
crontab -u microdep /home/microdep/microdep/etc/crontab.cfg
#! /bin/sh
if ! test -d /home/microdep ; then
useradd -m -G ssh microdep
fi
#! /bin/sh
if test -d /home/microdep/bin ; then
if test -l /home/microdep/bin/rude ; then
rm /home/microdep/bin/rude
rm /home/microdep/bin/crude
fi
fi
crontab -u microdep -r
rm /etc/sudoers.d/microdep
FROM debian:buster
WORKDIR /root/
COPY microdep microdep
COPY build.sh build.sh
RUN ./build.sh
CMD tar c *.deb
Scripts to run rude/crude, traceroute and collect results
#Set up client
#Manual set up client
##on client
~~~~~
......@@ -10,18 +10,27 @@ Scripts to run rude/crude, traceroute and collect results
apt install libpcap-dev
git clone https://scm.uninett.no/rude/rude.git
compile and link up in dragonlab/bin
compile and link up in microdep/bin :
ln -s ~/rude/rude/rude .
ln -s ~/rude/crude/crude .
add to /etc/sudoers.d/dragonlab
$USER ALL=(ALL) NOPASSWD: /usr/sbin/tcpdump
add to /etc/sudoers.d/microdep
$USER ALL=(ALL) NOPASSWD: /usr/local/sbin/get-icmp
~~~~~
## Edit ~/microdep/etc/local.cfg :
#node_name=<node name> # default full domainame
#config_url=https://drift.uninett.no/microdep/dragonlab-rude.conf
## make initial config
### Start polling when ready :
crontab dragonlab/etc/crontab.cfg
crontab microdep/etc/crontab.cfg
##on server
##--------------------------------------------------------------------------------
##on server when running with central push :
rsync -rvt dragonlab user@host:
......
......@@ -2,7 +2,7 @@
# start measurement jobs if not running
export USER=$(whoami)
source $HOME/dragonlab/etc/start.cfg
source $HOME/microdep/etc/start.cfg
stop=no
if test $# -gt 0; then
......@@ -12,9 +12,23 @@ T=$(env TZ=Europe/Oslo date +%T)
Tm=$(env TZ=Europe/Oslo date +%H:%M)
mkdir -p $logpath/$date
logdir=$logpath/$date
PIPE=$logdir/crude.pipe
PIPE2=$logdir/crude2.pipe
if test ! -p $PIPE ; then
mkfifo $PIPE
fi
if test ! -p $PIPE2 ; then
mkfifo $PIPE2
fi
if test $Tm = "00:00" -o $stop = yes; then
pkill -u $USER -f $crude || echo crude kill failed
pkill -u $USER -f $root/bin/crude-zip
pkill -u $USER -f 'cat /home/microdep/microdep/data/'
pkill -u $USER -f $root/bin/crude-ana
pkill -u $USER -f $rude || echo rude kill failed
pkill -u $USER -f $trace || echo trace kill failed
pkill -u $USER -f $tcptrace || echo tcptrace kill failed
......@@ -22,28 +36,35 @@ if test $Tm = "00:00" -o $stop = yes; then
pkill -u $USER -f $vmstat || echo vmstat kill failed
sleep 3 # allow previous days proceses to die
fi
if ! pgrep -u $USER -f $crude >/dev/null; then
$crude -k -p $crude_port | gzip -c > $logpath/$date/crude-$T.gz 2> /dev/null&
fi
if ! pgrep -u $USER -f $rude >/dev/null; then
$rude -s $rudecfg > /dev/null 2> /dev/null &
fi
# crude outputs to a pipe that is read my tee to qstream-gap-ana
if ! pgrep -u $USER -f $crude >/dev/null; then
$crude -k -p $crude_port >> $PIPE &
fi
if ! pgrep -u $USER -f $root/bin/crude-zip >/dev/null; then
$root/bin/crude-zip $PIPE $PIPE2 $logpath/$date/crude-$T.gz &
fi
if ! pgrep -u $USER -f $root/bin/crude-ana >/dev/null; then
$root/bin/crude-ana "$index" $PIPE $event_dir/${index}-events-`date +%a`.log &
fi
if ! pgrep -u $USER -f $trace >/dev/null; then
$HOME/dragonlab/bin/start-trace.sh
$HOME/microdep/bin/start-trace.sh
fi
if ! pgrep -u $USER -f $tcptrace >/dev/null; then
$HOME/dragonlab/bin/start-tcptrace.sh
$HOME/microdep/bin/start-tcptrace.sh
fi
if ! pgrep -u $USER -f $vmstat >/dev/null; then
$vmstat 2> /dev/null > /dev/null&
$vmstat 2> /dev/null > /dev/null &
fi
if ! pgrep -u root -f '/usr/sbin/tcpdump.* icmp' >/dev/null; then
$HOME/dragonlab/bin/start-icmp.sh
$HOME/microdep/bin/start-icmp.sh &
fi
#!/bin/bash
# kill mp-rude measurements at midnight CET
source $HOME/dragonlab/etc/start.cfg
source $HOME/microdep/etc/start.cfg
T=$(env TZ=Europe/Oslo date +%T)
if test $T = "00:00:00"; then
......
#! /bin/sh
set -e
INDEX=$1
PIPE=$2
LOG=$3
. $HOME/microdep/etc/start.cfg
if test -f "$LOG"; then
find "$LOG" -maxdepth 1 -mtime +5 -name '*.log' -type f -delete
fi
cat $PIPE | $root/bin/qstream-gap-ana \
-index $INDEX -json $LOG -minloss 5 -head -win 50 -jitter 60 -
exit 0
#! /bin/sh
set -e
cat "${1}" | tee "${3}" | gzip >> "${2}"
#!/bin/bash
# catch icmp tgraffic on default route
IF=`ip route get 158.38.62.1 | perl -ne 'print $1 if / dev (\w+) /'`
if test "$IF" != ""
then
tomidnight=$((`date --date 'tomorrow 00:00' +%s`-`date +%s` - 1))
/usr/sbin/tcpdump -i $IF -G $tomidnight -W 1 -w - icmp &
fi
#!/bin/sh
source $HOME/dragonlab/etc/start.cfg
source $HOME/microdep/etc/start.cfg
id=`ps xa | grep ntx7 | grep mapidump | awk '{print $1}'`
......
echo add to /etc/sudoers.d/microdep.sudo
sudo echo $USER 'ALL=(ALL) NOPASSWD: /usr/local/sbin/get-icmp.sh' > /etc/sudoers.d/microdep.sudo
touch $HOME/microdep/etc/tcpdump-imcp
\ No newline at end of file
#!/bin/bash
source $HOME/dragonlab/etc/start.cfg
source $HOME/microdep/etc/start.cfg
> $logpath/$date/ntp.gz
......
This diff is collapsed.
......@@ -4,6 +4,7 @@
my $target;
my $list='mp-list.txt';
my $default_port=10001;
use Getopt::Long;
@opts=( 'target=s' => \$target, 'list=s' => \$list);
......@@ -17,6 +18,9 @@ while(<LIST>){
$dns{$name}=$dns;
$port{$name}=$port;
}
if ($target && ! $port{$target} ){
$port{$target} = $default_port;
}
use Socket;
while(<>){
......@@ -28,19 +32,6 @@ while(<>){
}
}
$startcfg='
logpath="$HOME/dragonlab/data"
rudecfg="$HOME/dragonlab/etc/rude.cfg"
dump="$HOME/dragonlab/bin/starttcpdump.sh"
trace="$HOME/dragonlab/bin/trace.sh"
tcptrace="$HOME/dragonlab/bin/tcptrace.sh"
trace6="$HOME/dragonlab/bin/trace6.sh"
vmstat="$HOME/dragonlab/bin/vmstat.sh"
ntp="$HOME/dragonlab/bin/ntp-jitter.sh"
crude="$HOME/dragonlab/bin/crude"
rude="$HOME/dragonlab/bin/rude"
date=`env TZ=Europe/Oslo date +%Y%m%d`
';
my $flow_no=1;
my $rude; # fd to write config
......@@ -87,7 +78,8 @@ foreach $peer ( sort(keys %peers)){
}
if ($gotit){
if ($ip ){
printf $rude "0 %d ON 300%d %s:%s CONSTANT 100 64\n", $flow_no, $flow_no,$ip,$port{$dst};
printf $rude "0 %d ON 300%d %s:%s CONSTANT 100 64\n", $flow_no, $flow_no, $ip,
$port{$dst} || $default_port;;
printf $rude "90010000 %d OFF\n", $flow_no; # varer en dag +10 sek skuddr
@$tracetarget{$src} = () if ! $tracetarget{$src};
push (@{$tracetarget{$src}}, $ip );
......@@ -102,13 +94,14 @@ foreach $peer ( sort(keys %peers)){
close RUDE;
close $rude;
foreach $name ( keys %port){
if ( (! $target) || ( $target eq $name ) ){
$outdir=$name;
if ( -d $outdir ){
open ( $start, ">$outdir/start.cfg") || die "Could not open ${outdir}/start.cfg : $!" ;
printf $start "crude_port=%s\n", $port{$name};
printf $start "%s", $startcfg;
open ( $start, ">$outdir/parms.cfg") || die "Could not open ${outdir}/parms.cfg : $!" ;
printf $start "crude_port=%s\n", $port{$name} ;
# printf $start "%s", $startcfg;
close $start;
}
}
......
#!/bin/bash
. $HOME/microdep/etc/start.cfg
dato=`date +%F-%T`
sudo /usr/local/sbin/get-icmp.sh > ${logpath}/icmp-$dato.pcap 2> ${logpath}/icmp.log
#!/bin/bash
source $HOME/microdep/etc/start.cfg
IF=`ip route get 158.38.62.1 | perl -ne 'print $1 if / dev (\w+) /'`
if test "$IF" != ""
then
tomidnight=$((`date --date 'tomorrow 00:00' +%s`-`date +%s` - 1))
/usr/sbin/tcpdump -i $IF -G $tomidnight -W 1 -w ${logpath}/icmp-%F-%T.pcap icmp 2> ${logpath}/icmp.log
fi
#!/bin/bash
source $HOME/dragonlab/etc/start.cfg
tracetargets=`cat $HOME/dragonlab/etc/trace.cfg`
source $HOME/microdep/etc/start.cfg
tracetargets=`cat $HOME/microdep/etc/trace.cfg`
if [ ! -d $logpath/$date ]
......
#!/bin/bash
source $HOME/dragonlab/etc/start.cfg
tracetargets=`cat $HOME/dragonlab/etc/trace.cfg`
source $HOME/microdep/etc/start.cfg
tracetargets=`cat $HOME/microdep/etc/trace.cfg`
if [ ! -d $logpath/$date ]
......
#!/bin/bash
source $HOME/dragonlab/etc/start.cfg
source $HOME/microdep/etc/start.cfg
if [ -e $logpath/pids ]
then
......@@ -31,4 +31,4 @@ $rude -s $rudecfg > /dev/null 2> /dev/null &
echo "$!" >> $logpath/pids
$HOME/dragonlab/bin/start-trace.sh
$HOME/microdep/bin/start-trace.sh
#!/bin/bash
source $HOME/dragonlab/etc/start.cfg
source $HOME/microdep/etc/start.cfg
if [ ! -e $logpath/pids ]
then
......@@ -10,6 +10,6 @@ fi
for i in $(cat $logpath/pids); do kill $i; done
#ok sudo $HOME/dragonlab/bin/killtcpdump.sh
#ok sudo $HOME/microdep/bin/killtcpdump.sh
rm $logpath/pids
#!/bin/bash -x
source $HOME/dragonlab/etc/start.cfg
source $HOME/microdep/etc/start.cfg
> $logpath/$date/tcptraceroute_$1.gz
......
#!/bin/bash
source $HOME/dragonlab/etc/start.cfg
source $HOME/microdep/etc/start.cfg
log=$logpath/$date/traceroute_$1
......
#!/bin/bash
source $HOME/dragonlab/etc/start.cfg
source $HOME/microdep/etc/start.cfg
> $logpath/$date/traceroute_$1.gz
......
#!/bin/sh
# pick up changed config either in /etc or on web address
. $HOME/microdep/etc/start.cfg
if test -s /etc/mp-rude/rude-list.conf ; then # distributed by puppet
if test ! -s $root/etc/rude.conf -o /etc/mp-rude/rude-list.conf -nt $root/etc/rude.conf; then
cd $root/etc
$root/bin/rude-config-maker -target "$node_name" /etc/mp-rude/rude-list.conf
fi
else # get config from server
tmp=/tmp/rude-list.conf$$
curl -z $root/etc/rude-list.conf -o $tmp "$config_url"
if test -s $tmp ; then
cd $root/etc
cp $tmp $root/etc/rude-list.conf
$root/bin/rude-config-maker -target "$node_name" $root/etc/rude-list.conf
fi
if test -f $tmp; then
rm $tmp
fi
fi
#!/bin/bash
source $HOME/dragonlab/etc/start.cfg
source $HOME/microdep/etc/start.cfg
vmstat | perl -e 'while(<>) { $utc=`date -u +%s`; chop $utc; print "$utc $_"; }' | gzip -c > $logpath/$date/vmstat.gz
......
#! /bin/bash
set -e
rm -f *.deb
if [ -f /.dockerenv ]; then
apt-get update
apt-get -y upgrade
fi
package="microdep"
version="0.5"
target="${package}_${version}_all"
rm -rf "$target"
mkdir -p "$target"/home/microdep/microdep
cp -dR --preserve=mode bin etc "${target}"/home/microdep/microdep/
cp -dR --preserve=mode DEBIAN "${target}"/
sed -i -e "s/{VERSION}/${version}/" "${target}/DEBIAN/control"
chmod o-w -R "${target}"
dpkg -b "$target"
ls -l *.deb
echo add to /etc/sudoers.d/dragonlab
echo $USER 'ALL=(ALL) NOPASSWD: /usr/sbin/tcpdump'
echo touch $HOME/dragonlab/etc/tcpdump-imcp
\ No newline at end of file
#!/usr/bin/perl
# use PDL;
# use PDL::Ops;
# use PDL::Fit::Polynomial;
use Socket;
use Statistics::LineFit;
# date --date 'jan 1 2000' +%s
$min_tx=946681200;
$max_tx=1893452400; # 2030-01-01
$maxseqreorder=1000; #
$max_small_gap=10; # the max size of a small graph
$max_small_graphs=20;
$max_big_graphs=20;
$late_delay=3; # seconds to doom a packet late
require "newgetopt.pl";
$usage="$0 '[-title text] [-minloss n] [-win n] [-graph file] [max-small-graphs n] [-outdir dir] [-head|-rhead] [-id id] [-names file] [-json file] [-v] [file]...
Analyse gaps in a crude packet log
- output a list of statistical qos parameters as text or json
- make linear regression to see the delay trend around a gap
- make curves to show the delay change before and after a gap
Parameters
-rhead n - output headers so that R can make the headings in the text tables
-max-small-graphs n - limit number(20) of graphs to output from small few packet losses
-slep n - number(1000) of crude lines in the circular buffer
-json file - filename to store json event documents (intended for logstash ?)
";
&NGetOpt( 'h', 'help', 'id=s', 'slep=s', 'minloss=s', 'win=s', 'max-small-graphs=s', 'head', 'rhead', 'graph=s', 'outdir=s', 'title=s', 'names=s', 'json=s', 'v') || die "$!" . $usage ."\n";
if ( $opt_h || $opt_help) {
printf "$usage\n";
exit(0);
}
my @heads= qw/id date time tunix x1 nloss tloss seqloss x2 seqtail overlap x3 h_n h_jit h_ddelay h_delay h_min_d h_slope_10 h_slope_20 h_slope_30 h_slope_40 h_slope_50 x4 t_n t_jit t_ddelay t_delay t_min_d t_slope_10 t_slope_20 t_slope_30 t_slope_40 t_slope_50/;
if ($opt_rhead){
my @a=split(" ", $head);
my $h="";
foreach $a (@heads ){
$h.='"'.$a.'", ' }
chop($h); chop($h); # remove ', '
printf 'head<-c(' . $h . ")\n";
#id", "date", "time", "tunix", "x1", "nloss", "tloss", "seqloss", "x2", "seqtail", "overlap", "x3", "head_n", "head_jit", "head_ddelay", "head_delay", "head_slope", "x4", "tail_n", "tail_jit", "tail_ddelay", "tail_delay", "tail_slope_10", "tail_slope_20")'; printf "\n";
exit 0;
}
my %hix=(); # hash on name to index in @heads
foreach $i(0..$#heads){
$hix{$heads[$i]}=$i;
}
my $coder; # json coder
if ( $opt_json){
require JSON::XS;
my $json=$opt_json;
open JSON, ">$json" || die "Could not open $json ; $!";
$coder = JSON::XS->new->ascii->pretty->allow_nonref;
$encoder=$coder->canonical([1]);
}
if ($opt_graph){
require Chart::Clicker;
require Chart::Clicker::Data::Series;
require Chart::Clicker::Data::DataSet;
require Chart::Clicker::Renderer::Point;
}
if ( $opt_names){
get_names($opt_names);
}
$maxslep=$opt_slep || 1000 ;
$maxhead=$opt_win || 10; # packets to keep before
$maxtail=$opt_win || 10; # packets to keep after
$min_slopes=5; # slopes to report on text report
$minloss= $opt_minloss || 1;
$minrecover = $opt_recover || 5;
$outdir=$opt_outdir || ".";
$title=$opt_title || 'Delay';
$bv_fmt='^([\d]+)\s+([\d\.\:]+)\s+([\d\.]+)\s+([\d\.]+)'; # BV's condensed format for crude
$id= $opt_id || "ukjent" ;
my %npackets=(); # keep track of all ids
my $print_line;
my %duration; # seconds per id
read_crude();
if ( $opt_v ){
foreach $id ( sort keys %dupl){
printf STDERR "%-30s %d duplicates\n", $id, $dupl{$id};
}
foreach $id ( sort keys %reorder){
printf STDERR "%-30s %d reordered (%d ppm)\n", $id, $reorder{$id}, $reorder{$id}*10^6/$npackets{$id};
}
foreach $id ( sort keys %npackets){
printf STDERR "%-30s lasted %02d:%02d:%02d ( %d seconds ) and has %d small and %d big gaps and lost %.3f small and %.3f big seconds %d resets %d late %d ppm.\n", $id,
$duration{$id}/3600, $duration{$id}%3600/60, $duration{$id}%60, $duration{$id},
$nsmall_gaps{$id}, $nbig_gaps{$id},
$small_time{$id}, $big_time{$id}, $resets{$id}, $late_n{$id},
10**6 * ($small_time{$id} + $big_time{$id}) / $duration{$id}; # ppm
}
printf STDERR "Big gap limit %d packets.\n", $minloss;
# if (!%nbreak){
# print STDERR "No big gaps($minloss) found in $npackets packets.";
# }
}
foreach $id (keys %small_tx){
print STDERR "ID $id has Tx to small in $small_tx{$id} packets\n";
}
close JSON if $opt_json;
exit(0);