Onion Only IRCd - Part 1
Since the early days of QuakeNet I’ve always wanted to run an IRC server but I’ve never had a real reason to do so. With Ablative Hosting starting to gain traction I’ve found that some people don’t want to send an email to ask a question or get support. It seems I now have my reason.
This is not a guide for creating an anonymous .onion IRCd
Choosing an IRCd
As a rule Ablative (and Brass Horn Comms for that matter) either use software available in OpenBSDs base, at a push in ports or we write it ourselves.
There’s not a chance I was going to write an IRCd so that leaves us with the options in base and ports.
Base has
- irc-2.10.3.1p0v0.tgz
- ircII-20190117.tgz
- ircd-hybrid-8.2.24.tgz
- ircd-ratbox-3.0.10p3.tgz
This project has started off using ircd-hybrid which, as seen above, is 8.2.24 at time of writing.
Installing and initial configuration
We use Ansible to deploy all our software and this is no different, installing is simple;
---
- name: Install ircd
become: true
package:
name: "ircd-hybrid--"
environment:
PKG_PATH: "{{PKG_PATH}}"
notify:
- start ircd
The OpenBSD package includes a very verbose example configuration which we need to pare down. We hit our first stumbling block right at the beginning;
serverinfo {
# Yeah Gen3 .onions are too long :/
#name = "irc.hzwjmjimhr7bdmfv2doll4upibt5ojjmpo3pbp5ctwcg37n3hyk7qzid.onion";
#name = "irc.ablative.hosting";
}
Generation 3 .onions are too long for the server info block which is a shame, but as it’s only a cosmetic issue we’ll ignore it and move on.
Because Ablative has an EV SSL certificate we extended it to allow a wildcard (wildcard entries are not normally allowed for EV certificates but are allowed for .onions!) and can enable this IRCd to support SSL.
SSL for an .onion provides no additional encryption but it does provide stronger guarantees that you have connected to the server you intended to.
rsa_private_key_file = "/etc/ircd-hybrid/certificate.key";
ssl_certificate_file = "/etc/ircd-hybrid/certificate.crt";
ssl_dh_param_file = "/etc/ircd-hybrid/dhparam.pem";
To use Perfect Forward Secrecy a server needs Diffie-Hellman parameters but due to various issues you need to ensure you generate a strong set;
- name: Generate the dhparams
become: true
shell: "/usr/bin/openssl dhparam -out dhparam.pem 2048"
args:
chdir: /etc/ircd-hybrid/
creates: dhparam.pem
You can configure information about the administrator of the server, in this case any administrative problems can be referred to Ablative’s support team who’ll escalate / resolve as required;
admin {
name = "Support Team";
description = "Ablative Support Team";
email = "<support@ablative.hosting>";
};
We now hit the first part of the example config that will cause us issues when running an IRCd over .onion, the user classes;
class {
name = "users";
ping_time = 90 seconds;
number_per_ip = 2;
max_local = 2;
max_global = 10;
max_number = 100;
sendq = 100 kbytes;
recvq = 2560 bytes;
};
Because all of our users will appear from a single IP address (or more if using OnionBalance) these numbers will need to tweaked accordingly.
Once the various classes of users have been created (we might want to create different classes of users for say authenticated customers, staff, admins, opers etc) we need to tell the server which ports and IP addresses to listen on. This part of the config is quite important for how we partition user classes and permissions in a .onion centric server.
listen {
flags = hidden;
host = "10.10.0.1";
port = 6667;
flags = hidden;
host = "10.20.0.1";
port = 6665 .. 6669;
flags = hidden, ssl;
host = "10.20.0.1";
port = 6697;
};
The reason we bind the server to two different /24 networks is because we have 2 different interfaces on the IRCd server, one faces the ‘public’ Tor daemon and the other is a Gen3 authorized .onion.
Authenticating Anonymous Users - Gen3 Onion Authentication and IRCd Passwords
@kushaldas has recently written about creating authorized v3 .onions so I don’t need to cover it here.
Once you’ve configured your authenticated .onion you should now have two .onion addresses, one that points to 10.10.0.1 and requires Tor client authorization and another open service that anyone can connect to.
Just in case we have a situation where someone has configured their local network to route all traffic via Tor and that
Tor instance has the client cookie we can configure IRCd to also require a password when connecting from this IP address,
the password is stored in a hashed format using mkpasswd
;
auth {
user = "*@10.10.0.1";
password = "<snip>"
encrypted = yes;
spoof = "irc.ablative.hosting";
class = "opers";
flags = need_password, spoof_notice, exceed_limit, kline_exempt,
xline_exempt, resv_exempt, no_tilde, can_flood;
};
Then we configure the auth
section for everybody else;
auth {
user = "*@*";
spoof = "irc.ablative.hosting";
class = "users";
};
Now that we can classify our users we can define some IRC operators;
operator {
name = "gareth";
user = "*@10.10.0.1";
password = "<snip>";
encrypted = yes;
ssl_certificate_fingerprint = "<snip>";
#ssl_connection_required = yes;
class = "opers";
whois = "is a Smurf Target (IRC Operator)";
umodes = locops, servnotice, wallop;
flags = admin, connect, connect:remote, die, globops, kill, kill:remote,
opme, nick:resv, kline, module, rehash, restart, set, unkline, unxline, xline;
};
Note that in order to become an operator this user (e.g. me) has to be connecting from 10.10.0.1
, has to present a
password (again stored in hashed format) and provide an SSL certificate.
Ablative uses mutual TLS auth between all microservices so it seems natural to use certificates for client auth where we can.
End of Part 1
As it stands you could now run doas /etc/rc.d/ircd-hybrid start && doas /etc/rc.d/tor start
and have an up and running
IRCd server but there are certain features that people expect of an IRCd. Namely services such as NickServ and Chanserv.
Part 2 will discuss the deployment and configuration of services.
The Ablative IRCd is available at irc.hzwjmjimhr7bdmfv2doll4upibt5ojjmpo3pbp5ctwcg37n3hyk7qzid.onion:6667 and supports TLS on irc.hzwjmjimhr7bdmfv2doll4upibt5ojjmpo3pbp5ctwcg37n3hyk7qzid.onion:6697