add auditor to plugin
This commit is contained in:
parent
f312057e85
commit
2075c629fa
8 changed files with 137 additions and 17 deletions
5
sshpiperd/auditor/loader/load.go
Normal file
5
sshpiperd/auditor/loader/load.go
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
package loader
|
||||
|
||||
import (
|
||||
_ "github.com/tg123/sshpiper/sshpiperd/auditor/typescript_logger"
|
||||
)
|
||||
43
sshpiperd/auditor/provider.go
Normal file
43
sshpiperd/auditor/provider.go
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
package auditor
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/ssh"
|
||||
|
||||
"github.com/tg123/sshpiper/sshpiperd/registry"
|
||||
)
|
||||
|
||||
type AuditorHook func(conn ssh.ConnMetadata, msg []byte) ([]byte, error)
|
||||
|
||||
type Auditor interface {
|
||||
GetUpstreamHook() AuditorHook
|
||||
GetDownstreamHook() AuditorHook
|
||||
|
||||
Close() error
|
||||
}
|
||||
|
||||
type AuditorProvider interface {
|
||||
registry.Plugin
|
||||
|
||||
CreateAuditor(ssh.ConnMetadata) (Auditor, error)
|
||||
}
|
||||
|
||||
var (
|
||||
drivers = registry.NewRegistry()
|
||||
)
|
||||
|
||||
func Register(name string, driver AuditorProvider) {
|
||||
drivers.Register(name, driver)
|
||||
}
|
||||
|
||||
func All() []string {
|
||||
return drivers.Drivers()
|
||||
}
|
||||
|
||||
func Get(name string) AuditorProvider {
|
||||
if d, ok := drivers.Get(name).(AuditorProvider); ok {
|
||||
return d
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
package main
|
||||
package typescript_logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
|
|
@ -19,13 +20,13 @@ type filePtyLogger struct {
|
|||
oldtime time.Time
|
||||
}
|
||||
|
||||
func newFilePtyLogger(user string) (*filePtyLogger, error) {
|
||||
func newFilePtyLogger(outputdir string) (*filePtyLogger, error) {
|
||||
|
||||
now := time.Now()
|
||||
|
||||
filename := fmt.Sprintf("%d", now.Unix())
|
||||
|
||||
typescript, err := os.OpenFile(userSpecFile(user, fmt.Sprintf("%v.typescript", filename)), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
typescript, err := os.OpenFile(path.Join(outputdir, fmt.Sprintf("%v.typescript", filename)), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -37,7 +38,7 @@ func newFilePtyLogger(user string) (*filePtyLogger, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
timing, err := os.OpenFile(userSpecFile(user, fmt.Sprintf("%v.timing", filename)), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
timing, err := os.OpenFile(path.Join(outputdir, fmt.Sprintf("%v.timing", filename)), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
52
sshpiperd/auditor/typescript_logger/plugin.go
Normal file
52
sshpiperd/auditor/typescript_logger/plugin.go
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
package typescript_logger
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
|
||||
"github.com/tg123/sshpiper/sshpiperd/auditor"
|
||||
)
|
||||
|
||||
type plugin struct {
|
||||
Config struct {
|
||||
OutputDir string `long:"auditor-typescriptlogger-outputdir" default:"/var/sshpiper" description:"Place where logged typescript files were saved" ini-name:"auditor-typescriptlogger-outputdir"`
|
||||
}
|
||||
}
|
||||
|
||||
func (p *plugin) GetName() string {
|
||||
return "typescript-logger"
|
||||
}
|
||||
|
||||
func (p *plugin) GetOpts() interface{} {
|
||||
return &p.Config
|
||||
}
|
||||
|
||||
func (p *plugin) CreateAuditor(conn ssh.ConnMetadata) (auditor.Auditor, error) {
|
||||
dir := path.Join(p.Config.OutputDir, conn.User())
|
||||
err := os.MkdirAll(dir, 0700)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newFilePtyLogger(dir)
|
||||
}
|
||||
|
||||
func (p *plugin) Init(logger *log.Logger) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *filePtyLogger) GetUpstreamHook() auditor.AuditorHook {
|
||||
return l.loggingTty
|
||||
}
|
||||
|
||||
func (l *filePtyLogger) GetDownstreamHook() auditor.AuditorHook {
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
auditor.Register("typescript-logger", new(plugin))
|
||||
}
|
||||
|
|
@ -6,6 +6,8 @@ import (
|
|||
|
||||
"github.com/jessevdk/go-flags"
|
||||
|
||||
"github.com/tg123/sshpiper/sshpiperd/auditor"
|
||||
_ "github.com/tg123/sshpiper/sshpiperd/auditor/loader"
|
||||
"github.com/tg123/sshpiper/sshpiperd/challenger"
|
||||
_ "github.com/tg123/sshpiper/sshpiperd/challenger/loader"
|
||||
"github.com/tg123/sshpiper/sshpiperd/registry"
|
||||
|
|
@ -87,6 +89,7 @@ func main() {
|
|||
|
||||
addPlugins(parser, "upstream", upstream.All(), func(n string) registry.Plugin { return upstream.Get(n) })
|
||||
addPlugins(parser, "challenger", challenger.All(), func(n string) registry.Plugin { return challenger.Get(n) })
|
||||
addPlugins(parser, "auditor", auditor.All(), func(n string) registry.Plugin { return auditor.Get(n) })
|
||||
|
||||
if _, err := parser.Parse(); err != nil {
|
||||
return
|
||||
|
|
@ -97,7 +100,7 @@ func main() {
|
|||
err := ini.ParseFile(string(config.ConfigFile))
|
||||
|
||||
if err != nil {
|
||||
// set by user or
|
||||
// set by user
|
||||
if !o.IsSetDefault() {
|
||||
fmt.Printf("load config file %v failed %v", config.ConfigFile, err)
|
||||
fmt.Println()
|
||||
|
|
@ -108,7 +111,7 @@ func main() {
|
|||
// init log
|
||||
initLogger(config.Logfile)
|
||||
|
||||
// start to serve
|
||||
// no subcommand called, start to serve
|
||||
if parser.Active == nil {
|
||||
showVersion()
|
||||
dumpConfig()
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"golang.org/x/crypto/ssh"
|
||||
|
||||
"github.com/tg123/sshpiper/sshpiperd/auditor"
|
||||
"github.com/tg123/sshpiper/sshpiperd/challenger"
|
||||
"github.com/tg123/sshpiper/sshpiperd/upstream"
|
||||
)
|
||||
|
|
@ -18,6 +19,7 @@ type piperdConfig struct {
|
|||
|
||||
UpstreamDriver string `short:"u" long:"upstream-driver" description:"Upstream provider driver" default:"workingdir" env:"SSHPIPERD_UPSTREAM_DRIVER" ini-name:"upstream-driver"`
|
||||
ChallengerDriver string `short:"c" long:"challenger-driver" description:"Additional challenger name, e.g. pam, empty for no additional challenge" env:"SSHPIPERD_CHALLENGER" ini-name:"challenger-driver"`
|
||||
AuditorDriver string `long:"auditor-driver" description:"Auditor for ssh connections piped by SSH Piper " env:"SSHPIPERD_AUDITOR" ini-name:"auditor-driver"`
|
||||
}
|
||||
|
||||
func startPiper(config *piperdConfig) {
|
||||
|
|
@ -47,6 +49,19 @@ func startPiper(config *piperdConfig) {
|
|||
piper.AdditionalChallenge = ac.GetChallengerHandler()
|
||||
}
|
||||
|
||||
var bigbro auditor.AuditorProvider
|
||||
// install auditor
|
||||
if config.AuditorDriver != "" {
|
||||
bigbro = auditor.Get(config.AuditorDriver)
|
||||
|
||||
if bigbro == nil {
|
||||
logger.Fatalf("auditor driver %v not found", config.AuditorDriver)
|
||||
}
|
||||
|
||||
logger.Printf("using auditor %s", config.AuditorDriver)
|
||||
bigbro.Init(logger)
|
||||
}
|
||||
|
||||
privateBytes, err := ioutil.ReadFile(config.PiperKeyFile)
|
||||
if err != nil {
|
||||
logger.Fatalln(err)
|
||||
|
|
@ -83,18 +98,18 @@ func startPiper(config *piperdConfig) {
|
|||
return
|
||||
}
|
||||
|
||||
//if config.RecordTypescript {
|
||||
// auditor, err := newFilePtyLogger(p.DownstreamConnMeta().User())
|
||||
if bigbro != nil {
|
||||
a, err := bigbro.CreateAuditor(p.DownstreamConnMeta())
|
||||
if err != nil {
|
||||
logger.Printf("connection from %v failed to create auditor reason: %v", c.RemoteAddr(), err)
|
||||
return
|
||||
}
|
||||
defer a.Close()
|
||||
|
||||
// if err != nil {
|
||||
// logger.Printf("connection from %v failed to create auditor reason: %v", c.RemoteAddr(), err)
|
||||
// return
|
||||
// }
|
||||
p.HookUpstreamMsg = a.GetUpstreamHook()
|
||||
p.HookDownstreamMsg = a.GetDownstreamHook()
|
||||
|
||||
// defer auditor.Close()
|
||||
|
||||
// p.HookUpstreamMsg = auditor.loggingTty
|
||||
//}
|
||||
}
|
||||
|
||||
err = p.Wait()
|
||||
logger.Printf("connection from %v closed reason: %v", c.RemoteAddr(), err)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import (
|
|||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
|
|
@ -36,7 +37,7 @@ func init() {
|
|||
}
|
||||
|
||||
func userSpecFile(user, file string) string {
|
||||
return fmt.Sprintf("%s/%s/%s", config.WorkingDir, user, file)
|
||||
return path.Join(config.WorkingDir, user, file)
|
||||
}
|
||||
|
||||
func (file userFile) read(user string) ([]byte, error) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue