Auth middleware for node balancer

pull/559/head
kompotkot 2022-03-08 14:19:12 +00:00
rodzic 570131d9e1
commit 3405f6746f
6 zmienionych plików z 88 dodań i 11 usunięć

1
.gitignore vendored
Wyświetl plik

@ -1,2 +1,3 @@
.secrets/
.vscode/
.DS_Store

Wyświetl plik

@ -17,6 +17,10 @@ type NodeStatusResponse struct {
CurrentBlock uint64 `json:"current_block"`
}
type BugoutUserResponse struct {
ID string `json:"user_id"`
}
// Node - which one node client worked with
// LastCallTs - timestamp from last call
type Client struct {

Wyświetl plik

@ -4,9 +4,15 @@ Server API middlewares.
package cmd
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"strings"
"github.com/bugout-dev/moonstream/nodes/node_balancer/configs"
humbug "github.com/bugout-dev/humbug/go/pkg"
)
@ -40,3 +46,65 @@ func logMiddleware(next http.Handler) http.Handler {
}
})
}
// Bugout authentication
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
authHeaders := r.Header["Authorization"]
authHeadersLen := len(authHeaders)
if authHeadersLen == 0 {
http.Error(w, "Authorization header not found", http.StatusForbidden)
return
}
if authHeadersLen > 1 {
http.Error(w, "Too many authorization headers provided", http.StatusBadRequest)
return
}
authHeader := authHeaders[0]
// Extract Bearer token
headerSlice := strings.Split(authHeader, " ")
if len(headerSlice) != 2 {
http.Error(w, "Unacceptable token format provided", http.StatusBadRequest)
return
}
if headerSlice[0] != "Bearer" {
http.Error(w, "Unacceptable token format provided", http.StatusBadRequest)
return
}
// Check token is active
client := http.Client{Timeout: configs.BUGOUT_AUTH_CALL_TIMEOUT}
authReq, err := http.NewRequest("GET", fmt.Sprintf("%s/user", configs.BUGOUT_AUTH_URL), nil)
if err != nil {
http.Error(w, "Unable to construct authorization request", http.StatusInternalServerError)
return
}
authReq.Header.Set("Authorization", authHeader)
resp, err := client.Do(authReq)
if err != nil {
http.Error(w, "Unable to reach authorization server", http.StatusInternalServerError)
return
}
defer resp.Body.Close()
// Parse response from authorization server
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
http.Error(w, "Unable to read respose from authorization server", http.StatusInternalServerError)
return
}
var userResponse BugoutUserResponse
err = json.Unmarshal(body, &userResponse)
if err != nil {
http.Error(w, "Unable to parse respose from authorization server", http.StatusInternalServerError)
return
}
if userResponse.ID == "" {
http.Error(w, "Wrong authorization header", http.StatusForbidden)
return
}
next.ServeHTTP(w, r)
})
}

Wyświetl plik

@ -157,8 +157,8 @@ func InitServer() {
}
serveMux := http.NewServeMux()
serveMux.Handle("/nb/", authMiddleware(http.HandlerFunc(lbHandler)))
serveMux.HandleFunc("/ping", pingRoute)
serveMux.HandleFunc("/nb/", lbHandler)
// Set common middlewares, from bottom to top
commonHandler := logMiddleware(serveMux)

Wyświetl plik

@ -10,6 +10,13 @@ import (
"time"
)
// Bugout config
var BUGOUT_AUTH_URL = os.Getenv("BUGOUT_AUTH_URL")
var BUGOUT_NODE_BALANCER_APPLICATION_ID = os.Getenv("BUGOUT_NODE_BALANCER_APPLICATION_ID")
var BUGOUT_INTERNAL_CRAWLERS_USER_ID = os.Getenv("BUGOUT_INTERNAL_CRAWLERS_USER_ID")
var BUGOUT_AUTH_CALL_TIMEOUT = time.Second * 1
// Node config
type BlockchainConfig struct {
Blockchain string
IPs []string
@ -30,10 +37,8 @@ var ConfigList NodeConfigList
var MOONSTREAM_NODE_ETHEREUM_A_IPC_ADDR = os.Getenv("MOONSTREAM_NODE_ETHEREUM_A_IPC_ADDR")
var MOONSTREAM_NODE_ETHEREUM_B_IPC_ADDR = os.Getenv("MOONSTREAM_NODE_ETHEREUM_B_IPC_ADDR")
var MOONSTREAM_NODE_ETHEREUM_IPC_PORT = os.Getenv("MOONSTREAM_NODE_ETHEREUM_IPC_PORT")
var MOONSTREAM_NODE_POLYGON_A_IPC_ADDR = os.Getenv("MOONSTREAM_NODE_POLYGON_A_IPC_ADDR")
var MOONSTREAM_NODE_POLYGON_B_IPC_ADDR = os.Getenv("MOONSTREAM_NODE_POLYGON_B_IPC_ADDR")
var MOONSTREAM_NODE_POLYGON_IPC_PORT = os.Getenv("MOONSTREAM_NODE_POLYGON_IPC_PORT")
var MOONSTREAM_NODES_SERVER_PORT = os.Getenv("MOONSTREAM_NODES_SERVER_PORT")
var MOONSTREAM_CLIENT_ID_HEADER = os.Getenv("MOONSTREAM_CLIENT_ID_HEADER")
@ -56,8 +61,8 @@ func checkEnvVarSet() {
MOONSTREAM_CLIENT_ID_HEADER = "x-moonstream-client-id"
}
if MOONSTREAM_NODES_SERVER_PORT == "" || MOONSTREAM_NODE_ETHEREUM_IPC_PORT == "" || MOONSTREAM_NODE_POLYGON_IPC_PORT == "" {
log.Fatal("Some of environment variables not set")
if MOONSTREAM_NODES_SERVER_PORT == "" {
log.Fatal("MOONSTREAM_NODES_SERVER_PORT environment variable not set")
}
}
@ -70,12 +75,12 @@ func (nc *NodeConfigList) InitNodeConfigList() {
blockchainConfigList = append(blockchainConfigList, BlockchainConfig{
Blockchain: "ethereum",
IPs: []string{MOONSTREAM_NODE_ETHEREUM_A_IPC_ADDR, MOONSTREAM_NODE_ETHEREUM_B_IPC_ADDR},
Port: MOONSTREAM_NODE_ETHEREUM_IPC_PORT,
Port: "8545",
})
blockchainConfigList = append(blockchainConfigList, BlockchainConfig{
Blockchain: "polygon",
IPs: []string{MOONSTREAM_NODE_POLYGON_A_IPC_ADDR, MOONSTREAM_NODE_POLYGON_B_IPC_ADDR},
Port: MOONSTREAM_NODE_POLYGON_IPC_PORT,
Port: "8545",
})
// Parse node addr, ip and blockchain

Wyświetl plik

@ -1,15 +1,14 @@
# Required environment variables for load balancer
export BUGOUT_AUTH_URL="https://auth.bugout.dev"
export BUGOUT_NODE_BALANCER_APPLICATION_ID="<application_id_to_controll_access>"
export BUGOUT_INTERNAL_CRAWLERS_USER_ID="<application_user_id_of_moonstream_internal_crawlers>"
export MOONSTREAM_NODES_SERVER_PORT="<node_status_server_port>"
export HUMBUG_REPORTER_NODE_BALANCER_TOKEN="<bugout_humbug_token_for_crash_reports>"
# Ethereum nodes depends variables
export MOONSTREAM_NODE_ETHEREUM_IPC_PORT="<node_geth_http_port>"
export MOONSTREAM_NODE_ETHEREUM_A_IPC_ADDR="<node_geth_http_ip_addr>"
export MOONSTREAM_NODE_ETHEREUM_B_IPC_ADDR="<node_geth_http_ip_addr>"
# Polygon nodes depends variables
export MOONSTREAM_NODE_POLYGON_IPC_PORT="<node_bor_http_port>"
export MOONSTREAM_NODE_POLYGON_A_IPC_ADDR="<node_bor_http_ip_addr>"
export MOONSTREAM_NODE_POLYGON_B_IPC_ADDR="<node_bor_http_ip_addr>"