nff/README.md

243 lines
5.9 KiB
Markdown

# nff
This is a high performance configuration parser and written in Rust. The goal is
to receive possibly jumbled up nftables rule files, and output ✨ pretty ✨
human readable output in return. The main emphasis is on the syntax-aware
formatting with comprehensive grammar support. It is a future goal to allow
editors to hook into nff in order to format your rulesets directly from your
editor, or as a diagnostics source.
## Features
nff is in its early stages of development. While _most_ of the syntax is
supported, I cannot guarantee that _everything_ is supported just yet.
### Core Functionality
- **Syntax-aware formatting** - Deep understanding of nftables grammar with
semantic preservation
- **Multi-family support** - Handles `inet`, `ip`, `ip6`, `arp`, `bridge`, and
`netdev` table families
- **Flexible indentation** - Configurable tabs/spaces with custom depth
- **CIDR notation** - Proper handling of network addresses (`192.168.1.0/24`)
- **Chain properties** - Hooks, priorities (including negative), policies,
device bindings
### Advanced Features
- **CST** - Lossless representation preserving all tokens
- **Debug mode** - Comprehensive inspection of lexer tokens, AST, and CST
- **Validation** - Syntax checking with precise error locations
- **Optimization** - Configurable empty line reduction and whitespace control
## Usage
```bash
# Basic formatting
nff -f /etc/nftables.conf
# Custom indentation (4 spaces)
nff -f config.nft --indent spaces --spaces 4
# Optimize formatting (reduce empty lines)
nff -f config.nft --optimize
# Output to file
nff -f config.nft -o formatted.nft
# Syntax validation only
nff -f config.nft --check
# Debug output for development (or debugging)
nff -f config.nft --debug
```
## Architecture
### Processing Pipeline
nff implements a multi-stage pipeline:
```mermaid
graph TD
Input --> Lexer
Lexer --> Tokens
Lexer --> Parser
Tokens --> Parser
Parser --> CST
Parser --> AST
AST --> Formatter
Formatter --> Output
CST --> Formatter
```
## Installation
Recommended way of installing nff is to use Nix.
## Development
### Testing
```bash
# Run test suite
cargo test
# Run with verbose output
cargo test -- --nocapture
# Test specific module
cargo test lexer
```
### Code Quality
```bash
# Check compilation
cargo check
# Format code
cargo fmt
# Lint code
cargo clippy
# Check for unused dependencies
cargo machete
```
## Supported nftables Features
### Table Families
- **inet** - Dual-stack IPv4/IPv6 (most common)
- **ip** - IPv4 only
- **ip6** - IPv6 only
- **arp** - ARP protocol
- **bridge** - Bridge/Layer 2
- **netdev** - Network device (ingress/egress)
### Chain Types & Hooks
- **filter**: `input`, `forward`, `output`
- **nat**: `prerouting`, `input`, `output`, `postrouting`
- **route**: `output`
- **security**: `input`, `forward`, `output`
### Expression Types
- **Protocol matching**: `ip protocol tcp`, `tcp dport 80`
- **Interface matching**: `iifname "eth0"`, `oifname "wlan0"`
- **Address matching**: `ip saddr 192.168.1.0/24`, `ip6 daddr ::1`
- **Connection tracking**: `ct state established,related`
- **Port specifications**: `tcp dport { 22, 80, 443 }`
- **Rate limiting**: `limit rate 10/minute burst 5 packets`
- **Sets and maps**: Named sets with timeout support
### Actions & Statements
- **Verdicts**: `accept`, `drop`, `reject`, `return`
- **NAT**: `snat to 192.168.1.1`, `dnat to 192.168.1.100:80`
- **Marking**: `mark set 0x1`, `ct mark set 0x1`
- **Logging**: `log prefix "dropped: "`
- **Counters**: `counter packets 0 bytes 0`
## Examples
### Basic Firewall
Input (minified):
```nftables
table inet firewall{chain input{type filter hook input priority 0;policy drop;ct state established,related accept;iifname lo accept;tcp dport 22 accept}}
```
Output (formatted):
```nftables
#!/usr/sbin/nft -f
table inet firewall {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iifname lo accept
tcp dport 22 accept
}
}
```
### NAT Configuration
```nftables
#!/usr/sbin/nft -f
table ip nat {
chain prerouting {
type nat hook prerouting priority -100; policy accept;
iifname "eth0" tcp dport 80 dnat to 192.168.1.100:8080
}
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oifname "eth0" masquerade
}
}
```
### Rate Limiting
```nftables
#!/usr/sbin/nft -f
table inet protection {
chain input {
type filter hook input priority 0; policy accept;
tcp dport 22 limit rate 5/minute burst 10 packets accept
tcp dport 22 drop
}
}
```
## Contributing
### Code Style
- Follow `cargo fmt` formatting
- Use `cargo clippy` recommendations
- Maintain comprehensive documentation
- Add tests for new features
### Testing Strategy (WIP)
- **Unit tests**: Individual component validation
- **Integration tests**: End-to-end formatting verification
- **Regression tests**: Known issue prevention
- **Performance tests**: Benchmark critical paths
### Building
Build with `cargo build` as usual. If you are using Nix, you will also want to
ensure that the Nix package builds as expected.
## Technical Notes
### CST Implementation
The Concrete Syntax Tree (CST) preserves all source information including:
- Whitespace and indentation
- Comments and their positions
- Token-level error recovery
- Lossless round-trip formatting
### Parser Architecture
Below are the design goals of nff's architechture.
- **Error recovery**: Continues parsing after syntax errors
- **Incremental parsing**: Supports partial file processing
- **Memory efficiency**: Streaming token processing where possible
- **Grammar completeness**: Covers full nftables syntax specification
## License
nff is licensed under [MPL v2.0](LICENSE). See license file for more details on
what the license entails.