or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

high-level-interface.mdindex.mdipv4-tables-chains.mdipv6-support.mdrules-matches-targets.md

high-level-interface.mddocs/

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

```