How to Secure Ethereum JSON-RPC API with Password Protection Using Nginx

·

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:

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-utils

Step 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 demo

You’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:

👉 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 start

Or use:

sudo systemctl restart nginx

Testing and Troubleshooting

Access your domain in a browser. You should see a login prompt. After authentication:

Common issues and solutions:

Check logs for details:

tail -f /var/log/nginx/error.log

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