The last week, our company organized their annual internal education conference where we reside at a conference hotel and learn from each other with talks, workshops, and so on. For entertainment, I wanted to set up Pixelflut (English: Pixelflood), an application where participants can send single pixels via a network to a publicly viewable projector. Here is how I bypassed some restrictions of the hotel network.
First of all - what is Pixelflut? It is a quite simple protocol to send single pixels to a projector. It was nice to see how participants figured out a lot of ways to send whole images to Pixelflut - someone even managed to animate a DVD logo bouncing off the edges of the screen!
You can learn the basic protocol by sending HELP
to Pixelflut:
$ echo "HELP" | nc domain.tld 1337
HELP Commands:
HELP SIZE
HELP PX <x> <y>
HELP PX <x> <y> <rrggbb[aa]>
Just plugging a computer running Pixelflut into a power outlet and connecting it to the projector and the hotel network would have been simple. But inside this network, there are no static IP addresses. And I did not want to bother hotel staff with a request for a static hostname. So - how to make Pixelflut accessible by a unique hostname in the hotel network?
With my personal server setup, I am already using SSH tunnels. SSH is a quite powerful, yet simple, protocol to securely connect machines in the internet.
The first part - the name - is quite simple. I already operate a few servers with some domains. So I created a DNS entry like pixelflut.domain.tld and pointed a CNAME record to one of my servers.
But how to get traffic from my server to the local Pixelflut installation? I mean - the hotel surely has a firewall in place? Luckily, SSH offers the benefit of TCP port forwarding. With remote port forwarding, a local SSH client can offer one of its local ports to a remote server. And as a bonus, it can even expose the remote port on the server publicly.
To protect this setup in terms of security - I didn’t want to leave an SSH private key to my server on an unlocked and unattended notebook - I created a new user on the server:
$ sudo useradd pixelflut
I created a new SSH keypair, of which I added the public key to the new user’s home directory.
In the server’s /etc/ssh/sshd_config
, I added the following lines to restrict the SSH user to only allow forwarding of the TCP port 1337:
Match User pixelflut
ClientAliveInterval 60
ClientAliveCountMax 10
AllowTcpForwarding yes
GatewayPorts yes
X11Forwarding no
AllowAgentForwarding no
PermitOpen localhost:1337
ForceCommand echo 'This account can only be used for pixelflut.'
A little modification is also needed on the client side SSH config in order to keep the tunnel open reliably:
ServerAliveInterval 60
ServerAliveCountMax 10
Of course, we would need to open port 1337 in the server’s UFW firewall:
$ sudo ufw allow 1337/tcp
Now I can start Pixelflut on the notebook connected to the projector:
$ java -jar pixelwar-0.0.1-SNAPSHOT-jar-with-dependencies.jar
I am actually using the Pixelwar application here, as it served the best compatibility for current systems. Pixelwar will listen on the local TCP port 8080.
After that, I open the SSH tunnel from the Pixelflut notebook:
$ ssh -N -R 1337:localhost:8080 -i id_ed25519_pixelflut pixelflut@domain.tld
And that’s it! Pixelflut was available via pixelflut.domain.tld the entire two and a half days at the hotel. And it was very well received! The article image at the top is one of the created images.