Protecting your Ethereum node's JSON-RPC interface is crucial for maintaining the security and integrity of your blockchain infrastructure. Exposing the JSON-RPC endpoint directly to the internet without authentication can lead to unauthorized access, data leaks, or denial-of-service attacks. One of the most effective and straightforward methods to secure this endpoint is by using Nginx as a reverse proxy with HTTP Basic Authentication.
This guide walks you through setting up Nginx to protect your Ethereum JSON-RPC API, ensuring only authorized users can interact with your node. Whether you're running a private Dapp, demonstrating a blockchain application, or offering Ethereum functionality as part of a service, this setup enhances security with minimal complexity.
Why Secure Ethereum JSON-RPC?
The Ethereum JSON-RPC API allows applications (Dapps) to communicate with an Ethereum client like Geth (Go Ethereum), enabling functionalities such as querying blockchain data, sending transactions, and interacting with smart contracts. However, Geth and similar clients do not include built-in network-level security features by default.
👉 Discover how secure blockchain access can enhance your development workflow
Even if private APIs are disabled, exposing the JSON-RPC port (typically 8545) publicly leaves your node vulnerable. Attackers can exploit it for spam transactions, resource exhaustion, or unauthorized wallet interactions. Therefore, adding a layer of authentication via Nginx is a best practice for production and demonstration environments alike.
Core Security Keywords
To align with search intent and improve SEO visibility, the following core keywords are naturally integrated throughout this article:
- Ethereum JSON-RPC security
- Nginx reverse proxy
- HTTP Basic Authentication
- Protect Geth API
- Secure blockchain node
- Password-protect Ethereum
- Nginx password protection
- Dapp security
These terms reflect common queries from developers seeking to deploy secure Ethereum-based applications.
Setting Up Nginx with HTTP Basic Auth
Nginx is a high-performance web server and reverse proxy widely used for securing and routing HTTP traffic. By configuring Nginx as a reverse proxy in front of Geth, you can enforce authentication before any request reaches your Ethereum node.
Step 1: Install Nginx and Required Tools
On Ubuntu (14.04 or later), install Nginx along with apache2-utils, which includes the htpasswd tool for managing user credentials:
sudo apt update
sudo apt install nginx apache2-utilsStep 2: Create a Protected User
Use htpasswd to create a password-protected user. The -c flag creates a new file; omit it when adding additional users:
sudo htpasswd -c /etc/nginx/protected.htpasswd demoYou’ll be prompted to enter and confirm a password. This generates a .htpasswd file storing the username and encrypted password.
Step 3: Configure Nginx as a Reverse Proxy
Edit the default site configuration located at /etc/nginx/sites-enabled/default:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name your-domain.com;
# Protect the Ethereum JSON-RPC endpoint
location /eth {
auth_basic "Restricted access to this site";
auth_basic_user_file /etc/nginx/protected.htpasswd;
proxy_pass http://localhost:8545;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Serve static Dapp files with authentication
location / {
root /usr/share/nginx/html;
index index.html;
auth_basic "Restricted access to this site";
auth_basic_user_file /etc/nginx/protected.htpasswd;
}
}This configuration:
- Routes requests to
/ethto the Geth node running onlocalhost:8545 - Applies HTTP Basic Auth to both the API and static file routes
- Preserves original request headers for accurate logging and routing
👉 Learn how professional-grade API protection supports scalable Dapp deployment
Step 4: Start and Configure Geth
Run Geth in the background using screen or a systemd service:
screen -S geth-node
geth --http --http.addr "127.0.0.1" --http.port 8545 --http.api eth,net,web3 --syncmode "fast"Detach from the screen session with Ctrl+A, then D. This ensures Geth runs continuously.
Ensure Geth binds only to localhost (not 0.0.0.0) to prevent direct external access.
Configuring Your Dapp to Use the Secure Endpoint
Update your Dapp’s frontend code (e.g., using web3.js) to connect through the authenticated /eth path:
function getRPCURL() {
if (window.location.hostname === 'your-domain.com') {
return 'http://your-domain.com/eth';
} else {
return 'http://localhost:8545'; // For local development
}
}
web3.setProvider(new web3.providers.HttpProvider(getRPCURL()));Modern browsers will prompt users for a username and password when accessing the protected endpoint—ensuring seamless integration without custom login UIs.
Deploying Static Dapp Files
Place your Dapp’s HTML, CSS, and JavaScript files in /usr/share/nginx/html. You can automate deployment using tools like rsync:
#!/bin/bash
set -e
set -u
REMOTE="your-server"
npm run build
rsync -a -e "ssh" --rsync-path="sudo rsync" dist/* --chown www-data:www-data $REMOTE:/usr/share/nginx/html/This script builds your project and securely copies it to the server while setting correct ownership.
Restart Nginx to Apply Changes
After configuration updates:
sudo service nginx stop
sudo service nginx startOr use:
sudo systemctl restart nginxTesting and Troubleshooting
Access your domain in a browser. You should see a login prompt. After authentication:
- Your Dapp should load correctly
- Web3 connections should successfully query the blockchain
Common issues and solutions:
- 502 Bad Gateway: Geth is not running or unreachable. Verify with
curl http://localhost:8545 - 401 Unauthorized: Incorrect username/password. Recheck
.htpasswdcredentials - Connection refused: Nginx cannot reach Geth. Confirm Geth is bound to
127.0.0.1:8545
Check logs for details:
tail -f /var/log/nginx/error.logFrequently Asked Questions (FAQ)
Q: Is HTTP Basic Authentication secure enough for production?
A: While not foolproof, it provides a strong first layer of defense when combined with HTTPS and restricted IP access. For higher security, consider adding TLS encryption using Let’s Encrypt.
Q: Can I allow multiple users to access the API?
A: Yes. Use sudo htpasswd /etc/nginx/protected.htpasswd anotheruser (without -c) to add more users.
Q: Does this setup work with other Ethereum clients like Parity or Besu?
A: Absolutely. Any client exposing an HTTP-based JSON-RPC API on localhost can be protected using this Nginx configuration.
Q: Should I expose port 8545 publicly after this setup?
A: No. Keep port 8545 closed to external traffic. Only expose port 80 (or 443 with SSL) through Nginx.
Q: How do I automate certificate renewal for HTTPS?
A: Use Certbot with Let’s Encrypt to obtain free SSL certificates and set up auto-renewal via cron.
Q: Can I use API keys instead of username/password?
A: Yes, though that requires custom middleware. HTTP Basic Auth remains the simplest method for small-scale or private deployments.
👉 Explore how secure node access integrates into modern blockchain development platforms
Final Thoughts
Securing your Ethereum JSON-RPC API with Nginx and HTTP Basic Authentication is a simple yet powerful step toward safeguarding your blockchain infrastructure. It strikes an ideal balance between usability and security—perfect for private Dapps, demos, or internal tools.
By following this guide, you ensure that only authenticated users can interact with your Ethereum node, reducing attack surface and enhancing overall system resilience. As blockchain applications grow in complexity and value, foundational security practices like these become indispensable.
Remember: never expose critical APIs without protection. A few lines of Nginx configuration can prevent major security incidents down the line.