
Listener Configuration
Listeners accept incoming peer connections. Each listener binds to an address and transport protocol.
Configuration
Listeners use the global TLS configuration by default:
tls:
ca: "./certs/ca.crt"
cert: "./certs/agent.crt"
key: "./certs/agent.key"
mtls: true
listeners:
- transport: quic # quic, h2, ws
address: "0.0.0.0:4433" # Bind address
Transport Types
QUIC Listener
Best performance, UDP-based:
tls:
ca: "./certs/ca.crt"
cert: "./certs/agent.crt"
key: "./certs/agent.key"
mtls: true
listeners:
- transport: quic
address: "0.0.0.0:4433"
HTTP/2 Listener
TCP-based, firewall-friendly:
listeners:
- transport: h2
address: "0.0.0.0:8443"
path: "/mesh" # Optional URL path
WebSocket Listener
Maximum compatibility:
listeners:
- transport: ws
address: "0.0.0.0:443"
path: "/mesh" # Required for WebSocket
Plain WebSocket (Reverse Proxy)
For deployments behind a reverse proxy that handles TLS termination:
listeners:
- transport: ws
address: "127.0.0.1:8080" # Bind to localhost only
path: "/mesh"
plaintext: true # No TLS - proxy handles it
The plaintext option:
- Accepts unencrypted WebSocket connections (
ws://) - Only available for
wstransport - Does not require TLS certificates
- Should only be used behind trusted reverse proxies
Security considerations:
- Always bind to
127.0.0.1to prevent direct external access - Block the plaintext port from external access via firewall
- mTLS client authentication is not available in this mode
- Peer authentication and end-to-end encryption still work
See Reverse Proxy Deployment for Nginx, Caddy, and Apache configuration examples.
Multiple Listeners
An agent can listen on multiple transports simultaneously:
tls:
ca: "./certs/ca.crt"
cert: "./certs/agent.crt"
key: "./certs/agent.key"
mtls: true
listeners:
# Primary: QUIC for direct connections
- transport: quic
address: "0.0.0.0:4433"
# Fallback: HTTP/2 for firewall traversal
- transport: h2
address: "0.0.0.0:8443"
path: "/mesh"
# Alternative: WebSocket for maximum compatibility
- transport: ws
address: "0.0.0.0:443"
path: "/mesh"
TLS Configuration
Using Global Settings
By default, listeners use the global TLS configuration:
tls:
ca: "./certs/ca.crt"
cert: "./certs/agent.crt"
key: "./certs/agent.key"
mtls: true
listeners:
- transport: quic
address: "0.0.0.0:4433"
# Uses global cert, key, and mtls setting
Per-Listener Overrides
Override specific settings per listener:
tls:
ca: "./certs/ca.crt"
cert: "./certs/agent.crt"
key: "./certs/agent.key"
mtls: true
listeners:
# Uses global settings
- transport: quic
address: "0.0.0.0:4433"
# Override: different certificate
- transport: h2
address: "0.0.0.0:8443"
tls:
cert: "./certs/public.crt"
key: "./certs/public.key"
# Override: disable mTLS
- transport: ws
address: "0.0.0.0:443"
tls:
mtls: false
Mutual TLS (mTLS)
mTLS is controlled by the global mtls setting or per-listener override:
tls:
ca: "./certs/ca.crt"
cert: "./certs/agent.crt"
key: "./certs/agent.key"
mtls: true # Global: require client certs
listeners:
- transport: quic
address: "0.0.0.0:4433"
# mTLS enabled (from global)
- transport: h2
address: "0.0.0.0:8443"
tls:
mtls: false # Override: no client certs required
With mTLS:
- Only peers with valid certificates can connect
- Provides mutual authentication
- Recommended for production
See TLS Configuration for details.
Bind Address
All Interfaces
Accept connections from anywhere:
listeners:
- transport: quic
address: "0.0.0.0:4433" # All IPv4 interfaces
Specific Interface
Bind to specific IP:
listeners:
- transport: quic
address: "192.168.1.10:4433" # Specific interface
IPv6
listeners:
- transport: quic
address: "[::]:4433" # All IPv6 interfaces
Localhost Only
For testing or local-only access:
listeners:
- transport: quic
address: "127.0.0.1:4433" # Localhost only
Port Selection
| Transport | Default Port | Alternative Ports |
|---|---|---|
| QUIC | 4433 | Any UDP port |
| HTTP/2 | 8443, 443 | Any TCP port |
| WebSocket | 443, 80 | Any TCP port |
Firewall Considerations
# For restrictive firewalls, use HTTPS port
listeners:
- transport: h2
address: "0.0.0.0:443"
# Or WebSocket on standard HTTPS
listeners:
- transport: ws
address: "0.0.0.0:443"
path: "/mesh"
URL Path
HTTP/2 and WebSocket support URL paths:
listeners:
- transport: h2
address: "0.0.0.0:443"
path: "/mesh/v1"
Peers must use matching path:
peers:
- transport: h2
address: "server.example.com:443"
path: "/mesh/v1"
Examples
Development
tls:
ca: "./certs/ca.crt"
cert: "./certs/agent.crt"
key: "./certs/agent.key"
mtls: false # Relax for development
listeners:
- transport: quic
address: "127.0.0.1:4433"
Production (Multi-Transport)
tls:
ca: "/etc/muti-metroo/certs/ca.crt"
cert: "/etc/muti-metroo/certs/agent.crt"
key: "/etc/muti-metroo/certs/agent.key"
mtls: true
listeners:
# QUIC for performance
- transport: quic
address: "0.0.0.0:4433"
# HTTP/2 for TCP fallback
- transport: h2
address: "0.0.0.0:443"
path: "/mesh"
Docker/Kubernetes
tls:
ca_pem: "${TLS_CA}"
cert_pem: "${TLS_CERT}"
key_pem: "${TLS_KEY}"
mtls: true
listeners:
- transport: quic
address: "0.0.0.0:4433"
Troubleshooting
Port Already in Use
# Find what's using the port
lsof -i :4433
netstat -tlnp | grep 4433
# Kill the process or choose different port
Permission Denied
Ports below 1024 require root on Linux:
# Option 1: Use port > 1024
address: "0.0.0.0:4433"
# Option 2: Run as root (not recommended)
sudo muti-metroo run -c config.yaml
# Option 3: Use capabilities
sudo setcap 'cap_net_bind_service=+ep' muti-metroo
Certificate Errors
# Verify certificate
muti-metroo cert info ./certs/agent.crt
# Check key matches certificate
openssl x509 -noout -pubkey -in agent.crt | openssl md5
openssl ec -in agent.key -pubout 2>/dev/null | openssl md5
# (should match)
Related
- Peers - Outbound connections
- TLS Certificates - Certificate management
- Transports - Transport comparison