Limit Jitsi rooms with nginx

One of the best things about Jitsi is in my opinion also one of the worst things of it. It doesn’t need any preconfigured users and anybody can create new rooms.

With a bit of tweaking the nginx config, we can define allowed room-names and deny all others. That way you as admin can quickly shuffle around the allowed rooms or just leave one permanently allowed for quickly meet your friends.

Sure, this is quite a weak security measure, as anybody can enter the allowed rooms, but it is certainly better than letting anybody who knows your FQDN to create rooms as they desire.

The following config-block should be within the server{} declaration.
We allow two rooms in this example – roomone and roomtwo.
You will also need to replace YOUR.FQDN with the actual path to your config.js…

index index.html index.htm;
error_page 404 /static/404.html;

location = /config.js {
       alias /etc/jitsi/meet/;

location = /external_api.js {
       alias /usr/share/jitsi-meet/libs/external_api.min.js;

location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$
       add_header ‘Access-Control-Allow-Origin’ ‘*’;
       alias /usr/share/jitsi-meet/$1/$2;

location = /http-bind {
       proxy_pass      http://localhost:5280/http-bind;
       proxy_set_header X-Forwarded-For $remote_addr;
       proxy_set_header Host $http_host;

# xmpp websockets
location = /xmpp-websocket {
       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection “upgrade”;
       proxy_set_header Host $http_host;
       tcp_nodelay on;

location ~ ^/roomone {
       try_files $uri @root_path;
location ~ ^/roomtwo {
       try_files $uri @root_path;

location @root_path {
       rewrite ^/(.*)$ / break;

location ~ ^/([^/?&:'”]+)/config.js$
      set $subdomain “$1.”;
      set $subdir “$1/”;
   alias /etc/jitsi/meet/YOUR.FQDN-config.js;
location ~ ^/([^/?&:'”]+)/http-bind {
       set $subdomain “$1.”;
       set $subdir “$1/”;
       set $prefix “$1”;
       rewrite ^/(.*)$ /http-bind;

# websockets for subdomains
location ~ ^/([^/?&:'”]+)/xmpp-websocket {
       set $subdomain “$1.”;
       set $subdir “$1/”;
       set $prefix “$1”;
       rewrite ^/(.*)$ /xmpp-websocket;

PyKMIP as vcenter KSM server

There are multiple reasons why somebody would like to have a KSM server.
This article explains how to set up such a server with persistent database storage, so that an encrypted vm survives a complete (vcenter/esxi) reboot.
Although it works, it is certainly not recommended to do it this way in large environments.
But nevertheless, it’s a cheap way to get a vtpm.
Remark: After a reboot of vcenter, the trust seems still intact, but does not work anymore! In that case, just remove the KMS cluster-definition and re-add and trust it. After that you should be able to unlock encrypted VMs again.

I did this with an minimal Ubuntu server 18.04.1 64bit install. The service runs as the admin user (sudoer, not root). You might want to change that to even a less privileges user and probably setup iptables or other means to protect the TPM data! It is an sqlite db, so anybody with file-access could steal and read it! This tutorial also uses a self-signed certificate. If you have a PKI, it would certainly be better to use properly signed and managed ssl certs…
You have been warned! 😉

<$username> should get replaced with the actual username.
Commands in green should be executed as user.
Commands in red should get executed as root.
The switch between the two are the sudo and exit commands.

Login as user to the ubuntu machine.
sudo -i
apt-get update
apt-get upgrade
mkdir /usr/local/PyKMIP
mkdir /etc/pykmip
mkdir /var/log/pykmip
chown <$username>: -R /usr/local/PyKMIP
chown <$username>: -R /etc/pykmip
chown <$username>: -R /var/log/pykmip
apt -get installpython-dev libffi-dev libssl-dev libsqlite3-dev python-setuptools python-requests
openssl req -x509 -nodes -days 9999 -newkey rsa:2048 -keyout /etc/ssl/private/selfsigned.key -out /etc/ssl/certs/selfsigned.crt

Fill out the form…

chown <$username>: -R /etc/ssl/private

chown <$username>: /etc/ssl/certs/selfsigned.crt
cd /usr/local

If you need to use a proxy, then replace X.X.X.X with the ip of the proxy and PORT with the port your proxy server is available. You might also add “yourproxyusername:yourproxypassword@” directly in front of the ip, if your proxy requires authentication. We will need this one more time later on, so keep them in mind.
If you don’t need any proxy, the you can leave the following two commands out.

export https_proxy=http://X.X.X.X:PORT
export http_proxy=http://X.X.X.X:PORT

cd /usr/local
git clone

sudo -i

Again, the Proxy, but this time as root.

export https_proxy=http://X.X.X.X:PORT
export http_proxy=http://X.X.X.X:PORT

cd /usr/local/PyKMIP
python install
nano /etc/pykmip/server.conf

Enter these following lines between the — signs (but without them) in the nano editor.
Replace hostname=10.X.X.X with the servers IP.
Quit with ctrl-x followed by y and enter


We should now be ready to start the service!

cd /usr/local/PyKMIP
python bin/

Now you should be able to add the host as KSM server in vcenter with the ip and port 5696.

To make the connection complete, you need to press the “Make KMS trust vcenter” button.
Choose “KMS certificate and private key”
Open a new shell to the ubuntu server
cat /etc/ssl/certs/selfsigned.crt
copy the whole output inclusive the —begin and end — messages and paste it to the first field “KMS Certificate” in vcenter
cat /etc/ssl/private/selfsigned.key
copy the whole output inclusive the —begin and end — messages and paste it to the second field “KMS Private Key” in vcenter

Press the “Establish Trust” button.

To let the service start on every boot, you can add it to the crontab.

crontab -e

Add the following line. and save the file.

@reboot ( sleep 30s; python /usr/local/PyKMIP/bin/run_server & )

Icinga2 using default check_snmp for diskspace

To not have to install or even write plugins for simple things like the remaining diskspace of the root partition on a remote server, one can simply use the default check_snmp plugin from nagios. Just create your command in commands.conf like this (remember to replace -C with your snmp community string) :

object CheckCommand “snmpdisk” {
command = [ PluginDir + “/check_snmp” ]
arguments = {
“-H” = “$address$”
“-C” = “snmpcommunityofremoteservers”
“-o” = “UCD-SNMP-MIB::dskAvail.1”
“-w” = “$host.vars.d1w$”
“-c” = “$host.vars.d1c$”

Then in services.conf:

apply Service “disk” {
import “generic-service”
check_command = “snmpdisk”
assign where host.vars.htype == “snmp”

And then we can add the following to the host definition for a warning below 200gb and critical state below 100gb. These values could also be added to the command directly, but it’s probably easier to handle if we keep it a definition per host.:

vars.htype = “snmp”
vars.d1w = “200000000:100000000”
vars.d1c = “100000000:0”


Veröffentlicht unter linux

Guacamole autologin

After updating my guacamole installation to 0.6.2 and struggling for some time to get the autologin to work again, I decided it’s time for some little instructions (mainly for my future self 🙂 )
—-Update 6.12.12— added instructions for guacamole-0.7.0

Here we go:

#euse –enable cgi vnc
#emerge tomcat guacamole php
#/etc/init.d/tomcat start
#/etc/init.d/guacd start

make guacamole itself work via tomcat and test it…

Now it gets tricky… make php work within the guacamole application.

Download the javabridge from here
Place the .war file in the webapps folder and access it once via http. This will unpack its content and one can pick the three jar files from WEB-INF/lib and copy them over to the guacamole’s WEB-INF/lib. Also copy the whole cgi folder over to the guacamole directory. In it, I had to place a link to the php-cgi binary.
ln -sf /usr/bin/php-cgi /var/lib/tomcat-7/webapps/guacamole/WEB-INF/cgi/i386-linux/php-cgi
Next place the following lines in the guacamole’s web.xml under <web-app>

<servlet-mapping><servlet-name>PhpJavaServlet</servlet-name><url-pattern>*.phpjavabridge</url-pattern> </servlet-mapping>

After the guacamole-folder gets renamed/copied or somehow else redestributed to tomcat, php should be available within the container!

Next we need to modify the index to autologin…
copy index.xhtml to index.php and remove the xml header and place something like this in it to catch the delivered user credentials.

if (isset($_REQUEST[username])){
if (isset($_REQUEST[password])){

Add the following function in index.php right before root-ui.js gets loaded:

<script type=”text/javascript”>
window.onload = function() {

var data =
“username=<?php echo $username ?>”
+ “&password=<?php echo $password ?>”

// Log in
var xhr = new XMLHttpRequest();“POST”, “login”, false);
xhr.setRequestHeader(“Content-type”, “application/x-www-form-urlencoded”);

//This php part is for the redirect. if you don’t like it, leave it away…
if (isset($_REQUEST[id])){
echo “window.location = ‘client.xhtml?id=$startvnc’;”;

// Handle failures
if (xhr.status != 200)
throw new Error(“Invalid login”);


Guacamole-0.6.2: Then add the following function just below the complete loginForm.onsubmit funtion (it is a slightly modified version of it which gets executed at loadtime and holds the credendtials captured above.)

window.onload = function() {

// Get parameters from query string
var parameters =;

// Get username and password from form
var data =
“username=<?php echo $username ?>”
+ “&password=<?php echo $password ?>”

// Include query parameters in submission data
if (parameters) data += “&” + parameters;

try {

// Log in
var xhr = new XMLHttpRequest();“POST”, “login”, false);
xhr.setRequestHeader(“Content-type”, “application/x-www-form-urlencoded”);

// Handle failures
if (xhr.status != 200)
throw new Error(“Invalid login”);

// Ensure username/password fiels are blurred after submit



catch (e) {

var loginError = document.getElementById(“login-error”);

// Display error, reset and refocus password field
loginError.textContent = e.message;
password.value = “”;

return false;


// On success, hide loginUI, get and show connection list.
return false;


// On success, hide loginUI, get and show connection list.
return false;


If you also like to get automatically directed to a specific connection, then you should add the following to the index.php, directly before comment that says “// Remove all rows from connections list”:

if (isset($_REQUEST[id])){
echo “window.location = ‘client.xhtml?id=$startvnc’;”;

Now you should be able to use a form somewhere with username and password field (maybe as type=hidden, behind a simple “vnc” button) and the guacamole index.php as action=.

Have fun! 🙂

kvm ifup on convirt

Some time ago a Kernel change broke a qemu-kvm feature known as ifup script.

I came across this while i was installing convirt (a nice web management tool for not only kvm). New VMs with bridged ethernet just wouldnt start and spit out an error like:

could not configure /dev/net/tun (tap%d): Operation not permitted

A few google searches later i tried the suggestion over linux capabilities (libcap2), but that did not worked for me. Also running the VMs as root was not an option!

Luckily, /usr/sbin/kvm is just a symlink on gentoo, so i made a little wrapper-script for creating the tap interfaces on demand!

Be aware that your ifup-script might be called different, if youre not using convirt! I also had to set the suid bit on brctl as well as tunctl!


NEWTAP=`tunctl -u convirt | cut -d “‘” -f 2`
/sbin/brctl addif br0 $NEWTAP

for PARAM in $@; do
if `echo $PARAM | grep -q “qemu-ifup-br0″ `; then
NEWPARAM=`echo $PARAM | sed ‘s//etc/kvm/qemu-ifup-br0/no,ifname=’$NEWTAP’/g’`

/usr/bin/qemu-kvm $PARAMSTRING

Wenn ein Port zurückschlägt

Wer kennt das nicht: Ein in die Jahre gekommener Server sollte abgelöst oder abgeschaltet werden, jedoch weiss man nicht genau, ob noch jemand auf die betriebenen Serverdienste zugreifft oder nicht.
Natürlich kann man anhand der Logs versuchen herauszufinden obs überhaupt noch genutzt wird und allenfalls auch von wem und woher… Doch nicht immer sind diese Infos auch wirklich hilfreich, da allenfalls über ein VPN verbunden wurde oder der gesuchte Rechner bereits wieder abgestellt wurde!
Wenn man jedoch weiss, was der Dienst genau macht und wie man diesen Clientseitig allenfalls auf einen neuen Server umstellt, dann steht einer automatischen Umstellung eigentlich nicht viel im Wege! 🙂

-Man nehme einen Linux-Server im gleichen Subnet wie der Alte Server.
-Man installiert sich xinetd
-Falls es sich um Windows-clients handelt, ist wohl auf das Tool winexec auf dem Server nicht zu verzichten.
-Man baut sich ein client-script, dass die gewünschten Änderungen auf dem Client-Rechner vornimmt.
-Man baut sich ein Server-script, dass das Client-script ausführt. (Hier kann man vorzugsweise via ssh connecten oder halt via winexec.) <-Xinetd füllt freundlicherweise die System-Variable $REMOTE_HOST mit der IP des zugreiffenden Clients!!
-Nun konfiguriert man xinetd…
Dazu in /etc/xinetd.conf die “only_from” zeile auf ändern, damit Verbindungen von überall her angenommen werden. Für den eigentlichen Dienst habe ich einfach die rsh-config genommen und mir ein /etc/xinetd.d/madservice erstellt mit folgendem inhalt:

service madservice
socket_type     = stream
protocol        = tcp
wait            = no
user            = root
server          = /tmp/mad-service
log_on_failure  = USERID ATTEMPT
disable         = no

-Damit xinetd den Port kennt, auf den wir uns binden möchten, müssen wir diesen noch in /etc/services hinterlegen! (bspw: echo 12345 madservice >>/etc/services)
-Als nächstes zieht man dem alten Server den Stecker, bindet die ip als Alias auf dem Linux-Server (bspw: ifconfig eth0:0 netmask
-Xinetd starten und geniessen! 🙂

Windows Poweruser

Ich habe mich ja schon ein paarmal gefragt wie man mit ldap bloss so schlimme Sachen machen kann wie es MS im active directory getan hat. Aber hier mal was aus der funny facepalm Ecke.

~ # ldapsearch -D “CN=XXX,OU=XX,OU=ServiceAccounts,DC=XX,DC=XXX,DC=XX” -b “OU=XX,OU=XXUsers,DC=XX,DC=XXX,DC=XX” -W samaccountname=myuser | grep logonCount

logonCount: 65535

Tja… Ich hätte ja dieses feld mindestens 64 bit gross gemacht! 😉

Hello World

This is my brand new blog.

Even if I don’t think that I have very useful things to tell, I’ll try to collect my older posts and place them here… Please don’t blame me if they are terribly outdated and do not work for you or even kill some kittens or something like that!

I do not intend to write everything in multiple languages… So if you can’t get it what I wrote, please use a friendly search engine and or its babel service! 😉

After all, have fun!