From b9ceddd052804f00c2cc0700e961b73733d5e5f0 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Wed, 13 May 2020 21:57:17 +0100 Subject: [PATCH] api: add --http-host to restrict RPC bind address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ± ./build/ava --http-host localhost --public-ip ___ ________ __ ___ / _ \_/\ / _____/ ____ ____ | | ______ / _ \_/\ \/ \___/ / \ ____/ __ \_/ ___\| |/ / _ \ \/ \___/ \ \_\ \ ___/\ \___| < <_> ) \______ /\___ >\___ >__|_ \____/ \/ \/ \/ \/ ... INFO [05-14|21:09:54] /api/server.go#53: API server listening on "localhost:9650" INFO [05-14|21:09:54] /api/server.go#106: adding route /ext/vm/jvYyfQTxGMJLuGWa55kdP2p2zSUYsQ5Raupu4TW34ZAUBAbtq ... The node continues to partcipate in consensus, but RPC calls are restricted to the localhost interface $ ss -lnt | grep 965 LISTEN 0 4096 127.0.0.1:9650 0.0.0.0:* LISTEN 0 10 0.0.0.0:9651 0.0.0.0:* $ curl -X POST --data '{ > "id": '$(date +%s)', > "jsonrpc": "2.0", > "method": "admin.getNodeID", > "params":{} > }' -H 'content-type:application/json;' 127.0.0.1:9650/ext/admin {"jsonrpc":"2.0","result":{"nodeID":"2iEwniZihec5S2anxDpKGenZB7Cs112Ap"},"id":1589486853} $ curl -X POST --data '{ > "id": '$(date +%s)', > "jsonrpc": "2.0", > "method": "admin.getNodeID", > "params":{} > }' -H 'content-type:application/json;' 192.168.43.60:9650/ext/admin curl: (7) Failed to connect to 192.168.43.60 port 9650: Connection refused --- api/server.go | 29 ++++++++++++++++++++--------- api/server_test.go | 2 +- main/params.go | 2 ++ node/config.go | 1 + node/node.go | 2 +- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/api/server.go b/api/server.go index ffbdc03..2985395 100644 --- a/api/server.go +++ b/api/server.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "io" + "net" "net/http" "net/url" "sync" @@ -28,30 +29,40 @@ var ( // Server maintains the HTTP router type Server struct { - log logging.Logger - factory logging.Factory - router *router - portURL string + log logging.Logger + factory logging.Factory + router *router + listenAddress string } -// Initialize creates the API server at the provided port -func (s *Server) Initialize(log logging.Logger, factory logging.Factory, port uint16) { +// Initialize creates the API server at the provided host and port +func (s *Server) Initialize(log logging.Logger, factory logging.Factory, host string, port uint16) { s.log = log s.factory = factory - s.portURL = fmt.Sprintf(":%d", port) + s.listenAddress = fmt.Sprintf("%s:%d", host, port) s.router = newRouter() } // Dispatch starts the API server func (s *Server) Dispatch() error { handler := cors.Default().Handler(s.router) - return http.ListenAndServe(s.portURL, handler) + listener, err := net.Listen("tcp", s.listenAddress) + if err != nil { + return err + } + s.log.Info("API server listening on %q", s.listenAddress) + return http.Serve(listener, handler) } // DispatchTLS starts the API server with the provided TLS certificate func (s *Server) DispatchTLS(certFile, keyFile string) error { handler := cors.Default().Handler(s.router) - return http.ListenAndServeTLS(s.portURL, certFile, keyFile, handler) + listener, err := net.Listen("tcp", s.listenAddress) + if err != nil { + return err + } + s.log.Info("API server listening on %q", s.listenAddress) + return http.ServeTLS(listener, handler, certFile, keyFile) } // RegisterChain registers the API endpoints associated with this chain That diff --git a/api/server_test.go b/api/server_test.go index 75e03ad..dc0ba9c 100644 --- a/api/server_test.go +++ b/api/server_test.go @@ -30,7 +30,7 @@ func (s *Service) Call(_ *http.Request, args *Args, reply *Reply) error { func TestCall(t *testing.T) { s := Server{} - s.Initialize(logging.NoLog{}, logging.NoFactory{}, 8080) + s.Initialize(logging.NoLog{}, logging.NoFactory{}, "localhost", 8080) serv := &Service{} newServer := rpc.NewServer() diff --git a/main/params.go b/main/params.go index c18a937..269b433 100644 --- a/main/params.go +++ b/main/params.go @@ -93,6 +93,7 @@ func init() { consensusIP := fs.String("public-ip", "", "Public IP of this node") // HTTP Server: + httpHost := fs.String("http-host", "", "Address of the HTTP server") httpPort := fs.Uint("http-port", 9650, "Port of the HTTP server") fs.BoolVar(&Config.EnableHTTPS, "http-tls-enabled", false, "Upgrade the HTTP server to HTTPs") fs.StringVar(&Config.HTTPSKeyFile, "http-tls-key-file", "", "TLS private key file for the HTTPs server") @@ -269,6 +270,7 @@ func init() { } // HTTP: + Config.HTTPHost = *httpHost Config.HTTPPort = uint16(*httpPort) // Logging: diff --git a/node/config.go b/node/config.go index b35d997..848f74a 100644 --- a/node/config.go +++ b/node/config.go @@ -42,6 +42,7 @@ type Config struct { BootstrapPeers []*Peer // HTTP configuration + HTTPHost string HTTPPort uint16 EnableHTTPS bool HTTPSKeyFile string diff --git a/node/node.go b/node/node.go index 289de18..672c8ff 100644 --- a/node/node.go +++ b/node/node.go @@ -477,7 +477,7 @@ func (n *Node) initChains() error { func (n *Node) initAPIServer() { n.Log.Info("Initializing API server") - n.APIServer.Initialize(n.Log, n.LogFactory, n.Config.HTTPPort) + n.APIServer.Initialize(n.Log, n.LogFactory, n.Config.HTTPHost, n.Config.HTTPPort) go n.Log.RecoverAndPanic(func() { if n.Config.EnableHTTPS {