Restrict Passbolt access by IP but allow letsencrypt challenge

I’m not extremely familiar with NGINX. Is there a way to limit my passbolt installation (currently on a popular provider like Digital Ocean or Linode) by IP but allow LetsEncrypt challenge requests through for renewal? Basically I want to limit the installation to only people on the VPN network, but still renew SSL certificates for the installation.

I’m on the community version. Thanks for your help!

p.s. this could be a feature request.

Hi @d00 Welcome to the forum!

NGINX does have directives of allow and deny which can be used with ip addresses in server blocks.

Like:

allow 10.0.0.1;
allow 192.168.1.0/24;
deny all;

The addresses could be private or public and can be ranges.

With Let’s Encrypt, their FAQ says:

What IP addresses does Let’s Encrypt use to validate my web server?

We don’t publish a list of IP addresses we use to validate, and these IP addresses may change at any time. Note that we now validate from multiple IP addresses.

So, without knowing what ip address to allow, there are a handful of approaches that fall into these three categories:

  1. manually update certs by creating token string to paste into dns record so LE can verify (but this is burdensome and prone to forgetting about it)
  2. create complex functioning in NGINX to lookup dns of ip address
  3. use your domain manager API to programmatically add token to DNS record, and run update when needed

The acme.sh protocol has the API option and might be a solution for you if your domain manager offers API functionality.

Hi @d00

After enabled whitelisting like @garrett said above.

i am just am noob but i used these instructions from Xiao at LinuxBabe to make a shell script for Certbot

i think this shell script is ok to use for Passbolt security, i am running nginx whitelisting for 9 months now with no renew cert issues.

I hope this help :smile:

Certbot TLS Certificate Renewal

If you enable whitelisting in Apache/Nginx virtual host, 
then you will also block Let’s Encrypt servers to access your web server, 
which is required for renewing Let’s Encrypt TLS certificate with HTTP-01 challenge. 
To solve this problem, we can disable whitelisting before certificate renewal and enable it again after the renewal.

Create a shell script in the /root/ directory.

sudo nano /root/certbot-renewal.sh

If you use Nginx, add the following lines to this file.

#! /bin/bash

# disable whitelisting
sed -i 's/deny all;/#deny all;/g' /etc/nginx/conf.d/Passbolt.your-domain.com.conf
systemctl reload nginx

# renew TLS certificate
certbot renew --quiet

# enable whitelisting
sed -i 's/#deny all;/deny all;/g' /etc/nginx/conf.d/Passbolt.your-domain.com.conf
systemctl reload nginx

If you use Apache, add the following lines to this file.

#! /bin/bash

# disable whitelisting
sed -i 's/Require ip/#Require ip/g' /etc/apache2/sites-enabled/Passbolt.your-domain.com-le-ssl.conf
systemctl reload apache2

# renew TLS certificate
certbot renew --quiet

# enable whitelisting
sed -i 's/#Require ip/Require ip/g' /etc/apache2/sites-enabled/Passbolt.your-domain.com-le-ssl.conf
systemctl reload apache2

Save and close the file. Then add execute permission to this file.

sudo chmod +x /root/certbot-renewal.sh

Then edit the root user’s crontab file.

sudo crontab -e

Add the following line at the end of the file, so the shell script will run once a day.

@daily bash /root/certbot-renewal.sh

Save and close the file.
1 Like

@Duffman thanks for posting! I wanted to add that the notes on the guide say it’s disabling whitelisting but actually it’s disabling blacklisting with removing the deny all. So there is full public access while running cerbot.

If cerbot were to only run after hours…

An alternative but similar idea would be scripting to take the site down while updating the certs, maybe by removing a symlinked nginx configuration file for the site and adding a configuration file that handles only let’s encrypt incoming calls. So, rather than modifying the config file, it replaces it and restarts nginx, then updates via cerbot, then swaps back the replaced config and restarts nginx once more.

1 Like

Hi @garrett

Thanks for the clarification :smile:

Also, I was not thinking about the business side. I would set the cron entry to run once a month at 3am.
0 3 1 * * bash /root/certbot-renewal.sh

1 Like

Thanks all. I’ll look into these solutions a little more. I’ve already started digging into NGINX’s allow rules. I was also thinking about specific location path rules. Here are a list of endpoints that we would consider:

Private Routes, for users locked down to VPN access:

  • /fonts/*
  • /app/*
  • /css/*
  • /mfa/*
  • /locales/*
  • /account/*
  • /settings.json
  • /img/*
  • /js/*
  • /auth/*

Public routes available for Certbot and open to the public internet:

/acme/*
/

I’ll work on this approach for a bit and look at your other solutions should I run into any issues. Let me know what you think.

Thanks!

@d00 I don’t believe ip restrictions via allow|deny are available for location blocks. They are used in the server block.

https://nginx.org/en/docs/stream/ngx_stream_access_module.html#allow

OK that makes sense. Thanks. I’ll use UFW and set up a renewal script.

Thanks for the ideas!

1 Like