IRKERD(8)
π IRKERD β the relay that ships your notifications to IRC servers (yes bestie, manual section 8)
okay so picture this: you've got a /commands page called irkerd, and it's a little daemon whose whole personality is "deliver messages to IRC and look cute doing it." Let's get into it β¨
πΈ SYNOPSIS πΈ
irkerd [-c ca-file] [-d debuglevel] [-e cert-file] [-l logfile]
[-H host] [-n nick] [-p password] [-P password-file]
[--sasl-mechanism PLAIN|EXTERNAL] [--sasl-username username]
[--sasl-password password] [--sasl-password-file password-file]
[-i IRC-URL] [-t timeout] [-V] [-h] [message text]
like, that's the whole vibe. flags on flags on flags π
π¦ DESCRIPTION π¦
irkerd is a specialized write-only IRC client β think of it as an IRC client that only talks and never listens to the drama. Its entire purpose in life is shipping notification messages to IRC channels. The use case the designers had in their heads? Broadcasting notifications from commit hooks in version-control systems. very demure, very CI. π
The main glow-up of relaying through this daemon instead of having every app do its own little scripted send is simple: it can maintain connection state for multiple channels, so you don't get that obnoxious join/leave channel spam on literally every single message. it's giving "I'm already here, I never left" energy. π
irkerd is a socket server that listens for UDP or TCP packets on port 6659 for textual request lines containing JSON objects, terminated by a newline. Each JSON object must have two members:
"to"β a destination, or a list of destinations"privmsg"β the message text
examples, bestie, because examples ate:
{"to":"irc://chat.freenode.net/git-ciabot", "privmsg":"Hello, world!"}
{"to":["irc://chat.freenode.net/#git-ciabot","irc://chat.freenode.net/#gpsd"],"privmsg":"Multichannel test"}
{"to":"irc://chat.hypothetical.net:6668/git-ciabot", "privmsg":"Hello, world!"}
{"to":"ircs://chat.hypothetical.net/git-private?key=topsecret", "privmsg":"Keyed channel test"}
{"to":"ircs://:topsecret@chat.example.net/git-private", "privmsg":"Password-protected server test"}
Now, the channel-part rules, because this is where people get confused and honestly same:
If the channel part of the URL doesn't start with one of the prefix characters β#β, β&β, or β+β, then a β#β gets prepended to it before shipping β unless the channel part has the suffix ",isnick" (which is unconditionally removed, no takebacks, periodt).
The host part of the URL may have a port-number suffix separated by a colon, like in that third example. If you don't give one? irkerd sends plaintext messages to the default 6667 IRC port of each server, and SSL/TLS messages to 6697. defaults are iconic like that π
Passwords for password-protected servers can be set using the usual [{username}:{password}@]{host}:{port} form defined in RFC 3986, as shown in the fifth example. And heads up: non-empty URL usernames override the default βirkerβ username. π
When the "to" URL uses the ircs scheme (fourth and fifth examples, bestie, look up), the connection to the IRC server is made via SSL/TLS β versus a plaintext connection with the irc scheme. You can set -c /etc/ssl/certs/ca-certificates.crt to declare a custom CA file, but if you don't set it, irkerd will use OpenSSL's default file (via Python's ssl.SSLContext.set_default_verify_paths). And ssl.match_hostname is used to ensure the server certificate belongs to the intended host, as well as being signed by a trusted CA. security said slay π₯
To join password-protected (mode +k) channels, the channel part of the URL may be followed with a query-string indicating the channel key, of the form β?secretβ or β?key=secretβ, where βsecretβ is the channel key. π
Oh and β an empty message is completely legal and will cause irkerd to join or maintain a connection to the target channels without actually emitting a message. Use cases: advertising that an instance is up and running, or joining a channel to log its traffic. lurking, but officially. π
β¨ OPTIONS β¨
irkerd takes the following options, and yes we're going through all of them:
-dβ takes a following value and sets the debugging level from it. possible values are'critical','error','warning','info','debug'. honestly this one is mostly for developers, since these logs are designed to help traceirkerd's internal state. important: these tracing logs are independent of the traffic logs controlled by-l. two different girls, two different log files.
Where do the logs go? To standard error if irkerd is running in the foreground, or to /dev/syslog with facility "daemon" if it's running in the background. And how does it know which? It determines background-ness by comparing the process group id with the process group associated with the terminal attached to stdout (non-matches = background processes). We assume you aren't running irkerd in Windows or another OS that doesn't support os.getpgrp or tcgetpgrp. We also assume that if stdout is attached to a TTY associated with the same process group as irkerd, you do intend to log to stderr and not syslog. assumptions! we're making them! π«Ά
-eβ takes a following filename in pem format and uses it to authenticate to the IRC server. You must be connecting to the IRC server over SSL for this to function properly. this is commonly known as βCertFP.β π-lβ takes a following filename and logs traffic to that file. each log line is made of three|-separated fields: a numeric timestamp in Unix time, the FQDN of the sending server, and the message data. three fields, one line, no crumbs. π-Hβ takes a following hostname and binds to that address when listening for messages.irkerdbinds to localhost by default, but you may want to use your host's public address to listen on a local network.
β οΈ Listening on a public interface is not recommended, as it makes spamming IRC channels very easy. just. don't. π
-nβ takes a following value, setting the nick to be used. if the nick contains a numeric format element (such as%03d), it's used to generate suffixed fallback names in the event of a nick collision. fallback nick, but make it formatted. β¨-pβ takes a following value, setting a nickserv password to be used. if given, this password is shipped to authenticate the nick on receipt of a welcome message.-Pβ likep, but the argument is interpreted as a filename from which to read the password. (yes, that's the original lumping-together of "p", we're keeping it, it's part of the lore.)--sasl-mechanismβ enables SASL authentication and selects the mechanism to use. supported values are βPLAINβ and βEXTERNALβ.
When this option is specified, irkerd performs IRCv3 capability negotiation and attempts SASL authentication during connection setup, before completing registration. And if SASL is enabled, the traditional NickServ βidentifyβ message is not sent. no double-dipping. π
--sasl-usernameβ specifies the username used for SASL authentication. this is typically the account name registered with the IRC network.
This option is required when using the βPLAINβ mechanism. it is ignored for βEXTERNALβ, which uses client TLS certificate authentication instead. EXTERNAL said "I have a certificate, I don't need your username." π
--sasl-passwordβ specifies the password used for SASL authentication.
This option is required when using the βPLAINβ mechanism unless --sasl-password-file is used. the password is transmitted as part of the SASL exchange and is not sent via NickServ.
--sasl-password-fileβ like--sasl-password, but the password is read from the specified file instead of the command line. This is preferred for security reasons to avoid exposing credentials via process listings or shell history. bestie. please. use the file. π-tβ takes a following value, setting the connection timeout for server-socket opens. β³-iβ immediate mode, to be run in foreground. takes a following value interpreted as a channel URL. may take a second argument giving a message string; if the second argument is absent, the message is read from standard input (and may contain newlines). sends the message, then quits. in and out, no lingering. π¦-Vβ write the program version to stdout and terminate.-hβ print usage instructions and terminate.
π LIMITATIONS π
okay so, reality check time. not everything is slay:
Requests via UDP optimize for lowest latency and network load by avoiding TCP connection setup time; the cost is that delivery is not reliable in the face of packet loss. she's fast, she's not guaranteed. π
An irkerd instance with a publicly-accessible request socket could complicate blocking of IRC spam by making it easy for spammers to submit while hiding their IP addresses. the better way to deploy, then, is on places like project-hosting sites where the irkerd socket can be visible from commit-hook code but not exposed to the outside world. and honestly? priming your firewall with blocklists of IP addresses known to spew spam is always a good idea. always. π₯
The absence of any option to set the service port is deliberate. if you think you need to do that, you have a problem better solved at your firewall. periodt. π
IRC has a message length limit of 510 bytes; generate your privmsg attribute values with appropriate care. 510. not 511. watch it. π
IRC ignores any text after an embedded newline. be aware that irkerd will turn payload strings with embedded newlines into multiple IRC sends to avoid having message data discarded. so it's handled, but now you know why your one message became five. π
π And the bug note: Due to a bug in Python URL parsing, IRC urls with both a#and a key part may fail unexpectedly. The workaround is to remove the#.
π SEE ALSO π
irkerhook(1), π
π AUTHOR π
Eric S. Raymond <esr@snark.thyrsus.com>. See the project page at http://www.catb.org/~esr/irker for updates and other resources, including an installable repository hook script. π«Ά
that's the whole page bestie, go ship some notifications π
sign-off: this gem is irker, dated 07/26/2026, and it lives at IRKERD(8) in the Commands manual. mwah. π
π¦ where this page comes from
- arch rolling: irker 2.25-2 Β· BSD-2-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms