only allow admin access via unix socket
This commit is contained in:
parent
39cae64854
commit
13780f1c74
5 changed files with 73 additions and 16 deletions
|
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
|
|
@ -23,6 +24,7 @@ var (
|
|||
version string
|
||||
|
||||
listen string
|
||||
socket string
|
||||
path string
|
||||
|
||||
log logr.Logger
|
||||
|
|
@ -58,6 +60,7 @@ func main() {
|
|||
fs := flag.NewFlagSet("", flag.ExitOnError)
|
||||
klog.InitFlags(fs)
|
||||
fs.StringVar(&listen, "listen", ":7070", "listen ip:port")
|
||||
fs.StringVar(&socket, "socket", "keyctl.sock", "listen unix domain socket")
|
||||
fs.StringVar(&path, "path", "/var/keyctl", "db storage dir")
|
||||
fs.Parse(os.Args[2:])
|
||||
default:
|
||||
|
|
@ -66,7 +69,7 @@ func main() {
|
|||
|
||||
log = klogr.New().WithName("main")
|
||||
log.Info("starting keyctl", "version", version)
|
||||
srv, err := api.NewServer(klogr.New().WithName("srv"), listen)
|
||||
srv, err := api.NewServer(klogr.New().WithName("srv"), listen, filepath.Join(path, socket))
|
||||
if err != nil {
|
||||
klog.Fatalf("init failed: %s", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -19,6 +20,8 @@ import (
|
|||
type Client struct {
|
||||
endpoint string
|
||||
httpClient *http.Client
|
||||
dialer *net.Dialer
|
||||
dialerFunc func(ctx context.Context, network, addr string) (net.Conn, error)
|
||||
debugWriter io.Writer
|
||||
//insecure bool
|
||||
}
|
||||
|
|
@ -31,6 +34,22 @@ type ClientOption func(*Client)
|
|||
|
||||
func WithEndpoint(endpoint string) ClientOption {
|
||||
return func(client *Client) {
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
client.dialer = &net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}
|
||||
if u.Scheme == "unix" {
|
||||
client.dialerFunc = func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
return client.dialer.DialContext(ctx, "unix", u.Path)
|
||||
}
|
||||
client.endpoint = "http://unix"
|
||||
return
|
||||
}
|
||||
client.dialerFunc = client.dialer.DialContext
|
||||
client.endpoint = strings.TrimRight(endpoint, "/")
|
||||
}
|
||||
}
|
||||
|
|
@ -104,10 +123,7 @@ func NewClient(options ...ClientOption) *Client {
|
|||
return http.ErrUseLastResponse
|
||||
},
|
||||
Transport: &http.Transport{
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).DialContext,
|
||||
DialContext: client.dialerFunc,
|
||||
//ForceAttemptHTTP2: true,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.giftfish.de/ston1th/keyctl/pkg/api/types"
|
||||
|
|
@ -25,6 +26,7 @@ type Server struct {
|
|||
Data *types.ContextData
|
||||
|
||||
listen net.Listener
|
||||
socket net.Listener
|
||||
}
|
||||
|
||||
type notFoundHandler struct {
|
||||
|
|
@ -36,7 +38,7 @@ func (nf *notFoundHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
// NewHTTPServer returns a new HTTPServer
|
||||
func NewServer(log logr.Logger, listen string) (*Server, error) {
|
||||
func NewServer(log logr.Logger, listen, socket string) (*Server, error) {
|
||||
s := &Server{
|
||||
mux: mux.NewRouter(),
|
||||
log: log,
|
||||
|
|
@ -48,6 +50,13 @@ func NewServer(log logr.Logger, listen string) (*Server, error) {
|
|||
}
|
||||
s.listen = l
|
||||
|
||||
sock, err := unixListener(socket)
|
||||
net.Listen("unix", socket)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.socket = sock
|
||||
|
||||
s.mux.NotFoundHandler = ¬FoundHandler{s}
|
||||
for _, v := range serverv1.Routes {
|
||||
s.mux.HandleFunc(v.Path, s.contextWrapper(v.Handler)).Methods(v.Methods...)
|
||||
|
|
@ -55,6 +64,15 @@ func NewServer(log logr.Logger, listen string) (*Server, error) {
|
|||
return s, nil
|
||||
}
|
||||
|
||||
func unixListener(socket string) (sock net.Listener, err error) {
|
||||
sock, err = net.Listen("unix", socket)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = os.Chmod(socket, 0660)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Server) Start(db *db.DB) {
|
||||
s.srv = &http.Server{
|
||||
Handler: s.mux,
|
||||
|
|
@ -68,6 +86,12 @@ func (s *Server) Start(db *db.DB) {
|
|||
s.log.Error(err, "")
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
err := s.srv.Serve(s.socket)
|
||||
if err != nil && err != http.ErrServerClosed {
|
||||
s.log.Error(err, "")
|
||||
}
|
||||
}()
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ type Context struct {
|
|||
|
||||
Data *ContextData
|
||||
Log logr.Logger
|
||||
|
||||
ip string
|
||||
}
|
||||
|
||||
// Method returns the request method
|
||||
|
|
@ -69,7 +71,15 @@ func (c *Context) Form(name string) string {
|
|||
}
|
||||
|
||||
func (c *Context) ClientIP() (host string) {
|
||||
host, _, _ = net.SplitHostPort(c.Request.RemoteAddr)
|
||||
host = c.Request.RemoteAddr
|
||||
if host == "@" {
|
||||
return
|
||||
}
|
||||
if c.ip != "" {
|
||||
return c.ip
|
||||
}
|
||||
host, _, _ = net.SplitHostPort(host)
|
||||
c.ip = host
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ package server
|
|||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
|
||||
"git.giftfish.de/ston1th/keyctl/pkg/api/types"
|
||||
"git.giftfish.de/ston1th/keyctl/pkg/api/v1/schema"
|
||||
|
|
@ -14,16 +13,21 @@ import (
|
|||
|
||||
func local(h types.CtxHandler) types.CtxHandler {
|
||||
return func(ctx *types.Context) {
|
||||
addr, err := netip.ParseAddr(ctx.ClientIP())
|
||||
if err != nil {
|
||||
ctx.Err(types.ErrForbidden)
|
||||
ip := ctx.ClientIP()
|
||||
if ip == "@" {
|
||||
h(ctx)
|
||||
return
|
||||
}
|
||||
if !addr.IsLoopback() {
|
||||
ctx.Err(types.ErrForbidden)
|
||||
return
|
||||
}
|
||||
h(ctx)
|
||||
//addr, err := netip.ParseAddr(ip)
|
||||
//if err != nil {
|
||||
// ctx.Err(types.ErrForbidden)
|
||||
// return
|
||||
//}
|
||||
//if addr.IsLoopback() {
|
||||
// h(ctx)
|
||||
// return
|
||||
//}
|
||||
ctx.Err(types.ErrForbidden)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue