Added audit stream to HTTP proxy

This commit is contained in:
Peter 2021-01-20 19:03:05 +01:00
parent 03f3ae4173
commit 63a6516d99
Signed by: prskr
GPG key ID: C1DB5D2E8DB512F9
7 changed files with 65 additions and 43 deletions

View file

@ -0,0 +1,37 @@
package http
import (
"net/http"
"gitlab.com/inetmock/inetmock/pkg/audit"
"gitlab.com/inetmock/inetmock/pkg/audit/details"
)
func EventFromRequest(request *http.Request, app audit.AppProtocol) audit.Event {
httpDetails := details.HTTP{
Method: request.Method,
Host: request.Host,
URI: request.RequestURI,
Proto: request.Proto,
Headers: request.Header,
}
ev := audit.Event{
Transport: audit.TransportProtocol_TCP,
Application: app,
ProtocolDetails: httpDetails,
}
if request.TLS != nil {
ev.TLS = &audit.TLSDetails{
Version: request.TLS.Version,
CipherSuite: request.TLS.CipherSuite,
ServerName: request.TLS.ServerName,
}
}
ev.SetDestinationIPFromAddr(localAddr(request.Context()))
ev.SetSourceIPFromAddr(remoteAddr(request.Context()))
return ev
}

View file

@ -1,4 +1,4 @@
package mock
package http
import (
"context"
@ -8,8 +8,8 @@ import (
type httpContextKey string
const (
remoteAddrKey httpContextKey = "RemoteAddr"
localAddrKey httpContextKey = "LocalAddr"
remoteAddrKey httpContextKey = "gitlab.com/inetmock/inetmock/internal/endpoint/handler/http/context/remoteAddr"
localAddrKey httpContextKey = "gitlab.com/inetmock/inetmock/internal/endpoint/handler/http/context/localAddr"
)
func StoreConnPropertiesInContext(ctx context.Context, c net.Conn) context.Context {
@ -18,7 +18,7 @@ func StoreConnPropertiesInContext(ctx context.Context, c net.Conn) context.Conte
return ctx
}
func LocalAddr(ctx context.Context) net.Addr {
func localAddr(ctx context.Context) net.Addr {
val := ctx.Value(localAddrKey)
if val == nil {
return nil
@ -26,7 +26,7 @@ func LocalAddr(ctx context.Context) net.Addr {
return val.(net.Addr)
}
func RemoteAddr(ctx context.Context) net.Addr {
func remoteAddr(ctx context.Context) net.Addr {
val := ctx.Value(remoteAddrKey)
if val == nil {
return nil

View file

@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
imHttp "gitlab.com/inetmock/inetmock/internal/endpoint/handler/http"
"gitlab.com/inetmock/inetmock/pkg/api"
"gitlab.com/inetmock/inetmock/pkg/config"
"gitlab.com/inetmock/inetmock/pkg/logging"
@ -46,7 +47,7 @@ func (p *httpHandler) Start(ctx api.PluginContext, config config.HandlerConfig)
p.server = &http.Server{
Addr: config.ListenAddr(),
Handler: router,
ConnContext: StoreConnPropertiesInContext,
ConnContext: imHttp.StoreConnPropertiesInContext,
}
for _, rule := range options.Rules {

View file

@ -5,8 +5,8 @@ import (
"strconv"
"github.com/prometheus/client_golang/prometheus"
imHttp "gitlab.com/inetmock/inetmock/internal/endpoint/handler/http"
"gitlab.com/inetmock/inetmock/pkg/audit"
details "gitlab.com/inetmock/inetmock/pkg/audit/details"
"gitlab.com/inetmock/inetmock/pkg/logging"
"go.uber.org/zap"
)
@ -63,27 +63,6 @@ type emittingFileHandler struct {
}
func (f emittingFileHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
f.emitter.Emit(eventFromRequest(request))
f.emitter.Emit(imHttp.EventFromRequest(request, audit.AppProtocol_HTTP))
http.ServeFile(writer, request, f.targetPath)
}
func eventFromRequest(request *http.Request) audit.Event {
httpDetails := details.HTTP{
Method: request.Method,
Host: request.Host,
URI: request.RequestURI,
Proto: request.Proto,
Headers: request.Header,
}
ev := audit.Event{
Transport: audit.TransportProtocol_TCP,
Application: audit.AppProtocol_HTTP,
ProtocolDetails: httpDetails,
}
ev.SetDestinationIPFromAddr(LocalAddr(request.Context()))
ev.SetSourceIPFromAddr(RemoteAddr(request.Context()))
return ev
}

View file

@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
imHttp "gitlab.com/inetmock/inetmock/internal/endpoint/handler/http"
"gitlab.com/inetmock/inetmock/pkg/api"
"gitlab.com/inetmock/inetmock/pkg/config"
"gitlab.com/inetmock/inetmock/pkg/logging"
@ -29,7 +30,11 @@ func (h *httpProxy) Start(ctx api.PluginContext, cfg config.HandlerConfig) (err
return
}
listenAddr := cfg.ListenAddr()
h.server = &http.Server{Addr: listenAddr, Handler: h.proxy}
h.server = &http.Server{
Addr: listenAddr,
Handler: h.proxy,
ConnContext: imHttp.StoreConnPropertiesInContext,
}
h.logger = h.logger.With(
zap.String("handler_name", cfg.HandlerName),
zap.String("address", listenAddr),
@ -41,16 +46,18 @@ func (h *httpProxy) Start(ctx api.PluginContext, cfg config.HandlerConfig) (err
handlerName: cfg.HandlerName,
options: opts,
logger: h.logger,
emitter: ctx.Audit(),
}
proxyHttpsHandler := &proxyHttpsHandler{
proxyHTTPSHandler := &proxyHttpsHandler{
handlerName: cfg.HandlerName,
tlsConfig: tlsConfig,
logger: h.logger,
emitter: ctx.Audit(),
}
h.proxy.OnRequest().Do(proxyHandler)
h.proxy.OnRequest().HandleConnect(proxyHttpsHandler)
h.proxy.OnRequest().HandleConnect(proxyHTTPSHandler)
go h.startProxy()
return
}

View file

@ -1,12 +1,13 @@
package proxy
import (
"context"
"crypto/tls"
"net/http"
"net/url"
"github.com/prometheus/client_golang/prometheus"
imHttp "gitlab.com/inetmock/inetmock/internal/endpoint/handler/http"
"gitlab.com/inetmock/inetmock/pkg/audit"
"gitlab.com/inetmock/inetmock/pkg/logging"
"go.uber.org/zap"
"gopkg.in/elazarl/goproxy.v1"
@ -16,12 +17,14 @@ type proxyHttpHandler struct {
handlerName string
options httpProxyOptions
logger logging.Logger
emitter audit.Emitter
}
type proxyHttpsHandler struct {
handlerName string
tlsConfig *tls.Config
logger logging.Logger
emitter audit.Emitter
}
func (p *proxyHttpsHandler) HandleConnect(req string, _ *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
@ -45,15 +48,7 @@ func (p *proxyHttpHandler) Handle(req *http.Request, ctx *goproxy.ProxyCtx) (ret
totalRequestCounter.WithLabelValues(p.handlerName).Inc()
retReq = req
p.logger.Info(
"Handling request",
zap.String("source", req.RemoteAddr),
zap.String("host", req.Host),
zap.String("method", req.Method),
zap.String("protocol", req.Proto),
zap.String("path", req.RequestURI),
zap.Reflect("headers", req.Header),
)
p.emitter.Emit(imHttp.EventFromRequest(req, audit.AppProtocol_HTTP_PROXY))
var err error
if resp, err = ctx.RoundTrip(p.redirectHTTPRequest(req)); err != nil {
@ -95,7 +90,7 @@ func (p proxyHttpHandler) redirectHTTPRequest(originalRequest *http.Request) (re
MultipartForm: originalRequest.MultipartForm,
Trailer: originalRequest.Trailer,
}
redirectReq = redirectReq.WithContext(context.Background())
redirectReq = redirectReq.WithContext(originalRequest.Context())
return
}

View file

@ -93,6 +93,9 @@ func NewEventFromProto(msg *EventEntity) (ev Event) {
}
func parseIPPortFromAddr(addr net.Addr) (ip net.IP, port uint16) {
if addr == nil {
return
}
switch a := addr.(type) {
case *net.TCPAddr:
return a.IP, uint16(a.Port)