From f7d9e56cac765229c2638d79c4342b1036f98eac Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Sat, 24 Feb 2024 20:35:09 +0100 Subject: [PATCH] ssh: remove moduli, log negotiated algorithms Fixes #1324 Signed-off-by: Nicola Murino --- Dockerfile | 3 +- Dockerfile.alpine | 3 - Dockerfile.distroless | 3 +- docs/full-configuration.md | 3 +- go.mod | 44 ++++----- go.sum | 94 +++++++++--------- internal/config/config.go | 2 - internal/dataprovider/configs.go | 16 ++-- internal/httpd/httpd_test.go | 22 ++--- internal/sftpd/internal_test.go | 60 ++++-------- internal/sftpd/server.go | 160 +++++++++---------------------- internal/sftpd/sftpd.go | 20 ++-- internal/sftpd/sftpd_test.go | 35 ++++++- internal/vfs/sftpfs.go | 18 ++-- 14 files changed, 198 insertions(+), 285 deletions(-) diff --git a/Dockerfile b/Dockerfile index 784485ef..bd26b684 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM golang:1.22-bookworm as builder ENV GOFLAGS="-mod=readonly" -RUN apt-get update && apt-get -y upgrade && apt-get install --no-install-recommends -y openssh-server && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get -y upgrade && rm -rf /var/lib/apt/lists/* RUN mkdir -p /workspace WORKDIR /workspace @@ -47,7 +47,6 @@ RUN groupadd --system -g 1000 sftpgo && \ --comment "SFTPGo user" --uid 1000 sftpgo COPY --from=builder /workspace/sftpgo.json /etc/sftpgo/sftpgo.json -COPY --from=builder /etc/ssh/moduli /etc/sftpgo/moduli COPY --from=builder /workspace/templates /usr/share/sftpgo/templates COPY --from=builder /workspace/static /usr/share/sftpgo/static COPY --from=builder /workspace/openapi /usr/share/sftpgo/openapi diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 230da12e..3b9f82f5 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -25,8 +25,6 @@ RUN set -xe && \ export COMMIT_SHA=${COMMIT_SHA:-$(git describe --always --abbrev=8 --dirty)} && \ go build $(if [ -n "${FEATURES}" ]; then echo "-tags ${FEATURES}"; fi) -trimpath -ldflags "-s -w -X github.com/drakkan/sftpgo/v2/internal/version.commit=${COMMIT_SHA} -X github.com/drakkan/sftpgo/v2/internal/version.date=`date -u +%FT%TZ`" -v -o sftpgo -RUN apk add --update --no-cache openssh-client-common - FROM alpine:3.19 # Set to "true" to install jq and the optional git and rsync dependencies @@ -42,7 +40,6 @@ RUN addgroup -g 1000 -S sftpgo && \ adduser -u 1000 -h /var/lib/sftpgo -s /sbin/nologin -G sftpgo -S -D -H -g "SFTPGo user" sftpgo COPY --from=builder /workspace/sftpgo.json /etc/sftpgo/sftpgo.json -COPY --from=builder /etc/ssh/moduli /etc/sftpgo/moduli COPY --from=builder /workspace/templates /usr/share/sftpgo/templates COPY --from=builder /workspace/static /usr/share/sftpgo/static COPY --from=builder /workspace/openapi /usr/share/sftpgo/openapi diff --git a/Dockerfile.distroless b/Dockerfile.distroless index 35416090..a88e2fc4 100644 --- a/Dockerfile.distroless +++ b/Dockerfile.distroless @@ -2,7 +2,7 @@ FROM golang:1.22-bookworm as builder ENV CGO_ENABLED=0 GOFLAGS="-mod=readonly" -RUN apt-get update && apt-get -y upgrade && apt-get install --no-install-recommends -y media-types openssh-server && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get -y upgrade && apt-get install --no-install-recommends -y media-types && rm -rf /var/lib/apt/lists/* RUN mkdir -p /workspace WORKDIR /workspace @@ -38,7 +38,6 @@ COPY --from=builder --chown=1000:1000 /etc/sftpgo /etc/sftpgo COPY --from=builder --chown=1000:1000 /srv/sftpgo /srv/sftpgo COPY --from=builder --chown=1000:1000 /var/lib/sftpgo /var/lib/sftpgo COPY --from=builder --chown=1000:1000 /workspace/sftpgo.json /etc/sftpgo/sftpgo.json -COPY --from=builder --chown=1000:1000 /etc/ssh/moduli /etc/sftpgo/moduli COPY --from=builder /workspace/templates /usr/share/sftpgo/templates COPY --from=builder /workspace/static /usr/share/sftpgo/static COPY --from=builder /workspace/openapi /usr/share/sftpgo/openapi diff --git a/docs/full-configuration.md b/docs/full-configuration.md index 8663fdd8..e33f1504 100644 --- a/docs/full-configuration.md +++ b/docs/full-configuration.md @@ -143,8 +143,7 @@ The configuration file contains the following sections: - `host_keys`, list of strings. It contains the daemon's private host keys. Each host key can be defined as a path relative to the configuration directory or an absolute one. If empty, the daemon will search or try to generate `id_rsa`, `id_ecdsa` and `id_ed25519` keys inside the configuration directory. If you configure absolute paths to files named `id_rsa`, `id_ecdsa` and/or `id_ed25519` then SFTPGo will try to generate these keys using the default settings. - `host_certificates`, list of strings. Public host certificates. Each certificate can be defined as a path relative to the configuration directory or an absolute one. Certificate's public key must match a private host key otherwise it will be silently ignored. Default: empty. - `host_key_algorithms`, list of strings. Public key algorithms that the server will accept for host key authentication. The supported values are: `rsa-sha2-512-cert-v01@openssh.com`, `rsa-sha2-256-cert-v01@openssh.com`, `ssh-rsa-cert-v01@openssh.com`, `ssh-dss-cert-v01@openssh.com`, `ecdsa-sha2-nistp256-cert-v01@openssh.com`, `ecdsa-sha2-nistp384-cert-v01@openssh.com`, `ecdsa-sha2-nistp521-cert-v01@openssh.com`, `ssh-ed25519-cert-v01@openssh.com`, `ecdsa-sha2-nistp256`, `ecdsa-sha2-nistp384`, `ecdsa-sha2-nistp521`, `rsa-sha2-512`, `rsa-sha2-256`, `ssh-rsa`, `ssh-dss`, `ssh-ed25519`. Certificate algorithms are listed for backward compatibility purposes only, they are not used. Default values: `rsa-sha2-512`, `rsa-sha2-256`, `ecdsa-sha2-nistp256`, `ecdsa-sha2-nistp384`, `ecdsa-sha2-nistp521`, `ssh-ed25519`. - - `moduli`, list of strings. Diffie-Hellman moduli files. Each moduli file can be defined as a path relative to the configuration directory or an absolute one. If set and valid, `diffie-hellman-group-exchange-sha256` and `diffie-hellman-group-exchange-sha1` KEX algorithms will be available, `diffie-hellman-group-exchange-sha256` will be enabled by default if you don't explicitly set KEXs. Invalid moduli file will be silently ignored. Default: empty. - - `kex_algorithms`, list of strings. Available KEX (Key Exchange) algorithms in preference order. Leave empty to use default values. The supported values are: `curve25519-sha256`, `curve25519-sha256@libssh.org`, `ecdh-sha2-nistp256`, `ecdh-sha2-nistp384`, `ecdh-sha2-nistp521`, `diffie-hellman-group14-sha256`, `diffie-hellman-group16-sha512`, `diffie-hellman-group14-sha1`, `diffie-hellman-group1-sha1`. Default values: `curve25519-sha256`, `curve25519-sha256@libssh.org`, `ecdh-sha2-nistp256`, `ecdh-sha2-nistp384`, `ecdh-sha2-nistp521`, `diffie-hellman-group14-sha256`. SHA512 based KEXs are disabled by default because they are slow. If you set one or more moduli files, `diffie-hellman-group-exchange-sha256` and `diffie-hellman-group-exchange-sha1` will be available. + - `kex_algorithms`, list of strings. Available KEX (Key Exchange) algorithms in preference order. Leave empty to use default values. The supported values are: `curve25519-sha256` (will also enable the alias `curve25519-sha256@libssh.org`), `ecdh-sha2-nistp256`, `ecdh-sha2-nistp384`, `ecdh-sha2-nistp521`, `diffie-hellman-group14-sha256`, `diffie-hellman-group16-sha512`, `diffie-hellman-group14-sha1`, `diffie-hellman-group1-sha1`, `diffie-hellman-group-exchange-sha256`, `diffie-hellman-group-exchange-sha1`. Default values: `curve25519-sha256`, `ecdh-sha2-nistp256`, `ecdh-sha2-nistp384`, `ecdh-sha2-nistp521`, `diffie-hellman-group14-sha256`, `diffie-hellman-group-exchange-sha256`. SHA512 based KEXs are disabled by default because they are slow. - `ciphers`, list of strings. Allowed ciphers in preference order. Leave empty to use default values. The supported values are: `aes128-gcm@openssh.com`, `aes256-gcm@openssh.com`, `chacha20-poly1305@openssh.com`, `aes128-ctr`, `aes192-ctr`, `aes256-ctr`, `aes128-cbc`, `aes192-cbc`, `aes256-cbc`, `3des-cbc`, `arcfour256`, `arcfour128`, `arcfour`. Default values: `aes128-gcm@openssh.com`, `aes256-gcm@openssh.com`, `chacha20-poly1305@openssh.com`, `aes128-ctr`, `aes192-ctr`, `aes256-ctr`. Please note that the ciphers disabled by default are insecure, you should expect that an active attacker can recover plaintext if you enable them. - `macs`, list of strings. Available MAC (message authentication code) algorithms in preference order. Leave empty to use default values. The supported values are: `hmac-sha2-256-etm@openssh.com`, `hmac-sha2-256`, `hmac-sha2-512-etm@openssh.com`, `hmac-sha2-512`, `hmac-sha1`, `hmac-sha1-96`. Default values: `hmac-sha2-256-etm@openssh.com`, `hmac-sha2-256`. - `public_key_algorithms`, list of strings. Public key algorithms that the server will accept for client authentication. The supported values are: `ecdsa-sha2-nistp256`, `ecdsa-sha2-nistp384`, `ecdsa-sha2-nistp521`, `rsa-sha2-512`, `rsa-sha2-256`, `ssh-rsa`, `ssh-dss`, `ssh-ed25519`, `sk-ssh-ed25519@openssh.com`, `sk-ecdsa-sha2-nistp256@openssh.com`. Default values: `ecdsa-sha2-nistp256`, `ecdsa-sha2-nistp384`, `ecdsa-sha2-nistp521`, `rsa-sha2-512`, `rsa-sha2-256`, `ssh-ed25519`, `sk-ssh-ed25519@openssh.com`, `sk-ecdsa-sha2-nistp256@openssh.com`. diff --git a/go.mod b/go.mod index 4bf61dc8..f05b4f47 100644 --- a/go.mod +++ b/go.mod @@ -9,15 +9,15 @@ require ( github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5 github.com/alexedwards/argon2id v1.0.0 github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964 - github.com/aws/aws-sdk-go-v2 v1.25.1 - github.com/aws/aws-sdk-go-v2/config v1.27.3 - github.com/aws/aws-sdk-go-v2/credentials v1.17.3 - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1 - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.5 - github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.21.0 - github.com/aws/aws-sdk-go-v2/service/s3 v1.51.0 - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.0 - github.com/aws/aws-sdk-go-v2/service/sts v1.28.0 + github.com/aws/aws-sdk-go-v2 v1.25.2 + github.com/aws/aws-sdk-go-v2/config v1.27.4 + github.com/aws/aws-sdk-go-v2/credentials v1.17.4 + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.2 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.6 + github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.21.1 + github.com/aws/aws-sdk-go-v2/service/s3 v1.51.1 + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.1 + github.com/aws/aws-sdk-go-v2/service/sts v1.28.1 github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/cockroachdb/cockroach-go/v2 v2.3.6 github.com/coreos/go-oidc/v3 v3.9.0 @@ -65,7 +65,7 @@ require ( github.com/wagslane/go-password-validator v0.3.0 github.com/wneessen/go-mail v0.4.1 github.com/yl2chen/cidranger v1.0.3-0.20210928021809-d1cb2c52f37a - go.etcd.io/bbolt v1.3.8 + go.etcd.io/bbolt v1.3.9 go.uber.org/automaxprocs v1.5.3 gocloud.dev v0.36.0 golang.org/x/crypto v0.19.0 @@ -86,16 +86,16 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect github.com/ajg/form v1.5.1 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.1 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.1 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.20.0 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.20.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.1 // indirect github.com/aws/smithy-go v1.20.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/boombuler/barcode v1.0.1 // indirect @@ -108,7 +108,7 @@ require ( github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/go-jose/go-jose/v3 v3.0.1 // indirect + github.com/go-jose/go-jose/v3 v3.0.2 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect @@ -160,8 +160,8 @@ require ( github.com/tklauser/numcpus v0.7.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect @@ -187,5 +187,5 @@ replace ( github.com/jlaffaye/ftp => github.com/drakkan/ftp v0.0.0-20240210102745-f1ffc43f78d2 github.com/pkg/sftp => github.com/drakkan/sftp v0.0.0-20240214104840-fbb0b8bdb30c github.com/robfig/cron/v3 => github.com/drakkan/cron/v3 v3.0.0-20230222140221-217a1e4d96c0 - golang.org/x/crypto => github.com/drakkan/crypto v0.0.0-20231218163632-74b52eafd2c0 + golang.org/x/crypto => github.com/drakkan/crypto v0.0.0-20240224191538-9f4629f0732c ) diff --git a/go.sum b/go.sum index fe4528ed..2033b531 100644 --- a/go.sum +++ b/go.sum @@ -33,46 +33,46 @@ github.com/alexedwards/argon2id v1.0.0 h1:wJzDx66hqWX7siL/SRUmgz3F8YMrd/nfX/xHHc github.com/alexedwards/argon2id v1.0.0/go.mod h1:tYKkqIjzXvZdzPvADMWOEZ+l6+BD6CtBXMj5fnJppiw= github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964 h1:I9YN9WMo3SUh7p/4wKeNvD/IQla3U3SUa61U7ul+xM4= github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964/go.mod h1:eFiR01PwTcpbzXtdMces7zxg6utvFM5puiWHpWB8D/k= -github.com/aws/aws-sdk-go-v2 v1.25.1 h1:P7hU6A5qEdmajGwvae/zDkOq+ULLC9tQBTwqqiwFGpI= -github.com/aws/aws-sdk-go-v2 v1.25.1/go.mod h1:Evoc5AsmtveRt1komDwIsjHFyrP5tDuF1D1U+6z6pNo= +github.com/aws/aws-sdk-go-v2 v1.25.2 h1:/uiG1avJRgLGiQM9X3qJM8+Qa6KRGK5rRPuXE0HUM+w= +github.com/aws/aws-sdk-go-v2 v1.25.2/go.mod h1:Evoc5AsmtveRt1komDwIsjHFyrP5tDuF1D1U+6z6pNo= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 h1:gTK2uhtAPtFcdRRJilZPx8uJLL2J85xK11nKtWL0wfU= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1/go.mod h1:sxpLb+nZk7tIfCWChfd+h4QwHNUR57d8hA1cleTkjJo= -github.com/aws/aws-sdk-go-v2/config v1.27.3 h1:0PRdb/q5a77HVYj+2rvPiCObfMfl/pWhwa5cs3cnl3c= -github.com/aws/aws-sdk-go-v2/config v1.27.3/go.mod h1:WeRAr9ENap9NAegbfNsLqGQd8ERz5ypdIUx4j0/ZgKI= -github.com/aws/aws-sdk-go-v2/credentials v1.17.3 h1:dDM5wrgwOL5gTZ0Gv/bvewPldjBcJywoaO5ClERrOGE= -github.com/aws/aws-sdk-go-v2/credentials v1.17.3/go.mod h1:G96Nuaw9qJS+s3OnK8RW8VEKEOjXi8H5Jk4lC/ZyZbw= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1 h1:lk1ZZFbdb24qpOwVC1AwYNrswUjAxeyey6kFBVANudQ= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1/go.mod h1:/xJ6x1NehNGCX4tvGzzj2bq5TBOT/Yxq+qbL9Jpx2Vk= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.5 h1:IEv6homMJMnedG/2VWfNuV34ouXUmK8E7y4rAl59Fhs= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.5/go.mod h1:a+wq9mSuG13iSkVMR1O8VApmAISm1ca+E2RQpcB3flw= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.1 h1:evvi7FbTAoFxdP/mixmP7LIYzQWAmzBcwNB/es9XPNc= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.1/go.mod h1:rH61DT6FDdikhPghymripNUCsf+uVF4Cnk4c4DBKH64= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.1 h1:RAnaIrbxPtlXNVI/OIlh1sidTQ3e1qM6LRjs7N0bE0I= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.1/go.mod h1:nbgAGkH5lk0RZRMh6A4K/oG6Xj11eC/1CyDow+DUAFI= +github.com/aws/aws-sdk-go-v2/config v1.27.4 h1:AhfWb5ZwimdsYTgP7Od8E9L1u4sKmDW2ZVeLcf2O42M= +github.com/aws/aws-sdk-go-v2/config v1.27.4/go.mod h1:zq2FFXK3A416kiukwpsd+rD4ny6JC7QSkp4QdN1Mp2g= +github.com/aws/aws-sdk-go-v2/credentials v1.17.4 h1:h5Vztbd8qLppiPwX+y0Q6WiwMZgpd9keKe2EAENgAuI= +github.com/aws/aws-sdk-go-v2/credentials v1.17.4/go.mod h1:+30tpwrkOgvkJL1rUZuRLoxcJwtI/OkeBLYnHxJtVe0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.2 h1:AK0J8iYBFeUk2Ax7O8YpLtFsfhdOByh2QIkHmigpRYk= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.2/go.mod h1:iRlGzMix0SExQEviAyptRWRGdYNo3+ufW/lCzvKVTUc= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.6 h1:prcsGA3onmpc7ea1W/m+SMj4uOn5vZ63uJp805UhJJs= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.6/go.mod h1:7eQrvATnVFDY0WfMYhfKkSQ1YtZlClT71fAAlsA1s34= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2 h1:bNo4LagzUKbjdxE0tIcR9pMzLR2U/Tgie1Hq1HQ3iH8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2/go.mod h1:wRQv0nN6v9wDXuWThpovGQjqF1HFdcgWjporw14lS8k= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2 h1:EtOU5jsPdIQNP+6Q2C5e3d65NKT1PeCiQk+9OdzO12Q= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2/go.mod h1:tyF5sKccmDz0Bv4NrstEr+/9YkSPJHrcO7UsUKf7pWM= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.1 h1:rtYJd3w6IWCTVS8vmMaiXjW198noh2PBm5CiXyJea9o= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.1/go.mod h1:zvXu+CTlib30LUy4LTNFc6HTZ/K6zCae5YIHTdX9wIo= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.2 h1:en92G0Z7xlksoOylkUhuBSfJgijC7rHVLRdnIlHEs0E= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.2/go.mod h1:HgtQ/wN5G+8QSlK62lbOtNwQ3wTSByJ4wH2rCkPt+AE= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 h1:EyBZibRTVAs6ECHZOw5/wlylS9OcTzwyjeQMudmREjE= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1/go.mod h1:JKpmtYhhPs7D97NL/ltqz7yCkERFW5dOlHyVl66ZYF8= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.1 h1:5Wxh862HkXL9CbQ83BIkWKLIgQapGeuh5zG2G9OZtQk= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.1/go.mod h1:V7GLA01pNUxMCYSQsibdVrqUrNIYIT/9lCOyR8ExNvQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.1 h1:cVP8mng1RjDyI3JN/AXFCn5FHNlsBaBH0/MBtG1bg0o= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.1/go.mod h1:C8sQjoyAsdfjC7hpy4+S6B92hnFzx0d0UAyHicaOTIE= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.1 h1:OYmmIcyw19f7x0qLBLQ3XsrCZSSyLhxd9GXng5evsN4= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.1/go.mod h1:s5rqdn74Vdg10k61Pwf4ZHEApOSD6CKRe6qpeHDq32I= -github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.21.0 h1:NEWfVJgrDwEXrKDNrrX+2LtWhKVLYpJ2d7/gr1N1B54= -github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.21.0/go.mod h1:TzgisXFoXgCssgP11SzC6KrvcyCErz5c3w++m3xFOfo= -github.com/aws/aws-sdk-go-v2/service/s3 v1.51.0 h1:rNVsCe3bqTAhG+qjnHJKgYKdHEsqqo/GMK3gEYY8W6g= -github.com/aws/aws-sdk-go-v2/service/s3 v1.51.0/go.mod h1:lTW7O4iMAnO2o7H3XJTvqaWFZCH6zIPs+eP7RdG/yp0= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.0 h1:Xf3s55N9cqKvFK6D70zCXvXXN4ZovTCy7glL+gUhLEc= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.0/go.mod h1:RA3ERghFSivbTf0Sbsxv/grUuLMcyAjm0F/PylJMmEs= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.0 h1:6YL8G91QZ52KlPrLkEgEez5kejIVwChVCgND3qgY5j0= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.0/go.mod h1:x6/tCd1o/AOKQR+iYnjrzhJxD+w0xRN34asGPaSV7ew= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.0 h1:+DqIa5Ll7W311QLUvGFDdVit9uC4G0VioDdw08cXcow= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.0/go.mod h1:lZB123q0SVQ3dfIbEOcGzhQHrwVBcHVReNS9tm20oU4= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.0 h1:F7tQr61zYnTaeY50Rn4jwfVQbtcqJuBRwN/nGGNwzb0= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.0/go.mod h1:ozhhG9/NB5c9jcmhGq6tX9dpp21LYdmRWRQVppASim4= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.2 h1:zSdTXYLwuXDNPUS+V41i1SFDXG7V0ITp0D9UT9Cvl18= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.2/go.mod h1:v8m8k+qVy95nYi7d56uP1QImleIIY25BPiNJYzPBdFE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.2 h1:5ffmXjPtwRExp1zc7gENLgCPyHFbhEPwVTkTiH9niSk= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.2/go.mod h1:Ru7vg1iQ7cR4i7SZ/JTLYN9kaXtbL69UdgG0OQWQxW0= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.2 h1:1oY1AVEisRI4HNuFoLdRUB0hC63ylDAN6Me3MrfclEg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.2/go.mod h1:KZ03VgvZwSjkT7fOetQ/wF3MZUvYFirlI1H5NklUNsY= +github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.21.1 h1:cy+x/R8zd4Zluf+6ZWzbPPdLh+l4MeYPlYxdqK+Qr0M= +github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.21.1/go.mod h1:ITcPsa7HwiY6ddwbwmtuf+/q7sfr4MjH5HzUvn5FHBQ= +github.com/aws/aws-sdk-go-v2/service/s3 v1.51.1 h1:juZ+uGargZOrQGNxkVHr9HHR/0N+Yu8uekQnV7EAVRs= +github.com/aws/aws-sdk-go-v2/service/s3 v1.51.1/go.mod h1:SoR0c7Jnq8Tpmt0KSLXIavhjmaagRqQpe9r70W3POJg= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.1 h1:DtKw4TxZT3VrzYupXQJPBqT9ImyobZZE+JIQPPAVxqs= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.1/go.mod h1:bit9G2ORpSjUTr4PA4usvbBfbOyvMj0LbE1dXF14Sug= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.1 h1:utEGkfdQ4L6YW/ietH7111ZYglLJvS+sLriHJ1NBJEQ= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.1/go.mod h1:RsYqzYr2F2oPDdpy+PdhephuZxTfjHQe7SOBcZGoAU8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.1 h1:9/GylMS45hGGFCcMrUZDVayQE1jYSIN6da9jo7RAYIw= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.1/go.mod h1:YjAPFn4kGFqKC54VsHs5fn5B6d+PCY2tziEa3U/GB5Y= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.1 h1:3I2cBEYgKhrWlwyZgfpSO2BpaMY1LHPqXYk/QGlu2ew= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.1/go.mod h1:uQ7YYKZt3adCRrdCBREm1CD3efFLOUNH77MrUCvx5oA= github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -91,8 +91,6 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= github.com/cockroachdb/cockroach-go/v2 v2.3.6 h1:Wlv9TzkrG9V7i6u8dEtmXPrBzvfFp+CgJNs696rAajM= github.com/cockroachdb/cockroach-go/v2 v2.3.6/go.mod h1:1wNJ45eSXW9AnOc3skntW9ZUZz6gxrQK3cOj3rK+BC8= github.com/coreos/go-oidc/v3 v3.9.0 h1:0J/ogVOd4y8P0f0xUh8l9t07xRP/d8tccvjHl2dcsSo= @@ -111,8 +109,8 @@ github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/drakkan/cron/v3 v3.0.0-20230222140221-217a1e4d96c0 h1:EW9gIJRmt9lzk66Fhh4S8VEtURA6QHZqGeSRE9Nb2/U= github.com/drakkan/cron/v3 v3.0.0-20230222140221-217a1e4d96c0/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/drakkan/crypto v0.0.0-20231218163632-74b52eafd2c0 h1:Yel8NcrK4jg+biIcTxnszKh0eIpF2Vj25XEygQcTweI= -github.com/drakkan/crypto v0.0.0-20231218163632-74b52eafd2c0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +github.com/drakkan/crypto v0.0.0-20240224191538-9f4629f0732c h1:Jwxc0vhD7t484x2GDv8B5WbvrSwxML9V+A8esl7vkh8= +github.com/drakkan/crypto v0.0.0-20240224191538-9f4629f0732c/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= github.com/drakkan/ftp v0.0.0-20240210102745-f1ffc43f78d2 h1:ufiGMPFBjndWSQOst9FNP11IuMqPblI2NXbpRMUWNhk= github.com/drakkan/ftp v0.0.0-20240210102745-f1ffc43f78d2/go.mod h1:4p8lUl4vQ80L598CygL+3IFtm+3nggvvW/palOlViwE= github.com/drakkan/ftpserverlib v0.0.0-20240212100826-a241365cb085 h1:LAKYR9z9USKeyEQK91sRWldmMOjEHLOt2NuLDx+x1UQ= @@ -127,8 +125,6 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= -github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= @@ -148,8 +144,8 @@ github.com/go-chi/jwtauth/v5 v5.3.0 h1:X7RKGks1lrVeIe2omGyz47pNaNjG2YmwlRN5UKhN8 github.com/go-chi/jwtauth/v5 v5.3.0/go.mod h1:2PoGm/KbnzRN9ILY6HFZAI6fTnb1gEZAKogAyqkd6fY= github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4= github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= -github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= -github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= +github.com/go-jose/go-jose/v3 v3.0.2 h1:2Edjn8Nrb44UvTdp84KU0bBPs1cO7noRCybtS3eJEUQ= +github.com/go-jose/go-jose/v3 v3.0.2/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= @@ -411,14 +407,14 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= -go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= +go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0 h1:P+/g8GpuJGYbOp2tAdKrIPUX9JO02q8Q0YNlHolpibA= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0/go.mod h1:tIKj3DbO8N9Y2xo52og3irLsPI4GW02DSMtrVgNMgxg= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0 h1:doUP+ExOpH3spVTLS0FcWGLnQrPct/hD/bCPbDRUEAU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0/go.mod h1:rdENBZMT2OE6Ne/KLwpiXudnAsbdrdBaqBvTN8M8BgA= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= @@ -491,7 +487,6 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -499,7 +494,6 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/internal/config/config.go b/internal/config/config.go index d3c3aceb..846e5d58 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -259,7 +259,6 @@ func Init() { HostKeys: []string{}, HostCertificates: []string{}, HostKeyAlgorithms: []string{}, - Moduli: []string{}, KexAlgorithms: []string{}, Ciphers: []string{}, MACs: []string{}, @@ -2020,7 +2019,6 @@ func setViperDefaults() { viper.SetDefault("sftpd.host_keys", globalConf.SFTPD.HostKeys) viper.SetDefault("sftpd.host_certificates", globalConf.SFTPD.HostCertificates) viper.SetDefault("sftpd.host_key_algorithms", globalConf.SFTPD.HostKeyAlgorithms) - viper.SetDefault("sftpd.moduli", globalConf.SFTPD.Moduli) viper.SetDefault("sftpd.kex_algorithms", globalConf.SFTPD.KexAlgorithms) viper.SetDefault("sftpd.ciphers", globalConf.SFTPD.Ciphers) viper.SetDefault("sftpd.macs", globalConf.SFTPD.MACs) diff --git a/internal/dataprovider/configs.go b/internal/dataprovider/configs.go index 85f57083..a68abf72 100644 --- a/internal/dataprovider/configs.go +++ b/internal/dataprovider/configs.go @@ -28,18 +28,18 @@ import ( // Supported values for host keys, KEXs, ciphers, MACs var ( supportedHostKeyAlgos = []string{ssh.KeyAlgoRSA} - supportedPublicKeyAlgos = []string{ssh.KeyAlgoRSA, ssh.KeyAlgoDSA} + supportedPublicKeyAlgos = []string{ssh.KeyAlgoRSA, ssh.InsecureKeyAlgoDSA} supportedKexAlgos = []string{ - "diffie-hellman-group16-sha512", "diffie-hellman-group14-sha1", "diffie-hellman-group1-sha1", - "diffie-hellman-group-exchange-sha256", "diffie-hellman-group-exchange-sha1", + ssh.KeyExchangeDH16SHA512, ssh.InsecureKeyExchangeDH14SHA1, ssh.InsecureKeyExchangeDH1SHA1, + ssh.InsecureKeyExchangeDHGEXSHA1, } supportedCiphers = []string{ - "aes128-cbc", "aes192-cbc", "aes256-cbc", - "3des-cbc", + ssh.InsecureCipherAES128CBC, ssh.InsecureCipherAES192CBC, ssh.InsecureCipherAES256CBC, + ssh.InsecureCipherTripleDESCBC, } supportedMACs = []string{ - "hmac-sha2-512-etm@openssh.com", "hmac-sha2-512", - "hmac-sha1", "hmac-sha1-96", + ssh.HMACSHA512ETM, ssh.HMACSHA512, + ssh.InsecureHMACSHA1, ssh.InsecureHMACSHA196, } ) @@ -110,7 +110,7 @@ func (c *SFTPDConfigs) validate() error { c.HostKeyAlgos = hostKeyAlgos var kexAlgos []string for _, algo := range c.KexAlgorithms { - if algo == "diffie-hellman-group18-sha512" { + if algo == "diffie-hellman-group18-sha512" || algo == ssh.KeyExchangeDHGEXSHA256 { continue } if !util.Contains(supportedKexAlgos, algo) { diff --git a/internal/httpd/httpd_test.go b/internal/httpd/httpd_test.go index b2fc9a50..7c693292 100644 --- a/internal/httpd/httpd_test.go +++ b/internal/httpd/httpd_test.go @@ -8140,7 +8140,7 @@ func TestLoaddata(t *testing.T) { configs := dataprovider.Configs{ SFTPD: &dataprovider.SFTPDConfigs{ HostKeyAlgos: []string{ssh.KeyAlgoRSA, ssh.CertAlgoRSAv01}, - PublicKeyAlgos: []string{ssh.KeyAlgoDSA}, + PublicKeyAlgos: []string{ssh.InsecureKeyAlgoDSA}, }, SMTP: &dataprovider.SMTPConfigs{ Host: "mail.example.com", @@ -8207,7 +8207,7 @@ func TestLoaddata(t *testing.T) { assert.NoError(t, err) assert.Equal(t, configs.SMTP, configsGet.SMTP) assert.Equal(t, []string{ssh.KeyAlgoRSA}, configsGet.SFTPD.HostKeyAlgos) - assert.Equal(t, []string{ssh.KeyAlgoDSA}, configsGet.SFTPD.PublicKeyAlgos) + assert.Equal(t, []string{ssh.InsecureKeyAlgoDSA}, configsGet.SFTPD.PublicKeyAlgos) assert.Len(t, configsGet.SFTPD.KexAlgorithms, 0) assert.Len(t, configsGet.SFTPD.Ciphers, 0) assert.Len(t, configsGet.SFTPD.MACs, 0) @@ -8554,7 +8554,7 @@ func TestLoaddataMode(t *testing.T) { entry, _, err = httpdtest.UpdateIPListEntry(entry, http.StatusOK) assert.NoError(t, err) - configs.SFTPD.PublicKeyAlgos = append(configs.SFTPD.PublicKeyAlgos, ssh.KeyAlgoDSA) + configs.SFTPD.PublicKeyAlgos = append(configs.SFTPD.PublicKeyAlgos, ssh.InsecureKeyAlgoDSA) err = dataprovider.UpdateConfigs(&configs, "", "", "") assert.NoError(t, err) backupData.Configs = &configs @@ -13088,8 +13088,8 @@ func TestWebConfigsMock(t *testing.T) { checkResponseCode(t, http.StatusBadRequest, rr) // save SFTP configs form.Set("sftp_host_key_algos", ssh.KeyAlgoRSA) - form.Add("sftp_host_key_algos", ssh.CertAlgoDSAv01) - form.Set("sftp_pub_key_algos", ssh.KeyAlgoDSA) + form.Add("sftp_host_key_algos", ssh.InsecureCertAlgoDSAv01) + form.Set("sftp_pub_key_algos", ssh.InsecureKeyAlgoDSA) form.Set("form_action", "sftp_submit") req, err = http.NewRequest(http.MethodPost, webConfigsPath, bytes.NewBuffer([]byte(form.Encode()))) assert.NoError(t, err) @@ -13100,9 +13100,9 @@ func TestWebConfigsMock(t *testing.T) { assert.Contains(t, rr.Body.String(), util.I18nError500Message) // invalid algo form.Set("sftp_host_key_algos", ssh.KeyAlgoRSA) form.Add("sftp_host_key_algos", ssh.CertAlgoRSAv01) - form.Set("sftp_pub_key_algos", ssh.KeyAlgoDSA) + form.Set("sftp_pub_key_algos", ssh.InsecureKeyAlgoDSA) form.Set("sftp_kex_algos", "diffie-hellman-group18-sha512") - form.Add("sftp_kex_algos", "diffie-hellman-group16-sha512") + form.Add("sftp_kex_algos", ssh.KeyExchangeDH16SHA512) req, err = http.NewRequest(http.MethodPost, webConfigsPath, bytes.NewBuffer([]byte(form.Encode()))) assert.NoError(t, err) setJWTCookieForReq(req, webToken) @@ -13116,9 +13116,9 @@ func TestWebConfigsMock(t *testing.T) { assert.Len(t, configs.SFTPD.HostKeyAlgos, 1) assert.Contains(t, configs.SFTPD.HostKeyAlgos, ssh.KeyAlgoRSA) assert.Len(t, configs.SFTPD.PublicKeyAlgos, 1) - assert.Contains(t, configs.SFTPD.PublicKeyAlgos, ssh.KeyAlgoDSA) + assert.Contains(t, configs.SFTPD.PublicKeyAlgos, ssh.InsecureKeyAlgoDSA) assert.Len(t, configs.SFTPD.KexAlgorithms, 1) - assert.Contains(t, configs.SFTPD.KexAlgorithms, "diffie-hellman-group16-sha512") + assert.Contains(t, configs.SFTPD.KexAlgorithms, ssh.KeyExchangeDH16SHA512) // invalid form action form.Set("form_action", "") req, err = http.NewRequest(http.MethodPost, webConfigsPath, bytes.NewBuffer([]byte(form.Encode()))) @@ -13163,7 +13163,7 @@ func TestWebConfigsMock(t *testing.T) { assert.Len(t, configs.SFTPD.HostKeyAlgos, 1) assert.Contains(t, configs.SFTPD.HostKeyAlgos, ssh.KeyAlgoRSA) assert.Len(t, configs.SFTPD.PublicKeyAlgos, 1) - assert.Contains(t, configs.SFTPD.PublicKeyAlgos, ssh.KeyAlgoDSA) + assert.Contains(t, configs.SFTPD.PublicKeyAlgos, ssh.InsecureKeyAlgoDSA) assert.Equal(t, "mail.example.net", configs.SMTP.Host) assert.Equal(t, 587, configs.SMTP.Port) assert.Equal(t, "Example ", configs.SMTP.From) @@ -13234,7 +13234,7 @@ func TestWebConfigsMock(t *testing.T) { assert.Len(t, configs.SFTPD.HostKeyAlgos, 1) assert.Contains(t, configs.SFTPD.HostKeyAlgos, ssh.KeyAlgoRSA) assert.Len(t, configs.SFTPD.PublicKeyAlgos, 1) - assert.Contains(t, configs.SFTPD.PublicKeyAlgos, ssh.KeyAlgoDSA) + assert.Contains(t, configs.SFTPD.PublicKeyAlgos, ssh.InsecureKeyAlgoDSA) assert.Equal(t, 80, configs.ACME.HTTP01Challenge.Port) assert.Equal(t, 7, configs.ACME.Protocols) assert.Empty(t, configs.ACME.Domain) diff --git a/internal/sftpd/internal_test.go b/internal/sftpd/internal_test.go index 285dbf67..7c3b9c35 100644 --- a/internal/sftpd/internal_test.go +++ b/internal/sftpd/internal_test.go @@ -1837,7 +1837,6 @@ func TestConfigsFromProvider(t *testing.T) { err = c.loadFromProvider() assert.NoError(t, err) assert.Len(t, c.HostKeyAlgorithms, 0) - assert.Len(t, c.Moduli, 0) assert.Len(t, c.KexAlgorithms, 0) assert.Len(t, c.Ciphers, 0) assert.Len(t, c.MACs, 0) @@ -1845,10 +1844,10 @@ func TestConfigsFromProvider(t *testing.T) { configs := dataprovider.Configs{ SFTPD: &dataprovider.SFTPDConfigs{ HostKeyAlgos: []string{ssh.KeyAlgoRSA}, - KexAlgorithms: []string{kexDHGroupExchangeSHA256}, - Ciphers: []string{"aes128-cbc", "aes192-cbc", "aes256-cbc"}, - MACs: []string{"hmac-sha2-512-etm@openssh.com"}, - PublicKeyAlgos: []string{ssh.KeyAlgoDSA}, + KexAlgorithms: []string{ssh.InsecureKeyExchangeDHGEXSHA1}, + Ciphers: []string{ssh.InsecureCipherAES128CBC, ssh.InsecureCipherAES192CBC, ssh.InsecureCipherAES256CBC}, + MACs: []string{ssh.HMACSHA512ETM}, + PublicKeyAlgos: []string{ssh.InsecureKeyAlgoDSA}, }, } err = dataprovider.UpdateConfigs(&configs, "", "", "") @@ -1876,58 +1875,33 @@ func TestSupportedSecurityOptions(t *testing.T) { MACs: supportedMACs, Ciphers: supportedCiphers, } + var defaultKexs []string + for _, k := range supportedKexAlgos { + defaultKexs = append(defaultKexs, k) + if k == ssh.KeyExchangeCurve25519SHA256 { + defaultKexs = append(defaultKexs, keyExchangeCurve25519SHA256LibSSH) + } + } serverConfig := &ssh.ServerConfig{} err := c.configureSecurityOptions(serverConfig) assert.NoError(t, err) assert.Equal(t, supportedCiphers, serverConfig.Ciphers) assert.Equal(t, supportedMACs, serverConfig.MACs) - assert.Equal(t, supportedKexAlgos, serverConfig.KeyExchanges) + assert.Equal(t, defaultKexs, serverConfig.KeyExchanges) c.KexAlgorithms = append(c.KexAlgorithms, "not a kex") err = c.configureSecurityOptions(serverConfig) assert.Error(t, err) - c.KexAlgorithms = supportedKexAlgos + c.KexAlgorithms = append(supportedKexAlgos, "diffie-hellman-group18-sha512") c.MACs = []string{ - " hmac-sha2-256-etm@openssh.com ", "hmac-sha2-256", - " hmac-sha2-512-etm@openssh.com", "hmac-sha2-512 ", - "hmac-sha1 ", " hmac-sha1-96", + " hmac-sha2-256-etm@openssh.com ", " hmac-sha2-512-etm@openssh.com", + "hmac-sha2-256", "hmac-sha2-512 ", + " hmac-sha1-96", "hmac-sha1 ", } err = c.configureSecurityOptions(serverConfig) assert.NoError(t, err) assert.Equal(t, supportedCiphers, serverConfig.Ciphers) assert.Equal(t, supportedMACs, serverConfig.MACs) - assert.Equal(t, supportedKexAlgos, serverConfig.KeyExchanges) - c.KexAlgorithms = append(preferredKexAlgos, kexDHGroupExchangeSHA256) // removed because no moduli is provided - err = c.configureSecurityOptions(serverConfig) - assert.NoError(t, err) - assert.Equal(t, supportedCiphers, serverConfig.Ciphers) - assert.Equal(t, supportedMACs, serverConfig.MACs) - assert.Equal(t, preferredKexAlgos, serverConfig.KeyExchanges) -} - -func TestLoadModuli(t *testing.T) { - dhGEXSha1 := "diffie-hellman-group-exchange-sha1" - dhGEXSha256 := "diffie-hellman-group-exchange-sha256" - c := Configuration{} - c.Moduli = []string{".", "missing file"} - c.loadModuli(configDir) - assert.NotContains(t, supportedKexAlgos, dhGEXSha1) - assert.NotContains(t, supportedKexAlgos, dhGEXSha256) - assert.NotContains(t, preferredKexAlgos, dhGEXSha1) - assert.NotContains(t, preferredKexAlgos, dhGEXSha256) - assert.Len(t, supportedKexAlgos, 10) - moduli := []byte("20220414072358 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB5D1B922F") - moduliFile := filepath.Join(os.TempDir(), "moduli") - err := os.WriteFile(moduliFile, moduli, 0600) - assert.NoError(t, err) - c.Moduli = []string{moduliFile} - c.loadModuli(configDir) - assert.Contains(t, supportedKexAlgos, dhGEXSha1) - assert.Contains(t, supportedKexAlgos, dhGEXSha256) - assert.NotContains(t, preferredKexAlgos, dhGEXSha1) - assert.Contains(t, preferredKexAlgos, dhGEXSha256) - assert.Len(t, supportedKexAlgos, 12) - err = os.Remove(moduliFile) - assert.NoError(t, err) + assert.Equal(t, defaultKexs, serverConfig.KeyExchanges) } func TestLoadHostKeys(t *testing.T) { diff --git a/internal/sftpd/server.go b/internal/sftpd/server.go index 5117319e..f3dedac7 100644 --- a/internal/sftpd/server.go +++ b/internal/sftpd/server.go @@ -45,75 +45,32 @@ import ( ) const ( - defaultPrivateRSAKeyName = "id_rsa" - defaultPrivateECDSAKeyName = "id_ecdsa" - defaultPrivateEd25519KeyName = "id_ed25519" - sourceAddressCriticalOption = "source-address" - kexDHGroupExchangeSHA1 = "diffie-hellman-group-exchange-sha1" - kexDHGroupExchangeSHA256 = "diffie-hellman-group-exchange-sha256" + defaultPrivateRSAKeyName = "id_rsa" + defaultPrivateECDSAKeyName = "id_ecdsa" + defaultPrivateEd25519KeyName = "id_ed25519" + sourceAddressCriticalOption = "source-address" + keyExchangeCurve25519SHA256LibSSH = "curve25519-sha256@libssh.org" ) var ( + supportedAlgos = ssh.SupportedAlgorithms() + insecureAlgos = ssh.InsecureAlgorithms() sftpExtensions = []string{"statvfs@openssh.com"} - supportedHostKeyAlgos = []string{ - ssh.CertAlgoRSASHA512v01, ssh.CertAlgoRSASHA256v01, - ssh.CertAlgoRSAv01, ssh.CertAlgoDSAv01, ssh.CertAlgoECDSA256v01, - ssh.CertAlgoECDSA384v01, ssh.CertAlgoECDSA521v01, ssh.CertAlgoED25519v01, - ssh.KeyAlgoECDSA256, ssh.KeyAlgoECDSA384, ssh.KeyAlgoECDSA521, - ssh.KeyAlgoRSASHA512, ssh.KeyAlgoRSASHA256, - ssh.KeyAlgoRSA, ssh.KeyAlgoDSA, - ssh.KeyAlgoED25519, - } + supportedHostKeyAlgos = append(supportedAlgos.HostKeys, insecureAlgos.HostKeys...) preferredHostKeyAlgos = []string{ ssh.KeyAlgoRSASHA256, ssh.KeyAlgoRSASHA512, ssh.KeyAlgoECDSA256, ssh.KeyAlgoECDSA384, ssh.KeyAlgoECDSA521, ssh.KeyAlgoED25519, } - supportedPublicKeyAlgos = []string{ - ssh.KeyAlgoED25519, - ssh.KeyAlgoSKED25519, ssh.KeyAlgoSKECDSA256, - ssh.KeyAlgoECDSA256, ssh.KeyAlgoECDSA384, ssh.KeyAlgoECDSA521, - ssh.KeyAlgoRSASHA256, ssh.KeyAlgoRSASHA512, ssh.KeyAlgoRSA, - ssh.KeyAlgoDSA, - } - preferredPublicKeyAlgos = []string{ - ssh.KeyAlgoED25519, - ssh.KeyAlgoSKED25519, ssh.KeyAlgoSKECDSA256, - ssh.KeyAlgoECDSA256, ssh.KeyAlgoECDSA384, ssh.KeyAlgoECDSA521, - ssh.KeyAlgoRSASHA256, ssh.KeyAlgoRSASHA512, - } - supportedKexAlgos = []string{ - "curve25519-sha256", "curve25519-sha256@libssh.org", - "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", - "diffie-hellman-group14-sha256", "diffie-hellman-group16-sha512", - "diffie-hellman-group18-sha512", "diffie-hellman-group14-sha1", - "diffie-hellman-group1-sha1", - } - preferredKexAlgos = []string{ - "curve25519-sha256", "curve25519-sha256@libssh.org", - "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", - "diffie-hellman-group14-sha256", - } - supportedCiphers = []string{ - "aes128-gcm@openssh.com", "aes256-gcm@openssh.com", - "chacha20-poly1305@openssh.com", - "aes128-ctr", "aes192-ctr", "aes256-ctr", - "aes128-cbc", "aes192-cbc", "aes256-cbc", - "3des-cbc", - "arcfour", "arcfour128", "arcfour256", - } - preferredCiphers = []string{ - "aes128-gcm@openssh.com", "aes256-gcm@openssh.com", - "chacha20-poly1305@openssh.com", - "aes128-ctr", "aes192-ctr", "aes256-ctr", - } - supportedMACs = []string{ - "hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", - "hmac-sha2-512-etm@openssh.com", "hmac-sha2-512", - "hmac-sha1", "hmac-sha1-96", - } - preferredMACs = []string{ - "hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", + supportedPublicKeyAlgos = append(supportedAlgos.PublicKeyAuths, insecureAlgos.PublicKeyAuths...) + preferredPublicKeyAlgos = supportedAlgos.PublicKeyAuths + supportedKexAlgos = append(supportedAlgos.KeyExchanges, insecureAlgos.KeyExchanges...) + preferredKexAlgos = supportedAlgos.KeyExchanges + supportedCiphers = append(supportedAlgos.Ciphers, insecureAlgos.Ciphers...) + preferredCiphers = supportedAlgos.Ciphers + supportedMACs = append(supportedAlgos.MACs, insecureAlgos.MACs...) + preferredMACs = []string{ + ssh.HMACSHA256ETM, ssh.HMACSHA256, } revokedCertManager = revokedCertificates{ @@ -170,12 +127,6 @@ type Configuration struct { // HostKeyAlgorithms lists the public key algorithms that the server will accept for host // key authentication. HostKeyAlgorithms []string `json:"host_key_algorithms" mapstructure:"host_key_algorithms"` - // Diffie-Hellman moduli files. - // Each moduli file can be defined as a path relative to the configuration directory or an absolute one. - // If set and valid, "diffie-hellman-group-exchange-sha256" and "diffie-hellman-group-exchange-sha1" KEX algorithms - // will be available, `diffie-hellman-group-exchange-sha256` will be enabled by default if you - // don't explicitly set KEXs - Moduli []string `json:"moduli" mapstructure:"moduli"` // KexAlgorithms specifies the available KEX (Key Exchange) algorithms in // preference order. KexAlgorithms []string `json:"kex_algorithms" mapstructure:"kex_algorithms"` @@ -373,8 +324,6 @@ func (c *Configuration) Initialize(configDir string) error { return common.ErrNoBinding } - c.loadModuli(configDir) - sftp.SetSFTPExtensions(sftpExtensions...) //nolint:errcheck // we configure valid SFTP Extensions so we cannot get an error sftp.MaxFilelist = vfs.ListerBatchSize @@ -491,21 +440,34 @@ func (c *Configuration) configureKeyAlgos(serverConfig *ssh.ServerConfig) error return nil } +func (c *Configuration) checkKeyExchangeAlgorithms() { + var kexs []string + for _, k := range c.KexAlgorithms { + if k == "diffie-hellman-group18-sha512" { + logger.Warn(logSender, "", "KEX %q is not supported and will be ignored", k) + continue + } + kexs = append(kexs, k) + if strings.TrimSpace(k) == keyExchangeCurve25519SHA256LibSSH { + kexs = append(kexs, ssh.KeyExchangeCurve25519SHA256) + } + if strings.TrimSpace(k) == ssh.KeyExchangeCurve25519SHA256 { + kexs = append(kexs, keyExchangeCurve25519SHA256LibSSH) + } + } + c.KexAlgorithms = util.RemoveDuplicates(kexs, true) +} + func (c *Configuration) configureSecurityOptions(serverConfig *ssh.ServerConfig) error { if err := c.configureKeyAlgos(serverConfig); err != nil { return err } if len(c.KexAlgorithms) > 0 { - hasDHGroupKEX := util.Contains(supportedKexAlgos, kexDHGroupExchangeSHA256) - if !hasDHGroupKEX { - c.KexAlgorithms = util.Remove(c.KexAlgorithms, kexDHGroupExchangeSHA1) - c.KexAlgorithms = util.Remove(c.KexAlgorithms, kexDHGroupExchangeSHA256) - } - c.KexAlgorithms = util.RemoveDuplicates(c.KexAlgorithms, true) + c.checkKeyExchangeAlgorithms() for _, kex := range c.KexAlgorithms { - if kex == "diffie-hellman-group18-sha512" { - logger.Warn(logSender, "", "KEX %q is not supported and will be ignored", kex) + if kex == keyExchangeCurve25519SHA256LibSSH { + continue } if !util.Contains(supportedKexAlgos, kex) { return fmt.Errorf("unsupported key-exchange algorithm %q", kex) @@ -513,6 +475,7 @@ func (c *Configuration) configureSecurityOptions(serverConfig *ssh.ServerConfig) } } else { c.KexAlgorithms = preferredKexAlgos + c.checkKeyExchangeAlgorithms() } serverConfig.KeyExchanges = c.KexAlgorithms serviceStatus.KexAlgorithms = c.KexAlgorithms @@ -643,8 +606,8 @@ func (c *Configuration) AcceptInboundConnection(conn net.Conn, config *ssh.Serve } logger.Log(logger.LevelInfo, common.ProtocolSSH, connectionID, - "User %q logged in with %q, from ip %q, client version %q", user.Username, loginType, - ipAddr, string(sconn.ClientVersion())) + "User %q logged in with %q, from ip %q, client version %q, negotiated algorithms: %+v", + user.Username, loginType, ipAddr, string(sconn.ClientVersion()), sconn.Conn.(ssh.AlgorithmsConnMetadata).Algorithms()) dataprovider.UpdateLastLogin(&user) sshConnection := common.NewSSHConnection(connectionID, conn) @@ -812,7 +775,8 @@ func checkAuthError(ip string, err error) { common.AddDefenderEvent(ip, common.ProtocolSSH, common.HostEventNoLoginTried) dataprovider.ExecutePostLoginHook(&dataprovider.User{}, dataprovider.LoginMethodNoAuthTried, ip, common.ProtocolSSH, err) logEv := notifier.LogEventTypeNoLoginTried - if errors.Is(err, ssh.ErrNoCommonAlgo) { + var negotiationError *ssh.AlgorithmNegotiationError + if errors.As(err, &negotiationError) { logEv = notifier.LogEventTypeNotNegotiated } plugin.Handler.NotifyLogEvent(logEv, common.ProtocolSSH, "", ip, "", err) @@ -851,7 +815,7 @@ func loginUser(user *dataprovider.User, loginMethod, publicKey string, conn ssh. user.Username) return nil, fmt.Errorf("second factor authentication is not set for user %q", user.Username) } - remoteAddr := conn.RemoteAddr().String() + remoteAddr := util.GetIPFromRemoteAddress(conn.RemoteAddr().String()) if !user.IsLoginFromAddrAllowed(remoteAddr) { logger.Info(logSender, connectionID, "cannot login user %q, remote address is not allowed: %v", user.Username, remoteAddr) @@ -981,38 +945,6 @@ func (c *Configuration) checkHostKeyAutoGeneration(configDir string) error { return nil } -func (c *Configuration) loadModuli(configDir string) { - supportedKexAlgos = util.Remove(supportedKexAlgos, kexDHGroupExchangeSHA1) - supportedKexAlgos = util.Remove(supportedKexAlgos, kexDHGroupExchangeSHA256) - preferredKexAlgos = util.Remove(preferredKexAlgos, kexDHGroupExchangeSHA256) - c.Moduli = util.RemoveDuplicates(c.Moduli, false) - for _, m := range c.Moduli { - m = strings.TrimSpace(m) - if !util.IsFileInputValid(m) { - logger.Warn(logSender, "", "unable to load invalid moduli file %q", m) - logger.WarnToConsole("unable to load invalid host moduli file %q", m) - continue - } - if !filepath.IsAbs(m) { - m = filepath.Join(configDir, m) - } - logger.Info(logSender, "", "loading moduli file %q", m) - if err := ssh.ParseModuli(m); err != nil { - logger.Warn(logSender, "", "ignoring moduli file %q, error: %v", m, err) - continue - } - if !util.Contains(supportedKexAlgos, kexDHGroupExchangeSHA1) { - supportedKexAlgos = append(supportedKexAlgos, kexDHGroupExchangeSHA1) - } - if !util.Contains(supportedKexAlgos, kexDHGroupExchangeSHA256) { - supportedKexAlgos = append(supportedKexAlgos, kexDHGroupExchangeSHA256) - } - if !util.Contains(preferredKexAlgos, kexDHGroupExchangeSHA256) { - preferredKexAlgos = append(preferredKexAlgos, kexDHGroupExchangeSHA256) - } - } -} - func (c *Configuration) getHostKeyAlgorithms(keyFormat string) []string { var algos []string for _, algo := range algorithmsForKeyFormat(keyFormat) { @@ -1188,12 +1120,12 @@ func (c *Configuration) initializeCertChecker(configDir string) error { func (c *Configuration) getPartialSuccessError(nextAuthMethods []string) error { err := &ssh.PartialSuccessError{} if c.PasswordAuthentication && util.Contains(nextAuthMethods, dataprovider.LoginMethodPassword) { - err.PasswordCallback = func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { + err.Next.PasswordCallback = func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { return c.validatePasswordCredentials(conn, password, dataprovider.SSHLoginMethodKeyAndPassword) } } if c.KeyboardInteractiveAuthentication && util.Contains(nextAuthMethods, dataprovider.SSHLoginMethodKeyboardInteractive) { - err.KeyboardInteractiveCallback = func(conn ssh.ConnMetadata, client ssh.KeyboardInteractiveChallenge) (*ssh.Permissions, error) { + err.Next.KeyboardInteractiveCallback = func(conn ssh.ConnMetadata, client ssh.KeyboardInteractiveChallenge) (*ssh.Permissions, error) { return c.validateKeyboardInteractiveCredentials(conn, client, dataprovider.SSHLoginMethodKeyAndKeyboardInt, true) } } diff --git a/internal/sftpd/sftpd.go b/internal/sftpd/sftpd.go index 38e69177..92f30460 100644 --- a/internal/sftpd/sftpd.go +++ b/internal/sftpd/sftpd.go @@ -37,16 +37,16 @@ var ( systemCommands = []string{"git-receive-pack", "git-upload-pack", "git-upload-archive", "rsync"} serviceStatus ServiceStatus certKeyAlgoNames = map[string]string{ - ssh.CertAlgoRSAv01: ssh.KeyAlgoRSA, - ssh.CertAlgoRSASHA256v01: ssh.KeyAlgoRSASHA256, - ssh.CertAlgoRSASHA512v01: ssh.KeyAlgoRSASHA512, - ssh.CertAlgoDSAv01: ssh.KeyAlgoDSA, - ssh.CertAlgoECDSA256v01: ssh.KeyAlgoECDSA256, - ssh.CertAlgoECDSA384v01: ssh.KeyAlgoECDSA384, - ssh.CertAlgoECDSA521v01: ssh.KeyAlgoECDSA521, - ssh.CertAlgoSKECDSA256v01: ssh.KeyAlgoSKECDSA256, - ssh.CertAlgoED25519v01: ssh.KeyAlgoED25519, - ssh.CertAlgoSKED25519v01: ssh.KeyAlgoSKED25519, + ssh.CertAlgoRSAv01: ssh.KeyAlgoRSA, + ssh.CertAlgoRSASHA256v01: ssh.KeyAlgoRSASHA256, + ssh.CertAlgoRSASHA512v01: ssh.KeyAlgoRSASHA512, + ssh.InsecureCertAlgoDSAv01: ssh.InsecureKeyAlgoDSA, + ssh.CertAlgoECDSA256v01: ssh.KeyAlgoECDSA256, + ssh.CertAlgoECDSA384v01: ssh.KeyAlgoECDSA384, + ssh.CertAlgoECDSA521v01: ssh.KeyAlgoECDSA521, + ssh.CertAlgoSKECDSA256v01: ssh.KeyAlgoSKECDSA256, + ssh.CertAlgoED25519v01: ssh.KeyAlgoED25519, + ssh.CertAlgoSKED25519v01: ssh.KeyAlgoSKED25519, } ) diff --git a/internal/sftpd/sftpd_test.go b/internal/sftpd/sftpd_test.go index 9e42fd4f..9b6ce13e 100644 --- a/internal/sftpd/sftpd_test.go +++ b/internal/sftpd/sftpd_test.go @@ -255,11 +255,10 @@ func TestMain(m *testing.M) { ApplyProxyConfig: true, }, } - sftpdConf.KexAlgorithms = []string{"curve25519-sha256@libssh.org", "ecdh-sha2-nistp256", - "ecdh-sha2-nistp384"} - sftpdConf.Ciphers = []string{"chacha20-poly1305@openssh.com", "aes128-gcm@openssh.com", - "aes256-ctr"} - sftpdConf.MACs = []string{"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256"} + sftpdConf.KexAlgorithms = []string{"curve25519-sha256@libssh.org", ssh.KeyExchangeECDHP256, + ssh.KeyExchangeECDHP384} + sftpdConf.Ciphers = []string{ssh.CipherChacha20Poly1305, ssh.CipherAES128GCM, + ssh.CipherAES256CTR} sftpdConf.LoginBannerFile = loginBannerFileName // we need to test all supported ssh commands sftpdConf.EnabledSSHCommands = []string{"*"} @@ -8245,6 +8244,32 @@ func TestOpenUnhandledChannel(t *testing.T) { assert.NoError(t, err) } +func TestAlgorithmNotNegotiated(t *testing.T) { + u := getTestUser(false) + user, _, err := httpdtest.AddUser(u, http.StatusCreated) + assert.NoError(t, err) + + config := &ssh.ClientConfig{ + Config: ssh.Config{ + Ciphers: []string{ssh.InsecureCipherRC4}, + }, + User: user.Username, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + Auth: []ssh.AuthMethod{ssh.Password(defaultPassword)}, + Timeout: 5 * time.Second, + } + _, err = ssh.Dial("tcp", sftpServerAddr, config) + if assert.Error(t, err) { + negotiationErr := &ssh.AlgorithmNegotiationError{} + assert.ErrorAs(t, err, &negotiationErr) + } + + _, err = httpdtest.RemoveUser(user, http.StatusOK) + assert.NoError(t, err) + err = os.RemoveAll(user.GetHomeDir()) + assert.NoError(t, err) +} + func TestPermsSubDirsCommands(t *testing.T) { usePubKey := true u := getTestUser(usePubKey) diff --git a/internal/vfs/sftpfs.go b/internal/vfs/sftpfs.go index fa606ee5..55d9e677 100644 --- a/internal/vfs/sftpfs.go +++ b/internal/vfs/sftpfs.go @@ -956,17 +956,13 @@ func (c *sftpConnection) openConnNoLock() error { if c.config.Password.GetPayload() != "" { clientConfig.Auth = append(clientConfig.Auth, ssh.Password(c.config.Password.GetPayload())) } - // add more ciphers, KEXs and MACs, they are negotiated according to the order - clientConfig.Ciphers = []string{"aes128-gcm@openssh.com", "aes256-gcm@openssh.com", "chacha20-poly1305@openssh.com", - "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-cbc", "aes192-cbc", "aes256-cbc"} - clientConfig.KeyExchanges = []string{"curve25519-sha256", "curve25519-sha256@libssh.org", - "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", - "diffie-hellman-group14-sha256", "diffie-hellman-group-exchange-sha256", - "diffie-hellman-group16-sha512", "diffie-hellman-group-exchange-sha1", - "diffie-hellman-group14-sha1", "diffie-hellman-group1-sha1"} - clientConfig.MACs = []string{"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", - "hmac-sha2-512-etm@openssh.com", "hmac-sha2-512", - "hmac-sha1", "hmac-sha1-96"} + supportedAlgos := ssh.SupportedAlgorithms() + insecureAlgos := ssh.InsecureAlgorithms() + // add all available ciphers, KEXs and MACs, they are negotiated according to the order + clientConfig.Ciphers = append(supportedAlgos.Ciphers, ssh.InsecureCipherAES128CBC, + ssh.InsecureCipherAES192CBC, ssh.InsecureCipherAES256CBC) + clientConfig.KeyExchanges = append(supportedAlgos.KeyExchanges, insecureAlgos.KeyExchanges...) + clientConfig.MACs = append(supportedAlgos.MACs, insecureAlgos.MACs...) sshClient, err := ssh.Dial("tcp", c.config.Endpoint, clientConfig) if err != nil { return fmt.Errorf("sftpfs: unable to connect: %w", err)