Skip to main content

Authenticated UDP Migration

warning

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/.


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 8001

Expected output:

8001/udp ALLOW Anywhere # monad authenticated udp

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.

[[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:

[[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:

  1. Verify you incremented self_record_seq_num correctly
  2. Re-run monad-sign-name-record with the correct seq_num
  3. Copy the new signature to node.toml
  4. 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:

  1. Check logs: journalctl -u monad-bft -n 500 --no-pager
  2. Verify all configuration parameters match the examples
  3. Ensure your firewall and network policies allow UDP/8001
  4. Contact Monad support with your logs and configuration (sanitized of sensitive data)