Sign inSign up

aevrin/filter

By aevrin

•Updated 2 days ago

Image
0

6.2K

aevrin/filter repository overview

⁠Network Filter Container

A Docker container that provides network filtering capabilities for other containers, allowing you to restrict outbound network access to specific IPs, CIDR ranges, hostnames, and ports with protocol-specific rules. Code is largely AI generated (claude 3.7 Sonnet).

⁠Overview

This container acts as a network filter, enforcing strict firewall rules on outgoing connections. It's designed to be used with Docker's network_mode: service:filter to apply these rules to other containers.

⁠Features

  • Blocks all outgoing traffic by default
  • Supports multiple target types:
    • Individual IP addresses (IPv4 and IPv6)
    • CIDR notation (e.g., 192.168.1.0/24)
    • Hostnames/domains with automatic DNS resolution
  • Protocol-specific rules (TCP, UDP, ICMP)
  • Port restrictions per protocol
  • Automatic DNS re-resolution every 5 minutes
  • Docker internal DNS support (127.0.0.11)
  • Logging of dropped packets
  • Health checks to ensure firewall is active

⁠Configuration

The container is configured through environment variables:

⁠Required
  • ALLOWED_IPS: Comma-separated list of allowed destinations
    • Supports: IP addresses, CIDR ranges, hostnames/domains
    • Example: 10.10.10.252,192.168.1.0/24,api.github.com,database.internal
⁠Optional
  • ALLOWED_PROTOCOLS: Comma-separated list of allowed protocols

    • Default: tcp,udp,icmp
    • Example: tcp,udp (to block ICMP)
  • ALLOWED_TCP_PORTS: Comma-separated list of allowed TCP ports

    • If not specified, all TCP ports are allowed to the specified destinations
    • Example: 80,443,8080
  • ALLOWED_UDP_PORTS: Comma-separated list of allowed UDP ports

    • If not specified, all UDP ports are allowed to the specified destinations
    • Example: 53,123

⁠Docker Compose Example

services:
  filter:
    image: aevrin/filter:latest
    container_name: Filter-Compose
    hostname: filter-compose
    cap_add:
      - NET_ADMIN
    environment:
      - ALLOWED_IPS=10.10.10.252,192.168.1.0/24,api.github.com
      - ALLOWED_PROTOCOLS=tcp,udp,icmp
      - ALLOWED_TCP_PORTS=80,443
      - ALLOWED_UDP_PORTS=53,123
    restart: unless-stopped
  webserver:
    image: aevrin/easy:latest
    container_name: Webserver-Compose
    network_mode: service:filter
    depends_on:
      filter: 
        condition: service_healthy
    restart: unless-stopped

⁠Usage Examples

⁠Basic Web Server Access

Allow access only to specific web services:

environment:
  - ALLOWED_IPS=api.example.com,cdn.example.com
  - ALLOWED_PROTOCOLS=tcp
  - ALLOWED_TCP_PORTS=443
⁠Database Access with CIDR

Allow access to a database subnet:

environment:
  - ALLOWED_IPS=10.0.1.0/24
  - ALLOWED_PROTOCOLS=tcp
  - ALLOWED_TCP_PORTS=5432,3306
⁠Mixed Configuration

Combine different target types and protocols:

environment:
  - ALLOWED_IPS=8.8.8.8,192.168.1.0/24,api.github.com,db.internal
  - ALLOWED_PROTOCOLS=tcp,udp,icmp
  - ALLOWED_TCP_PORTS=80,443,22
  - ALLOWED_UDP_PORTS=53

⁠How It Works

  1. The filter container sets up iptables rules to:

    • Block all outgoing traffic by default
    • Allow loopback connections
    • Allow established connections
    • Allow Docker's internal DNS (127.0.0.11)
    • Process each entry in ALLOWED_IPS:
      • Direct IP addresses are used as-is
      • CIDR ranges are applied directly
      • Hostnames are resolved to IPs (both IPv4 and IPv6)
    • Apply protocol-specific rules with port restrictions
  2. DNS Resolution:

    • Hostnames are resolved when the container starts
    • Resolution is updated every 5 minutes automatically
    • Both IPv4 (A records) and IPv6 (AAAA records) are supported
  3. Other containers use network_mode: service:filter to share the network namespace with the filter container, inheriting its firewall rules.

⁠Important Notes

  • The filter container requires NET_ADMIN capability to manage iptables rules
  • All containers sharing the network namespace will be subject to the same firewall rules
  • DNS resolution updates occur every 5 minutes to handle IP changes
  • If a hostname cannot be resolved, a warning is logged but the container continues
  • ICMP is handled differently for IPv4 (icmp) and IPv6 (icmpv6)

⁠Security

This container provides a security layer by restricting outbound network access, which can help:

  • Prevent data exfiltration
  • Limit potential attack surface
  • Control which external services a container can access
  • Enforce protocol-specific restrictions

⁠Troubleshooting

Check the container logs to see configuration and dropped packets:

docker logs Filter-Compose

Look for log entries with prefixes:

  • OUTPUT-DROPPED: - Packets dropped from the container itself
  • FORWARD-DROPPED: - Packets dropped from containers using the filter's network

View current iptables rules:

docker exec Filter-Compose iptables -L -n -v
docker exec Filter-Compose ip6tables -L -n -v

⁠Advanced Configuration

⁠Protocol-Specific Rules

You can allow different ports for different protocols:

environment:
  - ALLOWED_IPS=example.com
  - ALLOWED_PROTOCOLS=tcp,udp
  - ALLOWED_TCP_PORTS=443  # HTTPS only
  - ALLOWED_UDP_PORTS=53   # DNS only
⁠CIDR Notation

Use CIDR notation for subnet access:

environment:
  - ALLOWED_IPS=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16  # Private networks
⁠Mixed Targets

Combine IPs, CIDRs, and hostnames:

environment:
  - ALLOWED_IPS=8.8.8.8,10.0.1.0/24,api.internal,github.com

⁠Limitations

  • DNS resolution happens every 5 minutes, so rapid IP changes might cause temporary access issues
  • Some complex applications might require additional protocols beyond TCP/UDP/ICMP
  • Rate limiting is not currently implemented

Tag summary

Content type

Image

Digest

sha256:605d61562…

Size

13 MB

Last updated

2 days ago

docker pull aevrin/filter