Tutorial - Using Fail2ban with Prosody to limit login attempts

For this tutorial, I’m starting from a clean install of the jitsi-meet package on Ubuntu 20.04 with default nginx.

For those that don’t know, Fail2ban monitors logs for IP addresses with failed access attempts and blocks potential attackers. We can point Fail2ban towards Prosody logs, but prosody doesn’t natively associate attempts with IP addresses. There’s also a proxy involved which causes the original client’s IP to get lost in translation. So, there’s a bit of work before fail2ban cab be used under the default jitsi/nginx environment .

1. Install extra Prosody modules

Note – you could just clone the log_auth module if that’s all you want, but I find it a nice bonus to grab all extra modules so I can test new ones occasionally and they don’t take up much space.

• Install mercurial

sudo apt install mercurial

• navigate to : /usr/lib > run the following:
new directories added called prosody-extra/prosody-modules

sudo hg clone https://hg.prosody.im/prosody-modules/ prosody-extra/prosody-modules

• Create symlinks for the modules you wish to use

sudo ln -s /usr/lib/prosody-extra/prosody-modules/mod_log_auth /usr/lib/prosody/modules

2. Enable log_auth module

• edit /etc/prosody/conf.avail/your.domain.cfg.lua , adding the new module location

plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/", "/usr/local/lib/prosody-extra/prosody-modules" }

• Next, look for “modules_enabled” in the same file and add the following:

"log_auth"; -- Enables logging of the IP address in a failed authentication attempt.

• Restart prosody

sudo systemctl restart prosody

At this point, IP addresses will be logged upon failed login attempts. We’ll need this for fail2ban to operate properly.

However, installing jitsi-meet doesn’t configure nginx to properly pass the client IP. The result is all clients show as the local host “”. To resolve this, continue on to step 3.

3. Configure NGINX to pass proxied IP

  • /etc/nginx/nginx.conf > add the following line:
log_format proxycombined '$proxy_protocol_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"';
  • /etc/nginx/modules-enabled/60-jitsi-meet.conf, add the following line to the server {} stanza:
proxy_protocol on;
  • /etc/nginx/sites-enabled/your.domain.conf, edit the first 4 lines of the server stanza for port444 as follows:
server {
    listen 4444 ssl http2 proxy_protocol;
    listen [::]:4444 ssl http2 proxy_protocol;
    server_name Your.Domain.Here;
    access_log /var/log/nginx/access.log proxycombined;
  • Lastly, edit the BOSH location in the same file, replacing $remote_addr replaced with $proxy_protocol_addr
    # BOSH
    location = /http-bind {
       proxy_set_header Host $http_host;
       proxy_set_header X-Forwarded-For $proxy_protocol_addr;
       proxy_pass http://localhost:5280/http-bind;

• After this , prosody will receive the actual client IP instead of the local host.
viewable at /var/log/prosody/prosody.log

4. Install fail2ban

sudo apt-get install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
  • Find “ignoreip =” and add any trusted Ips to this list so you don’t lock yourself out. If an SSH jail is enabled, this could be very bad, always add at least 1 IP you can use to fall back on.

  • Add the following under the jails section (end of file):

enabled = true
iptables-multiport[name="prosody", port="443,5222,5269"]
port    = 443,5222,5269
filter  = prosody-auth
logpath = /var/log/prosody/prosody*.log
maxretry = 3
bantime = -1s
findtime = 5m

You may change maxretry, bantime, and findtime to suit your needs. In my example, if an attacker exceeds 3 attempts in 5 minutes, then they’re banned forever (Negative bantime).

  • Create /etc/fail2ban/filter.d/prosody-auth.conf with the following contents:
failregex = Failed authentication attempt \(not-authorized\) for user .* from IP: <HOST>
ignoreregex =
  • Restart fail2ban
sudo service fail2ban restart
  • Useful commands

view jail status for Prosody

sudo fail2ban-client status prosody

Unban an ip, replace with the ip to unban

sudo fail2ban-client set prosody unbanip

view fail2ban log in realtime while testing

sudo tail -f /var/log/fail2ban.log

@Craig_Eustice Wow, what a great tutorial! :clap: :clap:

I would like to see this (and also other tutorials) integrated with Handbook: https://github.com/jitsi/handbook/ and make them officially available, in order to let those linked from this community. It would be very unfortunate to see this kind of tutorials be buried in the history of this community… :frowning:


@saghul @damencho @emcho what do you guys think about :point_up: ?

These too:

Some review would be needed, specially for older content.

For now I am tagging with “tutorial”, perhaps a link to that tag form the docs would be enough.

Could you summarize what problem is solved with this tutorial ? I know about all the components mentiones, just not sure what the use case is here.

Hi @MagicFab,
Use case is security, specifically threat mitigation. Simple authentication is vulnerable, this Tutorial adds an extra layer of security.

Essentially, any service that is exposed to the internet is susceptible to attacks from malicious parties. If your service requires authentication, illegitimate users and bots will attempt to break into your system by repeatedly trying to authenticate using different credentials.

Automated bot attacks that attempt to brute force credentials are common and can run through thousands of permutations per second. Luckily, services like fail2ban were created to help mitigate these attacks by slowing down or even banning malicious entities.

As I mentioned I know what fail2ban does.
Did you mean “moderator” / first-participant authentication ? Adding a short sentence to that effect at the start of the turorial / title would be very helpful and help find it easily.

It’s any and all authentication attempts. I think people searching for fail2ban understand that, but I made the title more specific, Thanks for the feedback :slight_smile:

1 Like

thanks for the write up,

I am seeing some errors with my installation here:

  • there is no 60-jitsi-meet.conf file in my standard isntallation on Ubuntu 18.04 (Following official isntall instructions),
  • placing the log_format directive in that conf file brings up an nginx config error stating that I am not allowed to place that statement in that config file.

unfortunately it is not that easy to find information on how to adopt these settings in my environment

Hi, So that’s an issue if you’re running a fresh Jitsi install and the file is missing. My example was Ubuntu 20.04, but I just spun up a VM with Ubuntu 18.04 / updated all packages and I have the 60-jitsi-meet.conf file.

I found one post that shows someone’s update removed it for whatever reason and resulted in issues-

Updated Ubuntu 18.04 /etc/nginx/modules-enabled/60-jitsi-meet.conf was removed and JWT issue


Sorry guys for reviving this topic after such long time.

Is there no file 60-jitsi-meet.conf because of this websockets configuration? :

and what about logging IP addresses in prosody log with websockets configured, is it same steps You described in tutorial ?

I’m curios why to use as plugin path : “/usr/local/lib/prosody-extra/prosody-modules”
but previously You linking /usr/lib/prosody-extra/prosody-modules/mod_log_auth to /usr/lib/prosody/modules.
The plugin path in prosody config shouldn’t be just /usr/lib/prosody/modules ?

Thanks and regards.

In this implementation, will Fail2ban catch only unsuccessful attempts to authenticate users to create conferences?

Will incorrect PIN code conclusions for access to an existing conference be blocked?