Packages
Elixir library for working with Linux nftables rules. Provides high-level APIs for building tables, chains, rules, maps and sets. Works with NFTables.Port for communicating with the kernel firewall.
Current section
Files
Jump to
Current section
Files
examples/distributed_query.exs
#!/usr/bin/env elixir
# Distributed Query Example
# Demonstrates how to build query commands without executing them,
# useful for distributed firewall architectures where queries are
# built on a C&C node and executed on remote firewall nodes.
Mix.install([{:nftables_ex, path: Path.expand("..", __DIR__)}])
alias NFTables.Query
defmodule DistributedQueryExample do
@moduledoc """
Example of using Query builder functions for distributed firewall operations.
"""
def demonstrate_query_builders do
IO.puts """
========================================
Distributed Query Builder Example
========================================
The Query module now provides build_* functions that generate
JSON commands without executing them. These can be sent to
remote nodes for execution.
"""
# 1. Build query for listing tables
IO.puts "\n1. List all tables (any family):"
json = Query.build_list_tables()
IO.puts " JSON: #{json}"
# 2. Build query for specific family
IO.puts "\n2. List tables for inet family:"
json = Query.build_list_tables(family: :inet)
IO.puts " JSON: #{json}"
# 3. Build query for chains
IO.puts "\n3. List all chains:"
json = Query.build_list_chains(family: :inet)
IO.puts " JSON: #{json}"
# 4. Build query for rules in specific chain
IO.puts "\n4. List rules in specific chain:"
json = Query.build_list_rules("filter", "INPUT")
IO.puts " JSON: #{json}"
# 5. Build query for all rules
IO.puts "\n5. List all rules for family:"
json = Query.build_list_rules(family: :inet)
IO.puts " JSON: #{json}"
# 6. Build query for sets
IO.puts "\n6. List all sets:"
json = Query.build_list_sets(family: :inet)
IO.puts " JSON: #{json}"
# 7. Build query for set elements
IO.puts "\n7. List elements in specific set:"
json = Query.build_list_set_elements("filter", "blocklist")
IO.puts " JSON: #{json}"
# 8. Build query for entire ruleset
IO.puts "\n8. List entire ruleset:"
json = Query.build_list_ruleset(family: :inet)
IO.puts " JSON: #{json}"
# 9. Build flush command
IO.puts "\n9. Flush ruleset (inet family):"
json = Query.build_flush_ruleset(family: :inet)
IO.puts " JSON: #{json}"
IO.puts """
========================================
Distributed Firewall Usage Pattern
========================================
"""
demonstrate_distributed_pattern()
end
def demonstrate_distributed_pattern do
IO.puts """
# On Command & Control Node:
# Build query commands centrally
defmodule MyApp.FirewallMonitor do
alias NFTables.Query
# Collect firewall state from multiple nodes
def collect_firewall_state(nodes) do
# Build queries
queries = [
{"tables", Query.build_list_tables(family: :inet)},
{"chains", Query.build_list_chains(family: :inet)},
{"rules", Query.build_list_rules(family: :inet)},
{"sets", Query.build_list_sets(family: :inet)}
]
# Send to all nodes in parallel
nodes
|> Enum.map(fn node ->
Task.async(fn ->
execute_queries_on_node(node, queries)
end)
end)
|> Task.await_many(timeout: 10_000)
end
defp execute_queries_on_node(node, queries) do
Enum.map(queries, fn {name, json_cmd} ->
# Send via your transport (Phoenix PubSub, gRPC, etc.)
response = MyTransport.execute_on_node(node, json_cmd)
{name, response}
end)
end
end
# On Firewall Node:
# Minimal execution layer
defmodule MyApp.FirewallNode do
def execute_command(json_cmd) do
{:ok, pid} = NFTables.start_link()
# Execute the pre-built command
case NFTables.Port.commit(pid, json_cmd, 5000) do
{:ok, response} -> {:ok, response}
{:error, reason} -> {:error, reason}
end
end
end
# Usage:
# On C&C node
state = MyApp.FirewallMonitor.collect_firewall_state([
"firewall-1.local",
"firewall-2.local",
"firewall-3.local"
])
# Analyze collected state
IO.inspect(state, label: "Collected Firewall State")
"""
end
end
# Run the demonstration
DistributedQueryExample.demonstrate_query_builders()