Complete Guide to Deploying TraefikShaper Security with Pangolin

This guide will walk you through integrating TraefikShaper with Pangolin to add dynamic IP whitelisting capabilities to your self-hosted services. This security layer allows temporary access to your services through an approval system.

What You’ll Achieve

  • Deploy TraefikShaper alongside your Pangolin installation
  • Create a /knock-knock endpoint for users to request access
  • Set up notifications via Discord, Telegram, or WhatsApp
  • Configure proper routing to prevent lockouts
  • Learn recovery procedures if things go wrong

Prerequisites

  • A working Pangolin installation with Traefik
  • Access to your server’s file system
  • Basic understanding of YAML and Docker

1. Installation and Setup

1.1. Update Your Docker Compose File

Add the TraefikShaper service to your docker-compose.yml:

services:
  # Your existing Pangolin services...
  
  traefikshaper:
    image: l4rm4nd/traefikshaper:latest
    container_name: traefikshaper
    restart: unless-stopped
    environment:
      - APPURL=https://your-domain.com #this is up to your convenience.
      - GRANT_HTTP_ENDPOINT=/knock-knock #you can change to custom also.
      - DEFAULT_PRIVATE_CLASS_SOURCE_RANGE=True
      - IPSTRATEGY_DEPTH=0
      - EXPIRATION_TIME=3600
      - APPRISE_NOTIFICATION_URL=discord://webhook_id/webhook_token
    volumes:
      - ./config/traefik/dynamic-whitelist.yml:/app/dynamic-whitelist.yml
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro

1.2. Create the Dynamic Whitelist File

Create a file at ./config/traefik/dynamic-whitelist.yml:

http:
  middlewares:
    dynamic-ipwhitelist:
      ipAllowList:
        ipStrategy:
          depth: 0
        sourceRange:
        - 127.0.0.1/32
        - 10.0.0.0/8
        - 172.16.0.0/12
        - 192.168.0.0/16

This adds localhost and private networks to the allowed IPs by default.

1.3. Modify Traefik’s Static Configuration

Edit ./config/traefik/traefik_config.yml to add the file provider:

providers:
  http:
    endpoint: "http://pangolin:3001/api/v1/traefik-config"
    pollInterval: "5s"
  file:
    directory: "/etc/traefik"
    watch: true

# Rest of your existing configuration...

Make sure to remove any middleware applied globally at the entrypoint level, as we’ll apply them to specific routers instead.

1.4. Update Dynamic Configuration

Edit ./config/traefik/dynamic_config.yml to add TraefikShaper’s routing rules:

http:
  routers:
    # Your existing routers, adding the whitelist middleware
    next-router:
      rule: "Host(`your-domain.com`) && !PathPrefix(`/api/v1`) && !PathPrefix(`/knock-knock`)"
      service: next-service
      entryPoints:
        - websecure
      middlewares:
        - dynamic-ipwhitelist@file
      tls:
        certResolver: letsencrypt
    
    # Add this for the knock-knock endpoint
    knock-knock-router:
      rule: "Host(`your-domain.com`) && PathPrefix(`/knock-knock`)"
      service: traefikshaper-service
      entryPoints:
        - websecure
      priority: 100
      tls:
        certResolver: letsencrypt
  
  services:
    # Your existing services...
    
    # Add this for TraefikShaper
    traefikshaper-service:
      loadBalancer:
        servers:
          - url: "http://traefikshaper:5000"

2. Setting Up Notifications

TraefikShaper uses the Apprise library for notifications, which supports many services. Here’s how to set up different notification channels:

2.1. Discord Notifications

  1. Create a webhook in your Discord server:

    • Server Settings → Integrations → Webhooks → New Webhook
    • Copy the webhook URL
  2. Format for TraefikShaper:

    discord://webhook_id/webhook_token
    

    From https://discord.com/api/webhooks/1234567890/abcdefg,
    extract: discord://1234567890/abcdefg

2.2. Telegram Notifications

  1. Create a Telegram bot using BotFather
  2. Get your chat ID using a bot like @userinfobot
  3. Format for TraefikShaper:
    tgram://bot_token/chat_id
    

2.3. WhatsApp Notifications

WhatsApp is supported through Apprise’s Gotify or REST integrations:

  1. Set up a Gotify server or use a WhatsApp-to-REST bridge service
  2. Format for Gotify:
    gotify://gotify-server.com/token
    

2.4. Multiple Notification Services

You can chain multiple notification services together:

discord://webhook_id/webhook_token,tgram://bot_token/chat_id

3. Testing Your Setup

  1. Start or restart your Pangolin stack:

    docker compose down
    docker compose up -d
    
  2. Try to access a protected resource - you should get blocked

  3. Visit /knock-knock on the same domain

  4. Check your notification service for an approval link

  5. Click the approval link to grant access to the requesting IP

  6. Try accessing the protected resource again - it should now work

4. Recovery Procedures

4.1. If You’re Locked Out

If you’ve locked yourself out and can’t access your services:

  1. Connect to your server via SSH
  2. Edit the whitelist file directly:
    nano ./config/traefik/dynamic-whitelist.yml
    
  3. Add your current IP to the sourceRange list:
    sourceRange:
    - 127.0.0.1/32
    - YOUR_IP_ADDRESS/32
    
  4. Restart TraefikShaper:
    docker restart traefikshaper
    

4.2. Complete Reset

If you need to start over:

  1. Reset the whitelist file:

    cat > ./config/traefik/dynamic-whitelist.yml << 'EOF'
    http:
      middlewares:
        dynamic-ipwhitelist:
          ipAllowList:
            ipStrategy:
              depth: 0
            sourceRange:
              - 127.0.0.1/32
              - 10.0.0.0/8
              - 172.16.0.0/12
              - 192.168.0.0/16
    EOF
    
  2. Restart TraefikShaper:

    docker restart traefikshaper
    

5. Advanced Configuration

5.1. Customizing Access Duration

Set how long temporary access lasts (in seconds):

environment:
  - EXPIRATION_TIME=86400  # 24 hours

5.2. IP Strategy Depth

If your Traefik instance is behind a proxy (like Cloudflare):

environment:
  - IPSTRATEGY_DEPTH=1

5.3. Excluded IPs

For specific handling of proxy IPs:

environment:
  - EXCLUDED_IPS=103.21.244.0/22,103.22.200.0/22

6. Troubleshooting

6.1. Traefik Configuration Errors

If Traefik fails to start with YAML errors:

  • Check for tab characters - YAML requires spaces
  • Verify that rules are formatted correctly
  • Ensure multiple path prefixes use separate conditions with &&

6.2. TraefikShaper Issues

If TraefikShaper shows “Invalid token” errors:

  • Each approval link can only be used once
  • Tokens expire after a short time
  • Check that SECRET_KEY hasn’t changed

6.3. Notification Problems

If you’re not receiving notifications:

  • Verify the notification URL format is correct
  • Check TraefikShaper logs for error messages
  • Test with a simpler notification service first

7. Security Considerations

  • Always include private subnets in your allowlist if needed internally
  • Consider setting up a dedicated domain for TraefikShaper
  • Keep approval times short for sensitive services
  • Regularly check what IPs have been whitelisted

8. Regular Maintenance

It’s good practice to periodically:

  1. Check the whitelist to remove unnecessary IPs
  2. Update the TraefikShaper container to the latest version
  3. Review your notification settings to ensure they still work
  4. Test the recovery procedures

By following this guide, you’ve added a powerful security layer to your Pangolin installation that gives you granular control over who can access your services, while providing a convenient mechanism for temporary access through notifications.

1 Like

Thanks for this guide!

Got everything working except for the approval page. I’ve set the ‘APPURL’ variable for traefik-shaper to ‘traefikshaper.my-domain.nl’ but when I try to access it I get a ‘SSL_ERROR_UNRECOGNIZED_NAME_ALERT’ error. I must be missing something but can’t figure it out. Any suggestions?

With this conf, It does not work as expected. When you accept the request, being linked to “next-service” it returns you to the Pangolin login, it does not redirect you to the service. Would it have a solution?

Can the article be updated, explained to actually work? Thanks

its working for general UI. not for individual resources. for individual resources you will need to use custom routers once you create your service and override them.

what custom routers?

docker exec pangolin curl http://localhost:3001/api/v1/traefik-config | jq run this and you will see all the routers for your resources

I have done what you say and I see that Traefikshaper runs in the “18-service”. I have modified it in Routers but nothing. what am I doing wrong?