mirror of
https://github.com/siderolabs/omni.git
synced 2025-08-08 02:27:00 +02:00
This commit implements session tracking and log audit for those types: - [x] auth.PublicKey - [x] auth.AccessPolicy - [x] auth.User - [x] auth.Identity - [x] omni.Machine - [x] omni.MachineLabels - [x] omni.Cluster - [x] omni.MachineSet (only empty owners for update, log create and delete in all cases) - [x] omni.MachineSetNode (only empty owners for update, log create and delete in all cases) - [x] omni.ConfigPatch - [x] Talos API Access - [x] Kubernetes API access Output example: ``` {"event_type":"update","resource_type":"Machines.omni.sidero.dev","event_ts":1723137771180,"event_data":{"session":{"user_agent":"Omni-Internal-Agent"},"machine":{"id":"18cec051-d975-483d-8d43-10ac6421648a","is_connected":true,"management_address":"fdae:41e4:649b:9303:da9b:1ed:a725:c3dd","labels":{"omni.sidero.dev/address":"fdae:41e4:649b:9303:da9b:1ed:a725:c3dd"}}}} {"event_type":"update","resource_type":"Machines.omni.sidero.dev","event_ts":1723137771180,"event_data":{"session":{"user_agent":"Omni-Internal-Agent"},"machine":{"id":"18cec051-d975-483d-8d43-10ac6421648a","is_connected":true,"management_address":"fdae:41e4:649b:9303:da9b:1ed:a725:c3dd","labels":{"omni.sidero.dev/address":"fdae:41e4:649b:9303:da9b:1ed:a725:c3dd"}}}} {"event_type":"update","resource_type":"Machines.omni.sidero.dev","event_ts":1723137771181,"event_data":{"session":{"user_agent":"Omni-Internal-Agent"},"machine":{"id":"18cec051-d975-483d-8d43-10ac6421648a","is_connected":true,"management_address":"fdae:41e4:649b:9303:da9b:1ed:a725:c3dd","labels":{"omni.sidero.dev/address":"fdae:41e4:649b:9303:da9b:1ed:a725:c3dd"}}}} {"event_type":"create","resource_type":"MachineLabels.omni.sidero.dev","event_ts":1723137787549,"event_data":{"session":{"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36","ip_address":"<snip>","user_id":"ea002172-b9da-423f-bd1d-b443b8a7b43c","role":"Admin","email":"dmitry.matrenichev@siderolabs.com","fingerprint":"da7b997eb68449a12bebc6a3bf4f59beaf167209"},"machine_labels":{"id":"18cec051-d975-483d-8d43-10ac6421648a","labels":{"222":""}}}} {"event_type":"update","resource_type":"MachineLabels.omni.sidero.dev","event_ts":1723137787553,"event_data":{"session":{"user_agent":"Omni-Internal-Agent"},"machine_labels":{"id":"18cec051-d975-483d-8d43-10ac6421648a","labels":{"222":""}}}} {"event_type":"update","resource_type":"MachineLabels.omni.sidero.dev","event_ts":1723137811532,"event_data":{"session":{"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36","ip_address":"<snip>","user_id":"ea002172-b9da-423f-bd1d-b443b8a7b43c","role":"Admin","email":"dmitry.matrenichev@siderolabs.com","fingerprint":"da7b997eb68449a12bebc6a3bf4f59beaf167209"},"machine_labels":{"id":"18cec051-d975-483d-8d43-10ac6421648a","labels":{"222":"","333":""}}}} {"event_type":"update","resource_type":"MachineLabels.omni.sidero.dev","event_ts":1723137811610,"event_data":{"session":{"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36","ip_address":"<snip>","user_id":"ea002172-b9da-423f-bd1d-b443b8a7b43c","role":"Admin","email":"dmitry.matrenichev@siderolabs.com","fingerprint":"da7b997eb68449a12bebc6a3bf4f59beaf167209"},"machine_labels":{"id":"18cec051-d975-483d-8d43-10ac6421648a","labels":{"222":"","333":""}}}} {"event_type":"update","resource_type":"MachineLabels.omni.sidero.dev","event_ts":1723137811611,"event_data":{"session":{"user_agent":"Omni-Internal-Agent"},"machine_labels":{"id":"18cec051-d975-483d-8d43-10ac6421648a","labels":{"222":"","333":""}}}} {"event_type":"destroy","resource_type":"MachineLabels.omni.sidero.dev","event_ts":1723137811621,"event_data":{"session":{"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36","ip_address":"<snip>","user_id":"ea002172-b9da-423f-bd1d-b443b8a7b43c","role":"Admin","email":"dmitry.matrenichev@siderolabs.com","fingerprint":"da7b997eb68449a12bebc6a3bf4f59beaf167209"},"machine_labels":{"id":"18cec051-d975-483d-8d43-10ac6421648a","labels":{"222":"","333":""}}}} {"event_type":"create","resource_type":"Users.omni.sidero.dev","event_ts":1723141793888,"event_data":{"new_user":{"role":"Admin","id":"7903a72c-87af-43b8-94dc-82bd961ab768"},"session":{"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36","ip_address":"<snip>","user_id":"ea002172-b9da-423f-bd1d-b443b8a7b43c","role":"Admin","email":"dmitry.matrenichev@siderolabs.com","fingerprint":"da7b997eb68449a12bebc6a3bf4f59beaf167209"}}} {"event_type":"create","resource_type":"Identities.omni.sidero.dev","event_ts":1723141793981,"event_data":{"new_user":{"id":"7903a72c-87af-43b8-94dc-82bd961ab768","email":"some-user-email@email.com"},"session":{"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36","ip_address":"<snip>","user_id":"ea002172-b9da-423f-bd1d-b443b8a7b43c","role":"Admin","email":"dmitry.matrenichev@siderolabs.com","fingerprint":"da7b997eb68449a12bebc6a3bf4f59beaf167209"}}} ``` Closes #37 Signed-off-by: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com>
84 lines
2.3 KiB
Go
84 lines
2.3 KiB
Go
// Copyright (c) 2024 Sidero Labs, Inc.
|
|
//
|
|
// Use of this software is governed by the Business Source License
|
|
// included in the LICENSE file.
|
|
|
|
// Package k8sproxy provides JWT-authenticated proxy to Kubernetes API server.
|
|
package k8sproxy
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/siderolabs/omni/internal/backend/runtime"
|
|
"github.com/siderolabs/omni/internal/backend/runtime/kubernetes"
|
|
)
|
|
|
|
// clusterContextKey is a type for cluster name.
|
|
type clusterContextKey struct{ ClusterName string }
|
|
|
|
// Handler implements the HTTP reverse proxy for Kubernetes clusters.
|
|
//
|
|
// Handler intercepts the request, verifies the authentication info and
|
|
// routes the request to matching Kubernetes cluster with impersonation headers.
|
|
//
|
|
// Handler itself implements httt.Handler interface.
|
|
type Handler struct {
|
|
multiplexer *multiplexer
|
|
chain http.Handler
|
|
}
|
|
|
|
// MiddlewareWrapper is an interface for middleware wrappers.
|
|
type MiddlewareWrapper interface {
|
|
Wrap(http.Handler) http.Handler
|
|
}
|
|
|
|
// NewHandler creates a new Handler.
|
|
func NewHandler(keyFunc KeyProvider, clusterUUIDResolver ClusterUUIDResolver, wrapper MiddlewareWrapper, logger *zap.Logger) (*Handler, error) {
|
|
multiplexer := newMultiplexer()
|
|
proxy := wrapper.Wrap(newProxyHandler(multiplexer, logger))
|
|
|
|
handler := &Handler{
|
|
multiplexer: multiplexer,
|
|
chain: AuthorizeRequest(proxy, keyFunc, clusterUUIDResolver),
|
|
}
|
|
|
|
type kubeRuntime interface {
|
|
RegisterCleanuper(kubernetes.ClusterCleanuper)
|
|
}
|
|
|
|
r, err := runtime.LookupInterface[kubeRuntime](kubernetes.Name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// register self as cluster cleanuper
|
|
r.RegisterCleanuper(handler)
|
|
|
|
return handler, nil
|
|
}
|
|
|
|
// ServeHTTP implements http.Handler interface.
|
|
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
h.chain.ServeHTTP(w, r)
|
|
}
|
|
|
|
// ClusterRemove implements ClusterCleanuper interface.
|
|
func (h *Handler) ClusterRemove(clusterName string) {
|
|
h.multiplexer.removeClusterConnector(clusterName)
|
|
}
|
|
|
|
// Describe implements prom.Collector interface.
|
|
func (h *Handler) Describe(ch chan<- *prometheus.Desc) {
|
|
h.multiplexer.Describe(ch)
|
|
}
|
|
|
|
// Collect implements prom.Collector interface.
|
|
func (h *Handler) Collect(ch chan<- prometheus.Metric) {
|
|
h.multiplexer.Collect(ch)
|
|
}
|
|
|
|
var _ prometheus.Collector = &Handler{}
|