> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monad.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Authenticated UDP Migration

<Warning>
  Please do not proceed until Monad Foundation provides notice.
</Warning>

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

```bash theme={null}
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/](https://docs.monad.xyz/node-ops/upgrade-instructions/).

***

### 2. Configure Firewall

Open UDP port 8001 for authenticated traffic:

```bash theme={null}
sudo ufw allow 8001/udp comment 'monad authenticated udp'
```

Verify the rule was added:

```bash theme={null}
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:

```bash theme={null}
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:

```bash theme={null}
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

```toml theme={null}
[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]`:

```toml theme={null}
[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`.

```toml theme={null}
[[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:

```toml theme={null}
[[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:

```bash theme={null}
sudo systemctl restart monad-bft
```

Monitor the logs for successful startup:

```bash theme={null}
journalctl -u monad-bft -f -n 50 --no-pager
```

***

## Verification

### Check Service Status

```bash theme={null}
systemctl status monad-bft --no-pager
```

Expected: `active (running)`

### Verify Port Binding

```bash theme={null}
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:**

```bash theme={null}
# 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:**

```bash theme={null}
# 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

```bash theme={null}
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

```bash theme={null}
sudo systemctl restart monad-bft
```

***

## Quick Health Check Script

Save this as `check_udp_auth.sh` for quick verification:

```bash theme={null}
#!/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:

```bash theme={null}
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)
