Adds JWT token checks
parent
051cb65495
commit
5521229f82
|
@ -15,6 +15,6 @@ All notable changes to this project will be documented in this file.
|
||||||
### Added
|
### Added
|
||||||
- Initial version in PHP
|
- Initial version in PHP
|
||||||
- New version in folder "go", written in Go
|
- New version in folder "go", written in Go
|
||||||
- Added endpoints for /nginx, /prosody, /jicofo, /jvb
|
- Added endpoints for /nginx, /prosody, /jicofo, /jvb, /jibri
|
||||||
- Added a config file and default values
|
- Added a config file and default values
|
||||||
- Initial vesion of a build script
|
- Initial vesion of a build script
|
||||||
|
|
|
@ -2,4 +2,7 @@ module jilo-agent
|
||||||
|
|
||||||
go 1.22.6
|
go 1.22.6
|
||||||
|
|
||||||
require gopkg.in/yaml.v2 v2.4.0 // indirect
|
require (
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
# the port on which the agent will listen
|
# the port on which the agent will listen
|
||||||
agent_port: 8081
|
agent_port: 8081
|
||||||
|
|
||||||
|
# secret for checking JWT (same as in Jilo Web agent config)
|
||||||
|
secret_key: "mysecretkey"
|
||||||
|
|
||||||
# the port we check for nginx
|
# the port we check for nginx
|
||||||
nginx_port: 80
|
nginx_port: 80
|
||||||
|
|
||||||
|
|
76
go/main.go
76
go/main.go
|
@ -12,9 +12,10 @@ Version: 0.1
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"encoding/json"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
"github.com/dgrijalva/jwt-go"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -27,6 +28,7 @@ import (
|
||||||
// Config holds the structure of the configuration file
|
// Config holds the structure of the configuration file
|
||||||
type Config struct {
|
type Config struct {
|
||||||
AgentPort int `yaml:"agent_port"`
|
AgentPort int `yaml:"agent_port"`
|
||||||
|
SecretKey string `yaml:"secret_key"`
|
||||||
NginxPort int `yaml:"nginx_port"`
|
NginxPort int `yaml:"nginx_port"`
|
||||||
ProsodyPort int `yaml:"prosody_port"`
|
ProsodyPort int `yaml:"prosody_port"`
|
||||||
JicofoStatsURL string `yaml:"jicofo_stats_url"`
|
JicofoStatsURL string `yaml:"jicofo_stats_url"`
|
||||||
|
@ -34,6 +36,13 @@ type Config struct {
|
||||||
JibriHealthURL string `yaml:"jibri_health_url"`
|
JibriHealthURL string `yaml:"jibri_health_url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Claims holds JWT access right
|
||||||
|
type Claims struct {
|
||||||
|
Username string `json:"sub"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
jwt.StandardClaims
|
||||||
|
}
|
||||||
|
|
||||||
// NginxData holds the nginx data structure for the API response to /nginx
|
// NginxData holds the nginx data structure for the API response to /nginx
|
||||||
type NginxData struct {
|
type NginxData struct {
|
||||||
NginxState string `json:"nginx_state"`
|
NginxState string `json:"nginx_state"`
|
||||||
|
@ -64,6 +73,8 @@ type JibriData struct {
|
||||||
JibriHealthData map[string]interface{} `json:"jibri_health_data"`
|
JibriHealthData map[string]interface{} `json:"jibri_health_data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var secretKey []byte
|
||||||
|
|
||||||
// getServiceState checks the status of the speciied service
|
// getServiceState checks the status of the speciied service
|
||||||
func getServiceState(service string) string {
|
func getServiceState(service string) string {
|
||||||
output, err := exec.Command("systemctl", "is-active", service).Output()
|
output, err := exec.Command("systemctl", "is-active", service).Output()
|
||||||
|
@ -145,6 +156,48 @@ func loadConfig(filename string) (Config) {
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// authenticationJWT handles the JWT auth
|
||||||
|
func authenticationJWT(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
tokenString := r.Header.Get("Authorization")
|
||||||
|
|
||||||
|
// empty auth header
|
||||||
|
if tokenString == "" {
|
||||||
|
http.Error(w, "Auth header not received", http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove "Bearer "
|
||||||
|
if len(tokenString) > 7 && tokenString[:7] == "Bearer " {
|
||||||
|
tokenString = tokenString[7:]
|
||||||
|
}
|
||||||
|
|
||||||
|
claims := &Claims{}
|
||||||
|
|
||||||
|
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
return secretKey, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// JWT errors
|
||||||
|
if err != nil {
|
||||||
|
if err == jwt.ErrSignatureInvalid {
|
||||||
|
http.Error(w, "Invalid JWT signature", http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
http.Error(w, "Error parsing JWT", http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// JWT invalid
|
||||||
|
if !token.Valid {
|
||||||
|
http.Error(w, "Invali JWT token", http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// nginxHandler handles the /nginx endpoint
|
// nginxHandler handles the /nginx endpoint
|
||||||
func nginxHandler(config Config, w http.ResponseWriter, r *http.Request) {
|
func nginxHandler(config Config, w http.ResponseWriter, r *http.Request) {
|
||||||
data := NginxData {
|
data := NginxData {
|
||||||
|
@ -201,23 +254,24 @@ func main() {
|
||||||
|
|
||||||
// load the configuration
|
// load the configuration
|
||||||
config := loadConfig("jilo-agent.conf")
|
config := loadConfig("jilo-agent.conf")
|
||||||
|
secretKey = []byte(config.SecretKey)
|
||||||
|
|
||||||
// endpoints
|
// endpoints
|
||||||
http.HandleFunc("/nginx", func(w http.ResponseWriter, r *http.Request) {
|
http.Handle("/nginx", authenticationJWT(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
nginxHandler(config, w, r)
|
nginxHandler(config, w, r)
|
||||||
})
|
})))
|
||||||
http.HandleFunc("/prosody", func(w http.ResponseWriter, r *http.Request) {
|
http.Handle("/prosody", authenticationJWT(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
prosodyHandler(config, w, r)
|
prosodyHandler(config, w, r)
|
||||||
})
|
})))
|
||||||
http.HandleFunc("/jicofo", func(w http.ResponseWriter, r *http.Request) {
|
http.Handle("/jicofo", authenticationJWT(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
jicofoHandler(config, w, r)
|
jicofoHandler(config, w, r)
|
||||||
})
|
})))
|
||||||
http.HandleFunc("/jvb", func(w http.ResponseWriter, r *http.Request) {
|
http.Handle("/jvb", authenticationJWT(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
jvbHandler(config, w, r)
|
jvbHandler(config, w, r)
|
||||||
})
|
})))
|
||||||
http.HandleFunc("/jibri", func(w http.ResponseWriter, r *http.Request) {
|
http.Handle("/jibri", authenticationJWT(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
jibriHandler(config, w, r)
|
jibriHandler(config, w, r)
|
||||||
})
|
})))
|
||||||
|
|
||||||
// start the http server
|
// start the http server
|
||||||
agentPortStr := fmt.Sprintf(":%d", config.AgentPort)
|
agentPortStr := fmt.Sprintf(":%d", config.AgentPort)
|
||||||
|
|
Loading…
Reference in New Issue