Tip of the day: If you still have users on plaintext port 6667, consider enabling Strict Transport Security to gently move users to SSL/TLS on port 6697.

Configuration

From UnrealIRCd documentation wiki
Jump to navigation Jump to search
This page contains changes which are not marked for translation.
Other languages:

This contains all information on the UnrealIRCd configuration file (unrealircd.conf and other *.conf files). Be sure to read the #Configuration file syntax. Other than that, it is mostly meant for reference as reading everything would be too long to read.

If you are ever in need of help due to a flood attack, DoS or DDoS, spamming or drone attack, then be sure to check the Security article for hands-on tips.

Configuration file syntax

Other languages:

UnrealIRCd configuration files use a block-based format. Each entry or block has a specific format. The format works like:

<block-name> <block-value> {
	<block-directive> <directive-value>;
}

<block-name> is the type of block, such as me for the Me block, or admin for the Admin block.

<block-value> may not always be present, but if it is then it may have two meanings: 1) sometimes it specifies a value, such as bobsmith in oper bobsmith {, 2) other times it defines a sub-type, like with deny dcc {.

<block-directive> is an individual variable specific to the block. <directive-value> is the associated value (if any). If <directive-value> contains spaces or characters that represents a comment it must be contained in double quotes like somevar "some value with spaces in it";. (By the way, if you want to use a quote character inside a quoted string then use \" and it will be understood as a quote character).

Finally, a <block-directive> may also have directives in it, and so on and so on.

Note: the configuration file is currently case sensitive so BLOCK-NAME is not the same as block-name.

IMPORTANT: You must terminate each line with a ; and terminate each block with a }. Only the start and end of the block (eg: me {) has no terminating ; character. If you forget a } or ; somewhere then UnrealIRCd will fail to read your configuration file correctly and will not boot!

Examples (correct):

me {
        name "irc.something.net";
        sid 001;
        info "Some nice server";
}
log ircd.log {
        flags {
                errors;
        }
}
set {
        maxchannelsperuser 10;

        options {
                hide-ulines;
        }
        
        anti-flood {
                connect-flood 3:60;
                nick-flood 3:60;
        }
}

Important: there is a special notation used to talk about entries in the config file and we use it throughout the UnrealIRCd documentation. Take the first example from above (the me block), the name is set to irc.something.net, we call this variable me::name. Similarly, in the last example we would refer to the connect-flood directive as set::anti-flood::connect-flood, and we call that block the set::anti-flood block. It does not mean you literally write set::anti-flood in the config file.

You can also put comments in the configuration file. Comments are text that isn't interpreted by UnrealIRCd and it's entirely up to you if you use it and what you write. UnrealIRCd supports 3 types of comments:

# This is a single line comment (type 1)
// This is also a single line comment (type 2)
/* This is a
   multi line
   comment */

Now that you know how the configuration file works in principle, copy conf/examples/example.conf to conf/ and rename the file to unrealircd.conf. Then, walk through it block per block, line by line. If you want to know more about a specific section then see the top of the Configuration article for all the available blocks and directives.

Sharing settings between servers

Other languages:

When you run multiple IRC servers (in the same IRC network) then it makes sense to put these "shared settings" in a separate configuration file(s) and only put server-specific settings directly in the unrealircd.conf directly.

For example, you could put all the shared settings in a file called network.conf, copy it to all your servers and include it from your unrealircd.conf. Or maybe you want to split them up like link.conf, class.conf, settings.conf, etc.

Even better: use Remote includes so your servers fetch a copy of it by HTTP(S) upon start and /REHASH.. then you only have to update one file, rehash your servers, and the settings are active network-wide.

Many settings can be shared among servers. Only the Me block and possibly the Listen block and some other settings are unique for each server.

Me block

The me block defines the identity of the server.

Syntax:

me {
	name <name-of-server>;
	info "<server-description>";
	sid <server-id>;
};

The item name specifies the name of the server, info specifies the server's info line, sid is an unique server id which is a digit followed by two digits/letters in uppercase. This is an unique server value meaning NO other servers on the network may have the same sid.

Example:

me {
	name "irc.foonet.com";
	info "FooNet Server";
	sid 001;
};

Admin block

The admin block defines the text displayed in a /admin request. You can specify as many lines as you want and they can contain whatever information you choose, but it is standard to include the admins nickname and email address at a minimum. Other information may include any other contact information you wish to give.

Syntax:

admin {
	<text-line>;
	<text-line>;
};

Example:

admin {
	"Bob Smith";
	"bob";
	"[email protected]";
};

Class block

Class blocks are classes in which connections will be placed, for example clients from allow blocks and servers from link blocks. You generally have multiple class blocks: one for servers, one for regular clients and one for IRCOps (the latter is optional).

Syntax

class <name> {
	pingfreq <ping-frequency>;
	connfreq <connect-frequency>;
	maxclients <maximum-clients>;
	sendq <send-queue>;
	recvq <recv-queue>;
	//options { nofakelag; };
};

name is the descriptive name, like "clients" or "servers", this name is used for referring to this class from allow/link/oper/etc blocks

pingfreq is the number of seconds between PINGs from the server (something between 90 and 180 is recommended).

connfreq is used only for servers and is the number of seconds between connection attempts if autoconnect is enabled

maxclients specifies the maximum (total) number of clients/servers which can be in this class

sendq specifies the amount of data which can be in the send queue (very high for servers with low bandwidth, medium for clients)

recvq specifies the amount of data which can be in the receive queue and is used for flood control (this only applies to normal users, try experimenting with values 3000-8000, 8000 is the default).

options::nofakelag allows this particular class to bypass the fake lag protection, it is almost never used. Read the FAQ on fake lag first before you try using this!

Examples

class clients
{
	pingfreq 90;
	maxclients 1000;
	sendq 200k;
	recvq 8000;
};
class servers
{
	pingfreq 60;
	connfreq 15;     /* try to connect every 15 seconds */
	maxclients 10;   /* max servers */
	sendq 20M;
};
class opers
{
	pingfreq 90;
	maxclients 50;
	sendq 1M;
	recvq 8000;
};

Allow block

Allow blocks specify who may connect to this server and what class to put the user in. You can have multiple allow blocks.

Syntax

allow {
        mask <mask>;
        class <connection-class>;
        maxperip <max-connections-per-ip-locally>;

        /* All the rest is optional: */
        global-maxperip <max-connections-per-ip-globally>;
        password <connection-password> { <auth-type>; }; /* OPTIONAL */
        redirect-server <server-to-forward-to>; /* OPTIONAL */
        redirect-port <port-to-forward-to>; /* OPTIONAL */
        options {
            <option>;
            <option>;
            ...
        };
};

Do you have multiple allow blocks? Then note that they will be read upside down, so you need specific host/ip allow blocks AFTER your general *@* allow blocks.

If a client does not match any allow block then the client is rejected with the message from set::reject-message.

required items

mask

You must specify a mask such as mask *;. Advanced users may wish to look at Mask item to see a lot more options that can be used for masks, such as lists, negative matching, matching SASL users, certificate fingerprints, etc.

class

Specifies the class name that connections using this allow block will be placed into.

maxperip

With maxperip you specify how many local connections may come from each IP. For example maxperip 4; means that only 4 clients may connect per-IP to this server.

Note that if you use Services then it may have a session limit too. If you bump maxperip in UnrealIRCd and then see kills/quits with the reason "Session limit exceeded" then you know it is not UnrealIRCd doing this but anope or other services. We recommend disabling the os_session module in your services since it is unneeded with UnrealIRCd.

global-maxperip

This specifies the global maximum number of connections from each IP (network-wide). If you don't have this, then it will default to maxperip+1.

optional items

password

The server password or another authentication method that the user authenticates with.

There are two possible behaviors for password control:

optional password to get extra rights

The default behavior is, if the password is incorrect, to continue matching next allow block:

allow { mask *; class clients; maxperip 2; }
allow { mask *; password "iwantmore"; class clients; maxperip 10; }

If a user connects with the password iwantmore then they will get a maxperip of 10. If the user does not connect with that password (either wrong or no password) then the user will get a maxperip of 2.

mandatory password

On the other hand, you may want to use passwords to keep other users out. In this case you need to use allow::options::reject-on-auth-failure as described below:

allow { mask *; class clients; maxperip 2; }
allow { mask *@*.nl; password "tehdutch"; class clients; maxperip 2; options { reject-on-auth-failure; } }

In this case anyone with a hostname of *.nl must provide the password tehdutch. If they don't, they will be rejected access and cannot connect to the server.

redirect-server & redirect-port

When the class is full (class::maxclients) we will redirect new users to this server. This requires support from the IRC client side, popular clients like mIRC support this but this feature is broken in case of SSL/TLS so is likely of little use in the modern world.

redirect-server specifies the server name and redirect-port the port (6667 by default).

options

One option gives you additional flexibility for matching:

  • tls: Only match if this client is connected via SSL/TLS.

Meaning, if this doesn't match, UnrealIRCd jumps to next allow block.

There are also two other options that don't have anything to do with matching but will affect the user/host:

  • useip: Always display IP instead of hostname.
  • noident: Don't use ident but use username specified by client.

And, finally, there's one special option that is rarely used:

  • reject-on-auth-failure: Reject the user if the password is not provided or does not match. See also the password option above for a longer explanation.

Example

Example 1: generic block and specific block

allow {
	mask *;
	class clients;
	maxperip 3;
};

allow {
	mask 1.2.3.*;
	class clients;
	maxperip 25;
};

Example 2: extended matching

NOTE: This options is available in UnrealIRCd 6.0.4 and later. If you are using an older version then see example 3 instead

allow {
	mask *;
	class clients;
	maxperip 3;
};

allow {
	mask {
                mask { 1.2.3.0/24; }
                account { TrustedUser1; TrustedUser2; }
                certfp { "1234567890abcdef1234567890abcdef123456"; } /* Add more than one certfp: "secondone"; "thirdone";  */
        }
	class clients;
	maxperip 25;
};

This will:

  • Grant the high maxperip 25 to users matching any of the following criteria (OR!):
    • Any user in the IP range 1.2.3.0/24, OR
    • Users identified to services via SASL with the account name TrustedUser1 or TrustedUser2, OR
    • A user which uses certificate fingerprint (sha256) 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
  • All the other clients get a maxperip 3

Example 3: extended matching (before UnrealIRCd 6.0.4)

allow {
	mask *;
	class clients;
	maxperip 3;
};

allow {
	mask 1.2.3.*;
	class clients;
	maxperip 25;
};

allow {
	mask { ~a:TrustedUser1; ~a:TrustedUser2; }
	class clients;
	maxperip 25;
};

This will:

  • Grant any user in the IP range 1.2.3.* a high maximum connections per IP of 25
  • Grant TrustedUser1 and TrustedUser2, if he identifies to services using SASL, also a maxperip of 25
  • All the other clients get a maxperip of 3

Listen block

The listen block defines the TCP/IP ports and/or UNIX socket that the IRCd will listen on.

Syntax

listen {
        /* For IPv4 or IPv6: */
        ip <ip>;
        port <port>;
        /* For UNIX sockets: */
        file <full path>;
        mode <mode>;
        spoof-ip <fake-ip>;

        /* Options: */
	options {
		<option>;
		<option>;
		...
	}

        /* Specific SSL/TLS configuration to this listen block */
	tls-options {
		...
	}
}

ip

Simply set ip to * (an asterisk) to bind to all available IP's on the machine, OR specify an IP to only bind to that IP address (this latter is usually required at shell providers).

port

This is the port you want to listen on, like 6667. You can also specify a port range, like 6667-6669.

file

This is the full path (filename) to a UNIX socket that will be created on the machine. This feature is rarely used, so if you don't what this is then don't use and don't set it. If you have a file item then you cannot have an ip or port in the same listen block.

mode

Optionally, if the listener is a file, then you can specify permissions mode here. Valid choices are: 0700 (user only, rwx------, the default), 0770 (user and group, rwxrwx---), and 0777 (world writable, rwxrwxrwx, not recommended). This can be useful if you have a webserver on the same machine which needs to access the *NIX socket, for example. This option only exists in UnrealIRCd 6.0.6 or later.

spoof-ip

If the socket is a file, then connections over this UNIX domain socket are spoofed to come from 127.0.0.1 by default. You can override this by setting spoof-ip to a different IP address. This can be useful for Running Tor hidden service with UnrealIRCd. This requires UnrealIRCd 6.1.0 or higher

options block (optional)

You can specify options for the port. Valid options are:

  • tls: SSL/TLS encrypted port
  • clientsonly: port is only for clients
  • serversonly: port is only for servers
  • rpc: for remote control via JSON-RPC
  • websocket: port is for WebSocket, and within that block:
    • You must specify a websocket type. Either text or binary, with text being the usual choice.
      options { websocket { type text; } }
    • You can optionally restrict from which websites websockets can be used by web browsers, via allow-origin.
      In this context websites means the site(s) hosting the HTML/JS page that makes the websocket, e.g. if the chat page is https://kiwiirc.com/nextclient/ then you would use { kiwiirc.com; }.
      Please don't confuse allow-origin with the Proxy block, the proxy block is about reverse proxies.
      The allow-origin directive does not restrict any NON-browsers from using websockets to connect to your server, as they could can just spoof the Origin header. It is only a browser restriction for regular users.
      The allow-origin contains of a list, like options { websocket { type text; allow-origin { kiwiirc.com; } } }
      And the default is to allow all: options { websocket { allow-origin { *; } } }
    • See #Websocket_port for a full example.

tls-options block (optional)

Valid options are all the SSL/TLS settings that also exist in set::tls. For example you may want to use an Lets Encrypt certificate/key on all normal client ports (via set::tls::certificate). But for this port you want to use another SSL certificate/key:

listen {
        ...
        tls-options {
                certificate "ssl/server.cert.pem";
                key "ssl/server.key.pem";
        }
}

Examples

Standard port 6667, insecure plaintext

listen {
        ip *;
        port 6667;
}

Standard SSL/TLS port 6697

listen {
        ip *;
        port 6697;
	options {
		tls;
	}
}

Or, with a Let's Encrypt certificate:

listen {
        ip *;
        port 6697;
        options { tls; }
        tls-options {
                certificate "/etc/letsencrypt/live/irc.example.org/fullchain.pem";
                key "/etc/letsencrypt/live/irc.example.org/privkey.pem";
        }
}

Websocket port

Example of Websockets on port 8000 with Let's Encrypt certificate:

listen {
    ip *;
    port 8000;
    options {
        tls;
        websocket {
            type text;  // type must be either 'text' or 'binary'
            // In 6.1.3+ you can optionally restrict origins, see websocket options
            // https://www.unrealircd.org/docs/Listen_block#options_block
            //allow-origin { *; }
        }
    }
    tls-options {
        certificate "/etc/letsencrypt/live/irc.example.org/fullchain.pem";
        key "/etc/letsencrypt/live/irc.example.org/privkey.pem";
        options {
            no-client-certificate;
        }
    }
}

If you wish to use a reverse proxy in front of websockets, then see the Proxy block. This is rare, but possible.

JSON-RPC port

A JSON-RPC port:

listen {
        ip *;
        port 8600;
        options { rpc; }
}

NOTE: this requires including rpc.modules.default.conf, see JSON-RPC.

Oper block

In oper blocks you define all the IRC Operators accounts. Once defined you use the /OPER command on IRC to become IRCOp.

Recommended reading:

Syntax

oper <name> {
        /* Required items: */
        mask <hostmask>;
        password <password>;
        class <class-name>;
        operclass <operclass-name>;
        /* Optional items to further limit who can /OPER */
        auto-login <yes|no>;
        require-modes <modes>
        maxlogins <num>;
        /* Optional items to define what will be set upon successful /OPER */
        vhost <new virtual hostname>;
        swhois <whois info>;
        modes <modes>;
        snomask <snomask>;
        server-notice-colors yes|no;
        server-notice-show-event yes|no;
};

Required items

name

The name in the oper name { block defines which name to use in the OPER command on IRC (/OPER name password). This name is case sensitive!

Most people use their nick name here. You can use latin characters (A-Z a-z), numbers and _-[]. Do not use special characters like ö (as in Björn) or Arabic/Greek/etc. Such characters may cause you problems with /OPER'ing due to character set differences.

password

The password item defines the password to use. Passwords are case sensitive. Instead of using a plaintext password here, we highly recommend you to use Hashed passwords or SSL certificate fingerprints, see Authentication types.

In UnrealIRCd 6.0.4 and later the password item is no longer required. If you don't put a password then be sure to use a good mask (see next)!

mask

The mask defines from which host/IP this oper block may be used, this can be used for increased security. Set this to mask *; if you want to permit any IP.

You may also use multiple masks, in which case the syntax becomes like: mask { 192.168.0.0/16; *.example.net; };.

See Mask item for more options. For example, instead of an IP address or host, you can require a certain certificate fingerprint: mask { certfp "00112233etc."; } or a Services account: mask { account TrustedUser; }.

class

After a successful /OPER attempt the user will be put in the class you specify here. It's recommended to use a special class you created for opers (eg: class opers;) that typically has higher flood limits than ordinary users.

operclass

This defines which Operclass block to use. The operclass block configures which privileges this IRCOp will have (which IRCOp commands you may use, etc..).

See the default list of operclasses from which you can choose. The highest are netadmin and netadmin-with-override.

Optional items

auto-login

NOTE: Requires UnrealIRCd 6.0.4 or later

If auto-login is set to yes then the user is automatically logged in if they match the mask. In this case there can be no password item.

This is generally only used for logins with certfp, see the automatic oper example at the end of this article.

maxlogins

This allows you to restrict the number of concurrent oper logins from this host, for example if you set it to 1 then only 1 person can be oper'ed via this block at any time.

vhost

This hostname (virtual host) will be set after you successfully oper up.

swhois

Allows you to add one or more extra lines to the /WHOIS information for this oper. For example:

swhois "a Network Administrator";

modes

Set these user modes after successful oper up.

snomask

By default an IRCOp gets the Snomasks from set::snomask-on-oper. You can use this oper::snomask to specify a different set of snomasks. See Snomasks for a full list.

snomask "+bBcdfk";

auto-join

By default an IRCOp will be joined to the channels in set::oper-auto-join. You can override this setting by setting an oper::auto-join in an individual oper block. If you use this, don't forget to use double quotes and optionally specify multiple channels with a comma. Eg: auto-join "#opers,#staff";

require-modes

Here you can put user modes that the user must have in order to use the OPER command. For example, you can put z here to require opers to use a SSL/TLS connection.

This setting is not used much anymore, as requiring IRCOps to be on TLS is already done via set::plaintext-policy::oper nowadays (which is even on by default).

server-notice-colors

Note: this setting only exists in UnrealIRCd 6 and later

Enable or disable colors in server notices (to snomasks). Valid options are yes and no. The default for all IRCOps is configured via set::server-notice-colors.

server-notice-show-event

Note: this setting only exists in UnrealIRCd 6.0.2 and later

Enable or disable showing of the susbystem.event (eg: connect.LOCAL_CLIENT_CONNECT) in server notices to snomasks. Valid options are yes and no. The default for all IRCOps is configured via set::server-notice-show-event.

Examples

Simple example

oper bobsmith {
	class opers;
	mask { smithco.com; *.somedialupisp.com; };
	password "f00";
        operclass netadmin;
	swhois "a Network Administrator";
};

Automatic oper

NOTE: This requires UnrealIRCd 6.0.4 or later

This uses the certificate fingerprint 00112233etc.. If the user connects with SSL/TLS with that client certificate fingerprint they become IRCOp automatically, they don't have to type the OPER command.

oper bobsmith {
        auto-login yes;
	mask { certfp "00112233etc."; }
        class opers;
        operclass netadmin;
	swhois "a Network Administrator";
};

Using security-groups

NOTE: This requires UnrealIRCd 6.0.4 or later

This uses the certificate fingerprint 00112233etc.. We create a security-group first, and then use that security-group in both the oper { } block and the except ban { } block.

security-group bobsmit {
        certfp "00112233etc.";
}

oper bobsmith {
        auto-login yes;
	mask { security-group bobsmith; }
        class opers;
        operclass netadmin;
	swhois "a Network Administrator";
};

/* Be nice and exempt the oper from server bans too */
except ban {
        mask { security-group Syzop; }
        type all;
}

Walking through bans, joining invite only channels

If IRCOps want to bypass channel restrictions, like joining a +i channel or walking through bans, op'ing yourself in a channel, etc. then see the OperOverride article for all information on this.

Operclass block

The operclass block is used to define ircop permissions. It is referred to from oper::operclass in the Oper block.

The operclass block allows you to define permissions in a very fine-grained manner. If you just want to use some good defaults, then see the default oper classses at the end of this article.

Syntax & Examples

operclass name {
        parent xyz; /* OPTIONAL: can be used to inherit permissions from another operclass block */
        permissions {
                .....permissions to grant to this oper class......
        };
};

Each operclass has a name. You define the privileges in operclass::permissions. Optionally you can use operclass::parent to have this operclass inherit all permissions from another operclass.

How permissions work

By default the oper using an operclass does not have special powers (this is not entirely true, actually). You must grant each privilege via operclass::permissions.

For example to grant the right to /KILL users:

operclass name {
        permissions {
                kill;

This would be the same as:

operclass name {
        permissions {
                kill {
                        allow;
                };

Many permissions allow you to define even more options, which go in a sub-block, like:

operclass name {
        permissions {
                kill {
                        allow { local yes; }; /* only allow KILL on local users, not remote */
                };

You can also have multiple allow blocks. The following would permit SPAMFILTER, but only in a limited matter:

operclass name {
        permissions {
                spamfilter {
                        /* May delete ANY spamfilter */
                        allow {
                                what del;
                        };
                        /* May add spamfilter with action 'block' */
                        allow {
                                action block;
                        };
                        /* (all the rest is denied) */
                };

Permissions list

See the Operclass permissions article for an overview and the full list of 100+ permissions that are available.

Default oper classes

UnrealIRCd ships with a number of operclass blocks, these are in the file operclass.default.conf. You can use these for inspiration or just use them directly from your Oper block.

The default operclass blocks consist of:

  • locop: this has the least amount of privileges. The powers of this IRCOp type are (mostly) limited to the local server, for example it can /KILL and /KLINE local users but not remote users. This IRCOp does not have any special privileges in channels nor can it "see" much additional information of users. For example, they can see the IP of users (so they can /KLINE properly) but they cannot see if a user is in a secret channel (+s).
  • globop: Global IRC Operator. Has a good set of privileges. Can for example /KILL and /GLINE users on all servers. Can "see" extra things (override::see) such as secret channels in /LIST and /WHOIS.
  • admin: Server administrator. Similar to globop but includes the ability to use a few more potentially dangerous but powerful commands such as /SPAMFILTER.
  • services-admin: This level adds the ability to use /SAJOIN, /SAPART and /SAMODE.
  • netadmin: This is the highest level. Compared to services-admin it also includes the ability to deop or kill services bots and some other unusual things.

In addition to the above we also have globop-with-override, admin-with-override, services-admin-with-override and netadmin-with-override: these operclasses are the same as above but add the ability to use OperOverride. In other words: to walk through bans, changes modes without being op'ed, and so on. See OperOverride for more information.

Customizing oper classes

If you want to tweak an operclass, change a few permissions, then you can do so in two ways:

  • By copy-pasting the block(s) from operclass.default.conf
  • By creating a new operclass and using 'inheritance'. You set operclass::parent to an operclass to use as a base and then extend the operclass by adding / removing permissions.

We highly suggest you read below about both methods and only after that decide which one to use.

Copy-pasting

NOTE: You should never edit operclass.default.conf directly as it will be overwritten upon each upgrade! (hence the name operclass.default.conf)

This method is easy:

  • Copy the relevant block(s) to your own configuration file
  • Give the operclass block(s) a different name
  • Edit the block to add/remove permissions

The downside of this method is that when we add new permissions in later UnrealIRCd versions then your (custom) IRCOp classes won't have these rights by default. You would have to edit your operclass and add the new permissions manually (or not). This can happen when we move existing permissions that are currently granted to all IRCOps to a new privilege flag, or when we split existing permissions into 2 separate permissions. Since the operclass system is relatively new this is likely to happen (almost) every UnrealIRCd release. Of course, if you understand this downside and find it acceptable, then it's perfectly fine if you use this method.

Using inheritance

Inheritance works better than copy-paste (for small changes, anyway) and requires less maintenance on your side. This is because when we add new rights in UnrealIRCd in later versions we will add them to the default blocks and your customized block would automatically inherit them.

Inheritance should work well in the majority of the cases. However if you have a lot of changes then it may be better to just go for the copy-pasting method explained earlier.

Example 1: limit rights

Say you like the locop operclass but want a few things changed:

  • You want the ircop to be able to 'see' extra things such as secret channels.
  • The locop class allows /ZLINE and /KLINE, but you want to only allow /KLINE.
operclass special {
       parent locop; /* we inherit the settings from 'locop' and then tweak them below.. */
       permissions {
                /* we add a 'tkl' block with only 'kline', this means: only allow kline (and not zline too) */
                tkl {
                        kline;
                };

                override { see; }; /* add the override::see capability */

                /* all the other permissions are inherited from the 'locop' operclass */
       };
};

Example 2: super-netadmin

In this example we will extend the netadmin IRCOp to also restart the server (via the /RESTART command).

The restart privilege is called server::restart. So we need to override the server privilege. First, you should have a look at which server permissions are there in the netadmin class. You should check out operclass.default.conf, but at the time of writing this article it is:

server { opermotd; info; close; remote; module; dns; addline; rehash; description; addmotd; addomotd; tsctl; };

So we will need to add restart; to that.

This is the complete block you will use:

operclass super-netadmin {
       parent netadmin; /* we inherit the settings from 'netadmin' and then tweak them below.. */
       permissions {
                /* we are going to change the 'server' block. We need to copy the rights from
                 * the 'netadmin' operclass and add 'restart' to it:
                 */
                server {
                        opermotd; info; close; remote; module; dns; addline; rehash; description; addmotd; addomotd; tsctl; restart;
                };
                /* all the other permissions are inherited from the 'netadmin' operclass */
       };
};

DRpass block

IRCOp's who have restart/die rights can restart the IRC Server through /RESTART and kill the server with the /DIE command.

This block allows you to set a password for these commands so IRCOp's need to use /DIE password and /RESTART password.

Please use encrypted password in this block (especially here). See Authentication types.

Syntax

drpass {
	restart <restart-password>;
	die <die-password>;
};

Example

drpass {
	restart "I-love-to-restart";
	die "die-you-stupid";
};

Include directive

The include directive allows you to include other configuration files. This way you can split up your configuration instead of having one large unrealircd.conf.

Syntax

include "<file-name>";
include '<url>';

You can use:

  • A relative file name, such as include "modules.default.conf"; this will be read from your conf directory in UnrealIRCd.
  • A full path, such as include "/var/opt/whatever.conf"; or include "C:\\something\\xyz.conf";
  • An URL using Remote includes, such as: include 'https://user:[email protected]/restricted/opers.conf';

Note: When using a URL you should use single quotations, as in the last example.

Commonly included files

UnrealIRCd ships with a number of configuration files out-of-the-box that you can choose to include:

  • modules.default.conf: these contain all the modules, you almost always want to load this file
  • badwords.conf: needed to make channel mode +G and user mode +G work ("bad words filter")
  • spamfilter.conf: spamfilter (example) configuration
  • aliases/anope.conf: recommended if you use anope services. This provides aliases such as the /NS and /IDENTIFY commands.
  • aliases/atheme.conf: same but for atheme services

Example

include "modules.default.conf"; /* Load all modules */
include "operclass.default.conf"; /* Default operclass blocks */
include "spamfilter.conf"; /* Spamfilter configuration */
include "badwords.conf";
include "help.conf";
/* CUSTOM example */
include "opers.conf"; /* Oper blocks are all in this file*/
include "links.conf"; /* All link blocks */

If you have enabled "Remote includes" (this is the default on Windows) then you can also use URL's:

include 'https://www.example.com/network/links.conf'; /* HTTP example */
include 'https://user:[email protected]/network/opers.conf'; /* HTTPS example WITH username/password (HTTP Basic Auth) */

If you use remote includes then we recommend to use https for security. Do not use http, as http allows 3rd parties to (theoretically) intercept/see your configuration file with all its secrets and sensitive information.

Loadmodule directive

With loadmodule you tell UnrealIRCd to load a particular module. See Modules for more information.

Normally you put include "modules.default.conf"; in your unrealircd.conf and only use loadmodule directly for loading 3rd party modules (if any).

Syntax

loadmodule <file-name-without-suffix>;

UnrealIRCd automatically adds the correct suffix (.DLL or .so) and will also automatically deal with modules/ vs src/modules/ directories.

Example

/* Just load all of UnrealIRCd's functionality (all 150+ modules) */
include "modules.default.conf";
/* If you want to load modules\m_something.dll */
loadmodule "m_something";
/* If you want to load modules/whatever.so */
loadmodule "whatever";

Note that for both examples UnrealIRCd will take care of any prefixing of the modules directory (modules/) and suffixing (.so or .dll).

/* If you want to load modules/third/something.so */
loadmodule "third/something";

Disabling modules

To disable certain functionality that is automatically loaded by modules.default.conf you could manually edit that file and comment the modules out (or delete the lines). However, these changes are overwritten on each upgrade!

A better option is to use the Blacklist-module directive which allows you to disable specific modules (any loadmodule lines for the module are ignored).

Blacklist-module directive

NOTE: Do not confuse this with the Blacklist block, which allows you to ban users based on DNSBL (DNS Blacklists)

With blacklist-module you can tell UnrealIRCd to never load a particular module. Any loadmodule lines for the module are ignored.

This can be used by advanced users to selectively disable modules that would otherwise be automatically loaded through conf/modules.default.conf. See under Example below for more information.

Syntax

blacklist-module <file-name-without-suffix>;

UnrealIRCd automatically adds the correct suffix (.DLL or .so) and will also automatically deal with modules/ vs src/modules/ directories.

In UnrealIRCd 6.1.0 and higher you can use wildcards, eg:

blacklist-module rpc/*;

Example

/* Just load all of UnrealIRCd's functionality (all 150+ modules) */
include "modules.default.conf";

/* We don't want these channel modes! See https://www.unrealircd.org/docs/Channel_Modes for names */
blacklist-module chanmodes/halfop;

/* Disable /ADMIN (admin) and usermode +B (usermodes/bot) too */
blacklist-module "admin";
blacklist-module "usermodes/bot";

Note that disabling certain basic modules can have undesired effects. Carefully read the comments in conf/modules.default.conf! For example, it would not be wise to disable the quit module.

See also

Log block

The log block is used to log server messages to log files but also to decide which messages get sent to which snomasks (server notices). It is normal to have several log blocks.

If you have no log block that logs to disk then UnrealIRCd will by default log everything to ircd.log. Logging to disk is available in standard text format (easy to read) or in json format (very detailed).

Syntax

All log blocks have at least one item in source in destination, like this:

log {
        source {
                // Sources go here (can be multiple items)
        };
        destination {
                // Destination goes here (usually only one, but can be multiple items)
        };
};

To create your own log block you:

  • First read Step 1 to select the source
  • Then read Step 2 to select a destination (there are also examples mentioned there)

Step 1: select sources (events)

log {
        source {
                <source1>;
                <source2>;
                ...
        };
}

Here you select the log sources you want to log. This can be:

  • A subsystem, like: oper
  • A log level severity, like: info
  • An event id, like: LINK_CONNECTING

Or a combination of the above, eg link.LINK_CONNECTING. You can also use negative matchers by use of an exclamation mark (!), eg: !link.LINK_CONNECTING.

See Log sources for a full list of subsystems and event ids.

Finally, there are also two special log sources:

  • all: this includes everything
  • nomatch: this includes anything that is not matched elsewhere. It should only be used for snomask s, as is done in conf/snomasks.default.conf. End-users should not change/use it.

Step 2: specify where to log to

Once you have selected one or more sources, you now specify where to log to: a file, syslog, snomask, channel or remote. Choose 1 of the options below.

Logging to a file

log {
        source {
                !debug;
                all;
        }
        destination {
                file "ircd.log" {
                        maxsize 100M; /* optional */
                        type text; /* either 'text' or 'json' */
                };
        }
}

The log::destination::file specifies where to log to. Examples:

  • ircd.log: a literal filename
  • ircd.%Y-%m-%d.log: a filename with strftime formatting. This example will give you a new log file for every day such as: ircd.2020-01-31.log.
  • /var/log/unrealircd/ircd.log: a full path (NOTE: be sure UnrealIRCd can write to the directory)

It has several options:

  • log::destination::file::maxsize: a maximum size of the log file. When the log file reaches this limit then log file will be renamed to name-of-log-file.old (overwriting any previous such .old file). You can use K/M/G to specify kilobytes/megabytes/gigabytes.
  • log::destination::file::type: the logging output type. Use text for human readable text, or json for more detailed machine readable output, see JSON logging.

Example: log all messages to disk

This simply logs all messages to disk in a human readable way:

log {
        source {
                !debug;
                all;
        }
        destination {
                file "ircd.log" { maxsize 100M; }
        }
}

Example 2: log all messages to disk in JSON format

This uses the JSON logging format. This is easier to parse by machines (external programs) and the logs include a lot more detail:

log {
        source {
                all;
                !debug;
        }
        destination {
                file "ircd.json.log" { maxsize 100M; type json; }
        }
}

Logging to syslog

If you want to log to *NIX syslog then you can do so like this:

log {
        source {
                all;
                !debug;
        }
        destination { syslog; }
}

Logging to a snomask

destination { snomask X; }

This specifies to which snomask the messages should go. The specified snomask should be a single letter. See below for an example.

Example: create your own custom snomask

Normally server notices regarding server linking end up in the "catch all" snomask s which generally all IRCOps have set, so all IRCOps will see them.

Maybe you don't like that and want to create a new snomask L for all the linking messages:

/* Custom snomask L for linking messages */
log {
        source {
                link;
        }
        destination {
                snomask L;
        }
}

After you add this, IRCOps will no longer see server messages about linking anymore by default. Only IRCOps who set themselves MODE yournick +s +L will see the linking messages. And naturally you can add L to oper::snomask for those IRCOps who still want to see these messages.

You can create as many snomasks as you like, as long as there are letters available. The standard default list of snomasks can be found here.

Logging to a channel

This feature is only available in UnrealIRCd 6.0.2 and later

This sends all the server notices to a channel:

log {
        source {
                !debug;
                all;
        }
        destination {
                channel "#opers" {
                        /* The following fields are optional. This shows the defaults: */
                        color yes; /* Log with colors? 'yes' or 'no'. Default is yes, unless overriden by set::server-notice-colors */
                        show-event yes; /* Show the event, eg connect.LOCAL_CLIENT_CONNECT. Default is yes, unless overriden by set::server-notice-show-event */
                        json-message-tag yes; /* Include JSON data in message tags */
                        oper-only yes; /* Only send messages to IRCOps in the channel */
                }
        }
}

Important notes on channel messages:

  • Messages are only delivered to locally connected users. It is recommended you use the same log blocks with the same channels and options on all your servers, if you want to see the messages everywhere no matter where you are connected to.
  • Because these are not "real" private messages in a channel, they will not show up in channel history (+H).
  • Via the json-message-tag option you can enable (the default) or disable JSON logging. See Enabling JSON logging on IRC on how JSON messages are delivered over IRC using message tags.
  • By default messages are only shown to IRCOps for security reasons. You can turn this off by setting oper-only no; but this is NOT recommended because then accidentally regular users may see a lot of sensitive information, not only in the text but also via the json-message-tag. So be very careful if you turn this off.

Logging to a remote IRC server

This means the log message should be forwarded to all other servers. This is used in conf/snomasks.default.conf so things like link errors and oper-ups can be seen network-wide. End-users probably don't need to change/use this. Important: if you use this incorrectly, you may see duplicate server notices.

TLD block

By default everyone gets to see the same MOTD (ircd.motd file), rules (ircd.rules file), opermotd, etc... With the tld block you can show different files to a user depending on their hostname or IP. This is for example useful if you want different motds for different languages.

The TLD block can also be used if you want to fetch an URL and use that as the default MOTD/RULES. See the last example at the bottom of this page.

Syntax

tld {
	mask <hostmask>;
	motd <motd-file>;
	rules <rules-file>;
	shortmotd <shortmotd-file>;
	opermotd <opermotd-file>;
	botmotd <botmotd-file>;
	channel <channel-name>;
	options {
		tls;
	};
};

The tld::mask is a mask item telling who should be affected by this TLD block.

The tld::motd, tld::shortmotd, tld::opermotd, tld::botmotd, and tld::rules items specify the motd, shortmotd, opermotd, botmotd, and rules file, respectively, to be displayed.

You can also specify tld::channel which makes clients auto join this channel (this will override the default channel(s) in set::auto-join). You can specify multiple channels, eg channel #one,#two,#three;

The tld::options block allows you to define additional requirements (rarely used): tld::options::tls only displays the file for SSL/TLS users, and tld::options::remote which only displays the file for remote users, exists.

TLD entries are matched upside down.

Examples

tld {
	mask *.es;
	motd "ircd.es.motd";
	rules "ircd.es.rules";
}

Or with UnrealIRCd 6.0.4+:

/* Spanish MOTD for Spanish speaking countries */
tld {
	mask { country { ES; AR; BO; CL; CO; CR; DO; EC; SV; GT; HN; MX; NI; PA; PY; PE; PR; UY; VE; } }
	motd "ircd.es.motd";
	rules "ircd.es.rules";
}

You can also use URLs:

tld {
	mask { country FR; }
	motd "https://example.org/files/ircd.fr.motd";
	rules "https://example.org/files/ircd.fr.rules";
}

Or just if you want to serve everyone the MOTD/RULES that are fetched remotely (mask *):

tld {
	mask *;
	motd "https://example.org/files/ircd.motd";
	rules "https://example.org/files/ircd.rules";
}

Ban nick block

The ban nick block allows you to disable use of a nickname on the server.

Syntax

ban nick {

	mask <nickname>;
	reason <reason-for-ban>;
};

The ban::mask allows wildcard masks to match multiple nicks, and ban::reason allows you to specify the reason for which this ban is placed. Most commonly these blocks are used to ban usage of the nicknames commonly used for network services.

Example

ban nick {
	mask "*C*h*a*n*S*e*r*v*";
	reason "Reserved for Services";
};

Ban user block

This block allows you to ban a user@host mask from connecting to the server. This is the same as adding a /KLINE on IRC, though it can also do a bit more complex things.

Syntax

ban user {
	mask <hostmask>;
	reason <reason-for-ban>;
};

The mask is like *.example.net or an IP mask. In the future this will be a Mask item. The reason is the reason for a ban being placed.

IMPORTANT: A ban user { } block (and a KLINE) is only a local server ban, therefore the user may still connect to other servers on the network. If you want server-wide bans, use the GLINE command (or Remote includes if you insist on configuration files).

Examples

Simple ban

ban user {
	mask *tirc@*.saturn.bbn.com;
	reason "Idiot";
}

Ban all except

There is the Except ban block to exempt users from all bans, but you can't really use it for broad exemptions like countries, since then you would no longer be able to ban users from such a country.

A future ban user { } block could use mask::exclude-* item, to "ban all, except..", but this is not implemented yet.

A better idea is to use require authentication { } instead, which still allows registered users in (users using SASL). Also note that banning countries in general is usually not really an effective way to combat drones/troublemakers, especially if you end up allowing big countries.

Ban IP block

This block bans an IP from accessing the server. This is the same as adding a /ZLINE on IRC.

Syntax

ban ip {
	mask <ipmask>;
	reason <reason-for-ban>;
};

The mask parameter is an IP which may contain wildcard characters, and reason is the reason why this ban is being placed.

Important points

All ban ip { } blocks and ZLINEs are processed very early. When the TCP/IP connection is accepted it is immediately closed with the ban reason sent as an error to the user. All this is done before DNS lookups, ident lookups, and before any TLS handshake.

Therefore:

  • You can only use IP addresses to place bans on
  • Clients using SSL/TLS almost always won't display the actual error message
  • Servers trying to link in to this server are also affected by ZLINEs

In many cases it is better to use the ban user { } block or KLINE instead. The reason ban ip { } and ZLINE exist is because it can be helpful if you are under very heavy drone/flood attacks where the server has to reject tens of thousands of connections per second.

Example

ban ip {
	mask 192.168.1.*;
	reason "Get a real ip u lamer!";
};

Ban server block

This block disables a server's ability to connect to the network. If the server links directly to your server, the link is denied. If the server links to a remote server, the local server will disconnect from the network.

Syntax

ban server {
	mask <server-name>;
	reason <reason-for-ban>;
};

The ban::mask field specifies a wildcard mask to match against the server attempting to connect's name, and ban::reason specifies the reason for which this ban has been placed.

Example

ban server {
	mask broken.server.my.network.com;
	reason "Its broken!";
};

Ban realname block

The ban realname block allows you to ban a client based on the GECOS (realname) field. This is useful to stop clone floods because often clone bots use the same realname.

Syntax

ban realname {
	mask <realname-mask>;
	reason <reason-for-ban>;
};

The ban::mask specifies the realname which should be banned. The mask may contain wildcards. The ban::reason specifies the reason why this ban is being placed.

Example

ban realname {
	mask "Bob*";
	reason "Bob sucks!";
};

Ban version block

The ban version block allows you to ban a client based on the IRC client software they use. This makes use of the clients CTCP version reply. Therefore if a client does not send out a CTCP version, the ban will not work. This feature is intended to allow you to block malicious scripts.

Syntax

ban version {
	mask <version-mask>;
	reason <reason-for-ban>;
	action [kill|tempshun|shun|kline|zline|gline|gzline];
};

The ban::mask specifies the version which should be banned. The mask may contain wildcards. The ban::reason specifies the reason why this ban is being placed. You can also specify ban::action, kill is the default, tempshun will shun the specific user connection only and would work very effective against zombies/bots at dynamic IPs because it won't affect innocent users. shun/kline/zline/gline/gzline will place a ban of that type on the ip (*@IPADDR), the duration of these bans can be configured with set::ban-version-tkl-time and defaults to 1 day.

Example

ban version {
	mask "*SomeLameScript*";
	reason "SomeLameScript contains backdoors";
};
ban version {
	mask "*w00tZombie*";
	reason "I hate those hundreds of zombies";
	action zline;
};

Except ban block

The except ban block allows you to exempt users from things like GLINEs, blacklists, spamfilter restrictions, etc. This is useful when you want an ISP banned, but still want specific users to be able to connect. IRCOps also often exempt their own IP to make sure they are never accidentally banned.

You can also use the /ELINE command on IRC to add/remove exemptions dynamically (which are stored in a permanent database, tkldb). Just run the ELINE command on IRC to see the syntax.

Syntax

except ban {
	mask ...;
	type { .... }; /* this is optional */
};

mask

The mask specifies the mask to be exempt from banning. It is recommended to use IP addresses in the mask if possible (eg: *@192.168.*) rather than hostnames (eg: *@*.someisp.xx).
In the mask you can use a hostname, or even Extended server bans, but then the except ban { } will be ineffective against exempting from ZLINE and GZLINE for technical reasons (when bans and except ban { } blocks are processed no DNS lookup and no ident lookup has been done yet).

In UnrealIRCd 6.0.4 and later you can use all the functionality of a Mask item here, so you can also exempt based on mask { account XYZ; }, certfp, security-group, etc. See also the examples further down.

type

Valid types are:

Type Meaning
kline Exempt from K-Line (KLINE)
gline Exempt from G-Line (GLINE)
zline Exempt from Z-Line (ZLINE)
gzline Exempt from Global Z-Line (GZLINE)
shun Exempt from Shun (SHUN)
spamfilter Can bypass spamfilters
qline Can bypass banned nick restrictions (QLINE)
blacklist Don't do any blacklist checking
connect-flood Exempt from set::anti-flood::connect-flood and set::max-unknown-connections-per-ip
maxperip Can bypass allow::maxperip restrictions
antirandom Bypass antirandom module
antimixedutf8 Bypass antimixedutf8 module
ban-version Bypass ban version { } blocks
handshake-data-flood Do not place ZLINE when client is flooding before registration phase
all All of the above, except qline

If you do not specify any type, then the exception defaults to: kline + gline + zline + gzline + shun.

A note on maxperip: If you give someone a maxperip exception and you use Services then services may have a session limit too. If you see kills/quits with the reason Session limit exceeded then you know it is not UnrealIRCd doing this but anope or other services. We recommend disabling the os_session module in your services since it is unneeded with UnrealIRCd.

Examples: 6.0.4 or later

The following examples are for UnrealIRCd 6.0.4 or later. If you use an older version skip to 6.0.3 or before.

Exempt by IP

To exempt an IP you should use except ban::mask::ip as it is the safest and fastest method:

// Single IP:
except ban {
	mask { ip 192.168.*; }
}

// Multiple IP's:
except ban {
	mask { ip { 192.168.*; 10.*; 127.*; } }
}

Exempt by security-group

Say, you have created a security group called irccloud with a list of IP's, then you can use:

except ban {
	mask { security-group irccloud; }
        type { blacklist; connect-flood; handshake-data-flood; maxperip; }
}

Exempt by certificate fingerprint

This would allow the user with the certficate fingerprint 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef, to bypass KLINE and GLINE server bans and spamfilter restrictions.

except ban {
	mask { certfp 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef; }
	type {
		kline;
		gline;
		spamfilter;
	}
}

Exempt by services account name

This would allow the user with a services account of ExampleAccount1 and ExampleAccount2 to bypass spamfilter restrictions:

except ban {
	mask { account { ExampleAccount1; ExampleAccount2; } }
	type {
		spamfilter;
	}
}

Examples: 6.0.3 or before

The following examples are for UnrealIRCd 6.0.3 or before. If you use a newer version then skip to 6.0.4 or later.

Exempt by IP

except ban {
	mask *@192.168.*;
	mask *@192.0.2.5;
}

except ban {
	mask { *@192.168.*; *@10.*; *@127.*; }
}

Exempt by certificate fingerprint

This would allow the user with the certficate fingerprint 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef, to bypass KLINE and GLINE server bans and spamfilter restrictions.

except ban {
	mask ~certfp:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef;
	type {
		kline;
		gline;
		spamfilter;
	}
}

Exempt by services account name

This would allow the user with a services account of ExampleAccount to bypass spamfilter restrictions:

except ban {
	mask ~account:ExampleAccount;
	type {
		spamfilter;
	}
}

Except throttle block

The except throttle block allows you to specify an IP mask that will not be affected by set::anti-flood::connect-flood (the throttling system).

Note that connection throttling is an important security measure. It provides primary and secondary protection against DoS, flood and brute force attacks, both for handshake and fully registered connections. If you exempt connections from this then you severely degrade these protections. You should only do so for IP's you trust.

Syntax

except throttle {
	mask <ipmask>;
};

The except::mask specifies an IP mask that will not be banned because of throttling.

Example

except throttle {
	mask 192.168.1.*;
}

except throttle {
	mask { 192.168.*; 10.*; 127.*; }
}

Require authentication block

The require authentication block allows you to specify IP/hosts of users that need to authenticate to a valid services account during connecting. This could, for example, be used to ban an ISP that is known for troublemakers, while still allowing legit users in from that IP if they have a valid account. Or, it can be used to simply require authentication for all users.

Authentication by the user is done either by using SASL (the recommended method) or via authprompt that will ask non-SASL users to authenticate interactively by typing /AUTH nickname:password.

Syntax

require authentication {
	mask <hostmask>;
	reason <reason-for-ban>;
};

The mask is a Mask item and the reason is the reason for the requirement. The reason is shown when the user is trying to connect without authentication.

Note that require authentication blocks configures a local requirement. The user may still connect to other servers on the network.

Example

Simple example

require authentication {
	mask *@*.tld;
	reason "Too many abusers from this country, please authenticate";
};

Require all except

There is the Except ban block to exempt users from all bans, but you can't really use it for broad exemptions like countries, since then you would no longer be able to ban users from such a country.

You can, however, use a require authentication { } block with a mask::exclude-* item, to "require authentication to all, except..":

require authentication {
	mask {
		mask *;
		exclude-country { NL; DE; FR; }
	}
	reason "Unregistered users are not allowed from your country";
}

NOTE:

  • Requiring authentication for (or banning on) countries is not particularly nice. If you allow multiple countries then the countermeasure is likely not effective at all.

Similar functionality

The same can be achieved online (on IRC) by adding a "soft kline":

/KLINE %*@*.tld Too many abusers from this country, please authenticate

The % prefix (percent symbol) will make it only ban unauthenticated users.

See also the Authentication article for all the different ways and possibilities to force authentication.

Deny DCC block

The deny dcc block allows you to specify a filename which will not be allowed to be sent via DCC over the server. This can be useful in helping stop distribution of trojans and viruses.

Syntax

deny dcc {
	filename <file-to-block>;
	reason <reason-for-ban>;
	soft [yes|no];
};

The deny::filename parameter specifies a wildcard mask of the filename to reject sends of, and deny::reason specifies the reason why this file is blocked.

There's also a deny::soft option, if set to 'yes' the dcc is blocked unless the user explicitly allows it via /DCCALLOW +nickname-trying-to-send. See dccallow.conf for a good example configuration for dccallow.

Example

deny dcc {
	filename virus.exe;
	reason "This is a GD Virus";
};
deny dcc {
	filename "*.exe";
	reason "Executable content";
	soft yes;
};

Allow DCC block

The allow dcc blocks allows you to specify exceptions over the Deny DCC block.

Syntax

allow dcc {
	filename "<filename-mask>";
	soft [yes|no];
};

The filename specifies the name of the file, wildcards are permitted. If allow dcc::soft is set to 'yes' it applies to 'soft dcc bans' list, if set to 'no' it applies to the normal ('hard') dcc bans.

Example

allow dcc {
	filename "*.jpg"; /* Images are usually safe */
	soft yes;
};

Deny version block

This block allows you to deny a server from linking in, based on the version of Unreal it is running and what compile time options it has.

Not to be confused with the Ban version block (which bans clients based on their CTCP VERSION reply!)

Syntax

deny version {
	mask <server-name>;
	version <version-number>;
	flags <compile-flags>;
};

The format for this block is somewhat complex but isn't too hard to figure out. The deny::mask directive specifies a wildcard mask of the server name this applies to. The deny::version specifies the protocol number of the version this refers to.

For example, 3.0 is 2301, 3.1.1/3.1.2 is 2302, 3.2 is 2303. The first character of this parameter can be one of the following >, <, =, !. This character tells the IRCd how to interpret the version. If the first character is a > then all version greater than the specified version are denied, if it is a < all versions lower are denied, if it is an = only that version is denied, and if it is a ! then all versions except the specified are denied. The deny::flags directive allows you to specify what compile time flags the server may or may not have. The flags are arranged one after the other with no separation between, if a character is prefixed by a ! then it means the server may not have this flag compiled into it, if it does not have a ! prefix, then it means the server must have this flag compiled.

Deny link block

This block allows you to use specific rules to deny a server from linking. It's slightly complex and typically only used on networks with 3 or more servers.

Syntax

deny link {
	mask <server-name>;
	rule <crule-expression>;
	type <type-of-denial>;
}

The mask specifies a wildcard mask of the server name to apply this rule to.

The rule directive can be complex. A crule expression allows you to control the link in great detail, and it is set up like a programming expression. If the entire expression of the rule evaluates to true, then the link is denied.

Four operators are supported:

  • connected(<servermask>): returns true if a server matching servermask is connected
  • directcon(<servermask>): returns true if the server matching servermask is directly connected to this server
  • via(<viamask>,<servermask>): returns true if a server matching servermask is connected by a server matching viamask
  • directop(): returns true if the operator issuing a /connect is directly connected to this server

These operators can be combined using && (and) and || (or). Items may also be enclosed in parenthesis () to allow grouping. In addition, if any of the four operators are preceded with a ! then it means NOT.

The type allows two different values::

  • auto: only applies to autoconnects, /connect will still work
  • all: applies to all connection attempts

Example

NOTE: This example is for UnrealIRCd 5.2.1 and later

deny link {
        mask {
                *;
                !foobar.hub;
        }
        rule !connected(foobar.hub);
        type all;
}

Deny channel block

The deny channel block allows you to disallow users from joining specific channels.

Normally, for managing channel access one would use bans (channel mode +b) and exempts (+e), along with Services and/or channel mode +P to remember the channel settings. Still, sometimes you want to block of a whole range of channels with wildcards, then you can use this deny channel { } feature.

Syntax

deny channel {
	channel "<channel-mask>";
	reason <reason-for-ban>;
	redirect "<channel-name>"; // optional
        mask "<ip/hostmask>"; // optional
	warn [on|off]; // optional
};

There are two required items:

  • channel is a wildcard mask matching channels the users may not join
  • reason specifies the reason why the channel may not be joined.

Optionally, you may specify:

  • redirect: when the user tries to join, redirect them to the redirect channel.
  • mask makes this deny channel block only apply to specific users. It is a Mask item with lots of options.
  • warn: if set to on this generates a notice to ircops when a user tries to join (the default is off)

Example

deny channel {
	channel "#unrealsucks";
	reason "No it doesn't!";
};

deny channel {
	channel "#*teen*sex*";
	reason "You == dead";
	warn on;
};

deny channel {
	channel "#operhelp";
	reason "Our network help channel is #help, not #operhelp";
	redirect "#help";
};

Exemptions

You can use the Allow channel block to make exceptions to the allow channel block.

Allow channel block

The allow channel block allows you to specify specific channels that users may join. It is used to exempt channels that were banned through the Deny channel block.

Syntax

allow channel {
	channel "<channel-mask>";
        mask "ip/hostmask"; // optional!
};

channel specifies the wildcard mask of the channels which may be joined.

The optional mask makes it possibly to apply this block only to certain users. It is a Mask item with lots of options.

Example

/* Deny joining all channels with 'help' in it */
deny channel {
        channel "#*help*";
        reason "We only have one official help channel. Please join #help instead.";
};

/* Allow #help */
allow channel {
	channel "#help";
};

/* Allow #lanhelp only to 192.168.* users */
allow channel {
	channel "#lanhelp";
        mask 192.168.*;
};

Vhost block

The vhost block allows you to specify a login/password that can be used with the /VHOST command on IRC to obtain a fake hostname.

NOTE: Most people use Services instead, which often provide a HostServ bot or capability. This basically allows you to centrally manage vhosts.

Syntax

vhost {
	vhost <vhost>;
	mask {
		<hostmask>;
		<hostmask>;
		...
	};
	login <login-name>;
	password <password>;
	swhois "<swhois info>";
};

The vhost::vhost parameter can be either a user@host or just a host that the user will receive upon successful /vhost. The vhost::mask block contains a user@host that the user must match to be eligible for the vhost, see Mask item for more information. The vhost::login in the login name the user must enter and vhost::password is the password that must be entered. The vhost::password allows you to specify a password or other authentication type. Lastly vhost::swhois allows you to add an extra line to a users whois, exactly as it does in the Oper Block oper::swhois.

Example

vhost {
	vhost my.own.personal.vhost.com;
	mask { *.isp.com; 192.168.*; 127.*; };
	login mynick;
	password mypassword;
	swhois "Im Special";
};

Badword block

The badword block allows you to manipulate the list used for user and channel mode +G to strip "bad words".

Syntax

badword <type> {
	word <text-to-match>;
	replace <replace-with>;
	action <replace|block>;
};

The badword:: specifies the type, which decides what messages this badword filter applies to. The valid types are:

  • channel: applies to channels with mode +G.
  • message: applies to private messages (not in-channel messages) sent by a user with the +G usermode.
  • all: applies to both channel and message

The badword::word can be a simple word or a regular expression we should search for. The badword::replace is what we should replace this match with. If badword::replace is left out, the word is replaced with <censored>. The badword::action defines what action should be taken if this badword is found. If you specify replace, then the badword is replaced, if you specify block, then the entire message is blocked. If you do not specify a badword::action, replace is assumed.

Example

badword channel {
	word shit;
	replace shoot;
};

ULines block

The ulines block lets you define certain servers as having extra abilities. If you use Services, such as anope or atheme, then that server name MUST be in your ulines { } in the config file of every UnrealIRCd server on your network.

Ulines should only be used for services and should NEVER match a regular UnrealIRCd server, otherwise you'll create security issues.

Syntax

ulines {
	<server-name>;
	<server-name>;
	...
};

Each entry is the name of the server which will receive the extra abilities.

Example

ulines {
	services.example.net;
};

Link block

If you are linking servers we recommend you to follow our Tutorial: Linking servers instead. The link block is, however, shown below for reference.

Syntax

link <server-name> {
    /* Below, often you will have both an incoming { } and outgoing { } sub-block.
     * However you may also choose to have only 1 of them if you always link in the same direction.
     */
    incoming {
        mask 1.2.3.*;
    };
    outgoing {
        bind-ip <ip-to-bind-to>; /* optional now */
        hostname irc1.some.net; /* may also be an IP */
        file /tmp/some.socket; /* if connecting to a UNIX domain socket (rarely used) */
        port 6697;
        options { tls; autoconnect; }; /* optional, but recommended */
        tls-options { protocols "TLSv1.2"; }; /* optional, only set this if you know what you are doing. */
    };
    password "some-password"; /* either a plaintext password that's the same for both sides or an SSL fingerprint (or certificate) */
    verify-certificate [yes|no]; /* optional, default is 'no' but is less secure */
    hub <hub-mask>; /* optional */
    leaf <leaf-mask>; /* optional */
    leaf-depth <depth>; /* optional */
    class <class-name>;
    ciphers <ssl-ciphers>; /* optional */
    options {
        quarantine; /* is a generic option. optional. */
    };
};

Note that you need link::incoming and/or link::outgoing. So at least one of them is required.

server-name

The server-name in your link <server-name> { block specifies the name of the server, that is the name you have specified in me::name on the other side of the link.

Incoming

incoming::mask

Only servers matching this (IP) mask may use this link block.

Outgoing

outgoing::hostname

Hostname of the server to connect. This could be the same as the server-name, but it may also be an IP or a different DNS name.

outgoing::port

Port of the other server to connect to

outgoing::file

Unix domain socket of the server to connect to. This is rarely used, so if you don't know what this is then don't use it.

outgoing::options (optional)

The following two options are available:

  • tls: connect to an SSL/TLS-only-port. If you use this, then be sure that the outgoing::port you specify is in fact a SSL/TLS-only port. Meaning: the server on the other side of the link must have listen::options::tls turned on for that port.
  • autoconnect: automatically connect to the server (or try to every XX seconds, anyway)
  • insecure: by default UnrealIRCd will attempt to 'upgrade' a connection to use SSL/TLS in order to get encrypted server links. This disables that functionality. Not recommended!
outgoing::tls-options (optional)

Valid options are all the SSL settings that also exist in set::tls. Normally you don't change such settings on a per link block basis, but it is possible.

For example you can set the permitted SSL protocols and ciphers:

link xyz {
        ...
        outgoing {
                tls-options {
                        protocols "TLSv1.2";
                        ciphers "AES256";
                };
        };
};
outgoing::bind-ip (optional)

Bind to this IP before connecting to the other server. The IP to bind to must be available on the machine (must not be an IP of another machine).

General link block settings

password

Password or other method to use to verify the authenticity of the link. This must be either: 1) a plaintext password that must be the same on both sides of the link, OR 2) an SSL/TLS fingerprint, which is our recommended and safest way to link, see our Tutorial.

verify-certificate

When set to 'yes' this will enable SSL/TLS certificate checking to make sure that:

  • The SSL/TLS certificate of the server you are linking with is valid and issued by a trusted Certificate Authority (eg: Let's Encrypt or some bought certificate)
  • The name in the link block matches the name(s) in the certificate (eg: if you're linking with irc1.test.net and it presents a certificate for irc2.someotherdomain.org it will fail)

Enable this if you (can) meet these criteria. It will protect you from active traffic interception attacks.

hub

The value is a mask of what servers this hub may connect (ex: *.my.net).

leaf

The value is a mask of what servers this hub may not connect.

leaf-depth

The value specifies the depth (number of hops) this server may have beneath it. For example, 1 means the server can't have any links under it (a leaf), 2 means it can link servers but those servers can't link anything under them (that is, this hub can only link leaves). A value of 0 means no limit, and is the default.

class

The class this server is put into (see Class block), often a separate server class is used for this.

options

There's only one generic option:

  • quarantine: This link may have no IRC Operators on it. If someone attempts te become OPER on the link they are de-oper'ed. Note that this does not provide true security: a person controlling a server can still modify the source and load any modules they want, thus still 'be able to do anything' if they have bad intentions.

For other link options see the link::outgoing block.

Example

See Tutorial: Linking servers

Alias block

The alias { } block specifies command aliases. With the help of these, commands like /NS HELP are translated to /MSG NickServ HELP.

Note that for aliases for services commands to work, your set::services-server must be set correctly.

Recommended aliases

It is recommended to have a line in your unrealircd.conf to include the aliases for your Services package. For example for anope, you use:

include "aliases/anope.conf";

This will add the /NS, /CS, /NICKSERV, /CHANSERV, etc. aliases so you don't have to write your own.

Note that the example.conf already contains such an include line for aliases/anope.conf, so you might already have it.

Syntax

Standard alias

alias <name> {
	target <nick-to-forward-to>;
	type <type-of-alias>;
	spamfilter <yes|no>;
};

(Note that <name> is referred to using "alias::")

(Note: see a description of the standard alias files UnrealIRCd has)

The alias block [standard alias] allows you to forward a command to a user, for example /chanserv sends a message to the user chanserv.

alias:: specifies the name of the command that will be the alias (eg: chanserv)

alias::target is the nickname or channel it will forward to. If alias:: would be the same as the target, alias::target may be left out.

alias::type specifies the type of alias, valid types are

  • services (the user is on the services server),
  • stats (the user is on the stats server),
  • normal (the user is a normal user on any server),
  • channel (the target is a channel name), and
  • command (this is not a "standard alias", see below).

alias::spamfilter (optional) causes the spamfilters will be checked if set to "yes" (default is 'no').

Command alias

alias <name> {
	/* For aliases to be sent to users/channels */
	format <regex-expression> {
		target <nick-to-forward-to>;
		type <type-of-alias>;
		parameters <parameter-string>;
	};
	/* For 'real aliases' */
	format <regex-expression> {
		command <command>;
		type real;
		parameters <parameter-string>;
	};
	/* Etc... You can have as many format blocks as you wish.. */
	format <regex-expression> {
		...
	};
	type command;
	spamfilter <yes|no>;
};

When an alias block has alias::type set to command, as shown above, it becomes a command alias. When the alias block is used in this format, it is much more flexible. For example, you could create an /identify alias.

alias:: is the name of the alias command as in standard alias block form (above).

alias::format specifies a regular expression which is matched against the text sent to the alias command. The sub-entries of the first matching alias::format will be used. Thus, you may have multiple alias::formats to make a command do different things depending on the text sent to it.

alias::format::target is the target to forward this alias to. This value is not used if alias::format::type is "real".

alias::format::type specifies the type of the alias that the message should be forwarded to. In addition to the types mentioned previously in "Syntax [standard alias]", "real" may be specified here for a "real alias" (a "real alias" is an alias that may be rewritten to something other than a PRIVMSG).

alias::format::parameters (for "real aliases") is what will be sent as the parameters to this alias. To specify one of the parameters given to the command alias specify % followed by a number. For example, %1 is the first parameter. To specify all parameters from a given parameter to the end, use % followed by the number and a -. For example, %2- returns all parameters from the second through the last. Additionally, you may specify %n which will be replaced by the nickname of the user who executed the command.

For examples of using the alias block in the command format, see aliases/*.conf.

Help block

The help block allows you to create entries for use with the /HELPOP command.

Syntax

help <name> {
	<text-line>;
	<text-line>;
	...
};

The help:: is the value that must be passed to /helpop as a parameter, if the help:: is left out, then it will be used when no parameter is passed to /helpop. The entries for the help block are the text that will be displayed to the user when requesting the /helpop.

Default help

Pretty much everyone would want to just include the help.conf included in UnrealIRCd:

include "help.conf";

Example

help something {
        "This is some really useful text.";
        "I don't know what to say...";
};

Official-channels block

Official channels are shown in /LIST even if no users are in the channel.

IMPORTANT: This feature is DEPRECATED. Instead, you should set channel mode +P (Permanent channel). This allows you to dynamically add and remove channels including all settings such as: topic, modes (regular modes and bans/exempts/invex), etc. All this information is stored in a database by the channeldb module (loaded by default).

Syntax

official-channels {
	"#channel" { topic "The default topic"; };
};

The topic is optional and is only shown in /LIST if the channel has 0 users.

Example

official-channels {
	"#Help" { topic "The official help channel, if nobody is present type /helpop helpme"; };
	"#Home";
	"#Main" { topic "The main channel"; };
};

Spamfilter block

The spamfilter block allows you to add local spam filters (not network-wide). See the Spamfilter article for more information about spamfilters.

Syntax

spamfilter {
        match-type [simple|regex];
	match '<text>';
	rule "<rule>"; /* optional */
	target { <target(s)> };
	action <action>;
	reason <reason>;
	ban-time <time>;
};

The match-type is one of:

match is the text to match on, which depends on the match-type. Note the use of single quotes in match 'text'; instead of match "text";. Using single quotes will prevent a regex from accidentally be interpreted as an URL by Remote includes.

You specify the targets via target:

Character Config item Description
c channel Channel message
p private Private message (from user->user)
n private-notice Private notice
N channel-notice Channel notice
P part Part reason
q quit Quit reason
d dcc DCC filename
a away Away message
t topic Setting a topic
T message-tag Ban Message tags sent by the client. This will be matched against name=value or just name if there is no value
u user User ban, will be matched against nick!user@host:realname
R raw Match a raw command / IRC protocol line (except message tags), eg LIST*

reason is used as the reason for the *LINE/kill/block message

ban-time is the duration of the *LINE, it is irrelevant for types like kill, block, etc.

The action specifies the action to be taken, such as kline. There are both "regular" actions and "soft" actions. The soft actions (eg: soft-kill) are not applied to users who are authenticated with Services (preferably with SASL):

Regular name Soft name Description
kill soft-kill Kills the user. The user may still reconnect.
tempshun soft-tempshun Shuns the current session of the user, this makes it so the user cannot send any commands anymore. When the user reconnects, the shun is gone.
shun soft-shun Puts a shun on the IP, this makes it so the user cannot send any commands anymore.
kline soft-kline Puts a kline on the IP. The user can no longer connect to this server.
gline soft-gline Puts a gline on the IP. The user can no longer connect to any server in this IRC network.
zline Puts a zline on the IP. The user can no longer connect to this server.
Note that a ZLINE causes very quick killing which means that SSL/TLS users will not see a proper error message and TKL exceptions won't work. Only use zlines if you are sure the user/IP is hostile, otherwise use a kline instead.
gzline Puts a gzline (global zline) on the IP. The user can no longer connect to any server in this IRC network.
Note that a (G)ZLINE causes very quick killing which means that SSL/TLS users will not see a proper error message and TKL exceptions won't work. Only use gzlines if you are sure the user/IP is hostile, otherwise use a gline instead.
block soft-block Block the message (or action) only
dccblock soft-dccblock Mark the user so they are unable to send files through DCC
viruschan soft-viruschan Part all channels, join set::spamfilter::virus-help-channel, disables all commands except PONG, ADMIN, and msg/notices to set::spamfilter::virus-help-channel
warn soft-warn Send a notice to IRCOps (spamfilter snomask), and inform the user that the message has been intercepted. No further action is taken, the message is not blocked.
set Set a tag on the user (or change REPUTATION). This can be:
  • action { set SCORE=5; } - set SCORE to 5
  • action { set SCORE++; } - increase the value of SCORE with 1
  • action { set SCORE+=5; } - increase the value of SCORE with 5
  • action { set SCORE--; } - decrease the value of SCORE with 1
  • action { set SCORE-=5; } - decrease the value of SCORE with 5

The tag name SCORE is just an example, it can be named anything you want and will persist for the lifetime of the connection.
You can use the special tag name REPUTATION to adjust the Reputation score of the users' IP.
You can evaluate a tag value via tag(SCORE) in spamfilter::rule in the Spamfilter block.
This feature only exists in UnrealIRCd 6.1.2 and higher. If you you decrease the reputation score (REPUTATION) then all your servers need to be on 6.1.2 and higher for this to work properly.

report Report the incident via a Spamreport block. This can be report name-of-spamreport-block; or it can be report; to call all spamreport blocks.
This feature only exists in UnrealIRCd 6.1.2 and higher
stop Stop processing any other spamfilter rules. This only works in spamfilter::action.
This feature only exists in UnrealIRCd 6.1.2 and higher

For action set, see also Spamfilter rule and Setting tags below.

Spamfilter rule

In UnrealIRCd 6.1.2 and later we support spamfilter::rule. If the rule matches, then the spamfilter is executed. This allows you to do complex things like:

rule "!inchannel('#main') && (online_time()<180 || reputation()<50)";

See Crule for the syntax and all the available functions.

Setting tags

Since UnrealIRCd 6.1.2 you can set tags of users. And also, you can have multiple actions, like set + block.

You can use any tag name (we use "SCORE" below) and it will exist for the lifetime of connection, until the user gets disconnected.

This would bump the SCORE tag up by 1 (and create it with a value of 1 if it does not exist yet):

action { set SCORE++; }

You can also set+block:

action { set SCORE++; block; }

Combined with #Spamfilter rule this allows you to combine things like:

spamfilter {
        match-type simple;
        match "this is one line";
        target { private; channel; }
        action { set SCORE++; }
        reason "Hit one";
}

spamfilter {
        match-type simple;
        match "this is another line";
        target { private; channel; }
        action { set SCORE++; }
        reason "Hit two";
}

spamfilter {
        rule "tag(SCORE)>1";
        action kill;
        reason "Score is at least 2!";
}

The last spamfilter block from above is special, you can see it has no match and it has no target. Such spamfilter blocks run when a tag has changed in value for the user (like by the "Hit one" and "Hit two" blocks before that).

Reporting hits

If you are sure you are catching good spambots with your spamfitler block, then you can report spamfilter hits to central services like DroneBL. That way other IRC users benefit from you catching spam/drones (just like you are benefiting from others doing this). See the Spamreport block.

See also

Please see the Spamfilter article for more information and in particular the examples in the same article.

For even more examples have a look at spamfilter.conf in UnrealIRCd.

Blacklist block

Other languages:

<translate> The blacklist block allows you to use a DNS blacklist (DNSBL). Every user that connects to your server will be checked against the blacklists specified.

Syntax

blacklist <name> {
        dns {
                name <blacklist hostname>;
                type <record|bitmask>;
                reply { <permitted replies> };
        };
        action <action>;
        reason <reason>;
        ban-time <time>;
        recheck <yes|no>;
        except { }
};

First of all, each blacklist has a <name>, which is just a short name for the blacklist block.

Currently the only supported type of blacklists are DNS blacklists. This is configured via blacklist::dns which consists of three items: blacklist::dns::name specifies the blacklist to use (eg: rbl.efnetrbl.org). blacklist::dns::type defines if the blacklist is of type record or bitmask, your blacklist should provide this info, if in doubts then use record. Finally, blacklist::dns::reply configures which DNS replies are considered a 'match'. Consult the documentation of the blacklist you use, as they are blacklist-specific!

The remainder of the blacklist block defines what should be done upon a match: blacklist::action specifies an action, such as kline (see Actions for a full list). blacklist::ban-time defines after how much time the *LINE (if any) should be removed.

blacklist::reason specifies the kill/ban reason shown to the user. You can use the following variables in this field, which will be replaced:

  • $ip: IP address of the banned user
  • $server: name of the IRC server
  • $blacklist: name of the blacklist block (eg. xyz for blacklist xyz { })
  • $dnsname: the blacklist::dns::name
  • $dnsreply: DNS reply code

blacklist::recheck defaults to yes. It can be set to no if you don't want this blacklist rechecked due to set::blacklist::recheck-time.

You can exempt users from all blacklist checks via the except ban block (with type 'blacklist'). You can also only filter out users for this specific blacklist, via blacklist::except, which is a mask item so has lots of options.

Example

These are the two most common blacklists that users use:

blacklist efnetrbl {
        dns {
                name rbl.efnetrbl.org;
                type record;
                reply { 1; 4; 5; };
        };
        action gline;
        ban-time 24h;
        reason "Proxy/Drone/TOR detected. Check https://rbl.efnetrbl.org/?i=$ip for details.";
};

<!--T:7-->
blacklist dronebl {
        dns {
                name dnsbl.dronebl.org;
                type record;
                reply { 3; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; };
        };
        action gline;
        ban-time 24h;
        reason "Proxy/Drone detected. Check https://dronebl.org/lookup?ip=$ip for details.";
};

See also

</translate>

Secret block

The secret { } block is used to define passwords (or ways to retrieve them) for encrypted database storage.

You refer to these secrets block(s) from the ::db-secret configuration item of the modules that use it.

Modules that support encrypted database storage

The following modules support encrypted database storage and can be used to refer to secret { } blocks:

Password requirements

All passwords must conform to the following password complexity requirements:

  • must be 10 characters or longer
  • must contain at least one lowercase letter
  • must contain at least one uppercase letter
  • must contain at least one digit

Why the password needs to be known

By definition, the password (key) to encrypt and decrypt needs to be known somehow. It is impossible to encrypt/decrypt data if you don't have the correct key, as that is the whole point of encryption. This is not an UnrealIRCd limitation but true for any system that uses symmetric encryption like AES. There is no way around this.

You can put your password directly in the configuration file, but that provides only marginal security. You don't have to do this! UnrealIRCd provides multiple options for the secret blocks, including an option where you have to type the password and it is never stored in plaintext in any file. All options are explained below with their pros and cons. Just go through them and make a decision on what you find the most suitable option for your network.

Syntax & Examples

The password can be specified directly in the configuration file or fetched from elsewhere.

Each secret block has a name:

secret name-of-secret {

This name is referred to from other places in the configuration file.

You can use a single secret block and use that same secret block from multiple places (channeldb, tkldb, etc), OR you can have multiple secret blocks (one for each purpose). It's up to you to decide.

Directly in the configuration file

This is the easiest, but the least secure method:

secret channeldb {
        password "Somepassw0rd";
}

From an external file

This way you can store the password in a text file in a different place, eg on a different disk, USB stick, etc.. something that isn't stored or backed up altogether with the rest of your unrealircd data.

The file only needs to exist during booting UnrealIRCd, so you could for example connect an USB stick when booting UnrealIRCd and then pull it out once booted. You can rehash the IRCd without the file being needed.

secret channeldb {
        password-file "/home/xyz/secret.txt";
}

The file (secret.txt in this example) should then contain 1 single line with the password.

Entering on-boot in a terminal

This is the most secure method. It requires you to type the password every time UnrealIRCd is (re)started. After that, you can rehash the IRCd without having to re-enter the key.

The downside is that you can no longer start UnrealIRCd automatically via cron or automatic boot scripts. You will ALWAYS need to start UnrealIRCd manually on a terminal (eg via SSH).

secret channeldb {
        password-prompt;
}

WebIRC block

The webirc block allows you to configure host spoofing for WebIRC / CGI:IRC gateways you trust, see WebIRC Support.

Note that a more modern method would be to use websockets. With websockets, clients (browsers) connect directly to the IRC server without any WebIRC gateway in-between, in which case you do not need any webirc { } blocks.

Syntax

webirc {
        mask 1.2.3.4; /* ip or host mask */
	password <password>;
};

mask is checked against the client (the WebIRC or CGI:IRC gateway) that is trying to connect.

password is the webirc password

How to configure with method 'webirc' (recommended method)

In both your web IRC client software and UnrealIRCd you have to set the same webirc password.

Example with KiwiIRC

The example below configures KiwiIRC and UnrealIRCd. Note that this is just an example, if you use something other than KiwiIRC you edit that instead of the KiwiIRC-side.

KiwiIRC-side (old and outdated)

Edit kiwiirc's config.js as follows (note: this is NOT a complete configuration file, it just shows 3 important sections):

// WebIRC passwords enabled for this server
conf.webirc_pass = {
    "irc1.yournetwork.org":        "ThisIsMySecretWebIRCPassword"
};

// Default settings for the client. These may be changed in the browser
conf.client = {
    server: 'irc1.yournetwork.org',
    port:    6697,
    ssl:     true,
    channel: '#test',
    nick:    'kiwi_?'
};
// or use conf.restrict_server etc... to achieve the same effect (see example config.js file).

// What matters is that the server name in conf.client or conf.restrict_server
// match the server name in conf.webirc_pass (and use the right password).
// So be sure to replace BOTH the irc1.yournetwork.org instances with the same server name.

// Now something else... "send ip as username"....
// Be sure *NOT* to list your server here !!!!
// If you add it here, then the IP will show up in the ident. This is NOT what you want
// as the IP is already sent via WEBIRC. Doing so would reveal the users' IP to everyone which is bad.
conf.ip_as_username = [
    "xxxx"
];

KiwiIRC-side (new aka nextclient)

Edit kiwiirc's webircgateway config.conf as follows (note: this is NOT a complete configuration file):

// WebIRC passwords enabled for this server
[upstream.1]
webirc = "xxxx"

UnrealIRCd-side

Then, in your unrealircd.conf you add a webirc block:

webirc {
	mask 127.0.0.1;
	password "ThisIsMySecretWebIRCPassword";
};

except ban {
        mask 127.0.0.1;
        type { connect-flood; handshake-data-flood; blacklist; };
};

The Except ban block block is highly recommended. This will ensure your webirc gateway is not seen as connection flooding and the blacklist exception will make it connect faster. If you don't have an except ban block for your webirc gateway then users will not be able to connect during peak hours or after a server restart.

Set block

Other languages:

<translate> The set block is used to tweak and configure the server settings.

Sharing settings

If you (already) run multiple IRC servers then have a look at Sharing settings between servers to ease the burden when updating settings. The set block is an ideal candidate to be shared.

Syntax used in this documentation

As described in Configuration file syntax we will refer to settings like set::options::hide-ulines or set::auto-join. You should NOT write set::options::hide-ulines in the configuration file! It's just a shorthand, an abbreviation. What we actually mean is that you should write them out like this:

set {
        options {
                hide-ulines;
        };
        auto-join "#something";
};

Or you could put them in separate set blocks like this:

set {
        auto-join "#something";
};

<!--T:228-->
set {
        options {
                hide-ulines;
        };
};

Or even just:

set { options { hide-ulines; }; };
set { auto-join "#something"; };

If the above is unclear, then maybe have another read at the Configuration file syntax article.

It is perfectly fine to have multiple set { } blocks! In fact it's quite normal to have one block with network-wide settings, and another set block with server-specific settings. We generally don't recommend having more than 2 set blocks because then it is too easy to loose track of them ("what settings is where?"), but technically it is perfectly possible and permitted.

Set block for a security group

Normally you have something like:

/* This is the general set block */
set {
        maxchannelsperuser 10;
}

In UnrealIRCd 6.1.1 and later you can also have a set block with a name of a security group, like:

/* This overrides the setting for unknown-users */
set unknown-users {
        maxchannelsperuser 5;
}

In the example of above the settings in the set unknown-users { } block will "override" the set { } setting, if the user is in the security group unknown-users.

You can also define your own security groups and then give these users MORE rights:

security-group trusted-bots { account { Bot1; Bot2; Bot3; } }

set trusted-bots {
        maxchannelsperuser 50;
}

In the Security-group block you can read all about security groups, how to define your own, and the two important standard groups known-users and unknown-users.

There is a limited list of settings that you can override in a set xyz { }:

See also the Special users article on how to give trusted users/bots more rights or higher flood rates than regular users (also for things other than set { } blocks).

Available settings

set::kline-address

Syntax: set::kline-address <email-address>

The email address that K:line questions should be sent to. This value must be specified. See also set::reject-message::kline if you want a more custom disconnect message on KLINE/ZLINE.

set::gline-address

Syntax: set::gline-address <email-address>

The email address that G:line questions should be sent to. See also set::reject-message::gline if you want a more custom disconnect message on GLINE/GZLINE.

set::modes-on-connect

Syntax: set::modes-on-connect <+modes>

The modes that will be set on a user at connection.

In UnrealIRCd 6.1.1 and higher you can also override this value in a set block for a security group.

set::modes-on-oper

Syntax: set::modes-on-oper <+modes>

The modes that will be set on a user when they /oper.

set::snomask-on-oper

Syntax: set::snomask-on-oper <+modes>

The snomask (server notice mask) that will be set on a user when they /OPER. See Snomasks for the full list.

The default value is +bBcdfkqsSoO

set::modes-on-join

Syntax: set::modes-on-join <+modes>

The modes that will be set on a channel when it is first created. Not all modes can be set using this command.

set::level-on-join

Syntax: set::level-on-join <none|voice|halfop|op|protect|owner>
Alternate syntax: set::level-on-join <letter>

The mode that a user will get when he's the first to join a channel. The default is "op" (channel operator). You can also specify a letter such as "o".

set::restrict-usermodes

Syntax: set::restrict-usermodes <modes>

Restrict users to set/unset the modes listed here (don't use + or -). For example you can set +G in modes-on-connect and G in restrict-usermodes, that way you can force all users to be +G and unable to do -G.

In UnrealIRCd 6.1.1 and higher you can also override this value in a set block for a security group.

set::restrict-channelmodes

Syntax: set::restrict-channelmodes <modes>

Restrict users to set/unset the channelmodes listed here (don't use + or -). For example you can set +G in modes-on-join and G in restrict-channelmodes, that way you can force all (new) channels to be +G and unable to do -G.

IMPORTANT: Users may evade these restrictions via the MLOCK command from Services. If you use anope, we suggest you restrict the modes there too via anope's nomlock feature, see the example below.

Example to force and restrict channel modes

This will make it so all channels are always +ntG and that users cannot set +L:

In UnrealIRCd:

set {
    modes-on-join "+ntG";
    restrict-channelmodes "ntGL";
}

In anope, in the module chanserv block:

    nomlock = "L"
    require = "ntG"

Remember that the channel modes on the Anope side will only be applied to newly registered channels.

set::restrict-extendedbans

Syntax: set::restrict-extendedbans <types|*>

Don't allow users to use any extended bans ("*") or disallow only certain ones (eg: "qc").

set::restrict-commands

This allows you to restrict a certain command to users depending on: how long they are connected, if they are identified to Services or if they are using WebIRC block, and their reputation score.

See Restrict commands for the documentation.

set::auto-join

Syntax: set::auto-join "<channels>"

The channel(s) a user will be forced to join at connection. To specify more than one channel use a comma separated list.

Important: don't forget to add quotes, otherwise your value is mistaken for a comment! Use: auto-join "#chan";

This setting can be overridden by tld::channel and in UnrealIRCd 6.1.1 and higher you can also override this value in a set block for a security group.

set::oper-auto-join

Syntax: set::oper-auto-join "<channels>"

The channel(s) a user will be forced to join when they /oper. To specify more than one channel use a comma separated list.

IMPORTANT: Don't forget to add double quotes, like: oper-auto-join "#chan,#chan2"; because otherwise you will get a parse error.

set::anti-spam-quit-message-time

Syntax: set::anti-spam-quit-message-time <timevalue>

A time value specifying the length of time a user must be connected for before a /quit message will be displayed. Used to prevent spam. A time value is a numeric string with d meaning days, h meaning hours, m meaning minutes, and s meaning seconds, for example 1d2h3m means 1 day, 2 hours, 3 minutes.

set::prefix-quit

Syntax: set::prefix-quit <text-to-prefix-quit>

Sets the text that will be used to prefix a quit message. If this value is set to 0 then the standard "Quit:" is used.

set::static-quit

Syntax: set::static-quit <quit message>

Sets a static quit message that will be sent whenever a client logs off the network. This eliminates the need for anti-spam-quit-message-time, as well as the set::prefix-quit. It will NOT replace ERRORS with the static-quit message.

In UnrealIRCd 6.1.1 and higher you can also override this value in a set block for a security group.

set::static-part

Syntax: set::static-part <no|yes|part message>

A value of 'yes' strips all part comments, a value of 'no' makes part just work as usual, anything else will be used as a part comment (eg: static-part "Bye!") but this can be quite annoying, so use with care.

In UnrealIRCd 6.1.1 and higher you can also override this value in a set block for a security group.

set::who-limit

Syntax: set::who-limit <limit>

Sets the limit for the maximum number of matches that will be returned for a /WHO, the default is 100.

This limit does not apply for WHO requests for a specific channel, eg WHO #channel. The limit also does not apply to IRCOps.

set::silence-limit

Syntax: set::silence-limit <limit>

Sets the limit on the maximum SILENCE list entries. If this directive is not specified, a limit of 15 is set.

set::maxbans

Syntax: set::maxbans <limit>

Sets the limit on the maximum amount of bans (+b) allowed per channel. The default is 60. The same limit is applied to exempts (+e) and invex (+I) as well.

set::maxbanlength

Syntax: set::maxbanlength <limit>

This setting has been removed in UnrealIRCd 6.1.1 as it was not deemed useful and only confusing

Similar to set::maxbans, but this sets the maximum amount of characters for all bans added up together, so basically this puts up a limit on the (semi-)maximum amount of memory all channel bans on a channel can take. The default is 2048 (bytes). With the default set::maxbans of 60 this allows 2048:60=34 characters per ban on average. Note that if you change this, the same limit is also applied to excepts (+e) and invex (+I).

set::allow-user-stats

Syntax 1: set::allow-user-stats <stats-list-in-letters>
Syntax 2: set::allow-user-stats {<long-stats-flag1> <long-stats-flag2>}

Specifies a list of /STATS flags that users may also see (non-IRCOps). The default is "" (empty), which means regular users may not see any /STATS.

Be careful if you tweak this, some stats are not meant to be exposed to regular users and the information contained in them will often aid attackers / "bad guys".

set::max-stats-matches

Syntax: set::max-stats-matches <count>

If, as an IRCOp, you do STATS gline and there are thousands of glines then in the past the oper would be disconnected due to flooding ("Max SendQ exceeded"). With max-stats-matches you limit the number of *LINE entries that are outputted. The default is 1000 entries which should be sufficient protection (assuming your oper class has a sendq of 500K or more). You can set this limit higher or lower, or to zero to disable the protection (no limit).

set::min-nick-length

Syntax: set::min-nick-length <length>

Specifies the minimum required length of a nick name. This defaults to 0 which means there's no minimum. The maximum is 30 (NICKLEN) but it should still be smaller than (or equal to) set::nick-length.

set::nick-length

Syntax: set::nick-length <length>

Specifies the maximum length of a nick name. This default and maximum is 30 (NICKLEN). This setting can only be used to impose a shorter nick length than that.

set::topic-length

Syntax: set::topic-length <length>

Specifies the maximum length of a channel topic. This default and maximum is 360. This setting can only be used to impose a shorter length.

set::away-length

Syntax: set::away-length <length>

Specifies the maximum length of the away reason in /AWAY. The default is 307 and the maximum is 360.

set::quit-length

Syntax: set::quit-length <length>

Specifies the maximum length of the quit reason in /QUIT. The default is 307 and the maximum is 395.

set::kick-length

Syntax: set::kick-length <length>

Specifies the maximum length of the kick reason in /KICK. The default is 307 and the maximum is 360.

set::maxchannelsperuser

Syntax: set::maxchannelsperuser <amount-of-channels>
Also: set::max-channels-per-user <amount-of-channels>

Specifies the number of channels a single user may be in at any one time. IRCOps are exempt from this restriction.

In UnrealIRCd 6.1.1 and higher you can also override this value in a set block for a security group. This way you could set a low set::max-channels-per-user of 5 as a default, and set it to 10 for known-users.

set::maxdccallow

Syntax: set::maxdccallow <amount-of-entries>

Specifies the maximum number of entries a user can have on his/her DCCALLOW list.

set::channel-command-prefix

Syntax: set::channel-command-prefix <command-prefixes>

With user mode +d a user can mark themselves as "deaf", that is: they don't receive channel messages. But, if the first character of a message starts with a certain character (the prefix) then the message does go through. The default value is `!. which is normally a good setting. It means something like !kick Blah is received by users (bots) that have +d.

set::allowed-nickchars

Syntax: set::allowed-nickchars { <list> }

Character sets / languages to allow in nick names, see Nick Character Sets.

set::allowed-channelchars

Syntax: set::allowed-channelchars [utf8|ascii|any]

Which characters to allow in channel names. This setting must be the same on all servers.

There are 3 possible settings (utf8, ascii and any):

Setting Allowed characters Comment
utf8 All valid UTF8 characters This is the default. It should be suitable for nearly everyone since UTF8 is the de-facto standard on IRC nowadays.
ascii Only a-z/A-Z/0-9 and a few other ASCII characters This is a strict setting. It can be used if you don't want any confusion with channel names, no UTF8, etc. Technically this would be safest. Freenode uses this in their software.
any Almost all characters are permitted This is a very loose setting and was the default in UnrealIRCd 4.x. The problem is that this breaks text websocket clients. It is NOT a recommended setting.

The following characters are ALWAYS REJECTED: ASCII values below 32 (control characters), the space character, comma, colon.

set::allow-userhost-change

Syntax: set::allow-userhost-change [never|always|not-on-channels|force-rejoin]

Specifies what happens when the user@host changes (+x/-x/chghost/chgident/setident/vhost/etc). never disables all the commands, always does always allow it even when in channels (may cause client desyncs) [default], not-on-channels means it's only allowed when the user is not on any channel. Finally, force-rejoin will force a rejoin in all channels and re-op/voice/etc if needed, it will do that for all IRC clients without the chghost capability.

set::topic-setter

Syntax: set::topic-setter [nick|nick-user-host]

You can see who set the TOPIC by doing /TOPIC #channel. Via this set option you configure what information is displayed about the setter:

  • nick: show only the nick of who set the topic
  • nick-user-host: show the nick!user@host of who set the topic

Until UnrealIRCd 6.1.0 the default was nick. From 6.1.1 onwards the default is nick-user-host.

set::ban-setter

Syntax: set::ban-setter [nick|nick-user-host]

You can see who set a ban/exempt/invex (+beI) by doing /MODE #channel b (or similar). Via this set option you configure what information is displayed about the setter:

  • nick: show only the nick of who set the ban/exempt/invex
  • nick-user-host: show the nick!user@host of who set the ban/exempt/invex

Until UnrealIRCd 6.1.0 the default was nick. From 6.1.1 onwards the default is nick-user-host.

set::options::hide-ulines

Syntax: set::options::hide-ulines

If this is present, Ulined servers will be hidden in /MAP and /LINKS for regular users (non-ircops). This is a very common thing to do.

set::options::flat-map

Syntax: set::options::flat-map

If this is present, all servers will appear as directly linked in /map and /links, thus you can no longer see which server is linked to which. This is a little help against (D)DoS attacks because evil people now no longer can easily see the 'weak points'.

set::options::show-opermotd

Syntax: set::options::show-opermotd

If present the opermotd will be shown to users once they successfully /oper.

set::options::identd-check

Syntax: set::options::identd-check

If present the presence of an identd server will be checked and the returned value will be used for the username. If no ident request is returned or the identd server doesn't exist, the user's specified username will be prefixed with a ~. If this value is omitted no such check is made.

set::options::show-connect-info

Syntax: set::options::show-connect-info

If present notices showing "ident request", "hostname lookup", etc. will be displayed when a user connects.

set::options::dont-resolve

Syntax: set::options::dont-resolve

Don't do any resolving (DNS lookups) on users that connect. This can be useful if many of your users don't have a host, to speed up connecting. Note that this also means you cannot have host-based allow blocks.

set::options::mkpasswd-for-everyone

Syntax: set::options::mkpasswd-for-everyone

Makes it so the MKPASSWD command can be used by everyone. This is not recommended on production servers. Normally this command is restricted to IRCOps only.

set::options::allow-part-if-shunned

Syntax: set::options::allow-part-if-shunned

Allow shunned user to use /part.

set::options::fail-oper-warn

Syntax: set::options::fail-oper-warn

If present, a user will be notified that his/her failed /oper attempt has been logged.

set::options::allow-insane-bans

Syntax: set::options::allow-insane-bans

Allow insane broad bans like /GLINE *@*.xx. This makes it very easy to accidentally ban everyone on your network, so use with great care!

set::options::disable-cap

Syntax: set::options::disable-cap

Disable IRC Client Capabilities Extensions (CAP). Note that this makes SASL and various other features unavailable or harder for clients to use.

set::dns::bind-ip

Syntax: set::dns::bind-ip <ip>

Specifies the IP to bind to for the resolver, rarely ever needed.

set::network-name

Syntax: set::network-name <name-of-network>

Specifies the name of the network on which this server is run. This value should be exactly the same on all servers on a network.

set::default-server

Syntax: set::default-server <server-name>

Defines the name of the default server to tell users to connect to if this server is full.

set::default-ipv6-clone-mask

Syntax: set::default-ipv6-clone-mask <value>

If two clients connect from different IPv6 addresses but only the last few bits are different, there is almost a guarantee that both clients are really one person. This option affects the enforcement of allow::maxperip. For example, if you set this option to 128, then each IPv6 address will be considered unique. Because of current IP allocation policies, the default and recommended setting is 64. You probably don't need to change this.

set::services-server

Syntax: set::services-server <server-name>

Specifies the name of the server that the services bots are connected to. See also Services.

set::stats-server

Syntax: set::stats-server <server-name>

Sets the name of the server on which the stats bot is located. If stats are not run this value may be left out.

set::sasl-server

Syntax: set::sasl-server <server-name>

Sets the name of the server to which SASL authenticate messages should be sent.

set::help-channel

Syntax: set::help-channel <network-help-channel>

Sets the name of the help channel for this network. This channel name is displayed if you type HELP(OP) with an unknown topic, eg HELPOP XYZ.

set::cloak-method

Syntax: set::cloak-method [ip|host]

This sets the method to use when cloaking a user. The default is host which will use hostname-based cloaking (and fallback to IP-based if no host is available). The alternative is to set this to ip which will make UnrealIRCd always do IP-based cloaking. This results in a XX.YY.ZZ.IP cloaked host which provides more anonymity. IRCOps can still see the real hostname of the user and GLINEs and such still work as well.

set::cloak-keys

Syntax: set::cloak-keys { "key1"; "key2"; "key3"; }

UnrealIRCd has a feature called Cloaking. The keys you specify here are used to generate such a +x host. ALL servers on the same network must use the same keys and they must be kept secret.

Each key consists of 50-100 characters, the characters should contain a mixture of: lowercase (a-z), uppercase (A-Z) and digits.

On *NIX you can use ./unrealircd gencloak on the command line to generate 3 random keys.
On Windows, you can use "C:\Program Files\UnrealIRCd 6\bin\unrealircdctl" gencloak

Example:

/* This is just an example, don't actually use these keys yourself!! */
set {
    cloak-keys {
        "g5Ea8V0j7gb3t7w8QFmFV7Qoacit6T62eOk3jlIn7Qg0YaGgBqj55";
        "mVv4uVw3306We2HvgPWTk1q0Nvnrl6uCr6Bor57c01d4eB5s60eQ3";
        "HPXLauAcFF058V4Ian7X1hlt0Yj0MGmooNqs5bALL3um5GwD3O6w0M5L";
    };
};
set::cloak-prefix

Syntax: set::cloak-prefix <prefix-value>

Defines the prefix that will be used on hidden hosts (+x). This is usually three or four letters representing the network name. Linked servers must have the same cloak-prefix for channel bans to function properly.

set::tls::certificate

Syntax: set::tls::certificate <filename>

Specifies the filename where the server's SSL certificate is located. The default is server.cert.pem.

set::tls::key

Syntax: set::tls::key <filename>

Specifies the filename where the server's SSL private key is located. The default is server.key.pem.

set::tls::trusted-ca-file

Syntax: set::tls::trusted-ca-file <filename>

Specifies the filename where the certificates of the trusted CAs are located. The default is curl-ca-bundle.crt (shipped with UnrealIRCd)

set::tls::protocols

Syntax: set::tls::protocols <list-of-protocols>

Specifies which SSL/TLS protocols are permitted. Available options are: All, TLSv1, TLSv1.1, TLSv1.2 and TLSv1.3. Prefix the protocol with a - (minus sign) to remove it.

Example: set { tls { protocols "All,-TLSv1,-TLSv1.1"; /* permit only TLSv1.2 and up */ }; };

See TLS Ciphers and protocols for more information and suggestions on a good setting.

set::tls::ciphers

Syntax: set::tls::ciphers <cipherlist>

Specifies which ciphers to be allowed for TLSv1.0, TLSv1.1 and TLSv1.2. See TLS Ciphers and protocols for more information and suggestions on a good setting.

set::tls::ciphersuites

Syntax: set::tls::ciphersuites <ciphersuitelist>

Specifies which ciphersuites to allow for TLSv1.3. See TLS Ciphers and protocols for more information.

set::tls::ecdh-curves

Syntax: set::tls::ecdh-curves <curvelist>

Specifies which ECDH(E) curves to be allowed. See TLS Ciphers and protocols for more information and suggestions on a good setting.

set::tls::renegotiate-bytes

Syntax: set::tls::renegotiate-bytes <value>

Specifies after how many bytes an SSL session should be renegotiated (eg: 20m for 20 megabytes).

set::tls::renegotiate-timeout

Syntax: set::tls::renegotiate-timeout <timevalue>

Specifies after how much time an SSL session should be renegotiated (eg: 1h for 1 hour).

set::tls::options::fail-if-no-clientcert

Syntax: set::tls::options::fail-if-no-clientcert

Forces clients that do not have a certificate to be denied. This would be an unusual setting to enable.

This option does not provide any security. A user can simply generate a client certificate and use it to connect, no verification is done.

set::tls::options::no-starttls

Syntax: set::tls::options::no-starttls

Disable STARTTLS. STARTTLS allows clients to use SSL/TLS on regular (non-SSL) ports, which is normally a good thing.

set::tls::outdated-protocols

This sets the outdated SSL/TLS protocols. It is used for set::outdated-tls-policy.

The default setting is "TLSv1.0,TLSv1.1" which marks TLSv1.0 and TLSv1.1 as outdated. In case you wonder, SSLv3 is not listed here because UnrealIRCd never allows such connections anyway.

set::tls::outdated-ciphers

This sets the outdated SSL/TLS ciphers. It is used for set::outdated-tls-policy.

The default setting is "AES*" which requires some explanation: This effectively marks all ciphersuites without Forward Secrecy as outdated. It stills allows AES perfectly fine, but only in combination with ECDHE/EECDH, which provides Forward Secrecy. For example AES128-SHA256 would be considered outdated and ECDHE-RSA-AES128-GCM-SHA256 is not.

If you use a weird ::ciphers setting, for example one that allows CAMELLIA, then you may have to tweak ::outdated-ciphers also. This is, however, an extremely uncommon configuration.

set::tls::sts-policy

This configures Strict Transport Security in UnrealIRCd.

Read SSL/TLS - Strict Transport Security for information on how to deploy this.

Example:

/* Read https://www.unrealircd.org/docs/SSL/TLS#Strict_Transport_Security
 * before deploying this.
 */
set {
        tls {
                sts-policy {
                        port 6697;
                        duration 5m;
                };
         };
};

IMPORTANT: Invalid/untrusted SSL/TLS certificates or a non-working TLS port WILL LOCK YOUR USERS OUT if you use sts-policy!

set::plaintext-policy

The plaintext-policy block allows you to configure what UnrealIRCd should do with users/opers/server who are not connected via SSL/TLS.

set {
    plaintext-policy {
        user allow; /* will allow users to connect without using SSL/TLS */
        oper warn; /* will warn oper if not connected via SSL/TLS */
        server deny; /* will deny server linking */
    };
};

An action of allow will allow the operation. The warn action will make the server send a warning notice. The deny action will reject the user/oper/server, meaning that the user cannot connect, the IRCOp cannot /OPER and the server may not link.

Optionally you can set a set::plaintext-policy::user-message and set::plaintext-policy::oper-message to change the default UnrealIRCd warn/deny text the user/ircop will receive.

set::outdated-tls-policy

The outdated-tls-policy block allows you to configure what UnrealIRCd should do with users/opers/server connecting with an outdated SSL/TLS protocol or cipher.

set {
    outdated-tls-policy {
        user warn; /* must be one of: allow, warn, deny */
        oper deny; /* must be one of: allow, warn, deny */
        server deny; /* must be one of: allow, warn, deny */
    };
};

An action of allow will allow the operation. The warn action will make the server send a warning notice. The deny action will reject the user/oper/server, meaning that the user cannot connect, the IRCOp cannot /OPER and the server may not link.

To decide which protocol and ciphers are considered outdated, the set::tls::outdated-protocols and set::tls::outdated-ciphers settings are used.

Optionally you can set a set::outdated-tls-policy::user-message and set::outdated-tls-policy::oper-message to change the default UnrealIRCd warn/deny text the user/ircop will receive.

set::ident::connect-timeout

Syntax: set::ident::connect-timeout <amount>

Amount of seconds after which to give up connecting to the ident server (default: 3s).

set::ident::read-timeout

Syntax: set::ident::read-timeout <amount>

Amount of seconds after which to give up waiting for a reply (default: 7s).

set::handshake-timeout

Syntax: set::handshake-timeout <amount>

Amount of seconds that a connection may be in the "handshake state", that is: the period between a TCP/IP connection accept() and the user getting online after NICK/USER have been received and DNS and ident lookups have completed (if those are enabled).

The default is 30 which is a safe value for everyone. Be careful if drastically lower this. DNS lookups, ident lookups and the handshake may take more time than you may think in some cases. You can probably set this to a value like 20 if you like. However, if you set this setting too low then you risk locking everyone out when for example your DNS server is a little slow (eg: under attack).

set::sasl-timeout

Syntax: set::sasl-timeout <amount>

The maximum time for SASL to take place. Time starts at the AUTHENTICATE command. The default is 15 seconds.

This protects against misbehaving or extremely laggy SASL servers (Services). Otherwise, a misbehaving server could lead to people no longer being able to connect.

set::anti-flood

The set::anti-flood block is used to configure nearly all anti flood settings in UnrealIRCd:

set::default-bantime

Syntax: set::default-bantime

Default bantime when doing /KLINE, /GLINE, /ZLINE, GZLINE, /SHUN, etc without a time parameter (like /GLINE *@some.nasty.isp), the default is permanent (0). Example: default-bantime 90d

set::modef-default-unsettime

Syntax: set::modef-default-unsettime <value>

For channelmode +f you can specify a default unsettime, if you specify 10 for example then a /MODE #chan +f [5j]:15 will be transformed to [5j#i10]:15. The default is no default unsettime.

set::modef-max-unsettime

Syntax: set::modef-max-unsettime <value>

The maximum amount of minutes for a mode +f unsettime (in +f [5j#i

set::modef-boot-delay

Syntax: set::modef-boot-delay <timevalue>

IMPORTANT: In UnrealIRCd 6.0.1+ this setting has been moved to set::anti-flood::channel::boot-delay, see Channel anti-flood settings#config

Ignore join flood controls in channel mode +f when the server has just been rebooted. This because users are likely to quickly reconnect in such a case, causing a lot of joins which normally trigger +f, causing channels to end up being +i or +R even if there was no true attack (just a server restart).

The default setting is 75 seconds. You can specify an alternative time in seconds (eg: 120), or by timespec (eg: 2m).

The downside of this setting is that if a server is restarted in the middle of a drone attack, then when it is booted up again, drones would be able to bypass limits for the specified amount of time. One needs to weigh this against the false positives in channel mode +f that are otherwise caused by server restarts (eg: channels ending up +i due to +f, only because a server has been restarted during scheduled maintenance).

set::ban-version-tkl-time

Syntax: set::ban-version-tkl-time <value>

If you specify an 'action' like zline/gline/etc in a Ban version block, then you can specify here how long the IP should be banned, the default is 86400 (1 day).

set::spamfilter::ban-time

Syntax: set::spamfilter::ban-time <value>

Same as above but for *lines/shuns added by spamfilter

set::spamfilter::ban-reason

Syntax: set::spamfilter::ban-reason <reason>

Default reason to use for entries added by spamfilter

set::spamfilter::utf8

Syntax: set::spamfilter::utf8 <yes|no>

In UnrealIRCd 6.0.7 and later you can enable experimental UTF8 matching support by setting this to yes. The default is no.

When UTF8 matching is enabled:

  • Case insensitive matches will then work better. For example, with extended Latin, a spamfilter on ę then also matches Ę.
  • Other PCRE2 features such as \p can then be used. For example with the regex \p{Arabic} to block all Arabic script. See this full list. Please do use this new tool with care. Blocking an entire language or script is quite a drastic measure.
set::spamfilter::virus-help-channel

Syntax: set::spamfilter::virus-help-channel <channel>

The channel to use for the 'viruschan' action in spamfilter

set::spamfilter::virus-help-channel-deny

Syntax: set::spamfilter::virus-help-channel-deny <yes|no>

If set to yes (or '1') it replies 'invite only' to any normal users that try to join the virus-help-channel. Only opers, people that match spamfilters and people that are /invite'd can join.

set::spamfilter::except

Syntax: set::spamfilter::except <target(s)>

These targets are exempt from spam filtering, that is: no action will be taken if you send a message/notice/etc to this target. This can be single target or comma separated list.. Ex: except "#help,#spamreport"

set::spamfilter::detect-slow-warn

Syntax: set::spamfilter::detect-slow-warn <value>

If a spamfilter takes longer than this amount of milliseconds to execute (1000ms = 1 second), then a warning notice will be sent to all opers (default: 250). See also Spamfilter#Slow Spamfilter Detection

set::spamfilter::detect-slow-fatal

Syntax: set::spamfilter::detect-slow-fatal <value>

If a spamfilter takes longer than this amount of milliseconds to execute (1000ms = 1 second), then the spamfilter will be removed (default: 500). See also Spamfilter#Slow Spamfilter Detection

set::spamfilter::show-message-content-on-hit

Syntax: set::spamfilter::show-message-content-on-hit <always|never|channel-only>

When a spamfilter hits, IRCOps receive a notice and a message is logged. By default this includes the message content, even for private messages. The message content helps IRCOps to see if a spamfilter hit is correct or not, which can then lead to tweaking or removing faulty spamfilters, which can be very important if a spamfilter is misbehaving.

The following values are supported:

  • always: always show message contents, this is the default.
  • channel-only: only hide message contents for private messages/notices
  • never: hide message contents for both private and channel messages/notices

UnrealIRCd has the following spying countermeasure (for many years) to help that spamfilters are not abused for spying. When a spamfilter hit happens that has an action like gline or blocking, it is visible to the user that an action was taken. There is also the action 'warn', which means: take no action and only warn IRCOps, that one would be easy to use as a spy tool, so when this happens and message content was revealed, numeric 659 (RPL_SPAMCMDFWD) is sent to the client to indicate that the message is allowed through but IRCOps were informed. With this new set::spamfilter::show-message-content-on-hit feature, when the message content was hidden due to this setting (eg due to 'never' or 'channel-only' for chanmsgs), the warn message will not be sent as there is no need to inform the user in such a case.

set::central-spamfilter

See Central Spamfilter.

set::check-target-nick-bans

Syntax: set::check-target-nick-bans <yes|no>

Whenever the user changes his/her nick, check if the NEW nick would be banned. If so, do not allow the nickchange. Default is yes.

set::ping-cookie

Syntax: set::ping-cookie <yes|no>

When a client connects, send a "ping cookie" consisting of a random string that the client should respond with. All clients should cope with this and do so without bothering the user. Ping cookies are a security measure. It helps in preventing blind HTTP-POST attacks and similar security issues. It also helps against TCP spoofing on very old operating systems.

The default is yes (enabled). Changing this to no is a big security risk.

set::watch-away-notification

Syntax: set::watch-away-notification <yes|no>

Allows you to enable/disable AWAY notification in WATCH. The default is yes (enabled).

set::max-targets-per-command

This limits the number of targets in a command. For example for PRIVMSG it defaults to 4, which means you can address up to 4 targets via /MSG nick1,nick2,nick3,nick4 hello. These imposed protocol limits apply to everyone, including opers.

The following are the defaults:

set {
    max-targets-per-command {
        privmsg 4;
        notice 1;
        tagmsg 1;
        names 1;
        whois 1;
        whowas 1;
        kick 4;
        list max;
        join max;
        part max;
        sajoin max;
        sapart max;
        kill max;
        dccallow max;
        userhost max;
        userip max;
        ison max;
        watch max;
    };
};

If you are tweaking the settings you should note that:

  • The commands NAMES and WHOWAS do not support more than 1
  • The setting for the commands USERHOST USERIP ISON WATCH can not be lowered
  • Other than the above there is no checking if the command exists or if the command itself allows multiple targets in the first place
set::hide-ban-reason

Syntax: set::hide-ban-reason <yes|no|auto>

This will hide the *LINE reason to anyone except the user being killed and IRCOps. There are 3 settings:

  • yes: always hide the ban reason to everyone else
  • no: never hide the ban reason
  • auto: only hide the ban reason to others if the reason contains the IP address of the user or an unrealircd.org URL. (Requires UnrealIRCd 6.1.3 or higher)

In UnrealIRCd 6.1.3 and higher the default is auto so that the IP address of the user is not accidentally exposed, for example via the dronebl.org ban reason which usually contains an URL with the IP.

In versions before 6.1.3, the auto option did not exist and the default is no.

set::antirandom

This module can automatically kill users that seem to have "random looking nicks".

This module is not loaded by default, you must load it manually:

loadmodule "antirandom";

<!--T:285-->
set {
	antirandom {
		/* THRESHOLD:
		 * This is the most important setting of all.
		 * For every randomly looking item the user gets a certain amount of
		 * 'points'. If the points reach the 'threshold' then the appropriate
		 * action is taken (killed, *lined, see later on).
		 *  lower = more randomly looking users will be caught
		 *          (but also more innocent users).
		 * higher = less chance of innocent users getting killed
		 *          (but also less chance on bots getting caught).
		 * <2:  DON'T!!
		 *  4:  Works good, probably a few more innocent kills, but if you have a
		 *      big problem with drone attacks then this might be a good setting.
		 *  5:  Works well with few innocent kills, probably good to begin with.
		 *  6:  If you want to be a tad more careful
		 * >6:  For the paranoid. Module can still be quite effective, though :)
		 */
		threshold 6;

		/* BAN-ACTION:
		 * Action to take whenever the user is caught as random, options:
		 * warn, kill, gline, gzline, kline, zline, shun, tempshun
		 */
		ban-action kill;

		/* BAN-TIME:
		 * Time to ban the user (irrelevant for tempshun/kill).
		 * Something between 1 hour and 2 days is recommended.
		 * If you set it higher than 3 or 4 days then you get quite a risk
		 * of catching innocent users due to dynamic IP, not to mention
		 * your *line list gets filled up... so choose it wisely.
		 */
		ban-time 4h;

		/* BAN-REASON:
		 * The ban or kill reason to use.
		 * Tip: you might want to put in an entry to a FAQ or an email address where
		 *      users can mail if they have been caught and don't know what to do.
		 * NOTE: One of the various reasons that "innocent users" are blocked is when
		 *       they randomly type in info for their nick, ident, or realname.
		 */
		ban-reason "You look like a bot. Be sure to fill in your nick/ident/realname properly.";

		/* CONVERT-TO-LOWERCASE:
		 * Convert nicks, idents, and realnames to lowercase before doing random checks?
		 * Useful to catch GnStA5FYhiTH51TUkf style random nicks as random.
		 * Enabled by default.
		 */
		convert-to-lowercase yes;

		/* SHOW-FAILEDCONNECTS:
		 * This will send out a notice whenever a randomly looking user has been caught
		 * during connecting. This can be pretty noisy.
		 * Especially recommended to enable during the first few days you use this module.
		 */
		show-failedconnects yes;

		/* EXCEPT BLOCK (UnrealIRCd 6.0.4 and later):
		 * Don't do antirandom checks for these users.
		 */
		except {
			/* Exempt WEBIRC gateways because these frequently
			 * cause false positives. So the default is yes.
			 */
			webirc yes;

			/* Exempt LAN users */
			ip { 192.168.*; 127.*; }

			// Or by hostname:
			//mask { *.example.net; }

			/* You can also exempt security groups: */
			// security-group known-users;

			/* For all options, see https://www.unrealircd.org/docs/Mask_item */
		}

                /* EXCEPT-HOSTS (before UnrealIRCd 6.0.4):
                 * On older versions of UnrealIRCd you should use this instead:
                 */
                //except-hosts {
                //        mask "192.168.0.0/16";
                //        mask "127.0.0.0/8";
                //};
	}
}
set::hide-list

This allows you to specify which channels should be hidden from list. Right now it only supports one option: deny-channel. This will hide channels that the user cannot join due to deny channel { } restrictions:

set { hide-list { deny-channel; }; };

Note that secret channels (channel mode +s) are always hidden and IRCOps always override restrictions (if they have sufficient access).

set::max-unknown-connections-per-ip

UnrealIRCd limits the number of connections per IP that are in an "unknown" state, that is: connections that are in a handshake. This is a security setting and it defaults to 3.

Only in very rare circumstances this may need to be adjusted. For example if you have hundreds of users coming from the same IP. If you only need to exempt a specific IP range, then it is better to use a except ban { } block with type connect-flood, or similarly an /ELINE with type 'c'.

Example: set { max-unknown-connections-per-ip 3; };

set::handshake-delay

Syntax: set { handshake-delay 2; };

This defines the MINIMUM time it should take for a user to get connected (finish the initial handshake).

This can be very useful if you have blacklist blocks, so DNSBL checking can finish before allowing the user in.

The default is 2 seconds if you have any blacklist { } block. You could set it slightly higher if your DNSBL checking is slow but for most people the default should be perfectly fine. Values of 10 or more are not permitted.

If you don't have any blacklist { } blocks then the delay defaults to 0 seconds (no delay) since it would not be useful.

set::handshake-boot-delay

Syntax: set::handshake-boot-delay <timevalue>

This setting only exists in UnrealIRCd 6.1.1 and higher

This delays the processing of incoming clients the first <timevalue> seconds that a server is booted. It can be quite messy when clients are already connected and the server is linking in other servers and/or services. This setting can potentially avoid that mess, by giving some time for linking autoconnects to kick in, before clients are allowed in.

The <timevalue>, the numbers of seconds, needs to be between 0 and 15. It can't be too high because otherwise clients will abandon their connection attempts. And it shouldn't be too low to give your servers a chance to link.

The following incoming connections are exempt from this delay:

If you link your servers NOT on a serversonly port (and they are not on localhost either), then these server connections are delayed up to <this> value as well, which is not good. We recommend linking servers to a listener::options::serversonly port. This is considered good standard practice and is also used in the example conf and in all our linking tutorials.

Note that after the specified amount of seconds has passed after IRCd startup, clients are no longer delayed during connect by this setting. They may still be delayed by set::handshake-delay which is a different setting.

set::reject-message

This allows you to change the messages that are sent to a user when their connection is rejected. This shows the defaults:

set {
   reject-message {
        password-mismatch "Password mismatch";
        too-many-connections "Too many connections from your IP";
        server-full "This server is full.";
        unauthorized "You are not authorized to connect to this server";
        kline "You are not welcome on this server. $bantype: $banreason. Email $klineaddr for more information.";
        gline "You are not welcome on this network. $bantype: $banreason. Email $glineaddr for more information.";
    };
};

The set::reject-message::password-mismatch message is sent when the user supplied a server password but it was not matching allow::password in the Allow block.

The set::reject-message::too-many-connections message is sent when allow::maxperip is hit in the Allow block.

The set::reject-message::server-full message is sent when class::maxclients is hit in the Class block.

The set::reject-message::unauthorized message is sent when the client is not matching any Allow block.

The set::reject-message::kline message is sent to the user when disconnecting them due to a KLINE or ZLINE. The set::reject-message::gline message is sent to the user upon GLINE or GZLINE. The message is only sent to the affected user and is not seen by other users or IRCOps. In both of these configuration items (::kline and ::gline) the following variables are available:

Variable Description Example
$bantype type of the ban (past tense) K-lined
$banreason reason of the ban (*LINE reason) Stop spamming users
$klineaddr set::kline-address [email protected]
$glineaddr set::gline-address (or, if not set, then set::kline-address) [email protected]
$ip IP address of the user 203.0.113.12
set::antimixedutf8

The antimixedutf8 module will detect and stop spam containing of characters of mixed "scripts", where (for example) some characters are in Latin script and other characters are in Cyrillic script.

Note that you need to load this module explicitly (it is not loaded by default).

loadmodule "antimixedutf8";
set {
        antimixedutf8 {
                /* Take action at this 'score' (lower = more sensitive)
                 *
                 * A score of 2 or 3 will catch a lot but also
                 * catch innocent users who are not using a pure
                 * Latin script, such as Russian people who
                 * commonly use a mix of Latin and Cyrillic.
                 *
                 * A score of 8 is a safe default.
                 */
                score 8;

                /* Action to take, see:
                 * https://www.unrealircd.org/docs/Actions
                 */
                ban-action block;

                /* Block/kill/ban reason (sent to user) */
                ban-reason "Mixed character spam";

                /* Duration of ban (does not apply to block/kill) */
                ban-time 4h; // For other types
        }
}
set::authentication-prompt

This will ask users to type /AUTH user:pass if they need to authenticate, for example if the user matches a soft ban or require authentication { } block. Technically, it does this by simulating a SASL session to Services.

The module is loaded by default with the following default settings:

loadmodule "authprompt";
set {
        authentication-prompt {
                /* Enabled or not? */
                enabled yes;

                <!--T:316-->
message "The server requires clients from this IP address to authenticate with a registered nickname and password.";
                message "Please reconnect using SASL, or authenticate now by typing: /QUOTE AUTH nick:password";
                /* As you can see you can have multiple 'message' items.
                 * It may be useful to refer to a webpage for more
                 * information and/or where users can register their nick.
                 */

                <!--T:317-->
fail-message "Authentication failed";
                /* Multiple fail-message lines are also supported */

                unconfirmed-message "You are trying to use an unconfirmed services account.";
                unconfirmed-message "This services account can only be used after it has been activated/confirmed.";
        };
};
// If you use the authprompt module then you may want to raise the
// timeout in which users must complete the handshake.
// By uncommenting the following, you can raise it from 30 to 60 seconds:
// set { handshake-timeout 60s; };
set::reputation

The reputation module provides reputation scores of users. This score can then be used by various modules to counter abuse.

The default settings are:

set {
        reputation {
                /* The database file, this will be in the 'data' subdirectory */
                database "reputation.db";

                /* Requires UnrealIRCd 6.1.2 or higher:
                 * The score bump timer bumps the reputation score every 5min,
                 * however it ONLY does it for people who meet this criteria:
                 * - user needs to be in any channel with 3 or more members
                 */
                score-bump-timer-minimum-channel-members 3;
        }
}

You can adjust the set::reputation::score-bump-timer-minimum-channel-members to meet the typical use at your network. For example, if almost all of your users are joined to at least one channel with 5 or more members (4 other members plus you) then you can set this to 5. On the other hand, if it is very normal on your network that everyone is only in channels with 1 other person and hardly ever in a bigger channel, then you can set it to 2. Set it to 0 to also do score bumping for people who are not in any channel at all, this would be the behavior in UnrealIRCd 6.1.1.1 and earlier versions.

It is also possible to encrypt all data in the reputation database, to do so you have to create a secret { } block and then refer to that secret block. In this example we refer to a secret block called reputationdb:

set {
        reputation {
                db-secret "reputationdb";
        }
}
set::tkldb

The tkldb module saves all TKLs (kline, gline, spamfilter, etc) to a database file so these are preserved accross server restarts.

The default settings are:

set {
        tkldb {
                database "tkl.db"; /* this file will be in the 'data' subdirectory */
        }
}

It is also possible to encrypt all data in the database, to do so you have to create a secret { } block and then refer to that secret block. In this example we refer to a secret block called tkldb:

set {
        tkldb {
                db-secret "tkldb";
        }
}
set::channeldb

The channeldb module saves all channel settings for channels that have mode +P ("permanent") set. For these channels it saves: channel creation time, topic, topic setter (name), topic timestamp, channel modes, channel list modes (+b/+e/+I lists). These are all stored in a database file so these are preserved across server restarts. You can also optionally store the channel history on disk too (if the channel is also +H).

The default settings are:

set {
        channeldb {
                database "channel.db"; /* this file will be in the 'data' subdirectory */
        }
}

It is also possible to encrypt all data in the database, to do so you have to create a secret { } block and then refer to that secret block. In this example we refer to a secret block called channeldb:

set {
        channeldb {
                db-secret "channeldb";
        }
}
set::connthrottle

The set::connthrottle settings are documented at the Connthrottle page.

set::broadcast-channel-messages

Syntax: set::broadcast-channel-messages [auto|always|never]

There are 3 possible settings:

  • always: always send all channel messages to all servers, regardless of whether they have channel members or not.
  • auto (the default): don't send messages to servers if they have no channel members, except for when the channel mode +H (history) is set. In case of +H we broadcast all messages to all servers.
  • never: never broadcast channel messages to all servers, only send to servers that have channel members.
set::history

Configure settings related to Channel history.

The set::history::channel::playback-on-join block describes the behavior when a user joins a +H channel. The set::history::channel::max-storage-per-channel block sets limits on what can be set via /MODE #chan +H. Note that these are separate things: only a few lines of history are shown on-join, many more lines can be fetched via the HISTORY command (and possibly other commands in the future).

This shows the default settings:

set {
        history {
                channel {
                        /* How many lines to playback on join? */
                        playback-on-join {
                                lines 15;
                                time 1d;
                        }
                        /* How much history to keep. These are the
                         * upper maximums for channel mode +H lines:time
                         */
                        max-storage-per-channel {
                                /* +r channels have larger maximums: */
                                registered {
                                        lines 5000;
                                        time 31d;
                                }
                                /* -r channels have less: */
                                unregistered {
                                        lines 200;
                                        time 31d;
                                }
                        }
                }
        }
}
Persistent channel history

You can also store channel history encrypted on disk. This means channel history is preserved across IRCd restarts. UnrealIRCd will only store channel history for channels that have both channel mode +H and +P set.

To enable this you need to create a Secret block like this:

/* This is only a simple example with passwords stored directly in the
 * configuration file.
 * To get better security, read https://www.unrealircd.org/docs/Secret_block
 * on alternative ways so you don't store passwords directly in the config.
 */
secret historydb {
        password "somepassword";
}

And then refer to that secret block which we named historydb:

set {
        history {
                channel {
                        persist yes;
                        db-secret "historydb";
                }
        }
}

UnrealIRCd has the following goals for storing channel history on disk:

  • All data within the .db's is encrypted
  • We use a well-known encryption library, a good cipher and KDF, see Dev:UnrealDB for in-depth technical details.
  • By default the log databases are stored in the data/history/ directory
  • All .db files are cryptographically hashed so a third party can't tell which .db file belongs to which channel
  • A 'master.db' file is present too, to achieve the above in a consistent and safe manner. Don't delete this file.
  • Be sure to look at Secret block to see the various ways to store the key (password) and pick one acceptable to your environment
set::part-instead-of-quit-on-comment-change

Syntax: set::part-instead-of-quit-on-comment-change [yes|no]

When a QUIT message is changed due to channel restrictions, such as stripping color or censoring a word, we normally change the QUIT message. This has an effect on ALL channels, not just the one that imposed the restrictions (eg: the QUIT reason loses color or is censored for all). We feel this is the best tradeoff and this is the default setting of no.

You can also set this setting to yes. That will change the QUIT into a PART when the QUIT comment is changed. The channel(s) with the changed comment see the user PARTing, and on all other channels that do not have the restrictions (eg: are -S and -G) they will see the user QUITting with the original message.

set::webredir::url

Syntax: set::webredir::url 'http://example.org/'

When someone (accidentally) types irc.example.org in their web browser then UnrealIRCd can send a HTTP redirect back to, say, https://example.org/. Note that this is mostly a gimmick rather than something terribly useful.

For this to work, the IRC server needs to listen on ports 443 and 80 (more information about that here!). However, nowadays more and more IRC servers listen on port 443 so users can bypass firewall restrictions that they may encounter on the regular ports 6667/6697 (and also because of websockets).

Usage example (only do this after reading the above):

Important: You must use single-quotes like 'this' instead of "this" when specifying a url.

loadmodule "webredir";
set { webredir { url 'https://...'; } }
set::automatic-ban-target

Syntax: set::automatic-ban-target [host|userhost|..]

The IRCd may add automatic bans, for example due to a blacklist hit, a spamfilter hit, or because of antirandom or antimixedutf8. When it does, on what should the ban be placed:

  • ip: place the ban on the IP address (eg: *@172.16.8.4)
  • userip: include the ident portion in the mask (eg: [email protected])
  • host: place the ban on the hostname (eg: *@something.example.org), fallback to ip.
  • userhost: include the ident portion in the mask (eg: [email protected]), fallback to user@ip.
  • account: ban by services account name (eg: ~a:accountname)
  • certfp: ban by certificate fingerprint (eg: ~S:00112233etc)

The last two possibilities are only useful if you have a very special setup, it does not apply to most users. The most common choices are ip (the default), host, or userip (if you trust idents).

Note: if the ban is of type ZLINE or GZLINE then it will always resort to ip since all other options don't work. The reason for that is that UnrealIRCd closes the connection immediately in case of a (G)ZLINE. Therefore it only knows the IP information as it has not done a DNS lookup, ident lookup, TLS handshake, etc. In fact, that is what makes a ZLINE different than a KLINE (and a GZLINE from a GLINE).

set::manual-ban-target

Syntax: set::manual-ban-target [host|userhost|..]

Similar to automatic-ban-target, but this is used if target a nick in a *LINE, for example if you type /KLINE nick. When that happens, on what should the ban be placed:

  • ip: place the ban on the IP address (eg: *@172.16.8.4)
  • userip: include the ident portion in the mask (eg: [email protected])
  • host: place the ban on the hostname (eg: *@something.example.org)
  • userhost: include the ident portion in the mask (eg: [email protected])
  • account: ban by services account name (eg: ~a:accountname)
  • certfp: ban by certificate fingerprint (eg: ~S:00112233etc)

he last two possibilities are only useful if you have a very special setup, it does not apply to most users. The most common choices are ip, host (the default), or userhost (if you trust idents).

Note: if the ban is of type ZLINE or GZLINE then it will always resort to ip since all other options don't work. The reason for that is that UnrealIRCd closes the connection immediately in case of a (G)ZLINE. Therefore it only knows the IP information as it has not done a DNS lookup, ident lookup, TLS handshake, etc. In fact, that is what makes a ZLINE different than a KLINE (and a GZLINE from a GLINE).

set::hide-idle-time

Syntax: set::hide-idle-time::policy [never | always | usermode | oper-usermode ];

This is a privacy setting which configures the visibility of "idle time" of users:

  • never: never hide idle time, the idle time is always shown to everyone
  • always: always hide idle time
  • usermode: show idle time, but hide idle time if user mode +I is set. This setting allows all users to set this mode +I.
  • oper-usermode: same as previous, but only IRCOps can set the +I user mode to hide idle time. This is the default setting.

The default setting is:

set { hide-idle-time { policy oper-usermode; } }

In all cases, IRCOps can still see idle time of users.

Note that even if you are allowed to see idle time, /WHOIS Nick will never show idle time for users on another server. This is a technical limitation (the idle time is not communicated actively across servers). If you want to see the idle time of a remote user you need to double whois: /WHOIS Nick Nick. Some clients do the latter by default in popups.

set::server-linking

This block configures the timeouts for outgoing servers and the linking strategy for link { } blocks with autoconnect set.

These are the defaults:

set {
        server-linking {
                autoconnect-strategy sequential;
                connect-timeout 10s;
                handshake-timeout 20s;
        }
}

set::server-linking::autoconnect-strategy has three options:

  • parallel: connect to all link { } blocks in parallel
  • sequential: try to connect to the first link block, then to the 2nd, then to the 3rd, then back to the 1st, etc.. (this is the default)
  • sequential-fallback: similar to sequential but after a successful connection, we will restart from the beginning of the link blocks again. Can be useful for leafs.

set::server-linking::connect-timeout specifies the maximum time to wait for the outgoing connect() or TLS_connect() call to succeed. The default is 10 seconds and this should be sufficient. If you are on a high-latency/low-bandwidth satellite connection then you could raise this. Otherwise we recommend keeping it at 10.

set::server-linking::handshake-timeout specifies the maximum time to wait for the server handshake to succeed, that is: to receive the "SERVER" command. This is usually received in the first few kilobytes of data, so should be relatively soon. The default is 20 seconds here, which should be plenty for everyone.

set::whois-details

Note: this setting is only available in UnrealIRCd 6

This allows you to configure which WHOIS information should be shown to who (and in what detail).

For each item there are 3 user groups that you can configure:

  • everyone: all users
  • self: if you are /WHOIS'ing yourself
  • oper: IRC Operators

Then the possible settings for each item are:

  • none: information is not shown
  • full: all information is shown
  • limited: only a limited amount of information is shown. This is only available for a few items:
    • for item channels: full will also show hidden channels (+s), limited will not (normally used for normal users)
    • for item oper: full will show the operlogin and operclass, limited will leave these details out
    • for item secure: full will show the TLS version and cipher in use, limited will leave these details out
    • for item idle: full will show the idle time, limited means it depends on the +I user mode and the set::hide-idle-time setting.

The default settings are:

set {
        whois-details {
                basic           { everyone full; }
                modes           { everyone none;        self full;      oper full; }
                realhost        { everyone none;        self full;      oper full; }
                registered-nick { everyone full; }
                channels        { everyone limited;     self full;      oper full; }
                server          { everyone full; }
                away            { everyone full; }
                oper            { everyone limited;     self full;      oper full; }
                secure          { everyone limited;     self full;      oper full; }
                bot             { everyone full; }
                services        { everyone full; }
                security-groups { everyone none;        self none;      oper full; }
                reputation      { everyone none;        self none;      oper full; }
                geo             { everyone none;        self none;      oper full; }
                certfp          { everyone full; }
                shunned         { everyone none;        self none;      oper full; }
                account         { everyone full; }
                swhois          { everyone full; }
                idle            { everyone limited;     self full;      oper full; }
        }
}
set::server-notice-colors

This setting only exists in UnrealIRCd 6

Enable or disable colors in server notices (to snomasks). The default is set { server-notice-colors yes; }. You can change it to no if you don't want these colors.

This sets the (default) setting for all IRCOps on this server. You can tweak individual IRCOp settings through the server-notice-colors setting in the Oper block.

set::server-notice-show-event

This setting only exists in UnrealIRCd 6.0.2 or newer

Enable or disable showing of the susbystem.event (eg: connect.LOCAL_CLIENT_CONNECT) in log messages on IRC. The default is set { server-notice-show-event yes; }. You can change it to no if you don't want this.

This sets the (default) setting for all IRCOps on this server. You can tweak individual IRCOp settings through the server-notice-show-event setting in the Oper block.

set::staff-file

Defines the location of the file that will be shown to users when using the /STAFF command.

set { staff-file 'network.staff' }
set::geoip-classic

See GeoIP.

set::geoip-csv

See GeoIP.

set::geoip-maxmind

See GeoIP.

set::limit-svscmds

Syntax: set::limit-svscmds [ulines|servers]

Certain commands in the server protocol used to be for services only, these are commands like SVSJOIN and SVSNICK. However, now that we have JSON-RPC these commands may also be used by the JSON-RPC API, so blocking them from non-services-servers is problematic.

The old implicit default (before this setting was introduced) was ulines, which say only servers in the ULines block may use these commands. The new default is servers which allows all servers to use the SVS* commands, which is needed if at least 1 server on the network provides JSON-RPC.

We recommend to stick to the default value of servers. But, if you don't use JSON-RPC, and for some reason would like to have the old restriction, then you can change it to ulines if you really want.

set::high-connect-rate

Syntax: set::high-connect-rate <value>

This is all explained in FAQ: High connection rate detected.

This allows tweaking that setting, the value is in connects per second. The default is 1000. Use special value 0 to never have high connection rate kick in.

set::blacklist

The set::blacklist block allows finetuning rechecks:

set::blacklist::recheck-time

After a user is connected, we will keep checking DNS blacklists regularly to see if the user has been blacklisted. This way a user that is blacklisted after connect will still be killed/*lined from the network.

By default we:

  • Do a first quick check after 2 minutes
  • Then every 15 minutes

The default settings are:

set {
    blacklist {
        recheck-time-first 2m;
        recheck-time 15m;
    }
}

If you want to DISABLE rechecks then you can use:

set { blacklist { recheck-time never; } }

Or, you can disable rechecks individually per blacklist via blacklist::recheck.

set::blacklist::recheck-time-first

See previous item (above).

set::best-practices

UnrealIRCd 6.1.2 and higher will give (security) tips on best practices. It is usually a good idea to follow this advice, but you may not be interested in them or find them a nuisance if you are running a small test network or for other reasons. You can turn the tips off via settings in this block. The current default for everything is yes and you can change it to no if you want.

Here is the current block with all default settings:

set {
    best-practices {
        /* Warn when an oper::password is plaintext in the config (not hashed).
         * At a later time it may also warn about plaintext passwords elsewhere.
         */
        hashed-passwords yes;
    }
}

</translate>