From 52ca0667ca1b30ecf73ffbefce169c6a15f1a3d4 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 7 Dec 2019 14:01:40 -0800 Subject: [PATCH] Add base support for internalizing the SFTP server --- config/config.go | 36 ++++++++++++++++++++++++++++++------ go.mod | 5 ++--- go.sum | 11 +++++++++++ sftp/server.go | 30 ++++++++++++++++++++++++++++++ wings.go | 10 ++++++++++ 5 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 sftp/server.go diff --git a/config/config.go b/config/config.go index abd4a03..b5ef9bc 100644 --- a/config/config.go +++ b/config/config.go @@ -2,6 +2,7 @@ package config import ( "fmt" + "github.com/mcuadros/go-defaults" "go.uber.org/zap" "gopkg.in/yaml.v2" "io/ioutil" @@ -87,6 +88,24 @@ type SystemConfiguration struct { // "0" as being crashed if the process stopped without any Wings interaction. E.g. // the user did not press the stop button, but the process stopped cleanly. DetectCleanExitAsCrash bool `default:"true" yaml:"detect_clean_exit_as_crash"` + + Sftp *SftpConfiguration `default:"SftpConfiguration" yaml:"sftp"` +} + +// Defines the configuration of the internal SFTP server. +type SftpConfiguration struct { + // If set to false, the internal SFTP server will not be booted and you will need + // to run the SFTP server independent of this program. + UseInternalSystem bool `default:"true" yaml:"use_internal"` + // If set to true disk checking will not be performed. This will prevent the SFTP + // server from checking the total size of a directory when uploading files. + DisableDiskChecking bool `default:"false" yaml:"disable_disk_checking"` + // The bind address of the SFTP server. + Address string `default:"0.0.0.0" yaml:"bind_address"` + // The bind port of the SFTP server. + Port int `default:"2022" yaml:"bind_port"` + // If set to true, no write actions will be allowed on the SFTP server. + ReadOnly bool `default:"false" yaml:"read_only"` } // Defines the docker configuration used by the daemon when interacting with @@ -145,9 +164,9 @@ type ApiConfiguration struct { // a tedious thing to have to do. func (c *Configuration) SetDefaults() { c.System = &SystemConfiguration{ - Username: "pterodactyl", - Data: "/srv/daemon-data", - TimezonePath:"/etc/timezone", + Username: "pterodactyl", + Data: "/srv/daemon-data", + TimezonePath: "/etc/timezone", } // By default the internal webserver should bind to all interfaces and @@ -191,8 +210,13 @@ func ReadConfiguration(path string) (*Configuration, error) { return nil, err } - c := &Configuration{} - c.SetDefaults() + sftp :=new(SftpConfiguration) + defaults.SetDefaults(sftp) + + c := new(Configuration) + c.System = new(SystemConfiguration) + c.System.Sftp = sftp + defaults.SetDefaults(c) // Replace environment variables within the configuration file with their // values from the host system. @@ -361,4 +385,4 @@ func getSystemName() (string, error) { } return string(b), nil -} \ No newline at end of file +} diff --git a/go.mod b/go.mod index 43e9fe2..00f74c7 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a github.com/beevik/etree v1.1.0 - github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 + github.com/buger/jsonparser v0.0.0-20191204142016-1a29609e0929 github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 // indirect github.com/creasty/defaults v1.3.0 github.com/docker/distribution v2.7.1+incompatible // indirect @@ -37,10 +37,9 @@ require ( github.com/opencontainers/image-spec v1.0.1 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/errors v0.8.0 + github.com/pterodactyl/sftp-server v1.0.4 github.com/remeh/sizedwaitgroup v0.0.0-20180822144253-5e7302b12cce github.com/sirupsen/logrus v1.0.5 // indirect - go.uber.org/atomic v1.3.2 // indirect - go.uber.org/multierr v1.1.0 // indirect go.uber.org/zap v1.9.1 golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 // indirect golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac // indirect diff --git a/go.sum b/go.sum index b9d3ddf..f07dc29 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,11 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= +github.com/buger/jsonparser v0.0.0-20181023193515-52c6e1462ebd/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 h1:D21IyuvjDCshj1/qq+pCNd3VZOAEI9jy6Bi131YlXgI= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/buger/jsonparser v0.0.0-20191204142016-1a29609e0929 h1:MW/JDk68Rny52yI0M0N+P8lySNgB+NhpI/uAmhgOhUM= +github.com/buger/jsonparser v0.0.0-20191204142016-1a29609e0929/go.mod h1:tgcrVJ81GPSF0mz+0nu1Xaz0fazGPrmmJfJtxjbHhUQ= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 h1:PUD50EuOMkXVcpBIA/R95d56duJR9VxhwncsFbNnxW4= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/creasty/defaults v1.3.0 h1:uG+RAxYbJgOPCOdKEcec9ZJXeva7Y6mj/8egdzwmLtw= @@ -55,6 +58,8 @@ github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -82,16 +87,22 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.8.3 h1:9jSe2SxTM8/3bXZjtqnkgTBW+lA8db0knZJyns7gpBA= +github.com/pkg/sftp v1.8.3/go.mod h1:NxmoDg/QLVWluQDUYG7XBZTLUpKeFa8e3aMf1BfjyHk= +github.com/pterodactyl/sftp-server v1.0.4 h1:hPUaUQvA6U/R8/bybQFDMBDcZaqqj+kufGBQZ3esP5M= +github.com/pterodactyl/sftp-server v1.0.4/go.mod h1:0LKDl+f1qY2TH9+B5jxdROktW0+10UM1qJ472iWbyvQ= github.com/remeh/sizedwaitgroup v0.0.0-20180822144253-5e7302b12cce h1:aP+C+YbHZfOQlutA4p4soHi7rVUqHQdWEVMSkHfDTqY= github.com/remeh/sizedwaitgroup v0.0.0-20180822144253-5e7302b12cce/go.mod h1:3j2R4OIe/SeS6YDhICBy22RWjJC5eNCJ1V+9+NVNYlo= github.com/sirupsen/logrus v1.0.5 h1:8c8b5uO0zS4X6RPl/sd1ENwSkIc0/H2PaHxE3udaE8I= github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/uber-go/zap v1.9.1/go.mod h1:GY+83l3yxBcBw2kmHu/sAWwItnTn+ynxHCRo+WiIQOY= go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 h1:O5YqonU5IWby+w98jVUG9h7zlCWCcH4RHyPVReBmhzk= golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= diff --git a/sftp/server.go b/sftp/server.go new file mode 100644 index 0000000..b51a707 --- /dev/null +++ b/sftp/server.go @@ -0,0 +1,30 @@ +package sftp + +import ( + "github.com/patrickmn/go-cache" + sftpserver "github.com/pterodactyl/sftp-server/src/server" + "github.com/pterodactyl/wings/config" + "path" + "time" +) + +func Initialize(config *config.Configuration) error { + c := sftpserver.Configuration{ + Data: []byte("{}"), + Cache: cache.New(5*time.Minute, 10*time.Minute), + User: sftpserver.SftpUser{ + Uid: config.System.User.Uid, + Gid: config.System.User.Gid, + }, + Settings: sftpserver.Settings{ + BasePath: config.System.Data, + ReadOnly: config.System.Sftp.ReadOnly, + BindAddress: config.System.Sftp.Address, + BindPort: config.System.Sftp.Port, + ServerDataFolder: path.Join(config.System.Data, "/servers"), + DisableDiskCheck: config.System.Sftp.DisableDiskChecking, + }, + } + + return c.Initalize() +} diff --git a/wings.go b/wings.go index 6788392..eaa5594 100644 --- a/wings.go +++ b/wings.go @@ -8,9 +8,11 @@ import ( "github.com/pkg/errors" "github.com/pterodactyl/wings/config" "github.com/pterodactyl/wings/server" + "github.com/pterodactyl/wings/sftp" "github.com/remeh/sizedwaitgroup" "go.uber.org/zap" "net/http" + "os" ) // Entrypoint for the Wings application. Configures the logger and checks any @@ -137,6 +139,14 @@ func main() { // Wait until all of the servers are ready to go before we fire up the HTTP server. wg.Wait() + // If the SFTP subsystem should be started, do so now. + if c.System.Sftp.UseInternalSystem { + if err := sftp.Initialize(c); err != nil { + zap.S().Fatalw("failed to initialize SFTP subsystem", zap.Error(errors.WithStack(err))) + os.Exit(1) + } + } + r := &Router{ Servers: servers, token: c.AuthenticationToken,