0
# High-Level Interface
1
2
Simplified dictionary-based interface for common iptables operations provided through the `iptc.easy` module. This interface eliminates the need for object instantiation and provides convenient functions for table, chain, and rule management using dictionary representations of rules.
3
4
## Capabilities
5
6
### Table Management Functions
7
8
High-level functions for managing entire tables and their contents.
9
10
```python { .api }
11
def flush_all(ipv6: bool = False) -> None:
12
"""
13
Flush all available tables.
14
15
Args:
16
ipv6: Use IPv6 tables if True
17
"""
18
19
def flush_table(table: str, ipv6: bool = False, raise_exc: bool = True) -> None:
20
"""
21
Flush all rules from a specific table.
22
23
Args:
24
table: Table name (filter, nat, mangle, raw, security)
25
ipv6: Use IPv6 tables if True
26
raise_exc: Raise exception on failure if True
27
"""
28
29
def flush_chain(table: str, chain: str, ipv6: bool = False, raise_exc: bool = True) -> None:
30
"""
31
Flush all rules from a specific chain.
32
33
Args:
34
table: Table name
35
chain: Chain name
36
ipv6: Use IPv6 tables if True
37
raise_exc: Raise exception on failure if True
38
"""
39
40
def zero_all(ipv6: bool = False) -> None:
41
"""
42
Zero all counters in all available tables.
43
44
Args:
45
ipv6: Use IPv6 tables if True
46
"""
47
48
def zero_table(table: str, ipv6: bool = False, raise_exc: bool = True) -> None:
49
"""
50
Zero all counters in a specific table.
51
52
Args:
53
table: Table name
54
ipv6: Use IPv6 tables if True
55
raise_exc: Raise exception on failure if True
56
"""
57
58
def zero_chain(table: str, chain: str, ipv6: bool = False, raise_exc: bool = True) -> None:
59
"""
60
Zero all counters in a specific chain.
61
62
Args:
63
table: Table name
64
chain: Chain name
65
ipv6: Use IPv6 tables if True
66
raise_exc: Raise exception on failure if True
67
"""
68
69
def get_tables(ipv6: bool = False) -> list:
70
"""
71
Get list of available table names.
72
73
Args:
74
ipv6: Use IPv6 tables if True
75
76
Returns:
77
List of table name strings
78
"""
79
```
80
81
### Chain Management Functions
82
83
Functions for creating, deleting, and managing chains within tables.
84
85
```python { .api }
86
def get_chains(table: str, ipv6: bool = False) -> list:
87
"""
88
Get list of chain names in a table.
89
90
Args:
91
table: Table name
92
ipv6: Use IPv6 tables if True
93
94
Returns:
95
List of chain name strings
96
"""
97
98
def has_chain(table: str, chain: str, ipv6: bool = False) -> bool:
99
"""
100
Check if a chain exists in a table.
101
102
Args:
103
table: Table name
104
chain: Chain name
105
ipv6: Use IPv6 tables if True
106
107
Returns:
108
True if chain exists
109
"""
110
111
def add_chain(table: str, chain: str, ipv6: bool = False, raise_exc: bool = True) -> bool:
112
"""
113
Create a new chain in a table.
114
115
Args:
116
table: Table name
117
chain: Chain name
118
ipv6: Use IPv6 tables if True
119
raise_exc: Raise exception on failure if True
120
121
Returns:
122
True if chain was created successfully
123
"""
124
125
def delete_chain(table: str, chain: str, ipv6: bool = False, flush: bool = False, raise_exc: bool = True) -> None:
126
"""
127
Delete a chain from a table.
128
129
Args:
130
table: Table name
131
chain: Chain name
132
ipv6: Use IPv6 tables if True
133
flush: Flush chain before deleting if True
134
raise_exc: Raise exception on failure if True
135
"""
136
```
137
138
### Rule Management Functions
139
140
Functions for adding, removing, and querying rules using dictionary representations.
141
142
```python { .api }
143
def has_rule(table: str, chain: str, rule_d: dict, ipv6: bool = False) -> bool:
144
"""
145
Check if a rule exists in a chain.
146
147
Args:
148
table: Table name
149
chain: Chain name
150
rule_d: Rule dictionary specification
151
ipv6: Use IPv6 tables if True
152
153
Returns:
154
True if rule exists
155
"""
156
157
def add_rule(table: str, chain: str, rule_d: dict, position: int = 0, ipv6: bool = False) -> None:
158
"""
159
Add a rule to a chain.
160
161
Args:
162
table: Table name
163
chain: Chain name
164
rule_d: Rule dictionary specification
165
position: Position to insert (0 = append to end)
166
ipv6: Use IPv6 tables if True
167
"""
168
169
def insert_rule(table: str, chain: str, rule_d: dict, ipv6: bool = False) -> None:
170
"""
171
Insert a rule at the beginning of a chain.
172
173
Args:
174
table: Table name
175
chain: Chain name
176
rule_d: Rule dictionary specification
177
ipv6: Use IPv6 tables if True
178
"""
179
180
def delete_rule(table: str, chain: str, rule_d: dict, ipv6: bool = False, raise_exc: bool = True) -> None:
181
"""
182
Delete a rule from a chain.
183
184
Args:
185
table: Table name
186
chain: Chain name
187
rule_d: Rule dictionary specification
188
ipv6: Use IPv6 tables if True
189
raise_exc: Raise exception on failure if True
190
"""
191
192
def get_rule(table: str, chain: str, position: int = 0, ipv6: bool = False, raise_exc: bool = True) -> dict:
193
"""
194
Get rule(s) from a chain.
195
196
Args:
197
table: Table name
198
chain: Chain name
199
position: Rule position (0 = all rules, >0 = specific rule)
200
ipv6: Use IPv6 tables if True
201
raise_exc: Raise exception on failure if True
202
203
Returns:
204
Rule dictionary (if position > 0) or list of rule dictionaries (if position = 0)
205
"""
206
207
def replace_rule(table: str, chain: str, old_rule_d: dict, new_rule_d: dict, ipv6: bool = False) -> None:
208
"""
209
Replace an existing rule with a new rule.
210
211
Args:
212
table: Table name
213
chain: Chain name
214
old_rule_d: Existing rule dictionary to replace
215
new_rule_d: New rule dictionary
216
ipv6: Use IPv6 tables if True
217
"""
218
219
def get_rule_counters(table: str, chain: str, rule_d: dict, ipv6: bool = False) -> tuple:
220
"""
221
Get packet and byte counters for a specific rule.
222
223
Args:
224
table: Table name
225
chain: Chain name
226
rule_d: Rule dictionary specification
227
ipv6: Use IPv6 tables if True
228
229
Returns:
230
Tuple of (packets, bytes)
231
"""
232
233
def get_rule_position(table: str, chain: str, rule_d: dict, ipv6: bool = False) -> int:
234
"""
235
Get the position of a rule in a chain.
236
237
Args:
238
table: Table name
239
chain: Chain name
240
rule_d: Rule dictionary specification
241
ipv6: Use IPv6 tables if True
242
243
Returns:
244
Rule position (1-based index)
245
"""
246
```
247
248
### Policy Management Functions
249
250
Functions for managing chain default policies.
251
252
```python { .api }
253
def get_policy(table: str, chain: str, ipv6: bool = False) -> str:
254
"""
255
Get the default policy for a chain.
256
257
Args:
258
table: Table name
259
chain: Chain name (built-in chains only)
260
ipv6: Use IPv6 tables if True
261
262
Returns:
263
Policy name string (ACCEPT, DROP, etc.)
264
"""
265
266
def set_policy(table: str, chain: str, policy: str = 'ACCEPT', ipv6: bool = False) -> None:
267
"""
268
Set the default policy for a chain.
269
270
Args:
271
table: Table name
272
chain: Chain name (built-in chains only)
273
policy: Policy name (ACCEPT, DROP, QUEUE, RETURN)
274
ipv6: Use IPv6 tables if True
275
"""
276
```
277
278
### Dump Functions
279
280
Functions for retrieving complete iptables state as structured data.
281
282
```python { .api }
283
def dump_all(ipv6: bool = False) -> dict:
284
"""
285
Get complete iptables state as nested dictionary.
286
287
Args:
288
ipv6: Use IPv6 tables if True
289
290
Returns:
291
Dictionary with all tables, chains, and rules
292
"""
293
294
def dump_table(table: str, ipv6: bool = False) -> dict:
295
"""
296
Get table state as dictionary.
297
298
Args:
299
table: Table name
300
ipv6: Use IPv6 tables if True
301
302
Returns:
303
Dictionary with chains and rules for the table
304
"""
305
306
def dump_chain(table: str, chain: str, ipv6: bool = False) -> list:
307
"""
308
Get all rules in a chain as list of dictionaries.
309
310
Args:
311
table: Table name
312
chain: Chain name
313
ipv6: Use IPv6 tables if True
314
315
Returns:
316
List of rule dictionaries
317
"""
318
```
319
320
### Batch Operations
321
322
Functions for performing multiple operations efficiently with disabled autocommit.
323
324
```python { .api }
325
def batch_begin(table: str = None, ipv6: bool = False) -> None:
326
"""
327
Start batch mode by disabling autocommit.
328
329
Args:
330
table: Table name (if None, affects all tables)
331
ipv6: Use IPv6 tables if True
332
"""
333
334
def batch_end(table: str = None, ipv6: bool = False) -> None:
335
"""
336
End batch mode by committing changes and re-enabling autocommit.
337
338
Args:
339
table: Table name (if None, affects all tables)
340
ipv6: Use IPv6 tables if True
341
"""
342
343
def batch_add_rules(table: str, batch_rules: list, ipv6: bool = False) -> None:
344
"""
345
Add multiple rules in batch mode.
346
347
Args:
348
table: Table name
349
batch_rules: List of (chain_name, rule_dict) tuples
350
ipv6: Use IPv6 tables if True
351
"""
352
```
353
354
### Validation Functions
355
356
Functions for testing rule validity without actually applying changes.
357
358
```python { .api }
359
def test_rule(rule_d: dict, ipv6: bool = False) -> bool:
360
"""
361
Test if a rule dictionary is valid.
362
363
Args:
364
rule_d: Rule dictionary to test
365
ipv6: Use IPv6 validation if True
366
367
Returns:
368
True if rule is valid
369
"""
370
371
def test_match(name: str, value, ipv6: bool = False) -> bool:
372
"""
373
Test if a match specification is valid.
374
375
Args:
376
name: Match name
377
value: Match parameters (string or dict)
378
ipv6: Use IPv6 validation if True
379
380
Returns:
381
True if match is valid
382
"""
383
384
def test_target(name: str, value, ipv6: bool = False) -> bool:
385
"""
386
Test if a target specification is valid.
387
388
Args:
389
name: Target name
390
value: Target parameters (string or dict)
391
ipv6: Use IPv6 validation if True
392
393
Returns:
394
True if target is valid
395
"""
396
```
397
398
### Rule Dictionary Conversion
399
400
Functions for converting between Rule objects and dictionary representations.
401
402
```python { .api }
403
def encode_iptc_rule(rule_d: dict) -> 'Rule':
404
"""
405
Convert rule dictionary to Rule object.
406
407
Args:
408
rule_d: Rule dictionary specification
409
410
Returns:
411
Rule object
412
"""
413
414
def decode_iptc_rule(rule: 'Rule') -> dict:
415
"""
416
Convert Rule object to dictionary representation.
417
418
Args:
419
rule: Rule object
420
421
Returns:
422
Rule dictionary
423
"""
424
```
425
426
## Usage Examples
427
428
### Basic Rule Management
429
430
```python
431
import iptc.easy as easy
432
433
# Add a simple rule using dictionary
434
rule_dict = {
435
'protocol': 'tcp',
436
'src': '192.168.1.0/24',
437
'tcp': {'dport': '22'},
438
'target': 'ACCEPT',
439
'comment': {'comment': 'Allow SSH from LAN'}
440
}
441
442
# Insert rule at beginning of INPUT chain
443
easy.insert_rule('filter', 'INPUT', rule_dict)
444
445
# Check if rule exists
446
if easy.has_rule('filter', 'INPUT', rule_dict):
447
print("Rule exists")
448
449
# Get all rules in chain
450
rules = easy.dump_chain('filter', 'INPUT')
451
for rule in rules:
452
print(rule)
453
454
# Delete the rule
455
easy.delete_rule('filter', 'INPUT', rule_dict)
456
```
457
458
### Chain Management
459
460
```python
461
import iptc.easy as easy
462
463
# Create custom chain
464
easy.add_chain('filter', 'my_custom_chain')
465
466
# Check if chain exists
467
if easy.has_chain('filter', 'my_custom_chain'):
468
print("Chain created successfully")
469
470
# List all chains in filter table
471
chains = easy.get_chains('filter')
472
print("Available chains:", chains)
473
474
# Add rule to custom chain
475
rule_dict = {
476
'protocol': 'tcp',
477
'tcp': {'dport': '80'},
478
'target': 'ACCEPT'
479
}
480
easy.add_rule('filter', 'my_custom_chain', rule_dict)
481
482
# Delete chain (flush first)
483
easy.delete_chain('filter', 'my_custom_chain', flush=True)
484
```
485
486
### Policy Management
487
488
```python
489
import iptc.easy as easy
490
491
# Set restrictive default policies
492
easy.set_policy('filter', 'INPUT', 'DROP')
493
easy.set_policy('filter', 'FORWARD', 'DROP')
494
easy.set_policy('filter', 'OUTPUT', 'ACCEPT')
495
496
# Check current policies
497
input_policy = easy.get_policy('filter', 'INPUT')
498
print(f"INPUT policy: {input_policy}")
499
```
500
501
### Complex Rule Examples
502
503
```python
504
import iptc.easy as easy
505
506
# Multi-match rule with state and tcp
507
rule_dict = {
508
'protocol': 'tcp',
509
'tcp': {'dport': '80'},
510
'state': {'state': 'NEW,ESTABLISHED'},
511
'target': 'ACCEPT',
512
'comment': {'comment': 'Allow new HTTP connections'}
513
}
514
easy.add_rule('filter', 'INPUT', rule_dict)
515
516
# NAT rule for port forwarding
517
nat_rule = {
518
'protocol': 'tcp',
519
'dst': '203.0.113.1',
520
'tcp': {'dport': '80'},
521
'target': {'DNAT': {'to-destination': '192.168.1.100:8080'}}
522
}
523
easy.add_rule('nat', 'PREROUTING', nat_rule)
524
525
# Rule with negation
526
block_rule = {
527
'protocol': 'tcp',
528
'tcp': {'dport': '22'},
529
'mac': {'mac-source': '!00:11:22:33:44:55'},
530
'target': 'DROP'
531
}
532
easy.add_rule('filter', 'INPUT', block_rule)
533
```
534
535
### Batch Operations
536
537
```python
538
import iptc.easy as easy
539
540
# Start batch mode for efficient multiple operations
541
easy.batch_begin('filter')
542
543
# Add multiple rules
544
rules = [
545
('INPUT', {'protocol': 'tcp', 'tcp': {'dport': '22'}, 'target': 'ACCEPT'}),
546
('INPUT', {'protocol': 'tcp', 'tcp': {'dport': '80'}, 'target': 'ACCEPT'}),
547
('INPUT', {'protocol': 'tcp', 'tcp': {'dport': '443'}, 'target': 'ACCEPT'}),
548
]
549
550
easy.batch_add_rules('filter', rules)
551
552
# Commit all changes at once
553
easy.batch_end('filter')
554
```
555
556
### Complete Firewall Setup
557
558
```python
559
import iptc.easy as easy
560
561
def setup_basic_firewall():
562
"""Set up a basic firewall configuration"""
563
564
# Set default policies
565
easy.set_policy('filter', 'INPUT', 'DROP')
566
easy.set_policy('filter', 'FORWARD', 'DROP')
567
easy.set_policy('filter', 'OUTPUT', 'ACCEPT')
568
569
# Allow loopback
570
easy.add_rule('filter', 'INPUT', {
571
'in_interface': 'lo',
572
'target': 'ACCEPT'
573
})
574
575
# Allow established connections
576
easy.add_rule('filter', 'INPUT', {
577
'state': {'state': 'ESTABLISHED,RELATED'},
578
'target': 'ACCEPT'
579
})
580
581
# Allow SSH from management network
582
easy.add_rule('filter', 'INPUT', {
583
'protocol': 'tcp',
584
'src': '192.168.100.0/24',
585
'tcp': {'dport': '22'},
586
'target': 'ACCEPT',
587
'comment': {'comment': 'SSH from management'}
588
})
589
590
# Allow HTTP and HTTPS
591
for port in ['80', '443']:
592
easy.add_rule('filter', 'INPUT', {
593
'protocol': 'tcp',
594
'tcp': {'dport': port},
595
'state': {'state': 'NEW,ESTABLISHED'},
596
'target': 'ACCEPT'
597
})
598
599
print("Basic firewall configured")
600
601
setup_basic_firewall()
602
```
603
604
### IPv6 Support
605
606
```python
607
import iptc.easy as easy
608
609
# IPv6 rule using the same interface
610
ipv6_rule = {
611
'protocol': 'tcp',
612
'src': '2001:db8::/32',
613
'tcp': {'dport': '22'},
614
'target': 'ACCEPT'
615
}
616
617
# Add IPv6 rule
618
easy.add_rule('filter', 'INPUT', ipv6_rule, ipv6=True)
619
620
# Dump IPv6 rules
621
ipv6_rules = easy.dump_chain('filter', 'INPUT', ipv6=True)
622
print("IPv6 rules:", ipv6_rules)
623
```
624
625
### Error Handling and Validation
626
627
```python
628
import iptc.easy as easy
629
630
# Test rule validity before adding
631
rule_dict = {
632
'protocol': 'tcp',
633
'tcp': {'dport': '80'},
634
'target': 'ACCEPT'
635
}
636
637
if easy.test_rule(rule_dict):
638
easy.add_rule('filter', 'INPUT', rule_dict)
639
print("Rule added successfully")
640
else:
641
print("Invalid rule")
642
643
# Test individual matches and targets
644
if easy.test_match('tcp', {'dport': '80'}):
645
print("Valid TCP match")
646
647
if easy.test_target('ACCEPT', None):
648
print("Valid ACCEPT target")
649
650
# Safe operations with exception handling
651
try:
652
easy.delete_rule('filter', 'INPUT', rule_dict, raise_exc=True)
653
except Exception as e:
654
print(f"Failed to delete rule: {e}")
655
```
656
657
## Rule Dictionary Format
658
659
The rule dictionary format uses the following structure:
660
661
```python
662
rule_dict = {
663
# Basic packet matching
664
'src': '192.168.1.0/24', # Source address/network
665
'dst': '10.0.0.1', # Destination address
666
'protocol': 'tcp', # Protocol (tcp, udp, icmp, etc.)
667
'in_interface': 'eth0', # Input interface
668
'out_interface': 'eth1', # Output interface
669
670
# Protocol-specific matches (match name as key)
671
'tcp': {
672
'sport': '80', # Source port
673
'dport': '443', # Destination port
674
'tcp_flags': 'SYN,ACK SYN' # TCP flags
675
},
676
677
'udp': {
678
'sport': '53',
679
'dport': '53'
680
},
681
682
'state': {
683
'state': 'NEW,ESTABLISHED,RELATED'
684
},
685
686
'comment': {
687
'comment': 'Rule description'
688
},
689
690
# Target (required)
691
'target': 'ACCEPT', # Simple target
692
693
# Or complex target with parameters
694
'target': {
695
'DNAT': {
696
'to-destination': '192.168.1.100:8080'
697
}
698
},
699
700
# Counters (optional)
701
'counters': (100, 5000) # (packets, bytes)
702
}
703
```