proxy protocol: added an option to make the proxy header required

now we can configure SFTPGo to accept or reject requests without the proxy
header when the proxy protocol is enabled
This commit is contained in:
Nicola Murino
2020-02-29 00:02:06 +01:00
parent 830e3d1f64
commit 7163fde724
7 changed files with 94 additions and 16 deletions

View File

@@ -3,6 +3,7 @@ package sftpd
import (
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
@@ -26,7 +27,10 @@ const (
defaultPrivateECDSAKeyName = "id_ecdsa"
)
var sftpExtensions = []string{"posix-rename@openssh.com"}
var (
sftpExtensions = []string{"posix-rename@openssh.com"}
errWrongProxyProtoVersion = errors.New("unacceptable proxy protocol version")
)
// Configuration for the SFTP server
type Configuration struct {
@@ -104,10 +108,12 @@ type Configuration struct {
// If you are running SFTPGo behind a proxy server such as HAProxy, AWS ELB or NGNIX, you can enable
// the proxy protocol. It provides a convenient way to safely transport connection information
// such as a client's address across multiple layers of NAT or TCP proxies to get the real
// client IP address instead of the proxy IP.
// Set to 1 to enable proxy protocol.
// You have to enable the protocol in your proxy configuration too, for example for HAProxy
// add "send-proxy" or "send-proxy-v2" to each server configuration line
// client IP address instead of the proxy IP. Both protocol v1 and v2 are supported.
// - 0 means disabled
// - 1 means proxy protocol enabled. Proxy header will be used and requests without proxy header will be accepted.
// - 2 means proxy protocol required. Proxy header will be used and requests without proxy header will be rejected.
// If the proxy protocol is enabled in SFTPGo then you have to enable the protocol in your proxy configuration too,
// for example for HAProxy add "send-proxy" or "send-proxy-v2" to each server configuration line.
ProxyProtocol int `json:"proxy_protocol" mapstructure:"proxy_protocol"`
}
@@ -193,13 +199,7 @@ func (c Configuration) Initialize(configDir string) error {
logger.Warn(logSender, "", "error starting listener on address %s:%d: %v", c.BindAddress, c.BindPort, err)
return err
}
var proxyListener *proxyproto.Listener
if c.ProxyProtocol == 1 {
proxyListener = &proxyproto.Listener{
Listener: listener,
}
}
proxyListener := c.getProxyListener(listener)
actions = c.Actions
uploadMode = c.UploadMode
setstatMode = c.SetstatMode
@@ -219,6 +219,23 @@ func (c Configuration) Initialize(configDir string) error {
}
}
func (c *Configuration) getProxyListener(listener net.Listener) *proxyproto.Listener {
var proxyListener *proxyproto.Listener
if c.ProxyProtocol > 0 {
var policyFunc func(upstream net.Addr) (proxyproto.Policy, error)
if c.ProxyProtocol == 2 {
policyFunc = func(upstream net.Addr) (proxyproto.Policy, error) {
return proxyproto.REQUIRE, nil
}
}
proxyListener = &proxyproto.Listener{
Listener: listener,
Policy: policyFunc,
}
}
return proxyListener
}
func (c Configuration) checkIdleTimer() {
if c.IdleTimeout > 0 {
startIdleTimer(time.Duration(c.IdleTimeout) * time.Minute)