crowdsecurity / cs-firewall-bouncer

Crowdsec bouncer written in golang for firewalls
MIT License
103 stars 41 forks source link

properly document docker usage #32

Open buixor opened 3 years ago

buixor commented 3 years ago

after users asking question on gitter, we should make the docker usage of the firewall bouncer more obvious

moritzj29 commented 2 years ago

this would be awesome! I set up the firewall bouncer in docker during the last day and it appears to be working. I found no documentation on this at all. Clearly, the automated setup is not meant for docker since it does not support running services. But the installed binaries work anyway...

An appropriate official Image would be very nice and lower the bar for giving Crowdsec a try...

I can post my Dockerfile /docker-compose.yml if anyone is interested, but it sounds like docker usage is already known and just not documented.

yfhyou commented 2 years ago

@moritzj29 would love for you to share your docker info with me. I'm a bit lost with this one, but could get traefik-bouncer running with their great docker documentation. Thanks!

moritzj29 commented 2 years ago

Hi @youngt2, I have been there ;)

Disclaimer: I'm by no means an expert on this stuff, so question everything you read and proceed with caution!

Concept

It is possible to deploy the cs-firewall-bouncer as a docker container and modify the hosts iptables from within the docker container. Typically, one would use the DOCKER-USER iptables chain to make the rules act on all docker networks. It does not act on the host though. If this is desired, I think one should modify the INPUT chain. The cs-firewall-bouncer config file already suggest some iptables chains.

Further reading

Setup

cs-firewall-bouncer Docker container

I did not find an appropriate docker image yet, therefore I built one myself:

FROM debian:stable-slim

RUN apt update \
    && apt install curl -y \
    && curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | bash \
    && apt install crowdsec-firewall-bouncer-iptables -y \
    && rm -rf /var/lib/apt/lists/* \
    # iptables is migrated to nf_tables backend in recent debian versions
    # -> incompatible with old iptables -> switch to legacy versions
    # https://wiki.debian.org/iptables
    && update-alternatives --set iptables /usr/sbin/iptables-legacy \
    && update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy

ENTRYPOINT crowdsec-firewall-bouncer -c /crowdsec-firewall-bouncer.yaml

I followed the official documentation for installing on debian. I required iptables therefore I set debian to use this instead of nf_tables.

docker-compose.yml

I added this to my docker-compose file:

  crowdsec-firewall-bouncer:
    build: ./crowdsec-firewall-bouncer
    # folder containing the Dockerfile to build
    container_name: crowdsec-firewall-bouncer
    restart: always
    depends_on:
      - crowdsec
    environment:
      - TZ=Europe/Berlin
    cap_add:
      # allow modification of host's iptable
      - NET_ADMIN
      - NET_RAW
    network_mode: "host"
    volumes:
      # https://github.com/crowdsecurity/cs-firewall-bouncer/blob/main/config/crowdsec-firewall-bouncer.yaml
      - ./crowdsec-firewall-bouncer/crowdsec-firewall-bouncer.yaml:/crowdsec-firewall-bouncer.yaml
      - ./crowdsec-firewall-bouncer/crowdsec-firewall-bouncer.log:/var/log/crowdsec-firewall-bouncer.log

Configuration File

The example config file is from this repo (https://github.com/crowdsecurity/cs-firewall-bouncer/blob/main/config/crowdsec-firewall-bouncer.yaml), adjust it to your needs (API URL + Key). I used the following, but there have been some updates in the meantime:

mode: iptables
pid_dir: /var/run/
update_frequency: 10s
daemonize: false
log_mode: file
log_dir: /var/log/
log_level: info
#api_url: http://192.168.101.16:8080/
api_key: *******your key***********
disable_ipv6: true
deny_action: DROP
deny_log: false
supported_decisions_types:
  - ban
#to change log prefix
#deny_log_prefix: "crowdsec: "
#to change the blacklists name
blacklists_ipv4: crowdsec-blacklists
#blacklists_ipv6: crowdsec6-blacklists
#if present, insert rule in those chains
iptables_chains:
#  - INPUT
#  - FORWARD
  - DOCKER-USER

Check the documentation on how to generate an API Key.

Checking

Now you can fire up our container and check if it is working. The bouncer adds blocked IPs to the crowdsec-blacklist ipset rule. Following commands may be helpful (execute on the host):

I hope this helps! I happy to add any comments/improvements to this post.

moritzj29 commented 2 years ago

If any of the maintainers comes along: Would it be possible to provide an official docker image of the firewall bouncer? It would be so much easier if the image build would be handled by the CI/CD infrastructure already in place.

yfhyou commented 2 years ago

@moritzj29 Great write up. Thank you so much for this.

This help me very much. I wasn't able to run the ipset list on my host machine as I received a ipset v7.5: Kernel error received: Operation not permitted error. I guess ipset is not allowed on my oracle cloud machine? Anyway, the correct lines are in the iptable and adding and removing IPs using cscli decisions add --ip xxx.xxx.xxx.xxx seems to block incoming connections tested with SSH. I did see the ipset inside the docker container using docker exec commands.

I also noted that there are two variables referenced in the config file you linked:

mode: ${BACKEND}
api_key: ${API_KEY}

but passing them as environment variables in the docker-compose didn't seem to work. I guess I don't understand enough about docker for that.

Regardless your write up was easy to follow and works. 😄

moritzj29 commented 2 years ago

glad I could help!

the mode is set depending on the cs-firewall-bouncer type, e.g. ìptables or nf_tables (different distributed packages). The config file is generic for all versions I guess.

Probably similar for the api_key, but I don't know why this should differ between versions. I think it is not possible to set it via environment variable...

zmeel commented 1 year ago

I'm trying to run your setup om my Synology DS415+ with Docker installed but get the follow error:

time="16-09-2022 07:35:59" level=info msg="ipset set-up : /usr/sbin/ipset -exist create crowdsec-blacklists nethash timeout 300"
time="16-09-2022 07:35:59" level=fatal msg="iptables init failed: error while creating set : exit status 1 --> ipset v7.10: Kernel error received: set type not supported\n"

I don't have a clue how to solve this. Any help?

Jasper51297 commented 1 year ago

@moritzj29 Thank you for this example, I just implemented it in my docker compose stack running on my Synology DS220+ and it works great! I think this is something that should be added to the documentation.