plugin-tor_routers: tor_routers

File tor_routers, 3.7 KB (added by avar, 3 years ago)

A plugin to graph the number of public Tor routers

Line 
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
36use strict;
37use IO::Socket::INET;
38
39# Config
40our $address = $ENV{host}  || "localhost";      # Default: localhost
41our $port    = $ENV{port}  || 9051;             # Default: 9051
42
43# Don't edit below this line
44
45sub 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
74if ($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
98if ($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
112my $socket = IO::Socket::INET->new("$address:$port")
113        or die("Couldn't connect to $address port $port: $!");
114
115my $msg = Authenticate($socket);
116if (defined($msg)) {
117        print $socket "QUIT\r\n";
118        close($socket);
119        die "$msg\n";
120}
121
122print $socket "GETINFO ns/all\r\n";
123my $replyline = <$socket>;
124if (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
131my $count;
132while (! (($replyline = <$socket>) =~ /^\.\s*$/)) {
133        my @reply = split(/\s+/, $replyline);
134    $count++ if $reply[0] eq 'r';
135}
136$replyline = <$socket>;
137if (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
144print $socket "QUIT\r\n";
145close($socket);
146
147print "ors.value $count\n";
148
149exit 0;
150
151# vim:syntax=perl