Secure Sockets Layer
Create a bind tag such as <bind ssl="gnutls" port="6697"> for SSL clients.
If you are using GnuTLS, then clients connecting on a plaintext port can also request an encrypted connection through the STARTTLS command.
Similar to clients, <bind:ssl> must be specified on the listening port for servers. Servers must also have SSL specified in their link block, using <link ssl="gnutls" ...>.
Note that services usually cannot link using SSL; you should bind a port to localhost for the use of services and keep your public-facing server link blocks encrypted.
In order to prevent man-in-the-middle attacks and to provide an additional layer of authentication, in version 1.2 and later you can specify the fingerprint of the SSL key in the link block. This will prevent a server from linking unless its SSL certificate matches the fingerprint; since this fingerprint is derived from the public key, it is not possible to forge this type of authentication without access to the private key.
The link block should be of the form: <link fingerprint="abc123..." ssl="gnutls" ...>. The fingerprint is shown in the linking snomask when an SSL link is established, or can be viewed as the MD5 fingerprint using certtool -i < cert.pem (or gnutls-certtool on OS X).
Oper blocks can use their SSL client certificate fingerprint as an additional authentication mechanism if m_sslinfo is loaded, or can use it to automatically oper up on connect.
We use MD5 fingerprints by default. If you've been paying attention to the news, you know that MD5 has been broken with respect to collisions, which has been used to create rogue CAs when signed using MD5. This attack does not apply to SSL certificate fingerprints as used in InspIRCd (including NickServ authentication by SSL fingerprint). Here's why:
The current attack is as follows: Alice generates two SSL certificates, and does a bit of work to make them have the same MD5 fingerprint. She can't choose the fingerprint that the certificates have, only add some carefully-chosen bits to cause the MD5 hashes of the two certificates to end up being identical. Then, she gets one of the two certificates signed by a CA, which gives her a signature saying "Certificate with MD5 abc123 is valid. Signed, Some CA." Once she hash this, she applies the signature to the other certificate, which is usually set up to be a lot more permissive than a normal certificate (for example, allowing "*.com" rather than "*.alice.com"). Once that's done, the verification by CN matching becomes worthless.
InspIRCd and NickServ don't care about the CN, or really any of the fields in your certificate. They just check if the MD5 matches the one you specified earlier. This is a whole lot simpler, and as it turns out, completely bypasses the attack. If Alice is trying to get in to Bob's oper block, she would need a preimage attack against MD5, and no such attack (even theoretical, the best work bound remains at 2^127) is publicly known at this time.
You can request that InspIRCd use SHA1 as its certificate hashing algorithm instead of MD5 by specifying <gnutls hash="sha1"> or <openssl hash="sha1"> in your configuration. This will invalidate all current fingerprints. Note that SHA-1 also has collision attacks, currently estimated at 2^52, and it is expected that a public collision will be found soon.
SSL provides the ability for both the client and the server to present a certificate for verification. In most cases, this is not used: only the server presents a certificate, and the client does not identify itself at all (or uses other means, such as a username/password).
InspIRCd will accept client certificates if your IRC client offers one during the SSL connection. The fingerprint of this client certificate is viewable with the /SSLINFO command, and can be used for NickServ authentication in place of the normal username/password. For information on how to create a client certificate and on how to set up common clients, look at OFTC's page on CertFP setup.
Client certificates also help to prevent man-in-the-middle attacks: if such an attack is being run on a connection, the server will not see the client certificate - it will only be presented to the attacker, who will be unable to forward the information. This is an improvement over a username/password which is trivial for an attacker to intercept. Even SASL is vulnerable to session hijacking in its strongest (theoretical) form, and all existing mechanisms (including DH-BLOWFISH) allow an active attacker to transparently intercept username/password pairs.
Signed Server Certificate
Note: you do not need a signed certificate to use SSL with InspIRCd! This is an optional step that will allow clients to identify your server to prevent man-in-the-middle attacks. Clients may allow certificates to be saved and checked against previously saved values on connect, which also effectively mitigates this attack.
TODO: explain in a nice step-by-step process, point to CACert as a free root of trust, and mention commercial ones. For now, it's the same as setting up a cert for an HTTPS server, there are lots of HOWTOs on that topic.
When using a CA-signed certificate, the private key (key.pem) is the same as with an unsigned certificate. You should have generated this yourself, and not given it out to the CA when getting a signed certificate; keep a backup in a secure location. The certificate file (cert.pem) needs to contain all certificates in the verification chain. This means that your certificate's hex value should be first, then its signing cert, then the cert that signed that, and so forth up to the trusted root CA. These extra certificates could be included in a separate file (called a CA bundle) provided by the CA. If your certificate chain is longer than 3 certificates, you will need to specify its length using <gnutls certcount="5">.
As of 2.1, gnutls will allow the use of multiple certificates for different bind IPs or ports. To use, specify blocks similar to <ssl_cert name="cert1" certfile="cert1.pem" keyfile="key1.pem"> and <bind port="6697" ssl_cert="cert1" ssl="gnutls">.
The files ca.pem and crl.pem have nothing to do with your server certificate, although they will commonly be from the same company.
Signed Client Certificates
You can also use a CA to validate client certificates - that is, the individual users' certificates that they use to connect to your server. As of 2.0, this can be used by connect blocks to match trusted certificates using <connect requiressl="trusted">.
This is what "ca.pem" and "crl.pem" are used for. You do not need them for anything else, and if you are not checking client certificates, you can ignore their error messages.
There is a third-party module to force nicks to match the CN on the certificate; when combined with forcing trusted certificates on all users, this can enforce nickname use to known nicks.
Related tools and documentation
- OpenVPN includes a toolkit named easy-rsa which can be used for creating certificates for vpns, client and server. If you know about SSL, you can use it to make certificates for IRC servers and clients, too.