diff --git a/weed/command/filer.go b/weed/command/filer.go index cee886d18..1d8a6c4b8 100644 --- a/weed/command/filer.go +++ b/weed/command/filer.go @@ -62,6 +62,7 @@ type FilerOptions struct { downloadMaxMBps *int diskType *string allowedOrigins *string + exposeDirectoryData *bool } func init() { @@ -93,6 +94,7 @@ func init() { f.downloadMaxMBps = cmdFiler.Flag.Int("downloadMaxMBps", 0, "download max speed for each download request, in MB per second") f.diskType = cmdFiler.Flag.String("disk", "", "[hdd|ssd|] hard drive or solid state drive or any tag") f.allowedOrigins = cmdFiler.Flag.String("allowedOrigins", "*", "comma separated list of allowed origins") + f.exposeDirectoryData = cmdFiler.Flag.Bool("exposeDirectoryData", true, "whether to return directory metadata and content in Filer UI") // start s3 on filer filerStartS3 = cmdFiler.Flag.Bool("s3", false, "whether to start S3 gateway") diff --git a/weed/command/scaffold/security.toml b/weed/command/scaffold/security.toml index 9626ee58c..c5b2a563c 100644 --- a/weed/command/scaffold/security.toml +++ b/weed/command/scaffold/security.toml @@ -24,6 +24,13 @@ expires_after_seconds = 10 # seconds [access] ui = false +# by default the filer UI is enabled. This can be a security risk if the filer is exposed to the public +# and the JWT for reads is not set. If you don't want the public to have access to the objects in your +# storage, and you haven't set the JWT for reads it is wise to disable access to directory metadata. +# This disables access to the Filer UI, and will no longer return directory metadata in GET requests. +[filer.expose_directory_metadata] +enabled = true + # this jwt signing key is read by master and volume server, and it is used for read operations: # - the Master server generates the JWT, which can be used to read a certain file on a volume server # - the Volume server validates the JWT on reading diff --git a/weed/command/server.go b/weed/command/server.go index b8ef25fad..63133b80c 100644 --- a/weed/command/server.go +++ b/weed/command/server.go @@ -118,6 +118,7 @@ func init() { filerOptions.showUIDirectoryDelete = cmdServer.Flag.Bool("filer.ui.deleteDir", true, "enable filer UI show delete directory button") filerOptions.downloadMaxMBps = cmdServer.Flag.Int("filer.downloadMaxMBps", 0, "download max speed for each download request, in MB per second") filerOptions.diskType = cmdServer.Flag.String("filer.disk", "", "[hdd|ssd|] hard drive or solid state drive or any tag") + filerOptions.exposeDirectoryData = cmdServer.Flag.Bool("filer.exposeDirectoryData", true, "expose directory data via filer. If false, filer UI will be innaccessible.") serverOptions.v.port = cmdServer.Flag.Int("volume.port", 8080, "volume server http listen port") serverOptions.v.portGrpc = cmdServer.Flag.Int("volume.port.grpc", 0, "volume server grpc listen port") diff --git a/weed/server/filer_server.go b/weed/server/filer_server.go index a04fd1910..9428c2edf 100644 --- a/weed/server/filer_server.go +++ b/weed/server/filer_server.go @@ -72,6 +72,7 @@ type FilerOption struct { DownloadMaxBytesPs int64 DiskType string AllowedOrigins []string + ExposeDirectoryData bool } type FilerServer struct { @@ -115,6 +116,10 @@ func NewFilerServer(defaultMux, readonlyMux *http.ServeMux, option *FilerOption) domains := strings.Split(allowedOrigins, ",") option.AllowedOrigins = domains + v.SetDefault("filer.expose_directory_metadata.enabled", true) + returnDirMetadata := v.GetBool("filer.expose_directory_metadata.enabled") + option.ExposeDirectoryData = returnDirMetadata + fs = &FilerServer{ option: option, grpcDialOption: security.LoadClientTLS(util.GetViper(), "grpc.filer"), diff --git a/weed/server/filer_server_handlers_read.go b/weed/server/filer_server_handlers_read.go index d1cd3beae..0f4037237 100644 --- a/weed/server/filer_server_handlers_read.go +++ b/weed/server/filer_server_handlers_read.go @@ -117,7 +117,7 @@ func (fs *FilerServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request) w.WriteHeader(http.StatusForbidden) return } - if query.Get("metadata") == "true" { + if query.Get("metadata") == "true" && fs.option.ExposeDirectoryData != false { writeJsonQuiet(w, r, http.StatusOK, entry) return } @@ -135,7 +135,7 @@ func (fs *FilerServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request) return } - if query.Get("metadata") == "true" { + if query.Get("metadata") == "true" && fs.option.ExposeDirectoryData != false { if query.Get("resolveManifest") == "true" { if entry.Chunks, _, err = filer.ResolveChunkManifest( fs.filer.MasterClient.GetLookupFileIdFunction(), diff --git a/weed/server/filer_server_handlers_read_dir.go b/weed/server/filer_server_handlers_read_dir.go index 2060e3374..be38fba1d 100644 --- a/weed/server/filer_server_handlers_read_dir.go +++ b/weed/server/filer_server_handlers_read_dir.go @@ -18,6 +18,11 @@ import ( // is empty. func (fs *FilerServer) listDirectoryHandler(w http.ResponseWriter, r *http.Request) { + if fs.option.ExposeDirectoryData == false { + http.NotFound(w, r) + return + } + stats.FilerHandlerCounter.WithLabelValues(stats.DirList).Inc() path := r.URL.Path @@ -95,4 +100,5 @@ func (fs *FilerServer) listDirectoryHandler(w http.ResponseWriter, r *http.Reque if err != nil { glog.V(0).Infof("Template Execute Error: %v", err) } + }