Last time, we looked at how one could maintain a persistent session in IRC through the use of a terminal multiplexer (such as screen or tmux) and SSH. While this has the advantage of being very easy to setup, there are a few very obvious disadvantages and trade-offs:
- You must be on a machine that is able to SSH into your remote server.
- You are confined to using the command-line IRC client running in the remote session.
- Any scripts that attempt to interact with your ‘local’ desktop (e.g. Growl notifications), are painful to setup, if not impossible.
For many, including myself, the first two are deal-breakers. I use a variety of computing devices on a daily basis, and asking me to SSH into a remote server from my smartphone to then attach a screen session is not reasonable. Luckily, there does exist a method for establishing a ‘perpetual’ IRC session that does not suffer from any of the disadvantages brought on by the SSH + multiplexer approach.
Bip, The IRC Proxy
Bip is an IRC proxy by Arnaud Cornet and Loïc Gomez, and is released under the GPLv2 license. From their about page:
[Bip keeps you] connected to your preferred IRC servers, can store the logs for you, and even send them back to your IRC client(s) upon connection. You may want to use bip to keep your logfiles (in a unique format and on a unique computer) whatever your client is, when you connect from multiple workstations, or when you simply want to have a playback of what was said while you were away.
Strangely, Bip does not seem to be very well known amongst people I would call "heavy" IRC users, despite it's very lengthy list of useful features and the relatively simple and straightforward setup.
Remote Server Setup
It may be possible to install Bip through a package manager, but we'll go right to building from source to ensure that everyone is on the same page. Feel free to skip this part if you are able to install bip through your distribution's package manager.
Note: You will need to have git
, make
, gcc
, lex
, and yacc
(the latter two are for lexing/parsing the bip configuration file) to compile from source.
$ git clone http://rcs-git.duckcorp.org/projects/bip/bip.git
$ cd bip
$ ./bootstrap
$ ./configure # Use the --prefix option to install somewhere other than /usr/local
$ make && make install
Assuming we have the proper dependencies installed and there were no errors, we should have two binaries — bip
and bipmkpw
— installed in /usr/local/bin/
(or whatever path was specified for the ––prefix option during the configure phase. In case you decided to skip the make install
part of the above instructions, the compiled binaries are available in the src
folder of your bip source directory. Place these binaries in an appropriate location, preferably reachable via $PATH
.
Configuration
Note: Nearly all of this configuration information can be found in the README
file included with bip.
For this configuration file to work, we need to create a directory to store a few things:
$ mkdir -p ~/.bin
Let's start off with the most bare-bones configuration file possible. Create a file named bip.conf
in your $HOME/.bip/
directory with the following contents:
# Remember to change out $HOME for your home directory (e.g. `/home/joel`) below.
ip = "0.0.0.0";
port = 6667;
log_level = 2;
log_root = "$HOME/.bip/logs";
log_sync_interval = 5;
# Network definition, a name and server info
network {
name = "freenode";
server { host = "irc.freenode.net"; port = 6667; };
};
user {
name = "joel";
password = "<password_hash_here>";
default_nick = "jperras";
default_user = "jperras";
default_realname = "Joël";
backlog = true; # enable backlog
backlog_lines = 200; # number of lines in backlog, 0 means
# no limit
backlog_always = false; # backlog even lines already backlogged
backlog_reset_on_talk = false;
backlog_reset_connection = false;
backlog_msg_only = true;
connection {
name = "primary"; # used by bip only
network = "freenode"; # which ircnet to connect to
# Autojoined channels:
channel { name = "#awesome-channel"; };
channel { name = "#secret-channel"; key = "passw0rd"; };
channel { name = "#unimportant"; backlog = false; };
};
};
Alright, let's go through what these options actually do.
ip = "0.0.0.0";
port = 6667;
The ip
string indicates from which IP bip should accept incoming connections, and port
is self-explanatory. By setting it to 0.0.0.0
, bip will accept a connection from any IP, which is most likely what you want. Additionally, restricting incoming connections to certain IP addresses for particular ports is something that can (and should) be pushed to your firewall.
Note: Be sure that you have left an opening in your firewall for connecting to your proxy!
log_level = 2;
log_root = "$HOME/.bip/logs";
log_sync_interval = 5;
A log_level
of 2 indicates that we want to log all errors and warnings, but ignore info and debug messages. The log_root
indicates where logs should be stored, and log_sync_interval
dictates at what time interval the log file is written to disk.
network {
name = "freenode";
server { host = "irc.freenode.net"; port = 6667; };
};
Next, we define a network that we would like to connect to. You can specify an arbitrary name
– I could have just as easily called this network opensource – and the relevant connection information in the server
key.
{
name = "joel";
password = "<some_long_password_hash>";
default_nick = "jperras";
default_user = "jperras";
default_realname = "Joël";
# ...
Here, we define a bip user named “joel” (this name is only used when you connect from your local client to your proxy), and a password. The password that you insert here should be created through the bipmkpw
binary, which will salt & hash an input string to produce the value that needs to be placed in the above user {}
block. The other three options of default_nick
, default_user
, and default_realname
should be self-evident if you have ever used IRC before.
backlog = true;
backlog_lines = 200;
backlog_always = false;
backlog_reset_on_talk = false;
backlog_reset_connection = false;
backlog_msg_only = true;
Now we start getting into the more interesting configuration options for bip. backlog = true
enables backlogging, which means that when your local client (e.g. smartphone, desktop client, web client) reconnects to your proxy, all the messages that have been logged since your last connection will be replayed to you. This is, in my opinion, the best reason to consider using an IRC proxy such as bip; you'll never miss a message, conversation or context again.
backlog_lines = 200
sets an upper limit to the number of messages per channel that will be sent to your client upon reconnection.backlog_always = false
indicates that you don't want to receive backlog messages that you have already seen. By setting this option totrue
, every time you connect a client to your proxy you will receivebacklog_lines
of backlog messages for each channel. If you do enable this option (which comes in handy when you regularly connect via two or more devices), make sure the value forbacklog_lines
is something reasonable.backlog_reset_on_talk
andbacklog_reset_connection
indicate that the backlog marker should be reset every time you talk, scoped to the particular channel or entire connection, respectively.
By setting backlog_msg_only = true
, we only log messages and ignore all IRC events, including joins/parts/quits/nick changes, and the like.
On to the connection definition:
connection {
name = "freenode"; # used by bip only
network = "freenode"; # IRC network
# Autojoined channels:
channel { name = "#awesome-channel"; };
channel { name = "#secret-channel"; key = "passw0rd"; };
channel { name = "#unimportant"; backlog = false; };
};
First, we give a name
to the connection (which will be useful in the following segment), and specify which network
(defined previously) that we wish to connect to.
Finally, we specify the channels that we wish to automatically connect to when first starting up the bip proxy. Note the use of key
for password protected channels, and the backlog = false
usage for channels that we never want to receive a backlog for.
Note that these channels are auto-joined when the bip daemon starts, and not each time your local client connects to the proxy. Once bip has started up and we connect to it, we are free to join/part channels at will, and these will be persisted between client connections.
Starting The Server
Alright, let's start the bip process:
$ /usr/local/bin/bip -f /path/to/bip.conf
Note: If things don't seem to be working as expected, tail'ing the bip log file may yield some clues as to what is going wrong.
The bip process will daemonize itself by default; use the -n
option to have it remain in the foreground, if so desired.
When you start the bip process, it initiates the IRC handshake & dance that normally occurs when you connect a local client to an IRC network. The channels that you defined in the bip configuration file are now connected to and being kept open by bip.
Connecting to the Proxy
Now that we've started the bip proxy on our remote server, let's fire up an IRC client and configure the server connection information.
Examples
I've included a few examples of how the server connection information should look like (given the example bip configuration that I've provided above), in both a GUI-based client as well as a text-based one.
Important: The password that must be used when connecting to your proxy must follow this pattern:
username:unHashedPassword:network
Where the username
portion corresponds to the value of the name
field in the user { }
block in your bip configuration, the unHashedPassword
portion is the un-hashed version of the password that you generated (using bipmkpw
) and pasted in your config, and network
is the name of the IRC network (also defined in your configuration) that you wish to connect to.
An interesting thing to note is that, with this particular scheme, it's quite simple to connect to a different network, or to add a new user to the proxy.
Irssi
servers = (
{
address = "my-proxy-host.com";
chatnet = "Proxy";
port = "7778";
password = "joel:myHashedPassword:freenode";
autoconnect = "yes";
}
Conclusion
And that's it! We are now perpetually connected to IRC, and can connect to our proxy using an unlimited number of devices in a completely transparent and seamless manner. Moreover, the logs for all channels that we are connected to are saved and automatically rotated on our remote server, making for an easy to maintain archive in the absence of another external channel logging mechanism.
Additionally, we can now generate an OpenSSL certificate for our remote server, and configure bip as well as our local clients to communicate with our proxy over a secured connection. This, along with many other features and options that I did not cover, are all documented in the README
and man pages that are installed alongside the bip binary; Please take a look for more information on using bip to it's full potential.