summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Thomas <nick@gitlab.com>2021-04-09 12:09:29 +0100
committerNick Thomas <nick@gitlab.com>2021-04-09 12:22:40 +0100
commit47fa4d7dad0e62f38aa2e7e119359872c215eae8 (patch)
tree5c57eb0322b7f063059027ce4bcec135aca1ea92
parent88f94337bb87c0cc51f6badf7a4ff1826f25efaa (diff)
downloadgitlab-shell-491-support-proxy-protocol.tar.gz
gitlab-sshd: Support the PROXY protocol491-support-proxy-protocol
-rw-r--r--Makefile2
-rw-r--r--cmd/gitlab-sshd/acceptance_test.go29
-rw-r--r--config.yml.example3
-rw-r--r--go.mod1
-rw-r--r--go.sum2
-rw-r--r--internal/config/config.go11
-rw-r--r--internal/sshd/sshd.go15
7 files changed, 53 insertions, 10 deletions
diff --git a/Makefile b/Makefile
index 749674b..4bd94e6 100644
--- a/Makefile
+++ b/Makefile
@@ -43,4 +43,4 @@ check:
bin/check
clean:
- rm -f bin/check bin/gitlab-shell bin/gitlab-shell-authorized-keys-check bin/gitlab-shell-authorized-principals-check
+ rm -f bin/check bin/gitlab-shell bin/gitlab-shell-authorized-keys-check bin/gitlab-shell-authorized-principals-check bin/gitlab-sshd
diff --git a/cmd/gitlab-sshd/acceptance_test.go b/cmd/gitlab-sshd/acceptance_test.go
index 1b6931b..949afe8 100644
--- a/cmd/gitlab-sshd/acceptance_test.go
+++ b/cmd/gitlab-sshd/acceptance_test.go
@@ -8,6 +8,7 @@ import (
"fmt"
"io"
"io/ioutil"
+ "net"
"net/http"
"net/http/httptest"
"os"
@@ -18,6 +19,7 @@ import (
"testing"
"github.com/mikesmitty/edkey"
+ "github.com/pires/go-proxyproto"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/ssh"
)
@@ -72,6 +74,7 @@ secret: "0123456789abcdef"
gitlab_url: "` + gitlabUrl + `"
sshd:
listen: "127.0.0.1:0"
+ proxy_protocol: true
web_listen: ""
host_key_files:
- "` + hostKeyPath + `"`)
@@ -89,13 +92,37 @@ func buildClient(t *testing.T, addr string, hostKey ed25519.PublicKey) *ssh.Clie
clientSigner, err := ssh.NewSignerFromKey(clientPrivKey)
require.NoError(t, err)
- client, err := ssh.Dial("tcp", addr, &ssh.ClientConfig{
+ // Use the proxy protocol to spoof our client address
+ target, err := net.ResolveTCPAddr("tcp", addr)
+ require.NoError(t, err)
+ conn, err := net.DialTCP("tcp", nil, target)
+ require.NoError(t, err)
+ t.Cleanup(func() { conn.Close() })
+
+ // Create a proxyprotocol header or use HeaderProxyFromAddrs() if you
+ // have two conn's
+ header := &proxyproto.Header{
+ Version: 2,
+ Command: proxyproto.PROXY,
+ TransportProtocol: proxyproto.TCPv4,
+ SourceAddr: &net.TCPAddr{
+ IP: net.ParseIP("10.1.1.1"),
+ Port: 1000,
+ },
+ DestinationAddr: target,
+ }
+ // After the connection was created write the proxy headers first
+ _, err = header.WriteTo(conn)
+ require.NoError(t, err)
+
+ sshConn, chans, reqs, err := ssh.NewClientConn(conn, addr, &ssh.ClientConfig{
User: "git",
Auth: []ssh.AuthMethod{ssh.PublicKeys(clientSigner)},
HostKeyCallback: ssh.FixedHostKey(pubKey),
})
require.NoError(t, err)
+ client := ssh.NewClient(sshConn, chans, reqs)
t.Cleanup(func() { client.Close() })
return client
diff --git a/config.yml.example b/config.yml.example
index 8a00375..248136b 100644
--- a/config.yml.example
+++ b/config.yml.example
@@ -66,6 +66,9 @@ audit_usernames: false
sshd:
# Address which the SSH server listens on. Defaults to [::]:22.
listen: "[::]:22"
+ # Set to true if gitlab-sshd is being fronted by a load balancer that implements
+ # the PROXY protocol
+ proxy_protocol: false
# Address which the server listens on HTTP for monitoring/health checks. Defaults to localhost:9122.
web_listen: "localhost:9122"
# Maximum number of concurrent sessions allowed on a single SSH connection. Defaults to 10.
diff --git a/go.mod b/go.mod
index 6016ae4..2eeb0ad 100644
--- a/go.mod
+++ b/go.mod
@@ -6,6 +6,7 @@ require (
github.com/mattn/go-shellwords v1.0.11
github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a
github.com/otiai10/copy v1.4.2
+ github.com/pires/go-proxyproto v0.5.0
github.com/prometheus/client_golang v1.9.0
github.com/sirupsen/logrus v1.7.0
github.com/stretchr/testify v1.6.1
diff --git a/go.sum b/go.sum
index df15888..3bb8cc4 100644
--- a/go.sum
+++ b/go.sum
@@ -396,6 +396,8 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
+github.com/pires/go-proxyproto v0.5.0 h1:A4Jv4ZCaV3AFJeGh5mGwkz4iuWUYMlQ7IoO/GTuSuLo=
+github.com/pires/go-proxyproto v0.5.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
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/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
diff --git a/internal/config/config.go b/internal/config/config.go
index 36f8625..2709277 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -18,6 +18,7 @@ const (
type ServerConfig struct {
Listen string `yaml:"listen,omitempty"`
+ ProxyProtocol bool `yaml:"proxy_protocol,omitempty"`
WebListen string `yaml:"web_listen,omitempty"`
ConcurrentSessionsLimit int64 `yaml:"concurrent_sessions_limit,omitempty"`
HostKeyFiles []string `yaml:"host_key_files,omitempty"`
@@ -52,15 +53,15 @@ type Config struct {
// The defaults to apply before parsing the config file(s).
var (
DefaultConfig = Config{
- LogFile: "gitlab-shell.log",
+ LogFile: "gitlab-shell.log",
LogFormat: "text",
- Server: DefaultServerConfig,
- User: "git",
+ Server: DefaultServerConfig,
+ User: "git",
}
DefaultServerConfig = ServerConfig{
- Listen: "[::]:22",
- WebListen: "localhost:9122",
+ Listen: "[::]:22",
+ WebListen: "localhost:9122",
ConcurrentSessionsLimit: 10,
HostKeyFiles: []string{
"/run/secrets/ssh-hostkeys/ssh_host_rsa_key",
diff --git a/internal/sshd/sshd.go b/internal/sshd/sshd.go
index 74029b0..7bd81ff 100644
--- a/internal/sshd/sshd.go
+++ b/internal/sshd/sshd.go
@@ -10,17 +10,20 @@ import (
"strconv"
"time"
+ log "github.com/sirupsen/logrus"
+
+ "github.com/pires/go-proxyproto"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
- log "github.com/sirupsen/logrus"
+ "golang.org/x/crypto/ssh"
+ "golang.org/x/sync/semaphore"
+
"gitlab.com/gitlab-org/gitlab-shell/internal/command"
"gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs"
"gitlab.com/gitlab-org/gitlab-shell/internal/command/readwriter"
"gitlab.com/gitlab-org/gitlab-shell/internal/config"
"gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/authorizedkeys"
"gitlab.com/gitlab-org/gitlab-shell/internal/sshenv"
- "golang.org/x/crypto/ssh"
- "golang.org/x/sync/semaphore"
)
const (
@@ -73,6 +76,12 @@ func Run(cfg *config.Config) error {
if err != nil {
return fmt.Errorf("failed to listen for connection: %w", err)
}
+ if cfg.Server.ProxyProtocol {
+ sshListener = &proxyproto.Listener{Listener: sshListener}
+
+ log.Info("Proxy protocol is enabled")
+ }
+ defer sshListener.Close()
log.Infof("Listening on %v", sshListener.Addr().String())