These are some notes on installing a buddycloud server on my webspace. Buddycloud is a program and set of protocols which is aiming to make a better alternative to Facebook, Google plus etc, that uses a federated network of independent servers, instead of the big server farms that the mainstream social networking services use. This should give people more choice about who has access to their data, and hopefully make the people running the servers more careful not to abuse people's trust as Facebook for example has done. See http://buddycloud.com/. Also see this article, which has some background on the idea.
I started by following the install instructions on their wiki. These notes are meant to be read in conjunction with that page. Also, they are by no means complete - I've just put down what seemed to be the important bits that took me a bit of effort to work out.
The webspace I'm using (http://www.webfaction.com) is pretty good, and has ssh/sftp access and a good management system which lets you set up SRV DNS records, which buddycloud needs. The first part of the install, up to building the prosody XMPP server, wasn't too hard. I had to buy a dedicated IP address, and ask webfaction technical support to open a couple of ports for prosody. The rest of it I could do through the control panel.
Webfaction provide a Lua interpreter, which prosody needs, but not any Lua libraries, so I had to install them first. The easiest way to do this turned out to be to use a program called 'LuaRocks', which is a package management program for Lua libraries. You can get this here. You will need to configure the installer to use your account's home directory instead of the standard system directories (use ./configure –prefix=$HOME), and create $HOME/share/lua and $HOME/lib/lua for the installed packages to go in.
The libraries you need before prosody will start are luaexpat, luafilesystem, luasec, and luasocket. You can install these by typing:
luarocks install packagename
This is enough to get prosody to run. I had to create a simple wrapper shell script for prosodyctl (the management program), which sets the Lua path right before calling prosody. This looks like this:
#!/bin/bash # # prosody-wrapper - script to set LUA_PATH and LUA_CPATH right before running prosodyctl. # export LUA_PATH="./?.lua;$HOME/share/lua/5.1/?.lua;$HOME/share/lua/5.1/?/init.lua;$HOME/lib/lua/5.1/?.lua;$HOME/lib/lua/5.1/?/init.lua" export LUA_CPATH="./?.so;$HOME/lib/lua/5.1/?.so;$HOME/lib/lua/5.1/loadall.so" prosodyctl "$@"
I saved this file as prosody-wrapper in my $HOME/bin directory and set execute permissions for my user. Type:
prosody-wrapper start
to start prosody.
Typing:
prosody-wrapper
on its own will give you a list of available commands.
You also need a log file directory for prosody, and a run directory to store the program's PID in - you set these in the prosody config file. I used $HOME/var/log/prosody and $HOME/var/run.
This is enough to get prosody running, and you can test that it's working by telnetting to the relevant ports (see the buddycloud install page). However, at this point prosody doesn't have the right libraries to connect to the database. You can start and stop the server using prosody-wrapper, but not add users for example.
To connect to the database, you need the LuaDBI library. This is not installable through LuaRocks, so you have to download and compile the source. The 0.5 release worked for me, with a slight hack. Having unpacked the tarball into a directory I had created (the tarball doesn't have a top directory), I just had to edit 'dbd/postgresql/dbd_postgresql.h' so that the first few lines look like this:
#include <libpq-fe.h> #include <pgsql/server/postgres_fe.h> #include <dbd/common.h>
This adds a path to the include for postgres_fe.h - without this the compiler can't find it.
Then go to the luadbi directory and type:
make psql
This creates 2 files in the luadbi top level directory: DBI.lua and dbdpostgresql.so. DBI.lua should go in $HOME/share/lua/5.1, and dbdpostgresql.so should go in $HOME/lib/lua/5.1.
Having done all this, prosody was running fine, and I could add users with:
prosody-wrapper adduser user@server
In order to connect to the webclient and channel server, prosody needs to have access to two localhost ports. I set these up by creating 2 'custom app (listening on port)'s in the webfaction control panel. Then I noted the port numbers to use for the bosh and component ports in prosody's config file.
My prosody config looks like this:
modules_enabled = {
"roster"; -- Allow users to have a roster.
"saslauth"; -- Authentication for clients and servers. Recommended if you want to log in.
"tls"; -- Add support for secure TLS on c2s/s2s connections
"dialback"; -- s2s dialback support
"disco"; -- Service discovery
"time"; -- Let others know the time here on this server
"ping"; -- Replies to XMPP pings with pongs
"posix"; -- Do posixy things
"register"; -- Allow users to register on this server using a client and change passwords
"bosh"; -- Enable BOSH clients, aka "Jabber over HTTP"
"watchregistrations"; -- Alert admins of registrations
-- "compression"; -- Enable mod_compression
"legacyauth"; -- Needed by strophe
};
storage = "sql"
sql = { driver = "PostgreSQL"; database = "highfellow_prosody"; username = "highfellow_prosody"; password = "..."; host = "localhost" }
admins = { "admin@highfellow.org" }
pidfile = "/home/highfellow/var/run/prosody/prosody.pid"
bosh_ports = {{ interface = "127.0.0.1";
port = 14048;
path = "http-bind" }
} -- enable bosh connections from a webserver that can reach 127.0.0.1
component_ports = { 56672 }
log = { error = "/home/highfellow/var/log/prosody/prosody.err"; info = "/home/highfellow/var/log/prosody/prosody.log" } -- Change 'info' to 'debug' for more verbose logging
consider_bosh_secure = true
VirtualHost "highfellow.org"
authentication = "internal_hashed"
allow_registration = true
anonymous_login = false
ssl = { key = "/home/highfellow/etc/prosody/certs/highfellow.org.key"; certificate = "/home/highfellow/etc/prosody/certs/highfellow.org.crt" }
VirtualHost "anon.buddycloud.highfellow.org"
authentication = "anonymous"
allow_registration = false
anonymous_login = true
disallow_s2s = true
Component "buddycloud.highfellow.org"
component_secret = "..."
The final thing I had to do with prosody was to replace mod_register.lua in $HOME/lib/prosody/modules with the version from the upcoming 0.9 release of prosody. You can get this here. Right click on the 'raw' link to get the file, then put it in the above directory to replace the existing file. Without this, the web client can't register new users (though you can create users using prosody-wrapper or a standard XMPP client). You can also disable self-registration of new users by setting 'allow_registration = false' under your main virtual host (in my case 'highfellow.org').
The way I set up the web interfaces had to take account of webfaction's way of setting up websites. This has separate entries for 'domains', 'applications', and 'websites'. Domains are normal DNS domains or subdomains; applications are web apps which have an install directory and are usually mounted to a URL path on a 'website', but can also be 'custom apps' which listen on a port on localhost (randomly assigned). Websites link domains with applications, on a particular IP address. I.e. a website is an IP address, a domain, and a set of mount points on that domain for applications you have created. It's a nice system, but I had to figure out for myself how to adapt it to the buddycloud install instructions.
The way I did this was to create 2 applications, one for http ('buddycloud_http_redirect') and one for https ('buddycloud_web'), which were both mounted at ”/” on different websites, (again one for http and one for https), both on the static IP I am paying for.
In the install directory for 'buddycloud_http_redirect', I created a .htaccess file, which looks like this:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
Then I installed buddycloud client to the install directory for the 'buddycloud_web' app, and created a .htaccess file which looked like this:
# all requests other than /web, /public and *.html are redirected to index.html
RewriteEngine On
#RewriteCond %{REQUEST_URI} !^/http-bind/$
RewriteCond %{REQUEST_URI} !^/web/
RewriteCond %{REQUEST_URI} !^/public/
RewriteCond %{REQUEST_URI} !^/config\.js$
RewriteCond %{REQUEST_URI} !^(.*)\.html$
RewriteRule ^(.*)$ /index.html
I also made a custom app to open a port for Prosody to handle BOSH requests (I was given port 14048), and mounted it on a sub-path (/bosh) of the https site. (Proxying is done automatically by Webfaction if you mount a custom app with a localhost port onto a mount point for a domain).
I then installed the web client, following the instructions on the install page. I had to make sure that the web client config matched the config I had set up for prosody and the prosody bosh interface. My config.js for the client looks like:
// export config
window.config = {
bosh_service: 'https://buddycloud.highfellow.org/bosh/http-bind/',
//bosh_service: 'http://bosh.metajack.im:5280/xmpp-httpbind',
home_domain: "buddycloud.highfellow.org",
anon_domain: "anon.buddycloud.highfellow.org",
/* For registration: */
domain: "highfellow.org"
};
This seems to work OK, in that http requests are successfully redirected to https, and the front page of the buddycloud client loads OK at buddycloud.highfellow.org (the domain I assigned to the https website).
I followed the instructions at: https://buddycloud.org/wiki/Build_the_buddycloud_server_yourself. (The pre-built version was incompatible with the libraries on the server I'm using).
I created the database using webfaction's control panel.
The only thing I had to do much differently was to edit 'build-binary.sh' so that it used $HOME for an install prefix, and $HOME/tmp/buddycloud-install for a temporary directory.
Having done this, it built OK, (I'd already installed libicu4 and libssl from their websites while trying to use the prebuilt version.)
My config.js for the buddycloud channel server looks like this:
/**
* XMPP Component connection
*
* change EXAMPLE.COM to match your domain
* jid referrs to your component address. Not a user JID
*/
exports.xmpp = { jid: 'buddycloud.highfellow.org',
password: '...', /* matches the 'component_secret' entry in the prosody config. */
host: 'localhost',
port: 56672 /* matches the 'component_ports' entry in the prosody config. */
};
/**
* PostgreSQL backend
*/
exports.modelBackend = 'postgres';
exports.modelConfig = {
host: 'localhost',
port: 5432,
database: 'highfellow_buddycloud',
user: 'highfellow_buddycloud',
password: '...',
poolSize: 4
};
/**
* Logging
*/
exports.logging = {
colorized: true,
/**
* one of "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"
*/
level: "INFO",
/* stdout: true, */
syslog: {
/* hostname: "orwell.local", port: 514 */
},
file: "/home/highfellow/var/log/buddycloud-server.log"
};
I created another init style wrapper script to start and stop the buddycloud server. This looks like this:
#!/bin/bash
#
# buddycloud-init - wrapper script to start buddycloud
#
PROG_NAME=buddycloud-server
PROG_PATH=$HOME/bin/$PROG_NAME
PID_PATH=$HOME/var/run/${PROG_NAME}.pid
prog='Buddycloud Server'
export LD_LIBRARY_PATH=/$HOME/lib:/lib:/usr/lib:/usr/local/lib
export PATH=$HOME/bin/:$PATH
start() {
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 1
echo -n "Starting $prog: "
nohup $PROG_PATH < /dev/null >/dev/null 2>&1 &
RETVAL=$?
echo $! > $PID_PATH
return $RETVAL
}
stop() {
echo -n "Shutting down $prog: "
kill `cat $PID_PATH`
RETVAL=$?
return $RETVAL
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
stop
start
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|status}"
RETVAL=3
esac
if [ $RETVAL==0 ] ; then
echo OK
else
echo FAILED
fi
exit $RETVAL
I put this in $HOME/bin as 'buddycloud-init', and made it executable by me. I could then start and stop the server by doing:
[highfellow@web225 bin]$ buddycloud-init start Starting Buddycloud Server: OK [highfellow@web225 bin]$ buddycloud-init stop Shutting down Buddycloud Server: OK
Having set all this up, I could then register and log in to a buddycloud account (andy@highfellow.org) on my new server (buddycloud.highfellow.org). I'm pleased to say that it works OK (including cross-server posting), and looks really promising. I'm looking forward to seeing what I can do with it, and maybe contributing a bit of code when I get the time and energy.