]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - tools/testssl
Implement a tool for testing SSL connectivity.
[user/henk/code/inspircd.git] / tools / testssl
1 #!/usr/bin/env perl
2 #
3 # InspIRCd -- Internet Relay Chat Daemon
4 #
5 #   Copyright (C) 2020 Sadie Powell <sadie@witchery.services>
6 #
7 # This file is part of InspIRCd.  InspIRCd is free software: you can
8 # redistribute it and/or modify it under the terms of the GNU General Public
9 # License as published by the Free Software Foundation, version 2.
10 #
11 # This program is distributed in the hope that it will be useful, but WITHOUT
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14 # details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 #
19
20
21 BEGIN {
22         require 5.10.0;
23 }
24
25 use feature ':5.10';
26 use strict;
27 use warnings FATAL => qw(all);
28
29 use IO::Socket();
30 use IO::Socket::SSL();
31
32 use constant {
33         CC_BOLD  => -t STDOUT ? "\e[1m"    : '',
34         CC_RESET => -t STDOUT ? "\e[0m"    : '',
35         CC_GREEN => -t STDOUT ? "\e[1;32m" : '',
36         CC_RED   => -t STDOUT ? "\e[1;31m" : '',
37 };
38
39 if (scalar @ARGV < 2) {
40         say STDERR "Usage: $0 <hostip> <port> [selfsigned]";
41         exit 1;
42 }
43
44 # By default STDOUT is only flushed at the end of each line. This sucks for our
45 # needs so we disable it.
46 STDOUT->autoflush(1);
47
48 my $hostip = shift @ARGV;
49 if ($hostip =~ /[^A-Za-z0-9.:]/) {
50         say STDERR "Error: invalid hostname or IP address: $hostip";
51         exit 1;
52 }
53
54 my $port = shift @ARGV;
55 if ($port =~ /\D/ || $port < 1 || $port > 65535) {
56         say STDERR "Error: invalid TCP port: $port";
57         exit 1;
58 }
59
60 my $self_signed = shift // '' eq 'selfsigned';
61
62 print "Checking whether ${\CC_BOLD}$hostip/$port${\CC_RESET} is reachable ... ";
63 my $sock = IO::Socket::INET->new(
64         PeerAddr => $hostip,
65         PeerPort => $port,
66 );
67
68 unless ($sock) {
69         say <<"EOM";
70 ${\CC_RED}no${\CC_RESET}
71
72 It seems like the server endpoint you specified is not reachable! Make sure that:
73
74   * You have specified a <bind> tag in your config for this endpoint.
75   * You have rehashed or restarted the server since adding the <bind> tag.
76   * If you are using a firewall incoming connections on TCP port $port are allowed.
77   * The endpoint your server is listening on is not local or private.
78
79 See https://docs.inspircd.org/3/configuration/#ltbindgt for more information.
80 EOM
81         exit 1;
82 }
83
84 say "${\CC_GREEN}yes${\CC_RESET}";
85 print "Checking whether ${\CC_BOLD}$hostip/$port${\CC_RESET} is using plaintext ... ";
86 my $error = $sock->recv(my $data, 1);
87
88 if ($error) {
89         say <<"EOM";
90 ${\CC_RED}error${\CC_RESET}
91
92 It seems like the server dropped the connection before sending anything! Make sure that:
93
94   * The endpoint you specified is actually your IRC server.
95   * If you are using a firewall incoming data on TCP port $port are allowed.
96
97 See https://docs.inspircd.org/3/configuration/#ltbindgt for more information.
98 EOM
99         exit 1;
100 } elsif ($data =~ /[A-Z:@]/) {
101         say <<"EOM";
102 ${\CC_RED}yes${\CC_RESET}
103
104 It appears that the server endpoint is using plaintext! Make sure that:
105
106   * You have one or more of the following modules loaded:
107     - ssl_gnutls
108     - ssl_openssl
109     - ssl_mbedtls
110
111   * If you have specified one or more <sslprofile> tags then the value of
112     <bind:ssl> is the same as an <sslprofile:name> field. Otherwise, it should
113     be set to "gnutls" for the ssl_gnutls module, "openssl" for the ssl_openssl
114     module, or "mbedtls" for the ssl_mbedtls module.
115
116   * If you have specified the name of an <sslprofile> in <bind:ssl> then the
117     value of <sslprofile:provider> is set to "gnutls" if using the ssl_gnutls
118     module, "openssl" if using the ssl_openssl module, or "mbedtls" if using
119     the ssl_mbedtls module.
120
121   * If you have your SSL configuration in a file other than inspircd.conf then
122     that file is included by inspircd.conf.
123
124 See the following links for more information:
125
126   https://docs.inspircd.org/3/modules/ssl_gnutls/#configuration
127   https://docs.inspircd.org/3/modules/ssl_mbedtls/#configuration
128   https://docs.inspircd.org/3/modules/ssl_openssl/#configuration
129 EOM
130         exit 1;
131 }
132
133 $sock->close();
134 say "${\CC_GREEN}no${\CC_RESET}";
135 print "Checking whether ${\CC_BOLD}$hostip/$port${\CC_RESET} can have an SSL session negotiated ... ";
136 $sock = IO::Socket::SSL->new(
137         PeerAddr => $hostip,
138         PeerPort => $port,
139         SSL_hostname => $hostip,
140         SSL_verify_mode => $self_signed ? IO::Socket::SSL::SSL_VERIFY_NONE : IO::Socket::SSL::SSL_VERIFY_PEER,
141 );
142
143 unless ($sock) {
144         say <<"EOM";
145 ${\CC_RED}no${\CC_RESET}
146
147 It appears that something is wrong with your server. Make sure that:
148
149   - You are not using an old version of GnuTLS, mbedTLS, or OpenSSL which only
150     supports deprecated algorithms like SSLv3.
151
152 The error provided by the SSL library was:
153
154   $IO::Socket::SSL::SSL_ERROR
155 EOM
156         exit 1;
157 }
158
159
160 say <<"EOM";
161 ${\CC_GREEN}yes${\CC_RESET}
162
163 It seems like SSL is working fine on your server. If you are having trouble
164 connecting try using a different client or connecting from a different host.
165
166 You may also find running some of the following commands to be helpful:
167
168    gnutls-cli-debug --port $port $hostip
169    openssl s_client -connect $hostip:$port -debug -security_debug
170
171 If you need any help working out what is wrong then visit our support channel
172 at irc.inspircd.org #inspircd.
173 EOM