Run IRC As A Tor Hidden Service (Inspircd + Anope)

IRC with InspIRCd and Anope works well as an internet-facing service.
Your domain name, the TLS certificates and SASL authentication make it secure.
Cloaking hides your address from other users.

But what about IRC Operators and Network Admins?
They can see the addresses/hosts the clients connect from.

As an IRC Operator you can increase the trust in your services.

You will learn now how to run InspIRCd as a Tor-only hidden service.

Planned Features

  1. IRC as Tor-only hidden service.
  2. Anope services.
  3. SASL authentication.

Prerequisites

  1. Debian or compatible system.
  2. root or sudo permission.
  3. tor daemon installed.

Installation

Install the packages using Debian’s apt:

sudo apt update
sudo apt install -y inspircd anope

Configuration

Tor Configuration

In the /etc/tor/torrc file configure your IRC hidden service and ports:

HiddenServiceVersion 3
HiddenServiceDir /var/lib/tor/irc_hidden_service/
HiddenServicePort 6667 127.0.0.1:6667

Do not open the 6667 port on your firewall.
Tor maps the onion service to your local port.

Restart Tor:

sudo systemctl restart tor

Your hidden service url is in /var/lib/tor/irc_hidden_service/hostname.

sudo cat /var/lib/tor/irc_hidden_service/hostname

InspIRCd Configuration

Backup the original config.

sudo mv /etc/inspircd/inspircd.conf /etc/inspircd/inspircd.conf.orig

Add your IRC configuration – sudo vim /etc/inspircd/inspircd.conf:

<server name="irc.your-hidden-service.onion"
        description="Your IRC Server"
        network="YourNetwork">

<admin name="YourName"
       description="yournick"
       email="your@mail.me">

<module name="hidechans">
<module name="spanningtree">
<module name="account">
<module name="services">
<module name="conn_umodes">
<module name="sha2">
<module name="cap">
<module name="sasl">
<module name="password_hash">
<module name="cloak">
<module name="cloak_user">

<cloak method="account"
       case="preserve"
       class=""
       invalidchar="strip"
       prefix="YourNetwork/"
       suffix="">

<bind address="127.0.0.1" port="6667" type="clients">

<connect allow="*"
         timeout="60"
         threshold="10"
         pingfreq="120"
         hardsendq="262144"
         softsendq="8192"
         recvq="8192"
         localmax="500"
         globalmax="500"
         maxchans="20"
         resolvehostnames="no"
         modes="+x">

<class name="Shutdown"
       commands="DIE RESTART REHASH LOADMODULE UNLOADMODULE RELOADMODULE">
<class name="ServerLink"
       commands="CONNECT SQUIT RCONNECT RSQUIT MKPASSWD">
<class name="BanControl"
       commands="KILL GLINE KLINE ZLINE QLINE ELINE">
<class name="OperChat"
       commands="WALLOPS GLOBOPS SETIDLE SPYLIST SPYNAMES">
<class name="HostCloak"
       commands="SETHOST SETIDENT CHGNAME CHGHOST CHGIDENT">
<class name="ServerStats"
       commands="STATS"
       privs="users/auspex channels/auspex servers/auspex users/mass-message users/flood/no-throttle users/flood/increased-buffers">

<type name="NetAdmin"
      classes="OperChat BanControl HostCloak Shutdown ServerLink ServerStats"
      host="netadmin.your-hidden-service.onion">
<type name="GlobalOp"
      classes="OperChat BanControl HostCloak"
      host="ircop.your-hidden-service.onion">
<type name="Helper"
      classes="HostCloak"
      host="helper.your-hidden-service.onion">

<oper name="plainoper"
      password="Your-Complex-PW"
      host="*@your-hidden-service.onion"
      type="NetAdmin"
      maxchans="60">

<files motd="/etc/inspircd/inspircd.motd">

<dns timeout="0">

<options prefixquit="Quit: "
         syntaxhints="no"
         announcets="yes"
         hostintopic="yes"
         pingwarning="15"
         splitwhois="no"
         exemptchanops="">

<security hideserver=""
          userstats="Pu"
          customversion=""
          flatlinks="no"
          hidesplits="no"
          hideulines="no"
          hidebans="no"
          maxtargets="20">

<performance quietbursts="yes"
             softlimit="1024"
             somaxconn="128"
             netbuffersize="10240">

<whowas groupsize="10"
        maxgroups="100000"
        maxkeep="3d">

<badnick nick="ChanServ" reason="Reserved For Services">
<badnick nick="NickServ" reason="Reserved For Services">
<badnick nick="OperServ" reason="Reserved For Services">
<badnick nick="MemoServ" reason="Reserved For Services">
<badnick nick="HostServ" reason="Reserved For Services">
<badnick nick="Global" reason="Reserved For Services">

<link name="services.your-hidden-service.onion"
      ipaddr="127.0.0.1"
      port="7000"
      allowmask="127.0.0.0/8"
      sendpass="Password-For-Services"
      recvpass="Password-For-Services">

<uline server="services.your-hidden-service.onion" silent="yes">
<bind address="127.0.0.1" port="7000" type="servers">
<sasl target="services.your-hidden-service.onion" requiressl="no">

Notes:

  1. Rewrite/change the network info in the server settings.
  2. Change the admin setting, but consider your privacy.
  3. In the cloak config change the YourNetwork/ prefix.
  4. In the oper config set up an oper nick and a strong password. Later you add a hashed one and this can be removed.
  5. DNS is disabled because all clients connect via Tor onion addresses.
  6. Running without TLS is acceptable over Tor-only networks, but TLS (e.g., port 6697) can still be enabled for layered security.
  7. This is a minimal functional configuration. Depending on your InspIRCd version, additional defaults may be required.

Anope Configuration

Backup the original config.

sudo mv /etc/anope/services.conf /etc/anope/services.conf.orig

Edit: sudo vim /etc/anope/services.conf

uplink
{
        host = "127.0.0.1"
        ipv6 = no
        ssl = no
        port = 7000
        password = "Password-For-Services"
}

serverinfo
{
        name = "services.your-hidden-service.onion"
        description = "Your Network Services"
        pid = "/run/anope/anope.pid"
        motd = "services.motd"
}

module
{
        name = "inspircd3"
        use_server_side_mlock = yes
        use_server_side_topiclock = yes
}

networkinfo
{
        networkname = "YourNetwork"
        nicklen = 31
        userlen = 10
        hostlen = 64
        chanlen = 32
        modelistsize = 100
        vhost_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-"
        allow_undotted_vhosts = false
        disallow_start_or_end = ".-"
}

options
{
        casemap = "ascii"
        strictpasswords = yes
        badpasslimit = 5
        badpasstimeout = 1h
        updatetimeout = 5m
        expiretimeout = 30m
        readtimeout = 5s
        timeoutcheck = 3s
        retrywait = 60s
        hideprivilegedcommands = yes
        hideregisteredcommands = yes
        languages = "ca_ES.UTF-8 de_DE.UTF-8 el_GR.UTF-8 es_ES.UTF-8 fr_FR.UTF-8 hu_HU.UTF-8 it_IT.UTF-8 nl_NL.UTF-8 pl_PL.UTF-8 pt_PT.UTF-8 ru_RU.UTF-8 tr_TR.UTF-8"
}

module { name = "enc_sha256" }

module {
        name = "db_flatfile"
        database = "anope.db"
        keepbackups = 10
}

include {
    type = "file"
    name = "nickserv.conf"
}

include {
    type = "file"
    name = "chanserv.conf"
}

include {
    type = "file"
    name = "operserv.conf"
}

include {
    type = "file"
    name = "hostserv.conf"
}

include {
    type = "file"
    name = "memoserv.conf"
}

include {
    type = "file"
    name = "global.conf"
}

log
{
        target = "services.log"
        bot = "Global"
        logage = 1
        users = "connect disconnect nick"
        rawio = no
        debug = no
}

module { name = "help" }
module { name = "m_sasl" }

opertype {
    name = "ServicesRoot"
    commands = "*"
    privileges = "*"
}

oper {
    name = "youropernick"
    type = "ServicesRoot"
}

Configure the services files for your requirements:

  • nickserv.conf
  • chanserv.conf
  • operserv.conf
  • hostserv.conf
  • memoserv.conf
  • global.conf

Start And Enable The Services

Start InspIRCd:

sudo systemctl enable inspircd.service
sudo systemctl start inspircd.service

Start Anope:

sudo systemctl enable anope.service
sudo systemctl start anope.service

Check logs if necessary:

journalctl -u inspircd
journalctl -u anope

Add An IRC Network Operator

When the password_hash module enabled in InspIRCd, you can generate passwords in your client, for example:

/MKPASSWD sha256 <pass>

Then add the hashed password to your InspIRCd configuration:

<oper
name="hashedopername"
hash="sha256"
password="1234abc1234hash"
host="*@your-hidden-service.onion"
type="NetAdmin">

After modifying the configuration file, log in as the oper (plainoper) you configured earlier and load the new config:

/rehash

If you can log in with the new operator/password (hashedopername):

  1. Remove the plain text one from your configuration.
  2. Rehash it again with /rehash.

Final Thoughts

Tor hides the client IP, but does not provide complete anonymity against global correlation attacks.

Join our discussions:


Discover more from Tom's IT Cafe

Subscribe to get the latest posts sent to your email.

Leave a comment