Skip to main content
Running Geth safely requires understanding which interfaces expose sensitive functionality and how to restrict access to them. The guidance below covers the most important areas.
Never expose the Geth HTTP or WebSocket RPC endpoints to the public internet without authentication and strict API restrictions. Attackers actively scan for exposed Ethereum nodes and will attempt to drain funds or manipulate node state.

IPC: the most secure interface

The IPC endpoint (a Unix socket on Linux/macOS, a named pipe on Windows) is enabled by default and exposes all Geth APIs. Because it is file-system based, access can be controlled entirely through OS-level file permissions — only local processes that can read the socket file can connect.
# Attach to the IPC endpoint (default location)
geth attach ~/.ethereum/geth.ipc

# Disable IPC if it is not needed
geth --ipcdisable
For production nodes where you need JSON-RPC access from application code running on the same host, prefer IPC over HTTP or WebSocket whenever possible.

Engine API and JWT authentication

Since The Merge, Geth exposes an authenticated RPC endpoint (the Engine API) for communication with the consensus layer client. This endpoint is protected by JWT (JSON Web Token) bearer authentication.
geth --authrpc.jwtsecret /path/to/jwt.hex
The --authrpc.jwtsecret flag points to a file containing a 32-byte hex-encoded secret shared between Geth and the consensus client. Both sides must use the same secret.

Generating a JWT secret

# Generate a random 32-byte secret and store it
openssl rand -hex 32 > /etc/geth/jwt.hex
chmod 600 /etc/geth/jwt.hex

Engine API flags

FlagDefaultDescription
--authrpc.jwtsecret(required)Path to the JWT secret file
--authrpc.addrlocalhostListening address for the Engine API
--authrpc.port8551Listening port for the Engine API
--authrpc.vhostslocalhostVirtual hostnames accepted by the Engine API server
The Engine API port (8551 by default) must be reachable by the consensus client but should not be exposed to the public internet. Bind it to a loopback or private network interface.

HTTP RPC security

The HTTP JSON-RPC server is disabled by default. When enabled, keep these rules in mind:

Bind to localhost unless you have a specific reason not to

# Safe: only reachable from the local machine
geth --http --http.addr 127.0.0.1

# Risky: reachable from any network interface
geth --http --http.addr 0.0.0.0
Only use 0.0.0.0 (or a non-loopback address) if you have a firewall, reverse proxy, or other access control in front of Geth. The Docker quick-start in the README explicitly notes this requirement.

Restrict the exposed API surface

The default API set (eth,net,web3) is appropriate for most use cases. Do not expose administrative or account-management APIs over HTTP:
# Recommended: expose only the standard APIs
geth --http --http.api eth,net,web3

# Avoid exposing these over HTTP in production:
# admin, debug, miner

CORS configuration

If browser-based dApps need to connect, use --http.corsdomain to allowlist specific origins rather than using a wildcard:
# Allowlist specific origins
geth --http --http.corsdomain "https://app.example.com"

# Avoid in production (allows any origin)
geth --http --http.corsdomain "*"
All browser tabs can access locally running web servers. If --http.corsdomain "*" is set on a node bound to localhost, malicious web pages visited in the same browser can call your node’s RPC methods.

HTTP RPC flags

FlagDefaultDescription
--httpfalseEnable the HTTP-RPC server
--http.addrlocalhostListening interface
--http.port8545Listening port
--http.apieth,net,web3APIs to expose
--http.corsdomain(empty)Allowed CORS origins
--http.vhostslocalhostAccepted virtual hostnames

WebSocket RPC security

The WebSocket interface has the same security considerations as HTTP. Keep it bound to localhost and restrict origins:
geth --ws --ws.addr 127.0.0.1 --ws.api eth,net,web3 --ws.origins "https://app.example.com"
FlagDefaultDescription
--wsfalseEnable the WebSocket-RPC server
--ws.addrlocalhostListening interface
--ws.port8546Listening port
--ws.apieth,net,web3APIs to expose
--ws.origins(empty)Allowed WebSocket origins

Account security: use Clef instead of --unlock

Geth supports unlocking accounts via --unlock for backwards compatibility, but this is not recommended in production. An unlocked account can sign transactions for as long as the node is running, giving any process or API consumer that reaches the RPC endpoint the ability to spend funds. The recommended approach for production account management is Clef, the standalone signing tool included in the go-ethereum repository:
# Start Clef as a signer backend
clef --keystore ~/.ethereum/keystore --chainid 1

# Connect Geth to Clef
geth --signer /path/to/clef.ipc
Clef provides:
  • Fine-grained signing rules (approve individual transaction types, rate-limit signings, etc.)
  • An interactive approval UI so you can audit each signing request
  • Separation of key material from the node process
--unlock and --password should only be used in development or automated testing environments, never on nodes holding real funds.

RPC rate limiting and proxying

For public-facing nodes, put a reverse proxy (nginx, Caddy, Traefik) in front of the HTTP/WebSocket endpoint to:
  • Enforce TLS/HTTPS
  • Apply per-IP rate limits
  • Require application-level authentication
  • Log and audit requests
Geth itself does not implement per-client rate limiting or TLS.

Vulnerability disclosure

If you discover a security vulnerability in Geth, do not file a public GitHub issue. Instead, report it through the Ethereum bug bounty programme: The Ethereum Foundation Security Team PGP key fingerprint for encrypted communication is:
AE96 ED96 9E47 9B00 84F3 E17F E88D 3334 FA5F 6A0A
Audit reports for Geth and related components are published in the repository under docs/audits/.

Build docs developers (and LLMs) love