Please do not proceed until Monad Foundation provides notice.
Overview
UDP Authentication provides secure, authenticated peer-to-peer communication for Monad nodes. This feature is currently opt-in and will become required in a future release.
Benefits:
- Enhanced Security: Cryptographically authenticated peer connections using your existing validator keys
- DoS Protection: Prevents resource exhaustion from spoofed packets
- Traffic Prioritization: Enables efficient QoS policies for transaction forwarding
- Performance: ~100x faster packet verification compared to per-packet ECDSA signatures
Prerequisites
- Monad Version:
0.12.6 or later
- Access: Root/sudo privileges on your node
- Keystore: Existing
/home/monad/monad-bft/config/id-secp file
- Network: Ability to open UDP port 8001 on your firewall
Instructions for node operators
1. Verify the Monad version
Verify the installation:
monad-node --version
# Expected output 0.12.6+
If not, please refer to the official documentation to upgrade to the latest recommended version: https://docs.monad.xyz/node-ops/upgrade-instructions/.
Open UDP port 8001 for authenticated traffic:
sudo ufw allow 8001/udp comment 'monad authenticated udp'
Verify the rule was added:
sudo ufw status | grep 8001
Expected output:
8001/udp ALLOW Anywhere # monad authenticated udp
Note: if the node is behind a Network Firewall, make sure to also open the port 8001.
3. Generate Authentication Signature
Generate your node’s authenticated name record signature:
source /home/monad/.env
monad-sign-name-record \
--address $(curl -4 -s ifconfig.me):8000 \
--authenticated-udp-port 8001 \
--self-record-seq-num 1 \
--keystore-path /home/monad/monad-bft/config/id-secp \
--password "$KEYSTORE_PASSWORD"
Important: The --self-record-seq-num value must be greater than your current self_record_seq_num in node.toml.
- If your config shows
self_record_seq_num = 0, use 1
- If your config shows
self_record_seq_num = 1, use 2
Example Output:
self_address = "15.235.224.21:8000"
self_record_seq_num = 1
authenticated_udp_port = 8001
self_name_record_sig = "f754ed009f82a5c0e402b8f573a1b7e44e9f5fc957cf6360316b5a3baf617f0d1ffe23558845747dd21a51408ac2555a4f4bb70a0032cdf59921d5905663e41200"
Warning: do not copy the authenticated_udp_port parameter, as the parameter name in node.toml is self_auth_port.
Save this output - you’ll need it in the next step.
4. Update Configuration
Edit your Monad configuration:
sudo vim /home/monad/monad-bft/config/node.toml
4.1 Update Peer Discovery Section
In the node configuration:
- replace the values in the
[peer_discovery] section with your output from Step 3
- add the
self_auth_port parameter
[peer_discovery]
self_address = "YOUR_IP:8000"
self_auth_port = 8001
self_record_seq_num = 1
self_name_record_sig = "YOUR_GENERATED_SIGNATURE_FROM_STEP_3"
4.2 Update Network Section
Add the authenticated_bind_address_port parameter to [network]:
[network]
bind_address_host = "0.0.0.0"
bind_address_port = 8000
authenticated_bind_address_port = 8001 # Add this line
max_rtt_ms = 300
max_mbps = 1000
4.3 Update Peer Records (Validators Only)
If you operate a validator with downstream full nodes, update peer configurations as they enable UDP authentication.
For peers that have enabled UDP authentication:
- update
record_seq_num and name_record_sig using the new values of the downstream node
- set the
auth_port = 8001
Note: Authenticated UDP activated nodes would appear in the peers.toml file with auth_port = 8001.
[[bootstrap.peers]]
address = "188.214.131.5:8000"
record_seq_num = 1
secp256k1_pubkey = "0x0342f3e447bd6951b2cf7cd717958a84e58dbe8cfbe2780f0247c69591216d2d7c"
name_record_sig = "0x215e845dade986e48f6fcb1f065f3ff993ddf0d38b0ef41a05f6621d71bf4c6c2d25747629ac8a3d583418857bc0b4c75140202e14919faf643f431ade4b944d00"
auth_port = 8001 # Add this for upgraded peers
For peers not yet enabled, nothing needs to be updated, auth_port line should be omited:
[[bootstrap.peers]]
address = "188.214.131.6:8000"
record_seq_num = 0
secp256k1_pubkey = "0x..."
name_record_sig = "0x..."
# No auth_port - this peer hasn't upgraded yet
Note: the downstream nodes peering configuration do not need to be updated.
Save and exit the file.
5. Restart and Verify
Restart the Monad service:
sudo systemctl restart monad-bft
Monitor the logs for successful startup:
journalctl -u monad-bft -f -n 50 --no-pager
Verification
Check Service Status
systemctl status monad-bft --no-pager
Expected: active (running)
Verify Port Binding
sudo ss -ulpn | grep 8001
Expected output:
udp UNCONN 0 0 0.0.0.0:8001 0.0.0.0:* users:(("monad-node",pid=12345,fd=20))
Troubleshooting
Issue: “invalid name record signature in config file”
Cause: The signature in node.toml doesn’t match the parameters.
Solution:
- Verify you incremented
self_record_seq_num correctly
- Re-run
monad-sign-name-record with the correct seq_num
- Copy the new signature to
node.toml
- Restart the service
Issue: Port 8001 Not Listening
Solution:
# Verify config
grep -A5 "\[network\]" /home/monad/monad-bft/config/node.toml | grep authenticated
# Check for startup errors
journalctl -u monad-bft -n 100 --no-pager | grep -i error
# Restart service
sudo systemctl restart monad-bft
Issue: Firewall Blocking Connections
Solution:
# Check current UFW rules
sudo ufw status numbered
# Add rule if missing
sudo ufw allow 8001/udp comment 'monad authenticated udp'
# Reload firewall
sudo ufw reload
Rollback Instructions
To disable UDP authentication if needed:
1. Generate New Signature Without Auth Port
source /home/monad/.env
monad-sign-name-record \
--address $(curl -4 -s ifconfig.me):8000 \
--self-record-seq-num 2 \
--keystore-path /home/monad/monad-bft/config/id-secp \
--password "$KEYSTORE_PASSWORD"
Note: Increment the seq_num from your current value.
2. Update Configuration
Edit /home/monad/monad-bft/config/node.toml:
- Update
self_record_seq_num and self_name_record_sig in [peer_discovery]
- Remove or comment out
authenticated_bind_address_port in [network]
- Remove all
auth_port entries from peer configurations
3. Restart Service
sudo systemctl restart monad-bft
Quick Health Check Script
Save this as check_udp_auth.sh for quick verification:
#!/bin/bash
echo "=== Monad UDP Authentication Health Check ==="
echo ""
echo "Checking Monad version..."
monad-node --version 2>/dev/null || echo "monad-node not found"
echo ""
echo "Checking firewall rule..."
sudo ufw status | grep 8001 || echo "No UFW rule for 8001/udp"
echo ""
echo "Checking port binding..."
sudo ss -tulpn | grep 8001 || echo "Port 8001 not bound"
echo ""
echo "Checking service status..."
systemctl is-active monad-bft || echo "Service not active"
echo ""
echo "Checking configuration..."
grep -q "authenticated_bind_address_port = 8001" /home/monad/monad-bft/config/node.toml && \
echo "authenticated_bind_address_port configured" || \
echo "authenticated_bind_address_port not found"
echo ""
echo "Complete!"
Make it executable:
chmod +x check_udp_auth.sh
./check_udp_auth.sh
Expected output:
=== Monad UDP Authentication Health Check ===
Checking Monad version...
monad-node {"commit":"e1e9489b8fc42c0a5af208bab20f6704f83c91c0","tag":"v0.12.7","branch":"","modified":true}
Checking firewall rule...
8001/udp ALLOW Anywhere # authenticated udp port
Checking port binding...
udp UNCONN 0 0 0.0.0.0:8001 0.0.0.0:* users:(("monad-node",pid=3433495,fd=13))
Checking service status...
active
Checking configuration...
authenticated_bind_address_port configured
Complete!
Additional Notes
- Backward Compatibility: Nodes can communicate with both authenticated and non-authenticated peers
- Gradual Rollout: You can enable authentication at your own pace during the opt-in period
- Future Requirement: UDP authentication will become mandatory in a future release (date TBD)
- Sequence Numbers: Always increment
self_record_seq_num when regenerating signatures
- Key Reuse: Authentication uses your existing validator keys (secp256k1)
Support
If you encounter issues not covered in this guide:
- Check logs:
journalctl -u monad-bft -n 500 --no-pager
- Verify all configuration parameters match the examples
- Ensure your firewall and network policies allow UDP/8001
- Contact Monad support with your logs and configuration (sanitized of sensitive data)