Nginx Proxy Manager Configuration with Crowdsec

What you will need

  • A small amount of experience using docker
  • A machine with docker already set up for this guide I will be using a portainer instance
  • A domain already pointing at your old Nginx proxy manager instance (I assume that you set up with a database)

Setting Up Nginx Proxy Manager

First, we will need to set up Nginx Proxy Manager via its docker-compose I will be using baudneo fork because we will need to use that fork later anyway. Make sure that you set your database passwords to something else.

you will also need to run the following before you run docker-compose up -d

mkdir /Nginx-Proxy-Manger
touch /Nginx-Proxy-Manger/crowdsec-openresty-bouncer.conf
# https://hub.docker.com/r/baudneo/nginx-proxy-manager
# https://www.crowdsec.net/blog/crowdsec-with-nginx-proxy-manager
version: "3"
services:
  app:
    # image: 'jc21/nginx-proxy-manager:latest'
    image: 'baudneo/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      # These ports are in format :
      - '80:80' # Public HTTP Port
      - '443:443' # Public HTTPS Port
      - '81:81' # Admin Web Port
      # Add any other Stream port you want to expose
      # - '21:21' # FTP
    environment:
      # crowdsec config
      TZ: Australia/Perth
      ADMIN_PANEL_LOG: "1"
      CROWDSEC_BOUNCER: "1"
      OPENRESTY_DEBUG: "0"

      CROWDSEC_LAPI: "http://crowdsecip:8080/"
      CROWDSEC_KEY: "yourkeyhere"
      
    
      DB_MYSQL_HOST: "172.25.0.3"
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "npm"
      DB_MYSQL_PASSWORD: "Verygoodpassword"
      DB_MYSQL_NAME: "npm"
      # Uncomment this if IPv6 is not enabled on your host
      # DISABLE_IPV6: 'true'
    volumes:
      - /Nginx-Proxy-Manger/data:/data
      - /Nginx-Proxy-Manger/letsencrypt:/etc/letsencrypt
      - /Nginx-Proxy-Manger/crowdsec-openresty-bouncer.conf:/data/crowdsec/crowdsec-openresty-bouncer.conf
    depends_on:
      - db
    networks:
      nginx:
        ipv4_address: 172.25.0.2

  db:
    image: 'jc21/mariadb-aria:latest'
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: 'Verygoodpassword'
      MYSQL_DATABASE: 'npm'
      MYSQL_USER: 'npm'
      MYSQL_PASSWORD: 'Verygoodpassword'
    volumes:
      - /Nginx-Proxy-Manger/data/mysql:/var/lib/mysql
    networks:
      nginx:
        ipv4_address: 172.25.0.3

networks:
  nginx:
    ipam:
      driver: default
      config:
        - subnet: 172.25.0.0/16

Now run docker-compose up -d –force-recreate

Now head over to http://dockerhost:81 and login

# Default password if setting it up for the first time
username “[email protected]”
password “changeme”

Setting Up Crowdsec and Metabase

Now we will need to set up Crowdsecs agent to monitor our Nginx Proxy Managers logs.

Step one run the following commands

nano ./crowdsec/acquis.yaml

Now put the following into that file

# https://www.reddit.com/r/selfhosted/comments/ujdzwu/how_do_i_install_crowdsec_on_my_nginx_proxy/
# https://hub.crowdsec.net/author/crowdsecurity/collections/nginx-proxy-manager
filenames:
 - /var/logs/default-host_access.log
 - /var/logs/proxy-host-*_access.log
 - /var/logs/proxy-host-*_error.log
labels:
  type: nginx-proxy-manager

step two edit/create this file

nano ./crowdsec/profiles.yaml

now place the following into that file

name: captcha_remediation
filters:
- Alert.Remediation == true && Alert.GetScope() == "Ip" && Alert.GetScenario() startsWith "crowdsecurity/http-"
decisions:
- type: captcha
  duration: 4h
on_success: break
---

name: default_ip_remediation
#debug: true
filters:
 - Alert.Remediation == true && Alert.GetScope() == "Ip"
decisions:
 - type: ban
   duration: 4h
# notifications:
#   - slack_default  # Set the webhook in /etc/crowdsec/notifications/slack.yaml before enabling this.
#   - splunk_default # Set the splunk url and token in /etc/crowdsec/notifications/splunk.yaml before enabling this.
#   - http_default   # Set the required http parameters in /etc/crowdsec/notifications/http.yaml before enabling this.
#   - email_default  # Set the required email parameters in /etc/crowdsec/notifications/email.yaml before enabling this.
on_success: break

Now its time for the docker-compose file

version: '3'
# https://github.com/crowdsecurity/example-docker-compose/blob/main/docker-compose.yml

services:
  crowdsec:
    image: crowdsecurity/crowdsec:v1.3.4
    restart: always
    ports:
      - 8080:8080
    environment:
      #this is the list of collections we want to install
      #https://hub.crowdsec.net/author/crowdsecurity/collections/nginx
      COLLECTIONS: "crowdsecurity/linux crowdsecurity/nginx-proxy-manager crowdsecurity/base-http-scenarios"
      #COLLECTIONS: "crowdsecurity/cloudflare-bouncer"
      GID: "${GID-1000}"
      TZ: Australia/Perth
    volumes:
      - ./crowdsec/acquis.yaml:/etc/crowdsec/acquis.yaml
      - ./crowdsec/profiles.yaml:/etc/crowdsec/profiles.yaml
      - /Nginx-Proxy-Manger/data/logs:/var/logs
      - crowdsec-db:/var/lib/crowdsec/data/
      - crowdsec-config:/etc/crowdsec/
    networks:
      crowdsec:
        ipv4_address: 172.23.0.2
  
  #metabase, because security is cool, but dashboards are cooler
  dashboard:
    #we're using a custom Dockerfile so that metabase pops with pre-configured dashboards
    build: ./crowdsec/dashboard
    restart: always
    ports:
      - 3000:3000
    environment:
      MB_DB_FILE: /data/metabase.db
      MGID: "${GID-1000}"
      TZ: Australia/Perth
    depends_on:
      - 'crowdsec'
    volumes:
      - crowdsec-db:/metabase-data/
    networks:
      crowdsec:
        ipv4_address: 172.23.0.3

volumes:
  logs:
  crowdsec-db:
  crowdsec-config:

networks:
  crowdsec:
    ipam:
      driver: default
      config:
        - subnet: 172.23.0.0/24

make the docker file for the dashboard

mkdir ./crowdsec/dashboard
nano ./crowdsec/dashboard/Dockerfile

paste the following into it

FROM metabase/metabase

RUN mkdir /data/ && wget https://crowdsec-statics-assets.s3-eu-west-1.amazonaws.com/metabase_sqlite.zip && unzip metabase_sqlite.zip -d /data/

now run docker-compose up -d –force-recreate

now check that the agent is understanding the logs correctly with the following command. Make sure that it has Parsed some lines.

docker exec crowdsec cscli metrics

Configuring Nginx Proxy Manager bouncer With Crowdsec

you will need to get an API key from your local agent to do this you will need to run the following command. Make sure that you put this key somewhere safe because there is no way to find the key after the initial generation.

docker exec crowdsec cscli bouncers add npm-proxy

Now we are gonna take this key and add it to the docker-compose of Nginx proxy manager by changing the following in your docker-compose file.

You will also need to add the IP of your crowdsec agent this will be http://dockerhostip:8080/

 CROWDSEC_LAPI: "http://crowdsecip:8080/"
 CROWDSEC_KEY: "yourkeyhere"

You will also need to edit the following file /Nginx-Proxy-Manger/crowdsec-openresty-bouncer.conf and enter the following into it along with the reCAPTCHA secret key and site key you can create one here.

ENABLED=true
API_URL=http://dockerhostip:8080
API_KEY=API-Key-Here
CACHE_EXPIRATION=1
# bounce for all type of remediation that the bouncer can receive from the local API
BOUNCING_ON_TYPE=all
FALLBACK_REMEDIATION=ban
REQUEST_TIMEOUT=3000
UPDATE_FREQUENCY=10
# live or stream
MODE=live
# exclude the bouncing on those location
EXCLUDE_LOCATION=
#those apply for "ban" action
# /!\ REDIRECT_LOCATION and RET_CODE can't be used together. REDIRECT_LOCATION take priority over RET_CODE
BAN_TEMPLATE_PATH=/crowdsec/templates/ban.html
REDIRECT_LOCATION=
RET_CODE=
#those apply for "captcha" action
# ReCaptcha Secret Key
SECRET_KEY= ReCaptchaSecretkeyhere
# Recaptcha Site key
SITE_KEY=RecaptchaSitekeyhere
CAPTCHA_TEMPLATE_PATH=/crowdsec/templates/captcha.html
CAPTCHA_EXPIRATION=3600

Now run docker-compose up -d –force-recreate

Testing

To check that this has been correctly configured we will ban ourselves to do this run the following commands:

# To ban
docker exec crowdsec cscli decisions add --ip 192.168.0.101

# To unban
docker exec crowdsec cscli decisions add --ip 192.168.0.101

You should see this if you successfully baned your self

One comment

  1. Testing
    To check that this has been correctly configured we will ban ourselves to do this run the following commands:

    # To ban
    docker exec crowdsec cscli decisions add –ip 192.168.0.101

    # To unban
    docker exec crowdsec cscli decisions add –ip 192.168.0.101

    Should be “docker exec crowdsec cscli decisions delete -i 192.168.0.101” to unban

Leave a Reply

Your email address will not be published. Required fields are marked *