Skip to main content

v0.12.6 - Authenticated UDP Migration

warning

These instructions are only applicable to testnet. This can be ignored for mainnet.

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: monad-node 0.12.6

If not, please refer to the official documentation to upgrade: https://docs.monad.xyz/node-ops/upgrade-instructions/v0.12.6.


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":"","tag":"0.12.3","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)