ADUFRAY

Tired of the proprietary, outdated Ventrilo platform for in-game voice services? Me too. Thankfully, now there’s Mumble, an open source, encrypted, cross-platform, low-latency voice chat system. I’ve only been messing around with it for a short time, but so far it’s a huge improvement over Ventrilo and TeamSpeak.

Initially I became frustrated, because the server software, aka “Murmur”, is significantly less friendly. The installation instructions for CentOS were garbage. There’s no EPEL package, much less a base-system package, you have to install someone’s Dropbox-hosted RPMs, a middleware repo, and one of the dependencies is Qt. Obviously the Qt dependency is for the client aspect, but still: gross. No instructions for a non-X11 version.

Thankfully, as a I mentioned, it’s open source. I found a nifty minimalistic server implementation called uMurmur. It’s designed to run on small embedded systems, so it’s very light-weight. It seems to have been built around OpenWRT, the open source router OS. Assuming you already have gcc, autoconf, and make installed, I think the only other requirements are libconfig, protobuf-c, and OpenSSL (or PolarSSL). The whole setup was pretty easy:

# yum install -y libconfig{,-devel} protobuf-c{,-devel}
# curl -O 'https://umurmur.googlecode.com/files/umurmur-0.2.14.tar.gz'
# tar -zxvf umurmur-0.2.14.tar.gz
# cd umurmur-0.2.14
# ./configure --with-ssl=openssl
# make && make install

The Makefile installs a single binary to /usr/local/bin, but no init script or default configuration. Here’s a quick init script I created (it’s sloppy, but it works):

/etc/init.d/umurmurd:

# umurmurd  Minimal Mumble server
#
# chkconfig: 345 20 80
# description: umurmurd is a minimal Mumble server
# processname: umurmurd

# Source function library.
. /etc/init.d/functions

RETVAL=0
prog="umurmurd"
PIDFILE="/var/run/umurmurd.pid"
LOCKFILE="/var/lock/subsys/umurmurd"

start() {
        echo -n "Starting $prog: "
        /usr/local/bin/umurmurd -r -p $PIDFILE
        RETVAL=$?
        [ $RETVAL -eq 0 ] && touch $LOCKFILE && success || failure
        echo
        return $RETVAL
}

stop() {
        echo -n "Shutting down $prog: "
        kill $(cat "$PIDFILE") 2>/dev/null >/dev/null && success || failure
        RETVAL=$?
        [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
        echo
        return $RETVAL
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
    if [ -f "$PIDFILE" ]; then
          echo -n "PIDFILE exists:";
          ps -p ${PIDFILE}
        else
          echo "not running";
        fi
        ;;
    restart)
        stop
        start
        ;;
    *)
        echo "Usage: $prog {start|stop|status|restart"
        exit 1
        ;;
esac
exit $?

And a very basic config file:

/etc/umurmur.conf:

max_bandwidth = 128000;
welcometext = "Welcome to Murmur!";
certificate = "/etc/pki/tls/certs/umurmur.crt";
private_key = "/etc/pki/tls/private/umurmur.key";
#password = "password_for_users";
admin_password = "admin_password";   # Set to enable admin functionality.
ban_length = 3600;            # Length in seconds for a ban. Default is 0. 0 = forever.
enable_ban = true;        # Default is false
max_users = 20;

# bindport = 64738;
# bindaddr = "192.168.1.1";

channels = ( {
    name = "Root";
    parent = "";
    description = "Root channel. No entry.";
    noenter = true;
  },
  {
    name = "Lobby";
    parent = "Root";
    description = "Lobby channel";
  },
  {
    name = "Silent";
    parent = "Root";
    description = "Silent channel";
    silent = true; # Optional. Default is false
  }
);

default_channel = "Lobby";

Before you exit your terminal, make sure to perform these last few steps:

# openssl genrsa -out /etc/pki/tls/private/umurmur.key 4096
# openssl req -new -x509 -nodes -sha1 -days 3650 -key /etc/pki/tls/private/umumur.key -out /etc/pki/tls/certs/umurmur.crt
# chkconfig --add umurmurd
# chkconfig umurmurd on
# service umurmurd start

And, if you’re running iptables, don’t forget to add the appropriate rules.

# iptables -I INPUT 1 -m state --state NEW -m tcp -p tcp --dport 64738 -j ACCEPT
# iptables -I INPUT 1 -m state --state NEW -m udp -p udp --dport 64738 -j ACCEPT
# service iptables save