Skip to content

Guide

Exposing RPC without giving it away

No. An open JSON-RPC port is an unauthenticated public interface to your node with no rate limit and no accounting — what to bind, what to put in front of it, and which namespaces never belong on a listener anybody else can reach.

Running a nodeAll three chainsUpdated 16 August 2026

Why not just open the port

This is the one part of running a node that is identical on every chain, which is why it is its own article rather than the same three paragraphs repeated in three others. The port numbers differ — 8545 on Ethereum and BNB Smart Chain, 8899 on Solana — and nothing else does.

Where a JSON-RPC listener belongsThe internet reaches a reverse proxy that terminates TLS, authenticates the caller and applies a rate limit; the proxy reaches the node's JSON-RPC listener bound to 127.0.0.1. A direct route from the internet to the node's port is shown crossed out.InternetTLSReverse proxyauth · rate limit · logsNode127.0.0.1:8545never bind the RPC port to a public interface
Two routes to the same listener. The proxy does the parts a node client does not: certificates, an identity for the caller, a limit per caller, a size cap, and a log line you can bill or debug from.
  • Assume it will be found. Open RPC ports are indexed continuously by scanners. “Nobody knows the address” is not a control, and the interval between binding a port and receiving your first uninvited request is measured in minutes.
  • A read-only interface is still an interface. Even with nothing writable exposed, an unbounded historical query is a denial of service you are paying for.

Bind narrow, serve little

Start by giving the node the smallest surface that still does your job.

# Ethereum / BNB Smart Chain
geth --http --http.addr 127.0.0.1 --http.api eth,net,web3

# Solana
agave-validator --rpc-bind-address 127.0.0.1 --private-rpc
Serve only the namespaces you use
eth, net and web3 cover almost every application. The administrative and debugging namespaces are for you, on localhost, and should not be enabled on a listener anybody else can reach.
Keep keys off it entirely
An RPC node does not need to be able to sign anything. If it cannot, an exposure is a resource problem rather than a loss.
Separate the control plane
Ethereum’s Engine API on 8551 is not an RPC endpoint and must never be treated as one — control of it is control of what your node believes. Metrics ports belong on your monitoring network, not on the internet.

What goes in front of it

A reverse proxy is doing five jobs the node client has no opinion about. All five are worth having before the first outside caller arrives.

  • TLS. Terminate it there; the node speaks plaintext on loopback and never needs a certificate.
  • An identity for the caller. An API key, mTLS, or a network boundary. Without one, “who is doing this” has no answer, and neither does “stop them”.
  • A rate limit per caller, and a separate one for the expensive methods. One unbounded eth_getLogs can occupy a node for minutes. It is the method every public provider restricts first, which is a strong hint.
  • A request size cap. JSON-RPC batching is a legitimate feature and an excellent way to turn one request into ten thousand.
  • Access logs. The thing you will want on the day the node is busy and nobody knows why.

The five-line check

Before an endpoint goes anywhere near a colleague, let alone a customer:

  • The node’s RPC listener is bound to 127.0.0.1, verified from another machine rather than assumed.
  • Only the namespaces you use are enabled on it.
  • Something in front terminates TLS and knows who the caller is.
  • There is a limit per caller, and a stricter one on the methods that can occupy the node.
  • Nothing on the machine can sign a transaction.

Then, and only then, the interesting problems: serving RPC at scale and knowing it is healthy.