Setup a simple IRC network (on a single server) with Charybdis, Atheme and Qwebirc on Debian Squeeze

Preamble

I'm offering this guide as a reminder to me and to my comrades how to set up this thing quickly and possibly without blatant errors. I'll use the diff output with some comments, to see what I've removed and added to the original configuration.

Diff output is simple: line prefixed by a "+" are additions, prefixed by "-" are deletions, all the rest is just context.

The configuration files of atheme and the ircd have a mixed comment syntax: both C-like (/* comment */) and shell/python/perl-like (# to the end of the line) are valid. The webchat is pure python in the configuration file and javascript in the menuitems (keep this in mind to comment out stuff).

Passwords and some ips are fake and there are no real mail addresses.

This means that you should go through the configurations files with the editor, using this text as a map, not as an actual patch that will work. In this way you'll be ready in an hour or two, instead of the 2 days the thing would require.

OK? Well, let's go.

Download

First: create a dedicated user to run the ircd and the services, and one for the webchat (I'll explain later), and install the packages required for the compiling and the webchat. Don't use the root account for anything else than installing packages from the distro.

adduser unreal
adduser webchat
apt-get install build-essential libssl-dev libtool autoconf \
                gettext bison flex mercurial git  \
                python python-twisted python-simplejson 

The python thing is for the webchat.

Login with the first user and retrieve the sources. We will use mercurial and git.

mkdir ~/src
cd src
hg clone http://hg.atheme.org/release/charybdis-3.2
git clone git://git.atheme.org/release/atheme-6.0

If you prefer the tarballs (but go with the tools above):

wget http://atheme.net/downloads/atheme-services-6.0.8.tar.bz2
wget http://distfiles.atheme.org/charybdis-3.2.1.tbz2

The tarballs are also at http://www.stack.nl/~jilles/irc. Yes, a bit confusing, so just go with hg and git.

Install the IRCd and the services.

Change into the directory of charybdis and compile.

cd charybdis-3.2
./configure --enable-openssl --prefix=$HOME/ircd
make
make install

If the configure fails, you're missing some development package. Just install it. The installation procedure will create a whole directory tree under $HOME/ircd.

While we're at it, compile the services too.

cd atheme-6.0
./configure --prefix=$HOME/atheme
make
make install

And they will be installed under $HOME/atheme

Configuring the IRCd

Configuring an IRCd is always something crazy. Tons of options, weird syntax, obscure options. If I got this right, this is what should be done. (I'm offering a commented diff). In doubt, look at etc/reference.conf, where the options are well commented.

Change in the directory where the configuration file reside, and copy the example to ircd.conf.

cd $HOME/ircd/etc
cp example.conf ircd.conf

Then open your editor and modify it. The original files are attached example.conf and atheme.conf.example.

--- example.conf    2011-09-04 11:58:51.000000000 +0200
+++ ircd.conf   2011-09-04 11:55:06.000000000 +0200
@@ -1,4 +1,5 @@
-/* doc/example.conf - brief example configuration file
+/* -*- mode: conf-javaprop; -*-
+ * doc/example.conf - brief example configuration file
  *
  * Copyright (C) 2000-2002 Hybrid Development Team
  * Copyright (C) 2002-2005 ircd-ratbox development team

The first chunk is for emacs only. It gives you the correct syntax highlight.

@@ -24,12 +25,12 @@
 #loadmodule "extensions/extb_ssl.so";
 #loadmodule "extensions/hurt.so";
 #loadmodule "extensions/m_findforwards.so";
-#loadmodule "extensions/m_identify.so";
+loadmodule "extensions/m_identify.so";
 #loadmodule "extensions/no_oper_invis.so";
 #loadmodule "extensions/sno_farconnect.so";
 #loadmodule "extensions/sno_globalkline.so";
 #loadmodule "extensions/sno_globaloper.so";
-#loadmodule "extensions/sno_whois.so";
+loadmodule "extensions/sno_whois.so";

 /*
  * IP cloaking extensions: use ip_cloaking_4.0

Add the module for the /identify command (very optional) and the module to notify the opers about /whois on them.

Then the real thing: load the module for the ip cloaking, to hide the ips. Then provide names and descriptions. The sid is something random. Just pick 1 digit and 2 alphanumeric.

@@ -38,15 +39,15 @@
  * releases.
  */

-#loadmodule "extensions/ip_cloaking_4.0.so";
+loadmodule "extensions/ip_cloaking_4.0.so";
 #loadmodule "extensions/ip_cloaking.so";

 serverinfo {
-   name = "hades.arpa";
-   sid = "42X";
-   description = "charybdis test server";
-   network_name = "AthemeNET";
-   network_desc = "Your IRC network.";
+   name = "irc.anarchyplanet.org";
+   sid = "58C";
+   description = "Main Anarchy Planet IRC server";
+   network_name = "AnarchyPlanet";
+   network_desc = "AnarchyPlanet IRC network";
    hub = yes;

    /* On multi-homed hosts you may need the following. These define

Change the name of the SSL certificates to something more significant. I'll take "ap" (Anarchy Planet). In the meanwhile (open another shell), create the certificates in $HOME/ircd/etc

openssl req -x509 -nodes -newkey rsa:2048 -keyout ap.key -out ap.cert
openssl dhparam -out dh.pem 2048
chmod 600 ap.key dh.pem

It will ask some questions. The important one is the "Common Name": set it to your server name (like irc.anarchyplanet.org), so clients won't complain (they will complain that the certificate is self-signed...)

@@ -57,10 +58,10 @@
    #vhost6 = "3ffe:80e8:546::2";

    /* ssl_private_key: our ssl private key */
-   ssl_private_key = "etc/test.key";
+   ssl_private_key = "etc/ap.key";

    /* ssl_cert: certificate for our ssl server */
-   ssl_cert = "etc/test.cert";
+   ssl_cert = "etc/ap.cert";

    /* ssl_dh_params: DH parameters, generate with openssl dhparam -out dh.pem 1024 */
    ssl_dh_params = "etc/dh.pem";

Set the name for the admin, and load some modules for logging (the f prefix is for "failed": failed user and failed oper).

@@ -82,21 +83,21 @@
 };

 admin {
-   name = "Lazy admin (lazya)";
-   description = "AthemeNET client server";
-   email = "nobody@127.0.0.1";
+   name = "melmoth";
+   description = "Anarchy Planet IRC admin";
+   email = "melmoth@invalid.tld";
 };

 log {
    fname_userlog = "logs/userlog";
-   #fname_fuserlog = "logs/fuserlog";
+   fname_fuserlog = "logs/fuserlog";
    fname_operlog = "logs/operlog";
-   #fname_foperlog = "logs/foperlog";
+   fname_foperlog = "logs/foperlog";
    fname_serverlog = "logs/serverlog";
-   #fname_klinelog = "logs/klinelog";
+   fname_klinelog = "logs/klinelog";
    fname_killlog = "logs/killlog";
    fname_operspylog = "logs/operspylog";
-   #fname_ioerrorlog = "logs/ioerror";
+   fname_ioerrorlog = "logs/ioerror";
 };

 /* class {} blocks MUST be specified before anything that uses them.  That

Reduce the ping timeout for servers. If you're asking why we need this, well, the services are considered a server.

@@ -122,7 +123,7 @@
 };

 class "server" {
-   ping_time = 5 minutes;
+   ping_time = 2 minutes;
    connectfreq = 5 minutes;
    max_number = 1;
    sendq = 4 megabytes;

Then make it listen on the loopback interface for plain connections, while the outside world should use ssl. You can obviously change this (just look at the examples). The host keyword wants an ip to bind to.

@@ -132,9 +133,11 @@
    /* If you want to listen on a specific IP only, specify host.
     * host definitions apply only to the following port line.
     */
-   #host = "192.169.0.1";
-   port = 5000, 6665 .. 6669;
-   sslport = 9999;
+   host = "127.0.0.1";
+   port = 6667;
+
+   host = "10.234.23.8";
+   sslport = 6697;

    /* Listen on IPv6 (if you used host= above). */
    #host = "3ffe:1234:a:b:c::d";

What the hell is spoofing? I don't know, I assume it's a certain class of clients that gets privileges or blocking. I removed all this block:

@@ -147,52 +150,6 @@
  * that matches a user will be used.  So place spoofs first, then specials,
  * then general access, then restricted.
  */
-auth {
-   /* user: the user@host allowed to connect.  Multiple IPv4/IPv6 user
-    * lines are permitted per auth block.  This is matched against the
-    * hostname and IP address (using :: shortening for IPv6 and
-    * prepending a 0 if it starts with a colon) and can also use CIDR
-    * masks.
-    */
-   user = "*@172.16.0.0/12";
-   user = "*test@123D:B567:*";
-
-   /* password: an optional password that is required to use this block.
-    * By default this is not encrypted, specify the flag "encrypted" in
-    * flags = ...; below if it is.
-    */
-   password = "letmein";
-   
-   /* spoof: fake the users user@host to be be this.  You may either
-    * specify a host or a user@host to spoof to.  This is free-form,
-    * just do everyone a favour and dont abuse it. (OLD I: = flag)
-    */
-        spoof = "I.still.hate.packets";
-
-   /* Possible flags in auth:
-    * 
-    * encrypted                  | password is encrypted with mkpasswd
-    * spoof_notice               | give a notice when spoofing hosts
-    * exceed_limit (old > flag)  | allow user to exceed class user limits
-    * kline_exempt (old ^ flag)  | exempt this user from k/g/xlines&dnsbls
-    * dnsbl_exempt           | exempt this user from dnsbls
-    * spambot_exempt         | exempt this user from spambot checks
-    * shide_exempt           | exempt this user from serverhiding
-    * jupe_exempt                | exempt this user from generating
-    *                              warnings joining juped channels
-    * resv_exempt            | exempt this user from resvs
-         * flood_exempt               | exempt this user from flood limits
-         *                                     USE WITH CAUTION.
-    * no_tilde     (old - flag)  | don't prefix ~ to username if no ident
-    * need_ident   (old + flag)  | require ident for user in this class
-    * need_ssl                   | require SSL/TLS for user in this class
-    * need_sasl                  | require SASL id for user in this class
-    */
-   flags = kline_exempt, exceed_limit;
-   
-   /* class: the class the user is placed in */
-   class = "opers";
-};

 auth {
    user = "*@*";

I.e., all the connections will be normal users.

Then set the IRC operator block. So opers will perform "/oper god password" and get the IRCop status.

Some clues:

  1. You can change the "god" string to something more sensible (and the the oper will perform "/oper sensiblename password"
  2. the user = string defines which mask is permitted to get the IRCop status
  3. the password is tricky. It's not a clear text string. So you have to execute ../bin/mkpasswd (relative to the configuration file), type in your password, take the string it returns and use that in the configuration file.
  4. You can also set the fingerprint of the SSL cert for that user. (optional, but cool, so just a password is not enough if the bad guys come).
  5. The snomask defines which kind of notice you receive. As I modified it, you receive almost all.

So do the following.

@@ -222,20 +179,21 @@
    privs = oper:admin, oper:die, oper:rehash, oper:spy;
 };

-operator "god" {
+operator "apoper" {
    /* name: the name of the oper must go above */

    /* user: the user@host required for this operator.  CIDR *is*
     * supported now. auth{} spoofs work here, other spoofs do not.
     * multiple user="" lines are supported.
     */
-   user = "*god@127.0.0.1";
+   user = "*username1@*";
+   user = "*username2@*";

    /* password: the password required to oper.  Unless ~encrypted is
     * contained in flags = ...; this will need to be encrypted using 
     * mkpasswd, MD5 is supported
     */
-   password = "etcnjl8juSU1E";
+   password = "asdjs45j3ljss";

    /* rsa key: the public key for this oper when using Challenge.
     * A password should not be defined when this is used, see 
@@ -253,12 +211,12 @@
     * fingerprint will be checked against the specified fingerprint
     * below.
     */
-   #fingerprint = "c77106576abf7f9f90cca0f63874a60f2e40a64b";
+   fingerprint = "953ed62a3246f2dbd96cdbfc0ec0d92b5cb2f5a8";

    /* snomask: specific server notice mask on oper up.
     * If this is specified an oper will not be given oper_snomask.
     */
-   snomask = "+Zbfkrsuy";
+   snomask = "+ZWbcfkrsuy";

    /* flags: misc options for the operator.  You may prefix an option
     * with ~ to disable it, e.g. ~encrypted.

Now the linking of the services. First, we define the server, then we name it in the service { } block. We have only one connect { }, the services, on localhost. For the services, AFAIK (from my experiments), you should use the same sendpassword and acceptpassword. The port they listen is fake and we say ~autoconn to prevent the ircd trying to connect to it.

@@ -276,45 +234,36 @@
    privset = "admin";
 };

-connect "irc.uplink.com" {
-   host = "192.168.0.1";
-   send_password = "password";
-   accept_password = "anotherpassword";
-   port = 6666;
-   hub_mask = "*";
-   class = "server";
-   flags = compressed, topicburst;
-
-   /* If the connection is IPv6, uncomment below.
-    * Use 0::1, not ::1, for IPv6 localhost. */
-   #aftype = ipv6;
-};
-
-connect "ssl.uplink.com" {
-   host = "192.168.0.1";
-   send_password = "password";
-   accept_password = "anotherpassword";
-   port = 9999;
+connect "services.int" {
+   host = "127.0.0.1";
+   send_password = "mypassword";
+   accept_password = "mypassword";
+   port = 6668;
    hub_mask = "*";
    class = "server";
-   flags = ssl, topicburst;
+   flags = ~autoconn;
 };

 service {
    name = "services.int";
 };

+/* we don't need this block */
+
 cluster {
    name = "*";
    flags = kline, tkline, unkline, xline, txline, unxline, resv, tresv, unresv;
 };

+
+/* opers can do everything */
 shared {
    oper = "*@*", "*";
    flags = all, rehash;
 };

-/* exempt {}: IPs that are exempt from Dlines and rejectcache. (OLD d:) */
+/* exempt {}: IPs that are exempt from Dlines and rejectcache. (OLD d:) 
+    so we don't kill ourself */
 exempt {
    ip = "127.0.0.1";
 };

Ok, some other settings. Increase the max of channels per user.

@@ -326,7 +275,7 @@
    use_forward = yes;
    knock_delay = 5 minutes;
    knock_delay_channel = 1 minute;
-   max_chans_per_user = 15;
+   max_chans_per_user = 20;
         max_bans = 100;
         max_bans_large = 500;
    default_split_user_count = 0;

Forbid channels with fake names.

@@ -335,7 +284,7 @@
    no_join_on_split = no;
    burst_topicwho = yes;
    kick_on_split_riding = no;
-   only_ascii_channels = no;
+   only_ascii_channels = yes;
    resv_forcepart = yes;
 };

Use the efnet blacklist, but point to the webchat if this is not supposed to happen.

@@ -371,7 +320,7 @@
  */
 blacklist {
    host = "rbl.efnetrbl.org";
-   reject_reason = "${nick}, your IP (${ip}) is listed in EFnet's RBL. For assistance, see http://efnetrbl.org/?i=${ip}";
+   reject_reason = "${nick}, your IP (${ip}) is listed in EFnet's RBL. For assistance, see http://efnetrbl.org/?i=${ip} or use the webchat and let us know the problem";

 #  host = "ircbl.ahbl.org";
 #  reject_reason = "${nick}, your IP (${ip}) is listed in ${dnsbl-host} for having an open proxy. In order to protect ${network-name} from abuse, we are not allowing connections with open proxies to connect.";

By thefault, users get the ip cloaking, so set the default user modes to +ix.

@@ -426,13 +375,13 @@
     * to make use of it, add +h to this option, i.e.:
     *  default_umodes = "+ih";
     */
-   default_umodes = "+i";
+   default_umodes = "+ix";

    default_operstring = "is an IRC Operator";
    default_adminstring = "is a Server Administrator";
    servicestring = "is a Network Service";
-   disable_fake_channels = no;
-        tkline_expire_notices = no;
+   disable_fake_channels = yes;
+        tkline_expire_notices = yes;
         default_floodcount = 10;
    failed_oper_notice = yes;
    dots_in_ident=2;

That's it. First make the configuration file readable only by the user that runs the ircd and start Charybdis.

chdir $HOME/ircd
chmod 600 etc/ircd.conf
./bin/ircd

Your ircd should be up and running now. Point your client to the server (eventually set your DNS) and try for yourself.

Configuring the services.

The only, really required configuring is the linking to the ircd. So look in the ircd.conf and pick the password. We will connect on the loopback interface, in plain, on 6667, using the password set above. Before the block, there is the options about modules. Just pick what you think you need. The nickserv/cert module is very cool, because you can identify to nickserv just providing a SSL certificate.

See http://www.oftc.net/oftc/NickServ/CertFP and http://dev.weechat.org/post/2009/12/01/SSL-certificates how to set up the clients.

chdir $HOME/atheme/etc
cp atheme.example.conf atheme.conf
chmod 600 atheme.conf

I've also activated all the modules for hostserv (the custom ip cloaking), but deactivated the xml-rpc and httpd modules (I don't want a web interface).

--- atheme.conf.example 2011-09-04 11:59:10.000000000 +0200
+++ atheme.conf 2011-09-04 11:55:18.000000000 +0200
@@ -107,7 +107,7 @@
  *
  * The rawsha1 module requires OpenSSL.
  */
-loadmodule "modules/crypto/posix";
+# loadmodule "modules/crypto/posix";

 /* Authentication module.
  *
@@ -186,12 +186,12 @@
  * VHOST command               modules/nickserv/vhost
  */
 loadmodule "modules/nickserv/main";
-#loadmodule "modules/nickserv/access";
+loadmodule "modules/nickserv/access";
 loadmodule "modules/nickserv/badmail";
-#loadmodule "modules/nickserv/cert";
+loadmodule "modules/nickserv/cert";
 #loadmodule "modules/nickserv/cracklib";
 loadmodule "modules/nickserv/drop";
-#loadmodule "modules/nickserv/enforce";
+loadmodule "modules/nickserv/enforce";
 loadmodule "modules/nickserv/ghost";
 loadmodule "modules/nickserv/group";
 loadmodule "modules/nickserv/help";
@@ -211,13 +211,13 @@
 loadmodule "modules/nickserv/resetpass";
 loadmodule "modules/nickserv/return";
 loadmodule "modules/nickserv/setpass";
-#loadmodule "modules/nickserv/sendpass";
+loadmodule "modules/nickserv/sendpass";
 loadmodule "modules/nickserv/sendpass_user";
 loadmodule "modules/nickserv/set_core";
 loadmodule "modules/nickserv/set_accountname";
 loadmodule "modules/nickserv/set_email";
 loadmodule "modules/nickserv/set_emailmemos";
-#loadmodule "modules/nickserv/set_enforcetime";
+loadmodule "modules/nickserv/set_enforcetime";
 loadmodule "modules/nickserv/set_hidemail";
 loadmodule "modules/nickserv/set_language";
 loadmodule "modules/nickserv/set_neverop";
@@ -553,14 +553,14 @@
  * VHOSTNICK command                            modules/hostserv/vhostnick
  * GROUP command                                modules/hostserv/group
  */
-#loadmodule "modules/hostserv/main";
-#loadmodule "modules/hostserv/help";
-#loadmodule "modules/hostserv/onoff";
-#loadmodule "modules/hostserv/offer";
-#loadmodule "modules/hostserv/request";
-#loadmodule "modules/hostserv/vhost";
-#loadmodule "modules/hostserv/vhostnick";
-#loadmodule "modules/hostserv/group";
+loadmodule "modules/hostserv/main";
+loadmodule "modules/hostserv/help";
+loadmodule "modules/hostserv/onoff";
+loadmodule "modules/hostserv/offer";
+loadmodule "modules/hostserv/request";
+loadmodule "modules/hostserv/vhost";
+loadmodule "modules/hostserv/vhostnick";
+loadmodule "modules/hostserv/group";

 /* HelpServ modules.
  * HelpServ allows users to request help from network staff in a few different ways.
@@ -573,10 +573,10 @@
  * The ticket system works like a bugtracker ot helpdesk ticket system, HELPME
  * works like a one-time alert. You should probably only load one of the two systems.
  */
-#loadmodule "modules/helpserv/main";
-#loadmodule "modules/helpserv/helpme";
-#loadmodule "modules/helpserv/ticket";
-#loadmodule "modules/helpserv/services";
+loadmodule "modules/helpserv/main";
+loadmodule "modules/helpserv/helpme";
+loadmodule "modules/helpserv/ticket";
+loadmodule "modules/helpserv/services";

 /* Channel listing service.
  *

The ALIS service is a cool /list replacement.

@@ -585,7 +585,7 @@
  *
  * Core components             modules/alis/main
  */
-#loadmodule "modules/alis/main";
+loadmodule "modules/alis/main";

 /* GroupServ module.
  * GroupServ allows users to create groups to easily mass-manage channel
@@ -605,7 +605,7 @@
  *
  * HTTP Server                 modules/misc/httpd
  */
-loadmodule "modules/misc/httpd";
+# loadmodule "modules/misc/httpd";

 /* XMLRPC server module.
  * 
@@ -614,7 +614,7 @@
  *
  * XMLRPC handler for the httpd            modules/xmlrpc/main
  */
-loadmodule "modules/xmlrpc/main";
+# loadmodule "modules/xmlrpc/main";

 /* Other modules.
  *

Ok, here starts the real configuration. Keep the recontime higher, if you don't want to be spammed by messages when you restart the services (because the ircd won't know that the services disconnected until the next ping, which is set to 2 minutes). Set netname, admin name (the nick the admin will use)

@@ -654,29 +654,29 @@
    /* (*)recontime
     * The number of seconds before we reconnect to the uplink.
     */
-   recontime = 10;
+   recontime = 30;

    /* (*)netname
     * The name of your network.
     */
-   netname = "misconfigured network";
+   netname = "AnarchyPlanet";

    /* (*)hidehostsuffix
     * P10 +x host hiding gives <account>.<hidehostsuffix>.
     * If using +x on asuka/bircd/undernet, this must agree
     * with F:HIDDEN_HOST.
     */
-   hidehostsuffix = "users.misconfigured";
+   hidehostsuffix = "anon.planet";

    /* (*)adminname
     * The name of the person running this service.
     */
-   adminname = "misconfigured admin";
+   adminname = "melmoth";

    /* (*)adminemail
     * The email address of the person running this service.
     */
-   adminemail = "misconfigured@admin.tld";
+   adminemail = "melmoth@invalid.tld";

    /* (*)mta
     * The full path to your mail transfer agent.

Set the loglevel

@@ -709,7 +709,7 @@
     *  rawdata     - log raw data sent and received by services
     *  wallops     - <not yet used>
     */
-   loglevel = { error; info; admin; network; wallops; };
+   loglevel = { all; }; # error; info; admin; network; wallops; };

    /* (*)maxlogins
     * What is the maximum number of sessions allowed to login to one

This is the linking. Set the server name, the host (127.0.0.1) for the loopback interfaces, already set in the example, the passord (from the connect{} block in the ircd.conf) and the port (6667), where the ircd listen in plain.

@@ -770,7 +770,7 @@
  * Multiple may be defined but only one will be used at a time (IRC
  * being a tree shaped network).
  */
-uplink "irc.example.net" {
+uplink "irc.anarchyplanet.org" {
    // The server name of the ircd you're linking to goes above.

    // host
// The hostname to connect to.
host = "127.0.0.1";
@@ -779,11 +779,11 @@

    // vhost
    // The source IP to connect from, used on machines with multiple interfaces.
    #vhost = "202.119.187.31";

    // password
    // The password used for linking.
-   password = "linkage";
+   password = "mypassword";

    // port
    // The port to connect to.

Remove the other servers.

@@ -791,11 +791,6 @@
 };

 /* this is an example for using an IPv6 address as an uplink */
-uplink "irc6.example.net" {
-   host = "::1";
-   password = "linkage";
-   port = 6667;
-};

 /* Services configuration.
  *

Don't be noisy.

@@ -815,7 +810,7 @@
 nickserv {
    // If you want NickServ to tell people about how great it is, enable the directive
    // below.
-   spam;
+#  spam;

    /* no_nick_ownership
     * Enable this to disable nickname ownership (old userserv{}).

Well, the comments are explicits.

@@ -858,7 +853,7 @@
    /* (*)expire
     * The number of days before inactive registrations are expired.
     */
-   expire = 30;
+   expire = 120;

    /* (*)enforce_expire
     * The number of days of no use after which to ignore enforcement
@@ -870,12 +865,12 @@
     * The number of seconds to delay nickchange enforcement settings
     * on nicks.
     */
-   #enforce_delay = 30;
+   enforce_delay = 120;

    /* (*)enforce_prefix
     * The prefix to use when changing the user's nick on enforcement
     */
-   #enforce_prefix = "Guest";
+   enforce_prefix = "Anon";

    /* (*)cracklib_dict
     * The location and filename prefix of the cracklib dictionaries
@@ -932,7 +927,7 @@
     * use a lot of CPU up, and will only work if you have
     * join_chans (in general) enabled as well.
     */
-   fantasy;
+   # fantasy;

    /* (*) hide_xop
     * Hide the XOP templates from sight.  This is useful if you

Remove the httpd, ldap and xml-rpc stuff, if you're not using it

@@ -1414,50 +1409,11 @@
  * The HTTP server in Services is used for serving XMLRPC requests. It can
  * also serve static documents and statistics pages.
  */
-httpd {
-   /* host
-    * The host that the HTTP server will listen on.
-    * Use 0.0.0.0 if you want to listen on all available hosts.
-    */
-   host = "0.0.0.0";
-
-   /* host (ipv6)
-    * If you want, you can have Atheme listen on an IPv6 host too.
-    * Use :: if you want to listen on all available IPv6 hosts.
-    */
-   #host = "::";
-
-   /* www_root
-    * The directory that contains the files that should be served by the httpd.
-    */
-   www_root = "/var/www";
-
-   /* port
-    * The port that the HTTP server will listen on.
-    */
-   port = 8080;
-};
-
 /* LDAP configuration.
  *
  * The ldap {} block contains settings specific to the LDAP authentication
  * module.
  */
-ldap {
-   /* (*)url
-    * LDAP URL of the server to use.
-    */
-   url = "ldap://127.0.0.1";
-
-   /* (*)dnformat
-    * Format string to convert an account name to an LDAP DN.
-    * Must contain exactly one %s which will be replaced by the account
-    * name.
-    * Services will attempt a simple bind with this DN and the given
-    * password; if this is successful the password is considered correct.
-    */
-   dnformat = "cn=%s,dc=jillestest,dc=com";
-};

 /******************************************************************************
  * LOGGING SECTION.                                                           *

Don't log in channels

@@ -1505,7 +1461,7 @@
  * Under no circumstances, should you log rawdata to IRC.  If you think
  * about it, you should realize that it will cause an infinite loop.
  */
-logfile "#services" { error; info; admin; request; register; };
+logfile "var/services.log" { error; info; admin; request; register; };

 /******************************************************************************
  * GENERAL PARAMETERS CONFIGURATION SECTION.                                  *
@@ -1518,7 +1474,7 @@
     * Network help channel. Shown to users when they request
     * help for a command that doesn't exist.
     */
-   #helpchan = "#help";
+   helpchan = "#help";

    /* (*)helpurl
     * Network webpage for services help. Shown to users when they

Don't have the bots joining channels.

@@ -1562,7 +1518,7 @@
     * akick/restricted/close, and to change the TS if changets is
     * enabled.
     */
-   join_chans;
+   #join_chans;

    /* (*)leave_chans
     * Do we leave registered channels after everyone else has left?

The nickname of the service operator.

@@ -1805,7 +1761,7 @@
 /* (*) Operator blocks specify accounts with certain privileges
  * Oper classes must be defined before they are used in operator blocks.
  */
-operator "jilles" {
+operator "melmoth" {
    /* operclass */
    operclass = "sra";
    /* password

That's it. Go in $HOME/atheme and start it

chdir $HOME/atheme
./bin/atheme-services

Now you can register/identify to nickserv and reclaim your admin privileges.

Start all

If you want to be cool, here is a script to start and stop all the circus: Executing it without arguments will provide the avaiable options.

#!/bin/bash

if [ $UID == 0 ]; then
        echo "Don't run this as root!"
        exit 3
fi


start_ircd () {
    echo "Starting the IRCd"
    cd $HOME/ircd
    ./bin/ircd
    cd -
}

stop_ircd () {
    echo "Killing the IRCd"
    cd $HOME/ircd
    kill `cat etc/ircd.pid` || killall ircd
    cd -
}

start_services () {
    echo "Starting the services (Atheme)"
    cd $HOME/atheme
    ./bin/atheme-services
    cd -
}

stop_services () {
    echo "Killing the services"
    cd $HOME/atheme
    kill `cat var/atheme.pid` || killall atheme-services
    cd -
}

case $1 in
    startall)
    start_ircd
    start_services
    ;;
    stopall)
    stop_ircd
    stop_services
    ;;
    startircd)
    start_ircd
    ;;
    stopircd)
    stop_ircd
    ;;
    startservices)
    start_services
    ;;
    stopservices)
    stop_services
    ;;
    restart)
    stop_services
    stop_ircd
    sleep 2
    start_ircd
    start_services
    ;;
    *)
    echo "Usage: startall | restart | stopall | stopircd | startircd  | stopservices | startservices "
    ;;
esac

If you want, you can add this script to the crontab (provided by atheme, but slightly modified)

#!/bin/sh
#
# crontab script for atheme
#

# Change this to the directory where you installed it
prefix=$HOME/atheme/
pidfile=var/atheme.pid
ircdpidfile=$HOME/ircd/etc/ircd.pid

cd "$prefix" || {
    echo "$0: couldn't cd to $prefix"
    exit 1
}

if [ -f "$pidfile" ] ; then
  PID=`cat "$pidfile"`

  if kill -0 $PID >/dev/null 2>&1; then
    exit 0
  fi

  rm -f "$pidfile"
fi

# check if the ircd is running
if [ -f "$ircdpidfile" ] ; then
    iPID=`cat "$ircdpidfile"` 
    if kill -0 $iPID > /dev/null 2>&1; then
    echo "$0: couldn't find atheme running, restarting..."
    ./bin/atheme-services
    exit 0
    else
    echo "The ircd is down!"
    exit 0
    fi
else
    echo "The ircd is down!"
fi

exit 0

You should also modify the MOTD in ircd/etc/ircd.motd and atheme/etc/atheme.motd to provide some useful information. But it's just estetics.

The Webchat (qwebirc)

The webchat system is quite simple to set up.

First login as the user (not the same as the ircd) that will run this service, and download the source:

hg clone http://hg.qwebirc.org/qwebirc
cd qwebirc

Create the certificates:

openssl req -x509 -nodes -newkey rsa:2048 \
       -keyout private.key -out webchat.cert
chmod 600 private.key

Configure:

cp config.py.example config.py

This is the trivial diff:

--- config.py.example   2011-09-03 20:20:29.000000000 +0200
+++ config.py   2011-09-04 08:47:13.000000000 +0200
@@ -18,11 +18,11 @@
 #         Hostname (or IP address) of IRC server to connect to.
 # OPTION: IRCPORT
 #         Port of IRC server to connect to.
-IRCSERVER, IRCPORT = "irc.myserver.com", 6667
+IRCSERVER, IRCPORT = "127.0.0.1", 6667

 # OPTION: REALNAME
 #         The realname field of IRC clients will be set to this value.
-REALNAME = "http://moo.com/"
+REALNAME = "Anarchy Planet webbechat"

 # OPTION: IDENT
 #        ident to use on irc, possible values include:
@@ -40,7 +40,7 @@
 #         This will not change the IP address that qwebirc listens on. 
 #         You will need to call run.py with the --ip/-i option if you 
 #         want that.
-#OUTGOING_IP = "127.0.0.1"
+OUTGOING_IP = "127.0.0.1"

 # OPTION: WEBIRC_MODE
 #         This option controls how the IP/hostname of the connecting
@@ -85,12 +85,12 @@
 # OPTION: BASE_URL
 #         URL that this qwebirc instance will be available at, add the
 #         port number if your instance runs on a port other than 80.
-BASE_URL = "http://foo.foo.org/"
+BASE_URL = "http://irc.anarchyplanet.org:9090/"

 # OPTION: NETWORK_NAME
 #         The name of your IRC network, displayed throughout the
 #         application.
-NETWORK_NAME = "FooNet"
+NETWORK_NAME = "Anarchy Planet"

 # OPTION: APP_TITLE
 #         The title of the application in the web browser.
@@ -135,18 +135,18 @@
 #
 # OPTION: FEEDBACK_FROM
 #         E-mail address that feedback will originate from.
-FEEDBACK_FROM = "moo@moo.com"
+# FEEDBACK_FROM = "moo@moo.com"

 # OPTION: FEEDBACK_TO:
 #         E-mail address that feedback will be sent to.
-FEEDBACK_TO = "moo@moo.com"
+# FEEDBACK_TO = "moo@moo.com"

 # OPTION: FEEDBACK_SMTP_HOST
 #         Hostname/IP address of SMTP server feedback will be sent
 #         through.
 # OPTION: FEEDBACK_SMTP_PORT
 #         Port of SMTP server feedback will be sent through.
-FEEDBACK_SMTP_HOST, FEEDBACK_SMTP_PORT = "127.0.0.1", 25
+# FEEDBACK_SMTP_HOST, FEEDBACK_SMTP_PORT = "127.0.0.1", 25

 # ADMIN ENGINE OPTIONS
 # ---------------------------------------------------------------------

Then remove some options in the drop down menu modifing "js/ui/menuitems.js" I did the following (look at the comments):

qwebirc.ui.UI_COMMANDS = [
  ["Options", "options"],
/*  ["Add webchat to your site", "embedded"], 
  ["Privacy policy", "privacy"],
  ["Feedback", "feedback"],
  ["Frequently asked questions", "faq"], */
  ["About qwebirc", "about"]
];

Leaving only the options and the about.

Then compile:

./compile.py

(Oh, it will complain if you don't have java installed. But it's just to compress the javascript, so who cares?).

Finally, run it:

./run.py -C webchat.cert -k private.key

It should be accessible at https://yourserver.org:9090

That's all.