{"id":20614919,"url":"https://github.com/lemmi/nftables","last_synced_at":"2026-03-19T16:43:39.776Z","repository":{"id":149981599,"uuid":"537398558","full_name":"lemmi/nftables","owner":"lemmi","description":null,"archived":false,"fork":false,"pushed_at":"2024-06-11T21:46:25.000Z","size":10,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-06T14:05:54.022Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lemmi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-16T09:52:12.000Z","updated_at":"2024-06-11T21:46:28.000Z","dependencies_parsed_at":null,"dependency_job_id":"c042b9b5-3a61-4a52-9848-619e5ed30088","html_url":"https://github.com/lemmi/nftables","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/lemmi/nftables","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemmi%2Fnftables","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemmi%2Fnftables/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemmi%2Fnftables/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemmi%2Fnftables/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lemmi","download_url":"https://codeload.github.com/lemmi/nftables/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemmi%2Fnftables/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28914339,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T12:13:43.263Z","status":"ssl_error","status_checked_at":"2026-01-30T12:13:22.389Z","response_time":66,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T11:13:54.249Z","updated_at":"2026-01-30T14:34:57.989Z","avatar_url":"https://github.com/lemmi.png","language":"Dockerfile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nftables\n\nThis is a container image to setup firewall rules with `nftables`. By default\nthe standard stateful firewall rules shipped with alpine are loaded. Custom\nrules can be added by bind mounting files into `/etc/nftables.d/*.nft`, or by\nrunning extra commands.\n\n## Intended use-case\n\nWith `ipvlan`/`macvlan`, containers can be exposed directly to the internet\nwith their own address. This allows to make full use of available IPv6\naddresses (on servers you are often provided with a full `/64`) without NAT,\nproxy ndp or complicated firewall rules on the container host.\n\nIt also leaves the container fully open to the internet and depending on your\nimage of choice, the container might unintentionally expose ports.\n\nBy setting up the network with the `nftables` container and reusing its network\nnamespace in other containers, containers can still be directly reachable, but\nonly on allowed ports.\n\n- `podman run --network container:nftables...`\n- docker-compose: `network_mode: service:nftables`\n\n### Example: firewalled service with caddy reverse-proxy\n\nWeb services can easily have their own address without complicated reverse proxy\nsetups needed to route to the traffic to containers and manage TLS certificates. \n\n1. service `nftables` will setup the network namespace and firewall\n2. service `caddy` will run as reverse-proxy and manage certificates\n3. service `service` is a webapplication that listens on port `:3000`\n    - `service` might be bound to a wildcard address and can't be configured to\n      only listen on localhost\n    - it might listen on other ports as well\n\nThis setup mimics the usual container behaviour. Containers will have outgoing\naccess to the internet, while only selected ports are exposed. \n\n```yaml\n---\nservices:\n  nftables:\n    image: ghcr.io/lemmi/nftables\n    command:\n      - nft add rule inet filter input meta nfproto ipv6 tcp dport {80, 443} counter accept;\n      - nft add rule inet filter input meta nfproto ipv6 udp dport 443 counter accept;\n    networks:\n      ipvlan:\n        ipv6_address: 2001:db8::\n    cap_add:\n      - CAP_NET_ADMIN\n\n  caddy:\n    image: caddy:alpine\n    command: caddy reverse-proxy --from example.com --to 'http://localhost:3000'\n    restart: always\n    network_mode: service:nftables\n    volumes:\n      - caddy:/data\n\n  service:\n    image: ...\n    network_mode: service:nftables\n\nvolumes:\n  caddy:\n\nnetworks:\n  ipvlan:\n    enable_ipv6: true\n    external: true\n```\n\n## Adding rules with volumes or bind mounts\n\nIn case more complicated rules are necessary, it's possible to provide them as\na file to be included after the main rules:\n\n`allow-web.nft`:\n```nftables\nadd rule inet filter input tcp dport {80, 443} counter accept;\n```\n\n```shell\npodman run \\\n    -v /path/to/allow-web.nft:/etc/nftables.d/allow-web.nft \\\n    --cap-add CAP_NET_ADMIN \\\n    ghcr.io/lemmi/nftables\n```\n\n## Adding rules with args\n\nFor very few rules, it's possible to provide them as command to the image.\nArguments are passed to `sh -c`.\n\n```shell\npodman run \\\n    --cap-add CAP_NET_ADMIN \\\n    ghcr.io/lemmi/nftables \\\n    nft add rule inet filter input tcp dport \"{80, 443}\" counter accept\n```\n\n## docker-compose\n\n### single rule\n\n```yaml\nservices:\n  nftables:\n    image: ghcr.io/lemmi/nftables\n    command: nft add rule inet filter input tcp dport {80, 443} counter accept\n```\n\n### multiple rules\n```yaml\nservices:\n  nftables:\n    image: ghcr.io/lemmi/nftables\n    command: \n      - nft add rule inet filter input tcp dport {80, 443} counter accept; # the ; is important\n      - nft list ruleset\n```\n\nThis can also be used to discard the default rules by running `nft flush ruleset`\nbefore the custom rules:\n\n```yaml\nservices:\n  nftables:\n    image: ghcr.io/lemmi/nftables\n    command:\n      - nft flush ruleset;\n      - nft add table inet filter;\n      - nft add chain inet filter input \"{ type filter hook input priority filter; policy accept;}\";\n      - nft add rule inet filter input counter;\n      - nft list ruleset;\n    cap_add:\n      - CAP_NET_ADMIN\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flemmi%2Fnftables","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flemmi%2Fnftables","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flemmi%2Fnftables/lists"}