Révision dee7dda2
Initial version
| plugins/other/tor_routers | ||
|---|---|---|
| 1 |
#!/usr/bin/perl -w |
|
| 2 |
# |
|
| 3 |
# Munin plugin to monitor Tor routers |
|
| 4 |
# |
|
| 5 |
# Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>, based on a plugin by Ge van Geldorp <ge@gse.nl> |
|
| 6 |
# |
|
| 7 |
# Parameters understood: |
|
| 8 |
# |
|
| 9 |
# host - Change which host to graph (default localhost) |
|
| 10 |
# port - Change which port to connect to (default 9051) |
|
| 11 |
# password - Plain-text control channel password (see torrc |
|
| 12 |
# HashedControlPassword parameter) |
|
| 13 |
# cookiefile - Name of the file containing the control channel cookie |
|
| 14 |
# (see torrc CookieAuthentication parameter) |
|
| 15 |
# |
|
| 16 |
# Using HashedControlPassword authentication has the problem that you must |
|
| 17 |
# include the plain-text password in the munin config file. To have any |
|
| 18 |
# effect, that file shouldn't be world-readable. |
|
| 19 |
# If you're using CookieAuthentication, you should run this plugin as a user |
|
| 20 |
# which has read access to the tor datafiles. Also note that bugs in versions |
|
| 21 |
# upto and including 0.1.1.20 prevent CookieAuthentication from working. |
|
| 22 |
# |
|
| 23 |
# Usage: place in /etc/munin/node.d/ (or link it there using ln -s) |
|
| 24 |
# |
|
| 25 |
# Parameters understood: |
|
| 26 |
# config (required) |
|
| 27 |
# autoconf (optional - used by munin-config) |
|
| 28 |
# |
|
| 29 |
# |
|
| 30 |
# Magic markers - optional - used by installation scripts and |
|
| 31 |
# munin-config: |
|
| 32 |
# |
|
| 33 |
#%# family=contrib |
|
| 34 |
#%# capabilities=autoconf |
|
| 35 |
|
|
| 36 |
use strict; |
|
| 37 |
use IO::Socket::INET; |
|
| 38 |
|
|
| 39 |
# Config |
|
| 40 |
our $address = $ENV{host} || "localhost"; # Default: localhost
|
|
| 41 |
our $port = $ENV{port} || 9051; # Default: 9051
|
|
| 42 |
|
|
| 43 |
# Don't edit below this line |
|
| 44 |
|
|
| 45 |
sub Authenticate |
|
| 46 |
{
|
|
| 47 |
my ($socket) = @_; |
|
| 48 |
my $authline = "AUTHENTICATE"; |
|
| 49 |
if (defined($ENV{cookiefile})) {
|
|
| 50 |
if (open(COOKIE, "<$ENV{cookiefile}")) {
|
|
| 51 |
binmode COOKIE; |
|
| 52 |
my $cookie; |
|
| 53 |
$authline .= " "; |
|
| 54 |
while (read(COOKIE, $cookie, 32)) {
|
|
| 55 |
foreach my $byte (unpack "C*", $cookie) {
|
|
| 56 |
$authline .= sprintf "%02x", $byte; |
|
| 57 |
} |
|
| 58 |
} |
|
| 59 |
close COOKIE; |
|
| 60 |
} |
|
| 61 |
} elsif (defined($ENV{password})) {
|
|
| 62 |
$authline .= ' "' . $ENV{password} . '"';
|
|
| 63 |
} |
|
| 64 |
print $socket "$authline\r\n"; |
|
| 65 |
my $replyline = <$socket>; |
|
| 66 |
if (substr($replyline, 0, 1) != '2') {
|
|
| 67 |
$replyline =~ s/\s*$//; |
|
| 68 |
return "Failed to authenticate: $replyline"; |
|
| 69 |
} |
|
| 70 |
|
|
| 71 |
return; |
|
| 72 |
} |
|
| 73 |
|
|
| 74 |
if ($ARGV[0] and $ARGV[0] eq "autoconf") {
|
|
| 75 |
# Try to connect to the daemon |
|
| 76 |
my $socket = IO::Socket::INET->new("$address:$port")
|
|
| 77 |
or my $failed = 1; |
|
| 78 |
|
|
| 79 |
if ($failed) {
|
|
| 80 |
print "no (failed to connect to $address port $port)\n"; |
|
| 81 |
exit 1; |
|
| 82 |
} |
|
| 83 |
|
|
| 84 |
my $msg = Authenticate($socket); |
|
| 85 |
if (defined($msg)) {
|
|
| 86 |
print $socket "QUIT\r\n"; |
|
| 87 |
close($socket); |
|
| 88 |
print "no ($msg)\n"; |
|
| 89 |
exit 1; |
|
| 90 |
} |
|
| 91 |
|
|
| 92 |
print $socket "QUIT\r\n"; |
|
| 93 |
close($socket); |
|
| 94 |
print "yes\n"; |
|
| 95 |
exit 0; |
|
| 96 |
} |
|
| 97 |
|
|
| 98 |
if ($ARGV[0] and $ARGV[0] eq "config") {
|
|
| 99 |
print "graph_title Routers\n"; |
|
| 100 |
print "graph_args -l 0\n"; |
|
| 101 |
print "graph_vlabel routers\n"; |
|
| 102 |
print "graph_category Tor\n"; |
|
| 103 |
print "graph_info This graph shows the number of known Tor ORs.\n"; |
|
| 104 |
|
|
| 105 |
print "ors.label routers\n"; |
|
| 106 |
print "ors.type GAUGE\n"; |
|
| 107 |
print "ors.info The number of known Tor ORs (onion routers)\n"; |
|
| 108 |
|
|
| 109 |
exit 0; |
|
| 110 |
} |
|
| 111 |
|
|
| 112 |
my $socket = IO::Socket::INET->new("$address:$port")
|
|
| 113 |
or die("Couldn't connect to $address port $port: $!");
|
|
| 114 |
|
|
| 115 |
my $msg = Authenticate($socket); |
|
| 116 |
if (defined($msg)) {
|
|
| 117 |
print $socket "QUIT\r\n"; |
|
| 118 |
close($socket); |
|
| 119 |
die "$msg\n"; |
|
| 120 |
} |
|
| 121 |
|
|
| 122 |
print $socket "GETINFO ns/all\r\n"; |
|
| 123 |
my $replyline = <$socket>; |
|
| 124 |
if (substr($replyline, 0, 1) != '2') {
|
|
| 125 |
print $socket "QUIT\r\n"; |
|
| 126 |
close($socket); |
|
| 127 |
$replyline =~ s/\s*$//; |
|
| 128 |
die "Failed to get orconn-status info: $replyline\n"; |
|
| 129 |
} |
|
| 130 |
|
|
| 131 |
my $count; |
|
| 132 |
while (! (($replyline = <$socket>) =~ /^\.\s*$/)) {
|
|
| 133 |
my @reply = split(/\s+/, $replyline); |
|
| 134 |
$count++ if $reply[0] eq 'r'; |
|
| 135 |
} |
|
| 136 |
$replyline = <$socket>; |
|
| 137 |
if (substr($replyline, 0, 1) != '2') {
|
|
| 138 |
print $socket "QUIT\r\n"; |
|
| 139 |
close($socket); |
|
| 140 |
$replyline =~ s/\s*$//; |
|
| 141 |
die "Failed to authenticate: $replyline\n"; |
|
| 142 |
} |
|
| 143 |
|
|
| 144 |
print $socket "QUIT\r\n"; |
|
| 145 |
close($socket); |
|
| 146 |
|
|
| 147 |
print "ors.value $count\n"; |
|
| 148 |
|
|
| 149 |
exit 0; |
|
| 150 |
|
|
| 151 |
# vim:syntax=perl |
|
Formats disponibles : Unified diff