Quick Start
Get Ze running with two BGP peers in under 5 minutes.
Build
git clone https://github.com/ze-software/ze.git
cd ze
make build # produces bin/ze, bin/ze-test, bin/ze-chaos
Requires Go 1.26+ on a macOS or Linux development host. Windows is not a supported development platform.
Or: go install
To just get a ze binary without cloning the repo, go install with the same
build tags make build uses:
go install -tags 'ze_core ze_distro ze_gnmi ze_grpc ze_isis ze_ldp ze_lg ze_mcp ze_ospf ze_rest ze_rsvpte ze_ssh ze_telemetry ze_web' codeberg.org/thomas-mangin/ze/cmd/ze@latest
This tracks the module's default branch (development version), not a tagged release -- there are no tagged releases yet.
Initialize
Ze runs an SSH server on localhost for CLI access (ze cli, ze show, ze signal). This keeps the control plane authenticated even in multi-user environments. Set up credentials once:
bin/ze init
This prompts for username, password, SSH host (default 127.0.0.1), port (default 2222), and node name (default: hostname). Credentials are stored locally with bcrypt-hashed passwords. For scripting (later fields fall back to their defaults):
echo -e "admin\nsecret" | bin/ze init
Running ze init a second time will refuse with error: database already exists. To reinitialize, use --force -- this backs up the old database as database.zefs.replaced-<date> before creating a new one:
bin/ze signal stop # stop daemon first
bin/ze init --force # prompts for confirmation, then backs up and reinitializes
Minimal Config
Save as example.conf:
plugin {
internal rib {
use bgp-rib
}
}
bgp {
router-id 10.0.0.1
peer test-peer {
connection {
remote {
ip 10.0.0.2
}
local {
ip 10.0.0.1
}
}
session {
asn {
local 65000
remote 65001
}
family {
ipv4/unicast {
prefix {
maximum 1000000
}
}
}
}
process rib {
receive [ state ]
send [ update ]
}
update {
attribute {
origin igp
next-hop 10.0.0.1
}
nlri {
ipv4/unicast add 192.168.1.0/24
}
}
}
}
Validate
bin/ze config validate example.conf
Expected output:
configuration valid: example.conf
Start
bin/ze example.conf
Ze logs to stderr. You should see something like:
level=INFO msg="hub ready" subsystem=hub plugins=1 peers=1 listen=":179"
level=INFO msg="peer connecting" subsystem=bgp.reactor peer=test-peer address=10.0.0.2
Silence means the default log level (warn) has nothing to report -- that's normal. To see all activity:
bin/ze -d example.conf # debug logging
Verify
In another terminal:
# Check daemon is running
bin/ze status
# List peers
bin/ze cli -c "show bgp peer list"
# Show peer details
bin/ze cli -c "show bgp peer test-peer detail"
# Watch live events
bin/ze cli -c "monitor bgp"
Test Without a Real Peer
Use the built-in test peer to accept any BGP session:
# Terminal 1: start a sink peer (accepts sessions, replies keepalive)
bin/ze-test peer --mode sink --port 1179 --asn 65001
# Terminal 2: start ze with config pointing to localhost:1179
bin/ze example-local.conf
Where example-local.conf is the config above with the peer's connection
block pointed at the local sink, so ze dials 127.0.0.1:1179 instead of
10.0.0.2:
connection {
remote {
ip 127.0.0.1
port 1179
}
local {
ip 127.0.0.1
}
}
The sink's --asn 65001 matches the peer's session { asn { remote 65001 } }.
Stop
bin/ze signal stop # graceful shutdown
bin/ze signal restart # graceful restart (preserves routes via GR)
Next Steps
- Configuration -- peer groups, capabilities, static routes
- Plugins -- RIB, route server, RPKI, graceful restart
- CLI Reference -- interactive CLI, route injection, monitoring
- Logging -- log levels, backends, per-subsystem tuning
- Operations -- SSH setup, signals, health checks, troubleshooting