This guide helps you deploy a TRUF.NETWORK node on AWS and expose it to external clients. Follow these steps to configure networking, security groups, and optional DNS settings for your node.
- AWS Account with EC2 access
- EC2 instance running your TN node (see options below)
- Node running and syncing with the network
- Basic familiarity with AWS Console
New to AWS? Check out the AWS EC2 Getting Started Guide first.
Choose how you want to deploy your TN node on AWS:
- AMI Deployment (Recommended) - Pre-configured Amazon Machine Image for 5-10 minute setup
- Manual Setup - Full control with manual installation on any EC2 instance
Already deployed using AMI? Your security groups are likely configured. Skip to Step 2 to find your endpoint URL.
This guide focuses on the networking configuration required to make your node accessible to external applications and the network. You'll configure:
- Security Group rules to allow necessary ports
- Public IP discovery for SDK integration
- Optional Route53 DNS setup for custom domains
- Connectivity testing to verify your setup
Before configuring your security groups, understand which ports your node needs:
| Port | Protocol | Purpose | Source |
|---|---|---|---|
| 6600 | TCP | P2P node communication | 0.0.0.0/0 (All IPv4) |
| 8484 | TCP | RPC service for queries | 0.0.0.0/0 (All IPv4) |
| Port | Protocol | Purpose | Source |
|---|---|---|---|
| 8000 | TCP | MCP Server for AI integration | Your IP or 0.0.0.0/0 |
| 22 | TCP | SSH access | Your IP (recommended) |
| Port | Protocol | Why |
|---|---|---|
| 5432 | TCP | PostgreSQL database - CRITICAL SECURITY RISK if exposed |
Important Notes:
- Port 6600: Enables two-way P2P communication. Your node can sync without this (via outbound connections), but opening it helps network health by accepting incoming peer connections.
- Port 8484: Required if you want users/applications to query data from your node.
- Port 8000: Only needed for MCP/AI integration (like Claude Code).
- Port 5432: Should ONLY bind to localhost (127.0.0.1). Never allow external access.
Security Best Practice: When adding SSH access (port 22), use your specific IP address (e.g.,
203.0.113.1/32) instead of0.0.0.0/0. Allowing SSH from anywhere significantly increases security risk.
Security groups act as virtual firewalls for your EC2 instances, controlling inbound and outbound traffic.
If your EC2 instance already has a security group:
-
Navigate to Security Groups:
- Go to AWS EC2 Console
- In the left navigation pane, under Network & Security, click Security Groups
- Find and select the security group attached to your EC2 instance
-
Add Inbound Rules:
- Click the Inbound rules tab
- Click Edit inbound rules
- Click Add rule for each port you need to open
-
Configure Required Rules:
Rule 1: P2P Communication
- Type: Custom TCP
- Port range:
6600 - Source type: Anywhere-IPv4
- Source:
0.0.0.0/0 - Description:
TN P2P communication
Rule 2: RPC Service
- Type: Custom TCP
- Port range:
8484 - Source type: Anywhere-IPv4
- Source:
0.0.0.0/0 - Description:
TN RPC service
Rule 3: SSH Access (if not already present)
- Type: SSH
- Port range:
22(auto-filled) - Source type: My IP (recommended) or Custom
- Source: Your IP address (e.g.,
203.0.113.1/32) or0.0.0.0/0(less secure) - Description:
SSH access
Optional Rule 4: MCP Server (only if using AI integration)
- Type: Custom TCP
- Port range:
8000 - Source type: My IP or Anywhere-IPv4
- Source: Your IP address or
0.0.0.0/0(depending on your use case) - Description:
MCP Server for AI
-
Save Rules:
- Click Save rules
- Changes take effect immediately
If you prefer to create a dedicated security group for your TN node:
- Navigate to EC2 Console → Network & Security → Security Groups
- Click Create security group
- Configure:
- Security group name:
tn-node-sg(or your preferred name) - Description:
Security group for TRUF.NETWORK node - VPC: Select the same VPC as your EC2 instance
- Security group name:
- Add the inbound rules from Option A above
- Click Create security group
- Attach the security group to your EC2 instance:
- Go to EC2 Dashboard → Instances
- Select your instance
- Actions → Security → Change security groups
- Select your new security group
- Click Save
# SSH into your EC2 instance
ssh -i ~/.ssh/your-key.pem ubuntu@your-instance-ip
# Check that ports 6600 and 8484 are listening
sudo ss -tulpn | grep -E '6600|8484'
# Expected output should show kwild listening on these ports:
# tcp LISTEN 0 4096 0.0.0.0:6600 0.0.0.0:*
# tcp LISTEN 0 4096 0.0.0.0:8484 0.0.0.0:*Your node's endpoint URL requires the EC2 instance's public IP address.
- Go to AWS EC2 Console
- In the left navigation, click Instances
- Find your TN node instance
- Look at the Public IPv4 address column or in the Details tab
If you have AWS CLI installed and configured:
# List all instances with their public IPs
aws ec2 describe-instances \
--query 'Reservations[*].Instances[*].[InstanceId,PublicIpAddress,Tags[?Key==`Name`].Value|[0]]' \
--output table
# Get specific instance public IP by instance ID
aws ec2 describe-instances \
--instance-ids i-1234567890abcdef0 \
--query 'Reservations[*].Instances[*].PublicIpAddress' \
--output text# Method 1: Query external service
curl -4 ifconfig.co
# Method 2: Using AWS EC2 metadata service
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/public-ipv4
# Method 3: Using dig
dig +short myip.opendns.com @resolver1.opendns.comFor a persistent IP address that doesn't change if you stop/start your instance:
- Navigate to EC2 Console → Network & Security → Elastic IPs
- Click Allocate Elastic IP address
- Click Allocate
- Select the newly allocated IP
- Click Actions → Associate Elastic IP address
- Select your EC2 instance
- Click Associate
Note: Elastic IPs are free when associated with a running instance, but you're charged $0.005/hour ($3.60/month) for unassociated Elastic IPs to prevent IP hoarding.
Once you have your public IP address, your node endpoint follows this format:
http://YOUR_EC2_IP:8484
Example:
If your EC2 instance's public IP is 54.210.123.45, your endpoint is:
http://54.210.123.45:8484
Verify that your node is accessible from external clients.
From your local machine (not the EC2 instance):
# Test health check endpoint
curl http://YOUR_EC2_IP:8484/api/v1/health
# Expected response (if healthy):
# {
# "healthy": true,
# "services": {
# "user": {
# "syncing": false,
# "block_height": "12345"
# }
# }
# }# SSH into your EC2 instance
ssh -i ~/.ssh/your-key.pem ubuntu@YOUR_EC2_IP
# If using AMI deployment (Docker):
docker exec tn-node ./kwild admin status
# If using manual setup (systemd):
kwild admin status# From your local machine, test if port 6600 is accessible
nc -zv YOUR_EC2_IP 6600
# Expected output:
# Connection to YOUR_EC2_IP 6600 port [tcp/*] succeeded!If this test fails, verify your security group rules are correctly configured.
Using a custom domain instead of an IP address makes your node endpoint more memorable and portable.
- A domain name (can be registered through Route53 or external registrar)
- Access to your domain's DNS settings
- Go to Route53 Console
- In the left navigation, click Hosted zones
- Click Create hosted zone
- Enter your domain name (e.g.,
example.com) - Choose Public hosted zone
- Click Create hosted zone
- Note the NS (Name Server) records - you'll need these for your domain registrar
If your domain is registered outside of AWS:
- Log in to your domain registrar (e.g., GoDaddy, Namecheap, Google Domains)
- Find DNS/Nameserver settings
- Replace your current nameservers with Route53's NS records:
(Your actual NS records will be different - use the ones from your hosted zone)
ns-1234.awsdns-01.org ns-5678.awsdns-02.co.uk ns-9012.awsdns-03.com ns-3456.awsdns-04.net - Save changes
Note: DNS propagation can take 24-72 hours, though it's usually much faster (within a few hours).
- In Route53 console, select your Hosted zone
- Click Create record
- Configure the record:
- Record name: Leave empty for apex domain (e.g.,
example.com) or enter subdomain (e.g.,nodefornode.example.com) - Record type: Select A - Routes traffic to an IPv4 address
- Value: Enter your EC2 instance's public IP address
- TTL:
300(5 minutes - recommended) or3600(1 hour) - Routing policy: Simple routing
- Record name: Leave empty for apex domain (e.g.,
- Click Create records
If you want more resilience and are using an Elastic IP:
- Click Create record
- Enable Alias toggle
- Configure:
- Record name: Leave empty or enter subdomain
- Record type: A
- Route traffic to:
- Select Alias to Elastic IP address
- Choose your AWS Region
- Select your Elastic IP
- Routing policy: Simple routing
- Click Create records
Advantage of Alias Records: No charge for queries, automatic updates if resource changes, better AWS integration.
If you prefer to keep your current DNS provider:
- Log in to your DNS provider's control panel
- Navigate to DNS management for your domain
- Create an A record:
- Name/Host:
@(apex domain) ornode(subdomain) - Type: A
- Value/Points To: Your EC2 instance's public IP
- TTL: 300 or 3600 seconds
- Name/Host:
- Save the record
# Wait a few minutes after creating the record, then test:
nslookup your-domain.com
# Or using dig:
dig your-domain.com A +short
# Expected output: Your EC2 instance's public IP addressWith DNS configured, your endpoint becomes:
http://your-domain.com:8484
Or for a subdomain:
http://node.your-domain.com:8484
Now that your node is accessible, you can use it with the TRUF.NETWORK SDKs.
import { NodeTNClient, StreamId, EthereumAddress } from '@trufnetwork/sdk-js';
import { Wallet } from 'ethers';
// Initialize client with your node endpoint
const wallet = new Wallet(process.env.PRIVATE_KEY);
const client = new NodeTNClient({
endpoint: 'http://YOUR_EC2_IP:8484', // or your domain
signerInfo: {
address: wallet.address,
signer: wallet,
},
chainId: 'tn-v2.1',
});
// Query stream data
const streamAction = client.loadAction();
const records = await streamAction.getRecord({
stream: {
streamId: StreamId.fromString('st...').throw(),
dataProvider: EthereumAddress.fromString('0x...').throw(),
},
});import (
"context"
"github.com/trufnetwork/kwil-db/core/crypto"
"github.com/trufnetwork/kwil-db/core/crypto/auth"
"github.com/trufnetwork/sdk-go/core/tnclient"
"github.com/trufnetwork/sdk-go/core/types"
)
ctx := context.Background()
// Set up signer
pk, _ := crypto.Secp256k1PrivateKeyFromHex("your-private-key")
signer := &auth.EthPersonalSigner{Key: *pk}
// Connect to your node
tnClient, err := tnclient.NewClient(
ctx,
"http://YOUR_EC2_IP:8484", // or your domain
tnclient.WithSigner(signer),
)
// Query stream data
composedActions, _ := tnClient.LoadComposedActions()
result, err := composedActions.GetRecord(ctx, types.GetRecordInput{
DataProvider: "0x...",
StreamId: "st...",
})CRITICAL: Never expose PostgreSQL port 5432 to the internet.
-
Verify PostgreSQL is bound to localhost only:
sudo ss -tulpn | grep 5432 # Should show 127.0.0.1:5432, NOT 0.0.0.0:5432
-
Ensure security groups don't allow port 5432:
- Check your security group inbound rules
- Port 5432 should NOT be in the list
- If present, remove it immediately
-
Docker users: Ensure PostgreSQL container uses localhost binding:
# Correct (localhost binding) docker run -p 127.0.0.1:5432:5432 ... # WRONG (exposed to internet) docker run -p 5432:5432 ...
For production deployments, consider enabling RPC private mode for enhanced security:
-
Edit your
config.toml:[rpc] # Enforce data privacy: authenticate JSON-RPC call requests private = true
-
Restart your node:
# If using AMI deployment (Docker): sudo systemctl restart tn-node # Or: docker restart tn-node # If using manual setup (systemd): sudo systemctl restart kwild
For more details, see the Kwil Private RPC documentation.
-
Use SSH keys instead of passwords:
# AWS automatically uses SSH keys for EC2 instances # Ensure your key pair is secure and not shared chmod 400 ~/.ssh/your-key.pem
-
Restrict SSH access in security group: Configure your security group to only allow SSH from your IP address (not
0.0.0.0/0). -
Use AWS Systems Manager Session Manager (Alternative):
- Eliminates need to expose port 22
- Provides secure browser-based SSH
- See AWS Session Manager documentation
- Enable VPC Flow Logs: Monitor network traffic for unusual patterns
- Use AWS CloudWatch: Set up alerts for unusual access patterns
- Enable CloudTrail: Audit all AWS API calls for security monitoring
- Consider AWS WAF: If using Application Load Balancer for HTTPS termination
- Regular security group audits: Review and remove unnecessary rules
Keep your system and node software up to date:
# Update system packages
sudo apt update && sudo apt upgrade -yIf using AMI deployment:
# Update Docker images
sudo tn-node-update
# Or manually: cd /opt/tn && sudo -u tn docker compose pull && sudo systemctl restart tn-nodeIf using manual setup:
# Update node binary (if building from source)
cd ~/node
git pull
task build
sudo mv .build/kwild /usr/local/bin/kwild
sudo systemctl restart kwild
# Or download latest release
# See: https://github.com/trufnetwork/node/releasesProblem: curl http://YOUR_EC2_IP:8484/api/v1/health times out or connection refused.
Solutions:
-
Check if kwild is running:
# If using AMI deployment (Docker): docker ps sudo systemctl status tn-node # If using manual setup (systemd): sudo systemctl status kwild
-
Verify kwild is listening on the correct port:
sudo ss -tulpn | grep 8484 -
Check security group rules:
- Go to EC2 Console → Security Groups
- Verify port 8484 is in inbound rules with source
0.0.0.0/0 - Check that the security group is attached to your instance
-
Check Network ACLs (if using custom VPC):
- Go to VPC Console → Network ACLs
- Verify inbound/outbound rules allow port 8484
-
Check kwild configuration:
# If using AMI deployment (Docker): docker exec tn-node ./kwild print-config # If using manual setup (systemd): kwild print-config # Look for rpc.listen_addr (should be 0.0.0.0:8484 for external access)
Problem: Domain doesn't resolve to your EC2 instance's IP.
Solutions:
-
Check if DNS propagation is complete:
dig your-domain.com @8.8.8.8 A +short
-
Verify nameservers (if using Route53):
dig your-domain.com NS +short # Should show Route53 nameservers (ns-*.awsdns-*.*) -
Check Route53 hosted zone:
- Verify A record exists and points to correct IP
- Check record name matches what you're querying
-
Wait for propagation: DNS changes can take up to 72 hours, though usually much faster.
Problem: Node shows syncing: true for extended periods.
Solutions:
-
Check peer connections:
# If using AMI deployment (Docker): docker exec tn-node ./kwild admin status | grep -i peer # If using manual setup (systemd): kwild admin status | grep -i peer
-
Verify port 6600 is accessible:
- Check security group allows inbound on 6600
- Test:
nc -zv YOUR_EC2_IP 6600from external machine
-
Check node logs:
# If using AMI deployment (Docker): docker logs -f tn-node # Or: sudo journalctl -u tn-node -f # If using manual setup (systemd): sudo journalctl -u kwild -f
Problem: Elastic IP doesn't connect to instance.
Solutions:
-
Verify Elastic IP is associated:
- EC2 Console → Elastic IPs
- Check Associated instance ID column
-
Check instance state: Instance must be running
-
Security groups follow Elastic IP: Security groups remain attached even after Elastic IP association
Problem: Unexpected AWS charges.
Common Causes:
- Unassociated Elastic IPs: $0.005/hour each - release unused IPs
- Data transfer: Significant inbound/outbound traffic - monitor CloudWatch metrics
- Instance type: Consider right-sizing (t3.medium vs t3.large)
- EBS volumes: gp3 is more cost-effective than gp2
- Snapshots: Review and delete old EBS snapshots
Cost optimization:
- Use AWS Cost Explorer
- Set up AWS Budgets with alerts
- Consider Reserved Instances for long-term nodes
- Monitor your node: Regularly check sync status
- AMI deployment:
docker exec tn-node ./kwild admin status - Manual setup:
kwild admin status
- AMI deployment:
- Enable extensions: Consider enabling
tn_cachefor better performance (see Node Operator Guide or AMI Deployment Guide)
- AMI Deployment Guide: Quick 5-10 minute AWS setup
- Node Operator Guide: Complete manual setup instructions
- Deployment Options Comparison: Compare all deployment methods
- AWS EC2 Documentation: Official AWS resources
- AWS Route53 Documentation: DNS management
- TRUF.NETWORK SDKs: SDK repositories and examples
Need help? We're here to assist:
- GitHub Issues: Node Repository
- Documentation: Full documentation
Successfully deployed? Consider sharing your node in the Available Nodes List to help grow the network!