Browse Source

add more details to the server status page

add all supported fields to the OpenAPI docs

Signed-off-by: Nicola Murino <[email protected]>
Nicola Murino 3 years ago
parent
commit
7f674a7fb3

+ 5 - 0
ftpd/ftpd.go

@@ -32,6 +32,11 @@ type PassiveIPOverride struct {
 	parsedNetworks []func(net.IP) bool
 }
 
+// GetNetworksAsString returns the configured networks as string
+func (p *PassiveIPOverride) GetNetworksAsString() string {
+	return strings.Join(p.Networks, ", ")
+}
+
 // Binding defines the configuration for a network listener
 type Binding struct {
 	// The address to listen on. A blank value means listen on all available network interfaces.

+ 1 - 0
ftpd/internal_test.go

@@ -975,6 +975,7 @@ func TestPassiveIPResolver(t *testing.T) {
 	}
 	err = b.checkPassiveIP()
 	assert.NoError(t, err)
+	assert.NotEmpty(t, b.PassiveIPOverrides[0].GetNetworksAsString())
 	assert.Equal(t, "192.168.1.1", b.PassiveIPOverrides[0].IP)
 	require.Len(t, b.PassiveIPOverrides[0].parsedNetworks, 1)
 	ip := net.ParseIP("192.168.1.2")

+ 2 - 2
httpd/httpd.go

@@ -634,8 +634,8 @@ func getConfigPath(name, configDir string) string {
 	return name
 }
 
-func getServicesStatus() ServicesStatus {
-	status := ServicesStatus{
+func getServicesStatus() *ServicesStatus {
+	status := &ServicesStatus{
 		SSH:          sftpd.GetStatus(),
 		FTP:          ftpd.GetStatus(),
 		WebDAV:       webdavd.GetStatus(),

+ 1 - 1
httpd/webadmin.go

@@ -141,7 +141,7 @@ type connectionsPage struct {
 
 type statusPage struct {
 	basePage
-	Status ServicesStatus
+	Status *ServicesStatus
 }
 
 type fsWrapper struct {

+ 77 - 0
openapi/openapi.yaml

@@ -4467,6 +4467,23 @@ components:
         - admin
         - api_key
         - share
+    SSHAuthentications:
+      type: string
+      enum:
+        - publickey
+        - password
+        - keyboard-interactive
+        - publickey+password
+        - publickey+keyboard-interactive
+    TLSVersions:
+      type: integer
+      enum:
+        - 12
+        - 13
+      description: >
+        TLS version:
+          * `12` - TLS 1.2
+          * `13` - TLS 1.3
     TOTPConfig:
       type: object
       properties:
@@ -5373,9 +5390,33 @@ components:
           description: the port used for serving requests
         enable_https:
           type: boolean
+        min_tls_version:
+          $ref: '#/components/schemas/TLSVersions'
         client_auth_type:
           type: integer
           description: 1 means that client certificate authentication is required in addition to HTTP basic authentication
+        tls_cipher_suites:
+          type: array
+          items:
+            type: string
+          description: 'List of supported cipher suites for TLS version 1.2. If empty  a default list of secure cipher suites is used, with a preference order based on hardware performance'
+        prefix:
+          type: string
+          description: 'Prefix for WebDAV resources, if empty WebDAV resources will be available at the `/` URI'
+        proxy_allowed:
+          type: array
+          items:
+            type: string
+          description: 'List of IP addresses and IP ranges allowed to set proxy headers'
+    PassiveIPOverride:
+      type: object
+      properties:
+        networks:
+          type: array
+          items:
+            type: string
+        ip:
+          type: string
     FTPDBinding:
       type: object
       properties:
@@ -5399,12 +5440,44 @@ components:
               * `0` - clear or explicit TLS
               * `1` - explicit TLS required
               * `2` - implicit TLS
+        min_tls_version:
+          $ref: '#/components/schemas/TLSVersions'
         force_passive_ip:
           type: string
           description: External IP address to expose for passive connections
+        passive_ip_overrides:
+          type: array
+          items:
+            $ref: '#/components/schemas/PassiveIPOverride'
         client_auth_type:
           type: integer
           description: 1 means that client certificate authentication is required in addition to FTP authentication
+        tls_cipher_suites:
+          type: array
+          items:
+            type: string
+          description: 'List of supported cipher suites for TLS version 1.2. If empty  a default list of secure cipher suites is used, with a preference order based on hardware performance'
+        passive_connections_security:
+          type: integer
+          enum:
+            - 0
+            - 1
+          description: |
+            Active connections security:
+              * `0` - require matching peer IP addresses of control and data connection
+              * `1` - disable any checks
+        active_connections_security:
+          type: integer
+          enum:
+            - 0
+            - 1
+          description: |
+            Active connections security:
+              * `0` - require matching peer IP addresses of control and data connection
+              * `1` - disable any checks
+        debug:
+          type: boolean
+          description: 'If enabled any FTP command will be logged'
     SSHServiceStatus:
       type: object
       properties:
@@ -5424,6 +5497,10 @@ components:
           type: array
           items:
             type: string
+        authentications:
+          type: array
+          items:
+            $ref: '#/components/schemas/SSHAuthentications'
     FTPPassivePortRange:
       type: object
       properties:

+ 5 - 0
service/service.go

@@ -263,6 +263,11 @@ func (s *Service) loadInitialData() error {
 	}
 	info, err := os.Stat(s.LoadDataFrom)
 	if err != nil {
+		if errors.Is(err, os.ErrNotExist) {
+			logger.Warn(logSender, "", "unable to load initial data, the file %#v does not exist", s.LoadDataFrom)
+			logger.WarnToConsole("unable to load initial data, the file %#v does not exist", s.LoadDataFrom)
+			return nil
+		}
 		return err
 	}
 	if info.Size() > httpd.MaxRestoreSize {

+ 20 - 0
sftpd/server.go

@@ -203,13 +203,30 @@ func (c *Configuration) getServerConfig() *ssh.ServerConfig {
 
 			return sp, nil
 		}
+		serviceStatus.Authentications = append(serviceStatus.Authentications, dataprovider.LoginMethodPassword)
 	}
+	serviceStatus.Authentications = append(serviceStatus.Authentications, dataprovider.SSHLoginMethodPublicKey)
 
 	return serverConfig
 }
 
+func (c *Configuration) updateSupportedAuthentications() {
+	serviceStatus.Authentications = util.RemoveDuplicates(serviceStatus.Authentications)
+
+	if util.IsStringInSlice(dataprovider.LoginMethodPassword, serviceStatus.Authentications) &&
+		util.IsStringInSlice(dataprovider.SSHLoginMethodPublicKey, serviceStatus.Authentications) {
+		serviceStatus.Authentications = append(serviceStatus.Authentications, dataprovider.SSHLoginMethodKeyAndPassword)
+	}
+
+	if util.IsStringInSlice(dataprovider.SSHLoginMethodKeyboardInteractive, serviceStatus.Authentications) &&
+		util.IsStringInSlice(dataprovider.SSHLoginMethodPublicKey, serviceStatus.Authentications) {
+		serviceStatus.Authentications = append(serviceStatus.Authentications, dataprovider.SSHLoginMethodKeyAndKeyboardInt)
+	}
+}
+
 // Initialize the SFTP server and add a persistent listener to handle inbound SFTP connections.
 func (c *Configuration) Initialize(configDir string) error {
+	serviceStatus.Authentications = nil
 	serverConfig := c.getServerConfig()
 
 	if !c.ShouldBind() {
@@ -270,6 +287,7 @@ func (c *Configuration) Initialize(configDir string) error {
 
 	serviceStatus.IsActive = true
 	serviceStatus.SSHCommands = c.EnabledSSHCommands
+	c.updateSupportedAuthentications()
 
 	return <-exitChannel
 }
@@ -381,6 +399,8 @@ func (c *Configuration) configureKeyboardInteractiveAuth(serverConfig *ssh.Serve
 
 		return sp, nil
 	}
+
+	serviceStatus.Authentications = append(serviceStatus.Authentications, dataprovider.SSHLoginMethodKeyboardInteractive)
 }
 
 func canAcceptConnection(ip string) bool {

+ 11 - 5
sftpd/sftpd.go

@@ -38,17 +38,23 @@ type HostKey struct {
 
 // ServiceStatus defines the service status
 type ServiceStatus struct {
-	IsActive    bool      `json:"is_active"`
-	Bindings    []Binding `json:"bindings"`
-	SSHCommands []string  `json:"ssh_commands"`
-	HostKeys    []HostKey `json:"host_keys"`
+	IsActive        bool      `json:"is_active"`
+	Bindings        []Binding `json:"bindings"`
+	SSHCommands     []string  `json:"ssh_commands"`
+	HostKeys        []HostKey `json:"host_keys"`
+	Authentications []string  `json:"authentications"`
 }
 
 // GetSSHCommandsAsString returns enabled SSH commands as comma separated string
-func (s ServiceStatus) GetSSHCommandsAsString() string {
+func (s *ServiceStatus) GetSSHCommandsAsString() string {
 	return strings.Join(s.SSHCommands, ", ")
 }
 
+// GetSupportedAuthsAsString returns the supported authentications as comma separated string
+func (s *ServiceStatus) GetSupportedAuthsAsString() string {
+	return strings.Join(s.Authentications, ", ")
+}
+
 // GetStatus returns the server status
 func GetStatus() ServiceStatus {
 	return serviceStatus

+ 2 - 0
sftpd/sftpd_test.go

@@ -445,6 +445,8 @@ func TestBasicSFTPHandling(t *testing.T) {
 	assert.True(t, status.IsActive)
 	sshCommands := status.GetSSHCommandsAsString()
 	assert.NotEmpty(t, sshCommands)
+	sshAuths := status.GetSupportedAuthsAsString()
+	assert.NotEmpty(t, sshAuths)
 }
 
 func TestBasicSFTPFsHandling(t *testing.T) {

+ 7 - 1
templates/webadmin/status.html

@@ -21,6 +21,8 @@
                     Address: "{{.GetAddress}}" {{if .HasProxy}}Proxy: ON{{end}}
                     <br>
                     {{end}}
+                    Accepted authentications: "{{.Status.SSH.GetSupportedAuthsAsString}}"
+                    <br>
                     Accepted commands: "{{.Status.SSH.GetSSHCommandsAsString}}"
                     <br>
                     {{range .Status.SSH.HostKeys}}
@@ -49,9 +51,13 @@
                     TLS: "{{.GetTLSDescription}}"
                     {{if .ForcePassiveIP}}
                     <br>
-                    PassiveIP: {{.ForcePassiveIP}}
+                    Passive IP: {{.ForcePassiveIP}}
                     {{end}}
                     <br>
+                    {{range .PassiveIPOverrides}}
+                    Passive IP: {{.IP}} for networks: {{.GetNetworksAsString}}
+                    <br>
+                    {{end}}
                     {{end}}
                     <br>
                     Passive port range: "{{.Status.FTP.PassivePortRange.Start}}-{{.Status.FTP.PassivePortRange.End}}"

+ 0 - 1
webdavd/webdavd.go

@@ -26,7 +26,6 @@ const (
 )
 
 var (
-	//server *webDavServer
 	certMgr       *common.CertManager
 	serviceStatus ServiceStatus
 )