Python bindings for iptables providing programmatic control over Linux netfilter rules
—
Full IPv6 support with dedicated classes for handling IPv6 addresses, prefixes, and protocol-specific matching. The IPv6 implementation provides the same interface as IPv4 with IPv6-specific handling for addresses, networks, and protocol features.
IPv6 tables work identically to IPv4 tables but operate on the IPv6 netfilter framework. Available tables include filter, mangle, raw, and security (no NAT table in IPv6).
class Table6(Table):
"""
IPv6 version of Table class for managing ip6tables tables.
Inherits all functionality from Table with IPv6-specific handling.
"""
def __init__(self, name: str, autocommit: bool = None):
"""
Initialize an IPv6 Table object.
Args:
name: Table name (filter, mangle, raw, security)
autocommit: Enable automatic commits (default: True)
"""IPv6 rules handle IPv6 addresses, prefix lengths, and IPv6-specific protocol features while maintaining the same interface as IPv4 rules.
class Rule6(Rule):
"""
IPv6 version of Rule class for managing ip6tables rules.
Inherits all functionality from Rule with IPv6 address handling.
"""
def __init__(self, entry=None, chain=None):
"""
Initialize an IPv6 Rule object.
Args:
entry: Optional low-level rule entry
chain: Optional parent chain
"""Function to check which IPv6 tables are available in the current kernel configuration.
def is_table6_available(name: str) -> bool:
"""
Check if specified IPv6 table is available in kernel.
Args:
name: Table name to check (filter, mangle, raw, security)
Returns:
True if IPv6 table is available
"""import iptc
# Create IPv6 table and chain
table6 = iptc.Table6(iptc.Table.FILTER)
chain = iptc.Chain(table6, "INPUT")
# Create rule for IPv6 SSH access
rule = iptc.Rule6()
rule.protocol = "tcp"
rule.src = "2001:db8::/32" # IPv6 network
rule.dst = "2001:db8::1/128" # Specific IPv6 address
# Add TCP match
tcp_match = rule.create_match("tcp")
tcp_match.dport = "22"
# Set target
rule.target = rule.create_target("ACCEPT")
# Insert rule
chain.insert_rule(rule)import iptc
# Check if IPv6 filter table is available
if iptc.is_table6_available("filter"):
table6 = iptc.Table6(iptc.Table.FILTER)
chain = iptc.Chain(table6, "INPUT")
# IPv6 rule with various address formats
rule = iptc.Rule6()
# Full IPv6 address
rule.src = "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
# Compressed IPv6 address
rule.dst = "2001:db8:85a3::8a2e:370:7334"
# IPv6 network with prefix
rule.src = "fe80::/64" # Link-local network
# IPv6 loopback
rule.dst = "::1/128"
rule.target = rule.create_target("ACCEPT")
chain.insert_rule(rule)import iptc
table6 = iptc.Table6(iptc.Table.FILTER)
chain = iptc.Chain(table6, "INPUT")
# Rule for ICMPv6 (IPv6 equivalent of ICMP)
rule = iptc.Rule6()
rule.protocol = "ipv6-icmp"
# Add ICMPv6 match for neighbor discovery
icmpv6_match = rule.create_match("icmp6")
icmpv6_match.icmpv6_type = "135" # Neighbor Solicitation
rule.target = rule.create_target("ACCEPT")
chain.insert_rule(rule)
# Rule for IPv6 extension headers
rule2 = iptc.Rule6()
rule2.protocol = "tcp"
# Match IPv6 extension headers
hbh_match = rule2.create_match("hbh") # Hop-by-Hop Options Header
hbh_match.hbh_len = "0"
rule2.target = rule2.create_target("DROP")
chain.insert_rule(rule2)import iptc
# Function to create similar rules for both IPv4 and IPv6
def create_ssh_rule(ipv6=False):
if ipv6:
if not iptc.is_table6_available("filter"):
print("IPv6 not supported")
return
table = iptc.Table6(iptc.Table.FILTER)
rule = iptc.Rule6()
rule.src = "2001:db8::/32"
else:
table = iptc.Table(iptc.Table.FILTER)
rule = iptc.Rule()
rule.src = "192.168.1.0/24"
chain = iptc.Chain(table, "INPUT")
rule.protocol = "tcp"
tcp_match = rule.create_match("tcp")
tcp_match.dport = "22"
rule.target = rule.create_target("ACCEPT")
chain.insert_rule(rule)
# Create rules for both IP versions
create_ssh_rule(ipv6=False) # IPv4 rule
create_ssh_rule(ipv6=True) # IPv6 ruleSince IPv6 doesn't use NAT in the traditional sense, port forwarding and load balancing are handled differently:
import iptc
# IPv6 doesn't have a NAT table, but you can do port redirection
table6 = iptc.Table6(iptc.Table.MANGLE)
chain = iptc.Chain(table6, "PREROUTING")
rule = iptc.Rule6()
rule.protocol = "tcp"
rule.dst = "2001:db8::1"
tcp_match = rule.create_match("tcp")
tcp_match.dport = "80"
# Use REDIRECT target for port redirection
redirect_target = rule.create_target("REDIRECT")
redirect_target.to_ports = "8080"
rule.target = redirect_target
chain.insert_rule(rule)import iptc
def setup_ipv6_firewall():
"""Set up basic IPv6 firewall rules"""
if not iptc.is_table6_available("filter"):
print("IPv6 filtering not available")
return
table6 = iptc.Table6(iptc.Table.FILTER)
# Get chains
input_chain = iptc.Chain(table6, "INPUT")
forward_chain = iptc.Chain(table6, "FORWARD")
output_chain = iptc.Chain(table6, "OUTPUT")
# Set default policies
input_chain.set_policy(iptc.Policy.DROP)
forward_chain.set_policy(iptc.Policy.DROP)
output_chain.set_policy(iptc.Policy.ACCEPT)
# Allow loopback traffic
rule = iptc.Rule6()
rule.in_interface = "lo"
rule.target = rule.create_target("ACCEPT")
input_chain.insert_rule(rule)
# Allow established and related connections
rule = iptc.Rule6()
state_match = rule.create_match("state")
state_match.state = "ESTABLISHED,RELATED"
rule.target = rule.create_target("ACCEPT")
input_chain.insert_rule(rule)
# Allow ICMPv6 (important for IPv6 functionality)
rule = iptc.Rule6()
rule.protocol = "ipv6-icmp"
rule.target = rule.create_target("ACCEPT")
input_chain.insert_rule(rule)
# Allow SSH from specific network
rule = iptc.Rule6()
rule.protocol = "tcp"
rule.src = "2001:db8::/32"
tcp_match = rule.create_match("tcp")
tcp_match.dport = "22"
rule.target = rule.create_target("ACCEPT")
input_chain.insert_rule(rule)
print("IPv6 firewall rules configured")
setup_ipv6_firewall()import iptc
def test_ipv6_addresses():
"""Test various IPv6 address formats"""
table6 = iptc.Table6(iptc.Table.FILTER)
chain = iptc.Chain(table6, "INPUT")
# Test different IPv6 address formats
ipv6_addresses = [
"::1", # Loopback
"::", # All zeros
"2001:db8::1", # Compressed
"2001:0db8:0000:0000:0000:0000:0000:0001", # Full
"fe80::1", # Link-local
"ff02::1", # Multicast
"2001:db8::/32", # Network
"fe80::/64" # Link-local network
]
for addr in ipv6_addresses:
try:
rule = iptc.Rule6()
rule.src = addr
rule.target = rule.create_target("ACCEPT")
# Test the rule (don't actually insert)
print(f"Valid IPv6 address: {addr}")
except Exception as e:
print(f"Invalid IPv6 address {addr}: {e}")
test_ipv6_addresses()Install with Tessl CLI
npx tessl i tessl/pypi-python-iptables