Browse Source

ssh: remove moduli, log negotiated algorithms

Fixes #1324

Signed-off-by: Nicola Murino <[email protected]>
Nicola Murino 1 year ago
parent
commit
f7d9e56cac

+ 1 - 2
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

+ 0 - 3
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

+ 1 - 2
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

+ 1 - 2
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: `[email protected]`, `[email protected]`, `[email protected]`, `[email protected]`, `[email protected]`, `[email protected]`, `[email protected]`, `[email protected]`, `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`, `[email protected]`, `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`, `[email protected]`, `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 `[email protected]`), `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: `[email protected]`, `[email protected]`, `[email protected]`, `aes128-ctr`, `aes192-ctr`, `aes256-ctr`, `aes128-cbc`, `aes192-cbc`, `aes256-cbc`, `3des-cbc`, `arcfour256`, `arcfour128`, `arcfour`. Default values: `[email protected]`, `[email protected]`, `[email protected]`, `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: `[email protected]`, `hmac-sha2-256`, `[email protected]`, `hmac-sha2-512`, `hmac-sha1`, `hmac-sha1-96`. Default values: `[email protected]`, `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`, `[email protected]`, `[email protected]`. Default values: `ecdsa-sha2-nistp256`, `ecdsa-sha2-nistp384`, `ecdsa-sha2-nistp521`, `rsa-sha2-512`, `rsa-sha2-256`, `ssh-ed25519`, `[email protected]`, `[email protected]`.

+ 22 - 22
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
 )

+ 44 - 50
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=

+ 0 - 2
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)

+ 8 - 8
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{
-		"[email protected]", "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) {

+ 11 - 11
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 <[email protected]>", 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)

+ 17 - 43
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{"[email protected]"},
-			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{
-		" [email protected] ", "hmac-sha2-256",
-		" [email protected]", "hmac-sha2-512 ",
-		"hmac-sha1 ", " hmac-sha1-96",
+		" [email protected] ", " [email protected]",
+		"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) {

+ 46 - 114
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 = "[email protected]"
 )
 
 var (
+	supportedAlgos        = ssh.SupportedAlgorithms()
+	insecureAlgos         = ssh.InsecureAlgorithms()
 	sftpExtensions        = []string{"[email protected]"}
-	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", "[email protected]",
-		"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", "[email protected]",
-		"ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521",
-		"diffie-hellman-group14-sha256",
-	}
-	supportedCiphers = []string{
-		"[email protected]", "[email protected]",
-		"[email protected]",
-		"aes128-ctr", "aes192-ctr", "aes256-ctr",
-		"aes128-cbc", "aes192-cbc", "aes256-cbc",
-		"3des-cbc",
-		"arcfour", "arcfour128", "arcfour256",
-	}
-	preferredCiphers = []string{
-		"[email protected]", "[email protected]",
-		"[email protected]",
-		"aes128-ctr", "aes192-ctr", "aes256-ctr",
-	}
-	supportedMACs = []string{
-		"[email protected]", "hmac-sha2-256",
-		"[email protected]", "hmac-sha2-512",
-		"hmac-sha1", "hmac-sha1-96",
-	}
-	preferredMACs = []string{
-		"[email protected]", "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)
 		}
 	}

+ 10 - 10
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,
 	}
 )
 

+ 30 - 5
internal/sftpd/sftpd_test.go

@@ -255,11 +255,10 @@ func TestMain(m *testing.M) {
 			ApplyProxyConfig: true,
 		},
 	}
-	sftpdConf.KexAlgorithms = []string{"[email protected]", "ecdh-sha2-nistp256",
-		"ecdh-sha2-nistp384"}
-	sftpdConf.Ciphers = []string{"[email protected]", "[email protected]",
-		"aes256-ctr"}
-	sftpdConf.MACs = []string{"[email protected]", "hmac-sha2-256"}
+	sftpdConf.KexAlgorithms = []string{"[email protected]", 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)

+ 7 - 11
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{"[email protected]", "[email protected]", "[email protected]",
-		"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-cbc", "aes192-cbc", "aes256-cbc"}
-	clientConfig.KeyExchanges = []string{"curve25519-sha256", "[email protected]",
-		"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{"[email protected]", "hmac-sha2-256",
-		"[email protected]", "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)