A http service to verify request and bounce them according to decisions made by CrowdSec.

GitHub GitHub go.mod Go version Go Report Card GitHub Workflow Status GitHub tag (latest SemVer) Docker Image Size (latest semver)

traefik-crowdsec-bouncer

A http service to verify request and bounce them according to decisions made by CrowdSec.

Description

This repository aim to implement a CrowdSec bouncer for the router Traefik to block malicious IP to access your services. For this it leverages Traefik v2 ForwardAuth middleware and query CrowdSec with client IP. If the client IP is on ban list, it will get a http code 403 response. Otherwise, request will continue as usual.

Demo

Prerequisites

Docker and Docker-compose installed.
You can use the docker-compose in the examples' folder as a starting point. Through traefik it exposes the whoami countainer on port 80, with the bouncer accepting and rejecting client IP.
Launch your all services except the bouncer with the follow commands:

git clone https://github.com/fbonalair/traefik-crowdsec-bouncer.git
cd examples
docker-compose up -d traefik crowdsec whoami 

Procedure

  1. Get an bouncer API key from CrowdSec with command docker exec crowdsec-example cscli bouncers add traefik-bouncer
  2. Copy the API key printed. You WON'T be able the get it again.
  3. Past this key as the value for bouncer environment variable CROWDSEC_BOUNCER_API_KEY, instead of "MyApiKey"
  4. Start bouncer in attach mode with docker-compose up bouncer
  5. Start a browser and visit http://localhost/. You will see the container whoami page, copy your IP address from X-Real-Ip line (i.e. 192.168.128.1).
    In your console, you will see lines showing your authorized request (i.e. "status":200).
  6. In another console, ban your IP with command docker exec crowdsec-example cscli decisions add --ip 192.168.128.1, modify the IP with your address.
  7. Visit http://localhost/ again, in your browser you will see "Forbidden" since this time since you've been banned. Though the console you will see "status":403.
  8. Unban yourself with docker exec crowdsec-example cscli decisions delete --ip 192.168.128.1
  9. Visit http://localhost/ one last time, you will have access to the container whoami.

Enjoy!

Usage

For now, this web service is mainly fought to be used as a container.

Prerequisites

You should have Traefik v2 and a CrowdSec instance running.
The container is available on docker as image fbonalair/traefik-crowdsec-bouncer. Host it as you see fit, though it must have access to CrowdSec and be accessible by Traefik.
Follow traefik v2 ForwardAuth middleware documentation to create a forwardAuth middle pointing to your bouncer host.
Generate a bouncer API key following CrowdSec documentation

Configuration

The webservice configuration is made via environment variables:

  • CROWDSEC_BOUNCER_API_KEY - CrowdSec bouncer API key required to be authorized to request local API (required)`
  • CROWDSEC_AGENT_HOST - Host and port of CrowdSec agent. i.e crowdsec-agent:8080 (required)`
  • CROWDSEC_BOUNCER_SCHEME - Scheme to query CrowdSec agent. Expected value: http, https. Default to http`
  • PORT - Change listening port of web server. Default listen on 8080
  • GIN_MODE - By default, run app in "debug" mode. Set it to "release" in production

Exposed routes

The webservice exposes 3 routes:

  • /api/v1/forwardAuth - Main route to be used by Traefik: query CrowdSec agent with the header X-Real-Ip as client IP`
  • /api/v1/ping - Simple health route that respond pong with http 200`
  • /api/v1/healthz - Another health route that query CrowdSec agent with localhost (127.0.0.1)`

Contribution

TBD

Comments
  • Bouncer doesn't correctly process X-Forwarded-For headers

    Bouncer doesn't correctly process X-Forwarded-For headers

    crowdsec-bouncer-traefik  | 2022-01-12T00:11:31Z DBG No decision for IP "192.168.0.13". Accepting
    crowdsec-bouncer-traefik  | {"level":"info","status":200,"method":"GET","path":"/api/v1/forwardAuth","ip":"192.168.0.13","latency":2.450771,"user_agent":"Gatus/1.0","time":"2022-01-12T00:11:31Z","message":"Request"}
    crowdsec-bouncer-traefik  | 2022-01-12T00:11:31Z DBG No decision for IP "192.168.0.13". Accepting
    crowdsec-bouncer-traefik  | {"level":"info","status":200,"method":"GET","path":"/api/v1/forwardAuth","ip":"192.168.0.13","latency":2.440972,"user_agent":"Gatus/1.0","time":"2022-01-12T00:11:31Z","message":"Request"}
    crowdsec-bouncer-traefik  | 2022-01-12T00:11:32Z DBG No decision for IP "172.20.6.1". Accepting
    crowdsec-bouncer-traefik  | {"level":"info","status":200,"method":"GET","path":"/api/v1/forwardAuth","ip":"172.20.6.1","latency":2.334519,"user_agent":"Prometheus/2.32.1","time":"2022-01-12T00:11:32Z","message":"Request"}
    crowdsec-bouncer-traefik  | 2022-01-12T00:11:34Z DBG No decision for IP "172.70.34.108". Accepting
    crowdsec-bouncer-traefik  | {"level":"info","status":200,"method":"GET","path":"/api/v1/forwardAuth","ip":"44.200.29.26","latency":2.456313,"user_agent":"axios/0.21.4","time":"2022-01-12T00:11:34Z","message":"Request"}
    

    As you can see the initial requests are internal addresses and the DBG lookup matches the subsequent request, however, the last request in the list is doing a Decision lookup for the last hop address (Cloudflare in this instance - 172.70.34.108) rather than the real address (44.200.29.26) and is allowing it even if it's banned.

    In the specific instance:

    crowdsec-bouncer-traefik  | 2022-01-12T00:11:54Z DBG No decision for IP "162.158.183.237". Accepting
    crowdsec-bouncer-traefik  | {"level":"info","status":200,"method":"GET","path":"/api/v1/forwardAuth","ip":"157.90.177.214","latency":2.464756,"user_agent":"Mozilla/5.0 (compatible; BLEXBot/1.0; +http://webmeup-crawler.com/)","time":"2022-01-12T00:11:54Z","message":"Request"}
    
    +---------+----------+-------------------+-----------------------------------+--------+---------+--------------------------------+--------+--------------------+----------+
    |   ID    |  SOURCE  |    SCOPE:VALUE    |              REASON               | ACTION | COUNTRY |               AS               | EVENTS |     EXPIRATION     | ALERT ID |
    +---------+----------+-------------------+-----------------------------------+--------+---------+--------------------------------+--------+--------------------+----------+
    | 1010386 | crowdsec | Ip:157.90.177.214 | crowdsecurity/http-bad-user-agent | ban    | US      |                             0  |      2 | 3h38m42.992170366s |     2623 |
    

    157.90.177.214 is banned but the bouncer allows it because the lookup is performed against 162.158.183.237 (Cloudflare) instead.

  • Bouncer can't connect to CrowdSec instance

    Bouncer can't connect to CrowdSec instance

    Hi!

    Face with strange behaviour, I have an several same install of crowdsec and traefik bouncer in docker, and right now I install this stuff to my vps, but, not understand what is wrong, maybe someone can help and resolve it, traefik bouncer can't connect to the crowdsec instance, 'coz ip address of container in not in bouncers list, and I can't understand whats is wrong in my compose or my settings of current stack.

    Here is an screen of bouncers list: image

    Here is an my containers: image

    And my stack:

    version: '3'
    
    networks:
      proxy:
        external: true
    
    volumes:
      config:
        driver: local
      db:
        driver: local
    
    services:
    
      crowdsec:
        image: crowdsecurity/crowdsec:latest
        container_name: crowdsec
        networks:
          - proxy
        environment:
          - TZ=Europe/Kiev
          - COLLECTIONS="crowdsecurity/linux crowdsecurity/traefik"
          - GID=${GID-1000}
        volumes:
          - ${DOCKER_HOST_PATH}/crowdsec/config/acquis.yaml:/etc/crowdsec/acquis.yaml
          - ${DOCKER_HOST_PATH}/crowdsec/config/profiles.yaml:/etc/crowdsec/profiles.yaml
          - ${DOCKER_HOST_PATH}/crowdsec/notifications/http.yaml:/etc/crowdsec/notifications/http.yaml
          - db:/var/lib/crowdsec/data/
          - config:/etc/crowdsec/
          # Traefik's logs read-only
          - ${DOCKER_HOST_PATH}/traefik/logs:/var/log/traefik:ro
          # Authelia's logs read-only
          #- ${DOCKER_HOST_PATH}/authelia/authelia.log:/var/log/authelia.log:ro
        restart: unless-stopped
        logging:
          driver: "json-file"
          options:
            max-size: "35m"
          
      traefik-crowdsec-bouncer:
        image: docker.io/fbonalair/traefik-crowdsec-bouncer:latest
        container_name: traefik-crowdsec-bouncer
        networks:
          - proxy
        depends_on:
          - crowdsec
        environment:
          - TZ=Europe/Kiev
          - CROWDSEC_BOUNCER_API_KEY=${BOUNCER_TRAEFIK_API_KEY}
          - CROWDSEC_AGENT_HOST=crowdsec:8080
          - CROWDSEC_BOUNCER_LOG_LEVEL=0
        restart: unless-stopped
        logging:
          driver: "json-file"
          options:
            max-size: "10m"
    

    The only difference from my previous stacks: I added telegram alerts, and my internal docker network is 192.168.135.0/24 - and that's all differents.

  • Bypassing Crowdsec for local IPs?

    Bypassing Crowdsec for local IPs?

    Hello,

    I was wondering if anyone has managed to do this / if it's possible at all currently?

    I know local IPs can be excluded from rate limiting in crowdsec, but I would like it if local devices can access local services via traefik, but without going through crowdsec.

    I presume this would require traefik to have some sort of arithmetic with and's and if's for middlewares, though I'm not completely sure.

  • Bouncer can't send ban request to crowdsec

    Bouncer can't send ban request to crowdsec

    I honestly don't know if this is bouncer issue or crowdsec. I tried to ddos my own website and check if bouncer block it. I saw some requests from bouncer but show error below. my logs file:

    2022-03-02T02:45:07Z WRN An error occurred while checking IP "" error="Get \"http://crowdsec:8080/v1/decisions?type=ban&ip=MYIP\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)"
    
  • Under load, bouncer bans legitimate traffic

    Under load, bouncer bans legitimate traffic

    Hi, When under heavy load requests are forbidden: traefik-bouncer-8567488c8-jckp2 traefik-bouncer 2022-08-18T11:22:49.158912821+10:00 2022-08-18T01:22:49Z WRN An error occurred while checking IP "" error="Get "http://crowdsec-service.crowdsec.svc.cluster.local:8080/v1/decisions?type=ban&ip=10.42.8.192": context deadline exceeded (Client.Timeout exceeded while awaiting headers)" Is it possible to introduce an environment variable to increase this timeout (until the initial load issues can be sorted) Cheers.

  • Working alongside thomseddon/traefik-forward-auth:2

    Working alongside thomseddon/traefik-forward-auth:2

    Hi,

    I am trying to get this to work alongside thomseddon/traefik-forward-auth:2 to add an additional layer of forward-auth but I cant seem to get it working.

    Traefik version 2.6.1

    Traefik args:

          - "--entrypoints.http.http.middlewares=crowdsec-bouncer@docker"
          - "--entrypoints.https.http.middlewares=crowdsec-bouncer@docker"
    

    docker-compose.yaml

    version: '3.8'
    services:
      crowdsec:
        image: crowdsecurity/crowdsec:latest
        environment:
          GID: "${GID-1000}"
          COLLECTIONS: "crowdsecurity/linux crowdsecurity/traefik"
        volumes:
          - ./config/acquis.yaml:/etc/crowdsec/acquis.yaml
          - crowdsec-db:/var/lib/crowdsec/data/
          - crowdsec-config:/etc/crowdsec/
          - /ztemp/logs/traefik:/var/log/traefik/:ro
        networks:
          - traefik_public
        restart: unless-stopped
        deploy:
          labels:
            - traefik.enable=false
    
      bouncer-traefik:
        image: docker.io/fbonalair/traefik-crowdsec-bouncer:latest
        container_name: bouncer-traefik
        environment:
          CROWDSEC_BOUNCER_API_KEY: <my-api-key>
          CROWDSEC_AGENT_HOST: crowdsec:8080
        networks:
          - traefik_public
        depends_on:
          - crowdsec
        restart: unless-stopped
        deploy:
          labels:
            - "traefik.enable=true"
            - "traefik.http.middlewares.crowdsec-bouncer.forwardauth.address=http://bouncer-traefik:8080/api/v1/forwardAuth"
            - "traefik.http.middlewares.crowdsec-bouncer.forwardauth.trustForwardHeader=true"
            - "traefik.http.services.crowdsec-bouncer.loadbalancer.server.port=8080"
    
    networks:
      traefik_public:
        external: true
    volumes:
      crowdsec-db:
    

    I am seeing the middleware in the traefik dash: image

    And if I look at my routers, both the foward-auth and the bouncer is associated: image

    image image

    However the request from blocked IPs DOES NOT get forbidden.

    Oddly, I also have a static service+router defined for a bare metal box outside docker and that is now also picking up the bouncer middleware and requests from blocked clients IS being blocked.

    I have tried removing the other foward-auth middleware from one of my services so its only got the bouncer associated and its still not rejecting banned clients:

    image

    Here are some logs from the bouncer:

    {"level":"info","status":200,"method":"GET","path":"/api/v1/forwardAuth","ip":"172.16.200.3","latency":45.521328,"user_agent":"Mozilla/5.0 (Linux; Android 12; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Mobile Safari/537.36","time":"2022-02-15T12:26:43Z","message":"Request"}
    {"level":"info","status":200,"method":"GET","path":"/api/v1/forwardAuth","ip":"172.16.200.3","latency":77.551311,"user_agent":"Mozilla/5.0 (Linux; Android 12; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Mobile Safari/537.36","time":"2022-02-15T12:26:43Z","message":"Request"}
    {"level":"info","status":200,"method":"GET","path":"/api/v1/forwardAuth","ip":"172.16.200.3","latency":32.077496,"user_agent":"Mozilla/5.0 (Linux; Android 12; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Mobile Safari/537.36","time":"2022-02-15T12:26:43Z","message":"Request"}
    {"level":"info","status":200,"method":"GET","path":"/api/v1/forwardAuth","ip":"172.16.200.3","latency":12.25493,"user_agent":"Mozilla/5.0 (Linux; Android 12; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Mobile Safari/537.36","time":"2022-02-15T12:26:43Z","message":"Request"}
    {"level":"info","status":200,"method":"GET","path":"/api/v1/forwardAuth","ip":"172.16.200.3","latency":26.94213,"user_agent":"Mozilla/5.0 (Linux; Android 12; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Mobile Safari/537.36","time":"2022-02-15T12:26:43Z","message":"Request"}
    {"level":"info","status":200,"method":"GET","path":"/api/v1/forwardAuth","ip":"172.16.200.3","latency":20.995469,"user_agent":"Mozilla/5.0 (Linux; Android 12; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Mobile Safari/537.36","time":"2022-02-15T12:26:43Z","message":"Request"}
    {"level":"info","status":200,"method":"GET","path":"/api/v1/forwardAuth","ip":"172.16.200.3","latency":15.450635,"user_agent":"Mozilla/5.0 (Linux; Android 12; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Mobile Safari/537.36","time":"2022-02-15T12:26:47Z","message":"Request"}
    {"level":"warn","status":403,"method":"GET","path":"/api/v1/forwardAuth","ip":"172.16.200.3","latency":25.430298,"user_agent":"Mozilla/5.0 (Linux; Android 12; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Mobile Safari/537.36","time":"2022-02-15T12:26:51Z","message":"Request"}
    {"level":"warn","status":403,"method":"GET","path":"/api/v1/forwardAuth","ip":"172.16.200.3","latency":12.728283,"user_agent":"Mozilla/5.0 (Linux; Android 12; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Mobile Safari/537.36","time":"2022-02-15T12:26:52Z","message":"Request"}
    

    The bottom two are blocks on a file provider service, the others are docker services.

    Any ideas? It's probably just a label/mis-config somewhere but I have tried loads of combinations to get to this stage.

    Thanks in advance.

  • Distroless image has no access to wget/curl

    Distroless image has no access to wget/curl

    Hi,

    First of all, thanks for this awesome bouncer. For which you have specified some nice health check APIs, which I was aiming to use to implement a docker HEALTHCHECK. However, because the distroless does not contain any wget or curl CMDs, it is not possible to do this.

    Can a light weight wget binary be added so that a HEALTHCHECK could properly be implemented.

  • Fix for Trusted Proxies and use ClientID()

    Fix for Trusted Proxies and use ClientID()

    Not sure if you accept pull requests so here goes? This is related to #10

    Sets this to work correctly on ClientID() which defaults to X-Forwarded-For behind a trusted proxy. Since this should be behind traefik and traefik decides which proxies it trusts before we can keep this set as 0.0.0.0/0 but there is an option to set this with the TRUSTED_PROXIES environmental variable.

    Note that this might not be as performant as setting SetTrustedProxy(nil) and using ClientID() if you don't have proxies before Traefik. I wanted to add in some logic to set SetTrustedProxy(nil) instead if TRUSTED_PROXY wasn't set at all but my experience with go isn't that great and honestly not sure it even matters in most use cases for this bouncer but it is a potential for improvement if you want the previous functionality to stand.

  • refactor: docker healthcheck to be more permissive

    refactor: docker healthcheck to be more permissive

    With the default Healthcheck, the timeout is set to strict. When using the bouncer on a node with a high load, the container runs fine but the healthcheck is not finished within 1s thus killing the container. By setting the healthcheck to a larger timeout and include some retries, the healthcheck should work fine even when executed on high load nodes.

  • Traefik 2.8.2 and above, crowdsec compatibility issue?!

    Traefik 2.8.2 and above, crowdsec compatibility issue?!

    I have Traefik 2.8.1 and CrowdSec 1.4.1 running fine. When I update Traefik to 2.8.2 or 2.8.3, I have errors in Traefik saying it can't find the crowdsec-bouncer router. If I go back to Traefik 2.8.1 without changing anything in CrowdSec at all, everything works fine again. Is there an incompatibility in crowdsec at the moment?

    Please let me know if you need any logs or more info. I am not a software developer, so not too well versed on github.

  • Bouncing Traefik TCP connections?

    Bouncing Traefik TCP connections?

    I have a few services that are exposed in Traefik via TCP entrypoints. I'd like to bounce TCP connections that CrowdSec identifies as threats. Does this bouncer only handle HTTP-based connections?

  • traefik-bouncer not connecting

    traefik-bouncer not connecting

    I am having a strange issue getting the traefik-bouncer up and running. Ive followed the steps and have got it going successfully on two other hosts but for whatever reason the host im attempting to get it going on will not connect to my traefik container. Im not sure what Im missing and super confused.

    cscli bouncers list:

    `---------------------------------------------------------------------------------------------------------------------------------------------------------------------- Name IP Address Valid Last API pull Type Version Auth Type

    blocklistMirror 172.168.90.1 ✔️ 2022-11-25T13:20:15Z crowdsec-blocklist-mirror v0.0.1-debian-pragmatic-0c8983c08afb28d82d18c4835458aaa0019- api-key 3fa4f traefik-bouncer ✔️ 2022-11-25T13:15:28Z api-key ----------------------------------------------------------------------------------------------------------------------------------------------------------------------`

    logs from traefik-bouncer in debug:

    `[GIN-debug] GET /api/v1/ping --> github.com/fbonalair/traefik-crowdsec-bouncer/controler.Ping (2 handlers) [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. [GIN-debug] Listening and serving HTTP on :8080 [GIN-debug] Environment variable PORT is undefined. Using port :8080 by default [GIN-debug] GET /api/v1/metrics --> github.com/fbonalair/traefik-crowdsec-bouncer/controler.Metrics (2 handlers) [GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value. [GIN-debug] GET /api/v1/healthz --> github.com/fbonalair/traefik-crowdsec-bouncer/controler.Healthz (2 handlers) [GIN-debug] GET /api/v1/forwardAuth --> github.com/fbonalair/traefik-crowdsec-bouncer/controler.ForwardAuth (2 handlers)

    • using code: gin.SetMode(gin.ReleaseMode)
    • using env: export GIN_MODE=release Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.`

    also was getting this error which prompted me to nuke the setup and start over:

    {"level":"warn","error":"invalid character 'p' after top-level value","time":"2022-11-24T01:29:00Z","message":"An error occurred while checking IP """}

    Any ideas? Thanks in advance.

  • viewing denied request only?

    viewing denied request only?

    Is there an easy way to log only 'denied' requests that have come from my middleware? I know that with logging set to DEBUG it will show all decision requests, but it would be nice if I could see just the denied requests somewhere to see what kind of traffic is being blocked by the bouncer.

  • HTML forbidden page

    HTML forbidden page

    Hello, I tried a sample HTML code as a return from the bouncer when blocked. But, It's showed on the browser as plain text and not HTML page.

    Is it planned to switch the bouncer reply to HTML ?

    2022-09-28 14_05_00

    CROWDSEC_BOUNCER_BAN_RESPONSE_MSG = "<!DOCTYPE html><html lang=\"en\"><head><title>403</title></head><body><h1>403</h1><h2>Access forbidden !</h2></body></html>"

  • Implement local cache for crowdsec

    Implement local cache for crowdsec

    https://github.com/fbonalair/traefik-crowdsec-bouncer/pull/32 With better implementation

    3 mode:

    • stream mode: use /decisions/stream to get in cache the decisions.
    • live mode: like before but with cached response from crowdsec
    • none mode: like before (every request ask crowdsec)
  • Implement local cache for crowdsec

    Implement local cache for crowdsec

    Proposal of a local cache for the bouncer related to #21

    More details can be found here https://github.com/fbonalair/traefik-crowdsec-bouncer/issues/21#issuecomment-1249543320

echo-http - Echo http service

echo-http - Echo http service Responds with json-formatted echo of the incoming request and with a predefined message. Can be install directly (go get

Dec 4, 2022
gorilla/csrf provides Cross Site Request Forgery (CSRF) prevention middleware for Go web applications & services 🔒

gorilla/csrf gorilla/csrf is a HTTP middleware library that provides cross-site request forgery (CSRF) protection. It includes: The csrf.Protect middl

Jan 9, 2023
A golang registry for global request variables.

context ?? This library is in maintenance mode. ⚠ ⚠ ⚠ Note ⚠ ⚠ ⚠ gorilla/context, having been born well before context.Context existed, does not play

Oct 27, 2022
Mahi is an all-in-one HTTP service for file uploading, processing, serving, and storage.
Mahi is an all-in-one HTTP service for file uploading, processing, serving, and storage.

Mahi is an all-in-one HTTP service for file uploading, processing, serving, and storage. Mahi supports chunked, resumable, and concurrent uploads. Mahi uses Libvips behind the scenes making it extremely fast and memory efficient.

Dec 29, 2022
A HTTP mole service
A HTTP mole service

httpmole provides a HTTP mock server that will act as a mole among your services, telling you everything http clients send to it and responding them whatever you want it to respond. Just like an actual mole.

Jul 27, 2022
HTTP/2 Apple Push Notification service (APNs) provider for Go with token-based connection

APNs Provider HTTP/2 Apple Push Notification service (APNs) provider for Go with token-based connection Example: key, err := apns.AuthKeyFromFile("Aut

Dec 29, 2022
A dead simple, stupid, http service.

A dead simple, stupid, http service implemented in a complicated way just for the sake of following Go design patterns and scalability. Useful for learning and testing basic kubernetes networking. Made on an insomniac night.

Sep 2, 2022
Link converter service converts URLs to deeplinks or deeplinks to URLs.

Link converter Link converter service converts URLs to deeplinks or deeplinks to URLs. The service responds to the incoming request and first checks w

Dec 23, 2021
Composable chains of nested http.Handler instances.

chain go get github.com/codemodus/chain Package chain aids the composition of nested http.Handler instances. Nesting functions is a simple concept. I

Sep 27, 2022
Go http.Hander based middleware stack with context sharing

wrap Package wrap creates a fast and flexible middleware stack for http.Handlers. Features small; core is only 13 LOC based on http.Handler interface;

Apr 5, 2022
Minimalist net/http middleware for golang

interpose Interpose is a minimalist net/http middleware framework for golang. It uses http.Handler as its core unit of functionality, minimizing compl

Sep 27, 2022
Add interceptors to GO http.Client

mediary Add interceptors to http.Client and you will be able to Dump request and/or response to a Log Alter your requests before they are sent or resp

Nov 17, 2022
Lightweight Middleware for net/http

MuxChain MuxChain is a small package designed to complement net/http for specifying chains of handlers. With it, you can succinctly compose layers of

Dec 10, 2022
Idiomatic HTTP Middleware for Golang

Negroni Notice: This is the library formerly known as github.com/codegangsta/negroni -- Github will automatically redirect requests to this repository

Jan 2, 2023
A tiny http middleware for Golang with added handlers for common needs.

rye A simple library to support http services. Currently, rye provides a middleware handler which can be used to chain http handlers together while pr

Jan 4, 2023
A collection of useful middleware for Go HTTP services & web applications 🛃

gorilla/handlers Package handlers is a collection of handlers (aka "HTTP middleware") for use with Go's net/http package (or any framework supporting

Dec 31, 2022
Simple middleware to rate-limit HTTP requests.

Tollbooth This is a generic middleware to rate-limit HTTP requests. NOTE 1: This library is considered finished. NOTE 2: Major version changes are bac

Dec 28, 2022
OpenID Connect (OIDC) http middleware for Go

Go OpenID Connect (OIDC) HTTP Middleware Introduction This is a middleware for http to make it easy to use OpenID Connect. Currently Supported framewo

Jan 1, 2023
Hex - Expectations for HTTP handlers

Hex is a simple wrapper that extends httptest.Server with an expectation syntax, allowing you to create mock APIs using a simple and expressive DSL:

Aug 9, 2021