Authenticated UDP Migration
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.6or later - Access: Root/sudo privileges on your node
- Keystore: Existing
/home/monad/monad-bft/config/id-secpfile - 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/.
2. Configure Firewall
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 8001Expected output:
8001/udp ALLOW Anywhere # monad authenticated udp3. Generate Authentication Signature
Generate your node's authenticated name record signature:
source /home/monad/.envmonad-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-numvalue must be greater than your currentself_record_seq_numinnode.toml.
- If your config shows
self_record_seq_num = 0, use1- If your config shows
self_record_seq_num = 1, use2
Example Output:
self_address = "15.235.224.21:8000"self_record_seq_num = 1authenticated_udp_port = 8001self_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.toml4.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_portparameter
[peer_discovery]self_address = "YOUR_IP:8000"self_auth_port = 8001self_record_seq_num = 1self_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 = 8000authenticated_bind_address_port = 8001 # Add this linemax_rtt_ms = 300max_mbps = 10004.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_numandname_record_sigusing 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.
[[peers]]address = "188.214.131.5:8000"record_seq_num = 1secp256k1_pubkey = "0x0342f3e447bd6951b2cf7cd717958a84e58dbe8cfbe2780f0247c69591216d2d7c"name_record_sig = "0x215e845dade986e48f6fcb1f065f3ff993ddf0d38b0ef41a05f6621d71bf4c6c2d25747629ac8a3d583418857bc0b4c75140202e14919faf643f431ade4b944d00"auth_port = 8001 # Add this for upgraded peersFor peers not yet enabled, nothing needs to be updated, auth_port line should be omited:
[[peers]]address = "188.214.131.6:8000"record_seq_num = 0secp256k1_pubkey = "0x..."name_record_sig = "0x..."# No auth_port - this peer hasn't upgraded yetNote: 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-bftMonitor the logs for successful startup:
journalctl -u monad-bft -f -n 50 --no-pagerVerification
Check Service Status
systemctl status monad-bft --no-pagerExpected: active (running)
Verify Port Binding
sudo ss -ulpn | grep 8001Expected 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_numcorrectly - Re-run
monad-sign-name-recordwith the correct seq_num - Copy the new signature to
node.toml - Restart the service
Issue: Port 8001 Not Listening
Solution:
# Verify configgrep -A5 "\[network\]" /home/monad/monad-bft/config/node.toml | grep authenticated
# Check for startup errorsjournalctl -u monad-bft -n 100 --no-pager | grep -i error
# Restart servicesudo systemctl restart monad-bftIssue: Firewall Blocking Connections
Solution:
# Check current UFW rulessudo ufw status numbered
# Add rule if missingsudo ufw allow 8001/udp comment 'monad authenticated udp'
# Reload firewallsudo ufw reloadRollback Instructions
To disable UDP authentication if needed:
1. Generate New Signature Without Auth Port
source /home/monad/.envmonad-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_numandself_name_record_sigin[peer_discovery] - Remove or comment out
authenticated_bind_address_portin[network] - Remove all
auth_portentries from peer configurations
3. Restart Service
sudo systemctl restart monad-bftQuick Health Check Script
Save this as check_udp_auth.sh for quick verification:
#!/bin/bashecho "=== 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.shExpected 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_numwhen 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)