chat

chat (name tbd) is a decentralized cross-platform chat application written in Java. You can obtain a recent release of the software from the automated CI builds here.

It is licensed under the GNU Affero General Public License (AGPL) which requires derivative works running over a network to release their source code. In other words, if you run a modified version of the chat server on your server, you must release the source under a compatible license.

The source code is available on sourcehut.

Usage

Download a recent client binary from the CI here and launch the jar. On windows, just double click it. On linux, run it with java -jar client.jar. Make sure your java version is at least 8/1.8.

You can register an account on the chat.swisschili.sh server. If you choose a username that is already registered, you will receive a cryptic error (some UNKNOWN gRPC popup window).

If your messages fail to send, check the client logs (stderr). If there is something related to encryption keys, log out and try logging back in or registering for a new account. This happens because the encryption the server is using has been updated, but your client is still using old keys.

Building from source

Gradle will handle almost everything for you, including downloading all dependencies and building a everything-included (“fat”) jar. To build the client jar run the following command in the root of the chat source code:

./gradlew client:shadowJar # only build the client
./gradlew server:shadowJar # only build the server
./gradlew shadowJar # build everything

I have not attempted to build from a windows host but the process should be very similar.

The binaries built by the automatic CI system are compiled with Java version 8. The code is forward compatible (Has been tested to work with 15), but the binaries later compilers produce will not be backwards compatible. For this reason, building with the oldest supported version (8) is recommended.

Hosting a server

The following examples will apply specifically to Debian, but similar steps should work on all Linux distributions.

In order to host a chat server you need the following dependencies:

  • Java version 8 or higher
  • RabbitMQ
  • MongoDB

Installing dependencies

Java

Install OpenJDK version 8 or later either from https://adoptopenjdk.net/ or from the Debian package. Version 8 is not included in the default Debian repositories, so use version 11 instead:

apt install openjdk-11-jre # replace jre with jdk if you plan on building from source

MongoDB

Next install MongoDB from the instructions provided here.

You will need to create a MongoDB user for the chat server. Start the mongo shell and run the following command to create a user, replace password with a secure password.

use chat
db.createUser({
  user: "chatServer",
  pwd: "password",
  roles: [
    { role: "readWrite", db: "chat" }
  ]
})

If all goes well mongo should say that the user was added successfully. else goto troubleshooting;.

RabbitMQ

Install RabbitMQ from the rabbitmq-server package:

apt install rabbitmq-server

Once installed, start the rabbitmq-server systemd service and you should be good to go.

Running the Server

Once you have the dependencies installed and the server jar on your server, it is time to run it. The only required argument is the MongoDB connection URL:

java -version # verify that it is 1.8 or later
java -jar server.jar -d mongodb://chatServer:password@localhost/chat

The MongoDB connection url is in the format of mongodb://user:password@host/database. Consult the manual for details.

If you would like to run this server in the background (once you exit your ssh session) you can do one of two things:

  1. Create a systemd service/unit file. This is easy but beyond the scope of this wiki

  2. Just use nohup: nohup java -jar server.jar whatever & will keep running after your ssh session ends, and write all logs to nohup.log.

Securing the server

Most of these steps are basic and apply to most server side applications in general, but they are good to mention:

  1. Run everything as the least possible privilege. In other words, do not run your server as root. In the unlikely event that the chat server itself is compromised you want the impact to be as minimal as possible.

  2. Use a firewall to block all services that do not need to be publicly accessible. In this case make sure to only allow ports you need (such as ssh, http) and port 4776, used by the chat server. Make sure your database and RabbitMQ server are not accessible. ufw is a good and easy to use firewall, included by default on Ubuntu. I would highly recommend it over the obtuse iptables.

  3. Make sure password authentication is disabled on your server. Look up how to do this if you are unsure. Always use key-based authentication when possible.

Troubleshooting

Check the server logs for errors! MongoDB will give you a descriptive error if your authentication is incorrect. If you get an error saying something along the lines of Connection refused that most likely means RabbitMQ is not running.

If you fail to run some operation in the mongo shell make sure you have sufficient privileges to do so. Consult the mongo manual when in doubt.