From b22b136d80a48ac06141491fda66360e2fbe5893 Mon Sep 17 00:00:00 2001 From: David Kocher Date: Tue, 29 Sep 2026 17:59:37 +0200 Subject: [PATCH 01/12] Add tutorials for SFTP authentication with FIDO2 security key, PKCS#11 smartcard and Kerberos. --- tutorials/sftp_kerberos.md | 121 +++++++++++++++++ tutorials/sftp_publickeyauth_pkcs11.md | 86 +++++++++++++ tutorials/sftp_publickeyauth_securitykey.md | 136 ++++++++++++++++++++ 3 files changed, 343 insertions(+) create mode 100644 tutorials/sftp_kerberos.md create mode 100644 tutorials/sftp_publickeyauth_pkcs11.md create mode 100644 tutorials/sftp_publickeyauth_securitykey.md diff --git a/tutorials/sftp_kerberos.md b/tutorials/sftp_kerberos.md new file mode 100644 index 00000000..661cd1d2 --- /dev/null +++ b/tutorials/sftp_kerberos.md @@ -0,0 +1,121 @@ +Configure Kerberos Authentication for SFTP +==== + +> Authentication with _Kerberos_ allows you to connect to a remote server without a password using the ticket you already obtained when logging in to your organization's realm with `kinit` or with your account on the Mac. The ticket is presented to the server using the SSH authentication method `gssapi-with-mic`, the equivalent of `ssh -o GSSAPIAuthentication=yes`. + +:::{important} +* Cyberduck [9.6.0](https://cyberduck.io/changelog/) or later required +* Mountain Duck [6.0.0](https://mountainduck.io/changelog/) or later required +::: + +Authentication with Kerberos is attempted after public key authentication and before prompting for a password when no password is saved for the bookmark. Without a valid ticket the method is skipped and the login continues with the next authentication method offered by the server. + +## Requirements + +- The server running OpenSSH is configured with `GSSAPIAuthentication yes` in `sshd_config` and has a keytab with the service principal `host/server.example.com@EXAMPLE.COM` for its fully qualified hostname. Refer to your administrator. +- Your principal such as `user@EXAMPLE.COM` is allowed to log in to the account on the server. By default the principal `user@EXAMPLE.COM` maps to the account `user`. Additional principals are listed in `~/.k5login` of the account on the server. +- The Kerberos configuration with the default realm and the Key Distribution Center (KDC) of your organization is found in `/etc/krb5.conf` or can be looked up in DNS. + +## Setup + +:::::{tabs} +::::{group-tab} macOS + +1. Obtain a ticket for your principal. Enter the password of your Kerberos account when prompted. + ``` + kinit user@EXAMPLE.COM + ``` + + :::{tip} + Tickets obtained with _Ticket Viewer.app_ in `/System/Library/CoreServices/Applications` or when logging in to a Mac bound to a directory service with Kerberos are used as well. + ::: + +2. Verify a ticket for the realm is listed and has not expired. + ``` + klist + ``` + +3. Verify the setup with OpenSSH before connecting with Cyberduck. Use the fully qualified hostname of the server. + ``` + ssh -o GSSAPIAuthentication=yes -o PreferredAuthentications=gssapi-with-mic user@server.example.com + ``` + + A service ticket for `host/server.example.com@EXAMPLE.COM` is now listed with `klist`. + +4. Add a new [Bookmark](../cyberduck/bookmarks.md) in Cyberduck or Mountain Duck. Enter the fully qualified hostname `server.example.com` in _Server_ and your account in _Username_. You do **not** need to set a value for _Password_ or select a _SSH Private Key_. + + :::{warning} + The hostname must match the service principal in the keytab of the server. Connecting using an IP address or a short hostname may fail when it cannot be resolved to the fully qualified name. + ::: + +5. Connect to the server. No prompt is displayed when the ticket is accepted. + +:::: +::::: + +## Kerberos Configuration + +The Kerberos configuration is read from `/etc/krb5.conf` or on macOS from `~/Library/Preferences/edu.mit.Kerberos` and `/Library/Preferences/edu.mit.Kerberos` first when found. A minimal configuration for the realm `EXAMPLE.COM` looks like +``` +[libdefaults] + default_realm = EXAMPLE.COM + +[realms] + EXAMPLE.COM = { + kdc = kdc.example.com + } + +[domain_realm] + .example.com = EXAMPLE.COM +``` + +Omit the `[realms]` section and add `dns_lookup_kdc = true` to `[libdefaults]` to look up the KDC from `_kerberos._tcp` and `_kerberos._udp` DNS SRV records of the realm instead. + +The following [hidden configuration options](hidden_properties.md) apply to all connections. + +| Option | Description | +|-----------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `java.security.krb5.conf` | Path to a Kerberos configuration file to use instead of the default location such as `/etc/krb5.conf`. | +| `java.security.krb5.realm` | Default realm such as `EXAMPLE.COM` overriding the configuration file. Must be set together with `java.security.krb5.kdc`. | +| `java.security.krb5.kdc` | Hostname of the KDC for the default realm overriding the configuration file. Must be set together with `java.security.krb5.realm`. Separate multiple KDCs with `:`. | +| `ssh.authentication.gssapi.ticketcache` | Path to a credentials cache file to read the ticket from instead of the default cache. Obtain a ticket written to the file with `kinit -c /path/to/file user@EXAMPLE.COM`. | + +Example to set the realm and KDC for Cyberduck on macOS. +``` +defaults write ch.sudo.cyberduck java.security.krb5.realm EXAMPLE.COM +defaults write ch.sudo.cyberduck java.security.krb5.kdc kdc.example.com +``` + +:::{note} +A KDC set with `java.security.krb5.kdc` is always contacted on the default port `88`. Use a configuration file with `kdc = kdc.example.com:port` for a KDC listening on a different port. +::: + +## Require Public Key and Kerberos Authentication + +Servers can require authentication with both a private key and a Kerberos ticket with `AuthenticationMethods publickey,gssapi-with-mic` in `sshd_config`. Select the private key in _SSH Private Key_ of the bookmark. After the key has been accepted, login completes with the Kerberos ticket. + +## Troubleshooting + +:::{warning} +When you are prompted for a password instead, no ticket was found or the server did not accept it. Verify with `klist` that the ticket for the realm has not expired and obtain a new ticket with `kinit` otherwise. Verify the login with `ssh -v -o GSSAPIAuthentication=yes user@server.example.com` which prints the reason why the method failed. +::: + +:::{warning} +The message _Server not found in Kerberos database_ printed by `ssh -v` indicates no service principal matches the hostname used to connect. Connect using the fully qualified hostname matching the keytab of the server. +::: + +:::{warning} +Authentication fails when the clock of your computer differs by more than five minutes from the KDC or the server. Enable _Set time and date automatically_ in _System Settings → General → Date & Time_. +::: + +:::{note} +The `GSSAPIAuthentication` directive in `~/.ssh/config` is not required. The authentication method is always attempted when offered by the server. Limit the methods tried with [`PreferredAuthentications`](../protocols/sftp/index.md#configuration-file) instead. +::: + +## References + +- [`GSSAPIAuthentication` in ssh_config](https://man.openbsd.org/ssh_config#GSSAPIAuthentication) +- [`GSSAPIAuthentication` in sshd_config](https://man.openbsd.org/sshd_config#GSSAPIAuthentication) +- [RFC 4462: GSS-API Authentication and Key Exchange for SSH](https://www.rfc-editor.org/rfc/rfc4462) +- [MIT Kerberos: krb5.conf](https://web.mit.edu/kerberos/krb5-latest/doc/admin/conf_files/krb5_conf.html) +- [Java Kerberos Requirements](https://docs.oracle.com/en/java/javase/21/security/kerberos-requirements1.html) for the lookup of the configuration file and the system properties `java.security.krb5.realm` and `java.security.krb5.kdc`. diff --git a/tutorials/sftp_publickeyauth_pkcs11.md b/tutorials/sftp_publickeyauth_pkcs11.md new file mode 100644 index 00000000..e43612e6 --- /dev/null +++ b/tutorials/sftp_publickeyauth_pkcs11.md @@ -0,0 +1,86 @@ +Configure Public Key Authentication for SFTP using a PKCS#11 Smartcard +==== + +> Public-key authentication with a smartcard allows you to connect to a remote server without a password. The private key is kept on the card and never leaves it. A _PKCS#11_ module, the native library shipped with the driver of your card, is used to read the public keys from the card and to sign the login with the corresponding private key protected by a PIN. This is the equivalent of `ssh -I /path/to/module.so`. + +:::{important} +* Cyberduck [9.6.0](https://cyberduck.io/changelog/) or later required +* Mountain Duck [6.0.0](https://mountainduck.io/changelog/) or later required +::: + +:::{note} +Only keys with a matching certificate on the card are found. Cards holding a key without a certificate, such as a key generated with `pkcs11-tool --keypairgen` only, cannot be used. +::: + +## Setup + +:::::{tabs} +::::{group-tab} macOS + +1. Install the _PKCS#11_ module for your card. [OpenSC](https://github.com/OpenSC/OpenSC) supports many cards including _PIV_, _CAC_ and _OpenPGP_ cards. + ``` + brew install opensc + ``` + + :::{tip} + Cyberduck and Mountain Duck already bundle _OpenSC_. Refer to the bundled library by its file name `opensc-pkcs11.so` instead of an absolute path when configuring the module. For a smartcard paired with macOS using `sc_auth pair`, the system module `/usr/lib/ssh-keychain.dylib` can be used instead. + ::: + +2. Verify the module can read the certificates from the card. Insert the card first. + ``` + pkcs11-tool --module /opt/homebrew/lib/opensc-pkcs11.so --list-objects --type cert + ``` + +3. Print the public keys on the card and save them to a file. + ``` + ssh-keygen -D /opt/homebrew/lib/opensc-pkcs11.so > ~/.ssh/smartcard.pub + ``` + +4. Add the public key to the `authorized_keys` in your `~/.ssh` directory on the server running OpenSSH. + ``` + ssh-copy-id -fi ~/.ssh/smartcard.pub user@remotehost + ``` + +5. Verify the setup with OpenSSH before connecting with Cyberduck. You are prompted for the PIN of the card. + ``` + ssh -I /opt/homebrew/lib/opensc-pkcs11.so user@remotehost + ``` + +6. Refer to the module in your OpenSSH configuration file `~/.ssh/config`. + ``` + Host * + PKCS11Provider /opt/homebrew/lib/opensc-pkcs11.so + ``` + + This [configuration](https://docs.cyberduck.io/protocols/sftp/#openssh-configuration-interoperability) directive is supported by Cyberduck and Mountain Duck. You can restrict the setting to a single alias in the configuration file instead of matching it for all connections with `*`. Alternatively set the [hidden configuration option](hidden_properties.md) `ssh.authentication.pkcs11.library` to the path of the module or to `opensc-pkcs11.so` for the bundled version. + +7. Add a new [Bookmark](../cyberduck/bookmarks.md) in Cyberduck or Mountain Duck. Enter the alias from your OpenSSH configuration or the hostname in _Server_. You do **not** need to set a value for _Password_ or select a _SSH Private Key_ because the keys are read from the card. + + :::{tip} + The server may respond with _[Too many authentication failures](../protocols/sftp/index.md#too-many-authentication-failures)_ when the card holds several keys. Select the public key saved in step 3 for _SSH Private Key_ to only offer the matching identity. + ::: + +8. Connect to the server and enter the PIN of the card when prompted. + +:::: +::::: + +## Troubleshooting + +:::{warning} +When no key from the card is offered, verify the card holds a certificate for the key with `pkcs11-tool --module --list-objects --type cert`. A key without a certificate on the card is not found. +::: + +:::{warning} +When the connection continues with a prompt for a password, the module could not be loaded. Verify the path set with `PKCS11Provider` and that the same path works with `ssh -I`. +::: + +:::{note} +Removing the card while connected fails the session. Reconnect with the card inserted. +::: + +## References + +- [OpenSC supported hardware](https://github.com/OpenSC/OpenSC/wiki/Supported-hardware-%28smart-cards-and-USB-tokens%29) +- [`PKCS11Provider` in ssh_config](https://man.openbsd.org/ssh_config#PKCS11Provider) +- [Use a FIDO2 Security Key](sftp_publickeyauth_securitykey.md) for authentication with a key in the Secure Enclave or on a hardware token such as a YubiKey. diff --git a/tutorials/sftp_publickeyauth_securitykey.md b/tutorials/sftp_publickeyauth_securitykey.md new file mode 100644 index 00000000..c9b6bccf --- /dev/null +++ b/tutorials/sftp_publickeyauth_securitykey.md @@ -0,0 +1,136 @@ +Configure Public Key Authentication for SFTP using a FIDO2 Security Key +==== + +> Public-key authentication with a _FIDO2_ security key allows you to connect to a remote server without a password. The private key never leaves the authenticator, which is either the Secure Enclave of your Mac unlocked with _Touch ID_ or a hardware token such as a _YubiKey_ you touch to confirm. OpenSSH calls these keys `sk-ecdsa-sha2-nistp256@openssh.com` and `sk-ssh-ed25519@openssh.com`. + +:::{important} +* Cyberduck [9.6.0](https://cyberduck.io/changelog/) or later required +* Mountain Duck [6.0.0](https://mountainduck.io/changelog/) or later required +::: + +The key file in `~/.ssh` holds a reference to the credential on the authenticator but no private key. Signing a login is therefore delegated either to a _security key provider_ library talking to the authenticator or to an [SSH agent](#let-an-ssh-agent-handle-the-security-key) holding the key. + +:::{important} +The server must run _OpenSSH 8.2_ or later. Earlier versions do not know the `sk-*` key types and ignore the entry in `authorized_keys`. Verify the version of the server with `ssh -v user@remotehost` and look for the line `remote software version`. +::: + +## Create a Key in the Secure Enclave unlocked with Touch ID + +:::::{tabs} +::::{group-tab} macOS + +1. Create an identity in the Secure Enclave protected with _Touch ID_. The private key is generated on the device and cannot be extracted. + ``` + sc_auth create-ctk-identity -l "MacBook Touch ID SSH" -k p-256-ne -t bio + ``` + + :::{tip} + `-k p-256-ne` creates a non-extractable key on the NIST P-256 curve, the only curve supported by the Secure Enclave. `-t bio` requires _Touch ID_ to use the key. + ::: + +2. Write the key file for the credential. Run the command in `~/.ssh` as the files are written to the current working directory. + ``` + cd ~/.ssh && ssh-keygen -w /usr/lib/ssh-keychain.dylib -K + ``` + + This writes `id_ecdsa_sk_rk` and `id_ecdsa_sk_rk.pub`. Repeat the command with `-K` whenever you need the files again on another Mac with access to the same identity. + +3. Add the public key to the `authorized_keys` in your `~/.ssh` directory on the server running OpenSSH. + ``` + ssh-copy-id -fi ~/.ssh/id_ecdsa_sk_rk.pub user@remotehost + ``` + +4. Verify the setup with OpenSSH before connecting with Cyberduck. Confirm the prompt with _Touch ID_. + ``` + ssh -o SecurityKeyProvider=/usr/lib/ssh-keychain.dylib -i ~/.ssh/id_ecdsa_sk_rk user@remotehost + ``` + +5. In the [Bookmark](../cyberduck/bookmarks.md) or [Connection](../cyberduck/connection.md) window, in _SSH Private Key_ select `id_ecdsa_sk_rk` in your `~/.ssh` directory. You do **not** need to set a value for _Password_. + +6. Connect to the server and confirm the prompt with _Touch ID_ to allow the Secure Enclave to sign the login. + +:::: +::::: + +## Create a Key on a Hardware Token such as YubiKey + +:::::{tabs} +::::{group-tab} macOS + +1. Insert the security key and create a credential on the token. Touch the token when it blinks. + ``` + cd ~/.ssh && ssh-keygen -t ed25519-sk -O resident + ``` + + :::{tip} + Use `-t ecdsa-sk` instead for tokens without support for Ed25519 credentials, such as a _YubiKey_ with a firmware version earlier than 5.2.3. Add `-O verify-required` to require the PIN of the token in addition to touching it. The option `-O resident` stores the credential on the token allowing to write the key files again on another machine with `ssh-keygen -K`. + ::: + + :::{note} + If `ssh-keygen` reports it cannot find a library to use the security key, install [libfido2](https://github.com/Yubico/libfido2) with `brew install libfido2` and repeat the command with the option `-w /opt/homebrew/lib/libsk-libfido2.dylib`. + ::: + +2. Add the public key to the `authorized_keys` in your `~/.ssh` directory on the server running OpenSSH. + ``` + ssh-copy-id -fi ~/.ssh/id_ed25519_sk.pub user@remotehost + ``` + +3. Refer to the middleware library of the token in your OpenSSH configuration file `~/.ssh/config` when it is not the default `/usr/lib/ssh-keychain.dylib` used for keys in the Secure Enclave. + ``` + Host * + SecurityKeyProvider /opt/homebrew/lib/libsk-libfido2.dylib + ``` + + This [configuration](https://docs.cyberduck.io/protocols/sftp/#openssh-configuration-interoperability) directive is supported by Cyberduck and Mountain Duck. Alternatively set the [hidden configuration option](hidden_properties.md) `ssh.authentication.securitykey.provider` to the path of the library. + +4. In the [Bookmark](../cyberduck/bookmarks.md) or [Connection](../cyberduck/connection.md) window, in _SSH Private Key_ select `id_ed25519_sk` in your `~/.ssh` directory. + +5. Connect to the server and touch the security key when it blinks. Enter the PIN of the token when prompted for a key created with `-O verify-required`. + +:::: +::::: + +## Let an SSH Agent handle the Security Key + +Instead of talking to the authenticator, Cyberduck and Mountain Duck can leave the security key to an SSH agent. The agent prompts for the touch or the PIN and returns the signature. + +:::::{tabs} +::::{group-tab} macOS + +1. Add the security key to the SSH agent of OpenSSH. You are asked to confirm with _Touch ID_ or to touch the token. + ``` + ssh-add ~/.ssh/id_ecdsa_sk_rk + ``` + +2. Verify the agent holds the key. The key type is printed as `ECDSA-SK` or `ED25519-SK`. + ``` + ssh-add -l + ``` + +3. Add a new [Bookmark](../cyberduck/bookmarks.md). No _SSH Private Key_ needs to be selected because the key is offered by the agent. + + :::{tip} + The server may respond with _[Too many authentication failures](../protocols/sftp/index.md#too-many-authentication-failures)_ when the agent holds many keys. Select the public key `id_ecdsa_sk_rk.pub` for _SSH Private Key_ to only offer the matching identity from the agent. + ::: + +:::: +::::: + +Other SSH agents manage keys of their own instead of a credential on a security key, with the approval prompt of the application taking the place of the touch. Refer to the tutorials for the [1Password SSH Agent](sftp_publickeyauth_1password.md), the [Bitwarden SSH Agent](sftp_publickeyauth_bitwarden.md) and [yubikey-agent](sftp_publickeyauth_yubikey.md) for the setup of the agent socket with `IdentityAgent` in `~/.ssh/config`. + +## Troubleshooting + +:::{warning} +When the connection fails with the message _Add the security key … to the SSH authentication agent_, the middleware library of the authenticator could not be loaded. Verify the path set with `SecurityKeyProvider` or add the key to an SSH agent instead. +::: + +:::{warning} +When the server refuses the key without prompting for a touch, the public key is not accepted. Verify the entry in `authorized_keys` and that the server runs _OpenSSH 8.2_ or later. +::: + +## References + +- [Cyberduck 9.6.0](https://cyberduck.io/changelog/) or later is required for authentication with a security key without an SSH agent. +- [OpenSSH 8.2 release notes announcing FIDO/U2F support](https://www.openssh.com/txt/release-8.2) +- [PROTOCOL.u2f describing the `sk-*` key types](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.u2f) +- [Yubico Developers: Securing SSH with FIDO2](https://developers.yubico.com/SSH/Securing_SSH_with_FIDO2.html) From f8ea6dbbcaa563368b3bb99108619ea1f8f94a65 Mon Sep 17 00:00:00 2001 From: David Kocher Date: Tue, 29 Sep 2026 18:00:13 +0200 Subject: [PATCH 02/12] Link tutorials for SFTP authentication with FIDO2 security key, PKCS#11 smartcard and Kerberos. --- protocols/sftp/index.md | 56 ++++++++++++++++++++++++++++++++++++++++- tutorials/index.md | 12 +++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/protocols/sftp/index.md b/protocols/sftp/index.md index a70650e1..90630b8b 100644 --- a/protocols/sftp/index.md +++ b/protocols/sftp/index.md @@ -45,6 +45,8 @@ The following configuration options from `~/.ssh/config` are supported for SFTP - *ProxyJump* to connect via SSH tunnel through bastion server. - *PreferredAuthentications* to limit authentication methods tried to login. - *IdentitiesOnly*. Only try explicitly set private keys to authenticate but not all identities found in SSH agent. Resolves _Too many authentication failures_ errors with servers limiting the number of attempted authentication requests. +- *SecurityKeyProvider* for the middleware library signing with a [FIDO2 security key](../../tutorials/sftp_publickeyauth_securitykey.md) for `sk-ecdsa-sha2-nistp256@openssh.com` and `sk-ssh-ed25519@openssh.com` keys. +- *PKCS11Provider* for the module reading keys from a [smartcard](../../tutorials/sftp_publickeyauth_pkcs11.md). - A [bookmark](../../cyberduck/bookmarks.md) will update its public key authentication setting from the *IdentityFile* configuration in `~/.ssh/config`. Also when opening a new [connection](../../cyberduck/connection.md#toolbar-button) using *File → Open Connection…, IdentityFile* and *User* parameters in the OpenSSH user config file are auto completed. Example `~/.ssh/config` configuration: @@ -112,6 +114,42 @@ OpenSSH private keys of type `rsa`, `dsa`, `ecdsa` and `ed25519` (in OpenSSL `PE Applies to SSH servers, which are configured with [`TrustedUserCAKeys`](https://man.openbsd.org/sshd_config#TrustedUserCAKeys), refer to your software vendor for configuration. To configure authentication with a User CA signed private key, configure the private key as described in [Configure Public Key Authentication](#public-key-authentication) step 3. The signed public key file _must_ reside next to the private key file, suffixed `-cert.pub` or `.pub`. The [`CertificateFile`](https://man.openbsd.org/ssh_config#CertificateFile) configuration directive in `~/.ssh/config` is not supported. Pay attention to the server configuration and [`PubkeyAcceptedAlgorithms`](https://man.openbsd.org/sshd_config#PubkeyAcceptedAlgorithms) specifically which determines the allowed private key algorithms to authenticate with. +#### Security Key (FIDO2) Authentication + +:::{important} +* Cyberduck [9.6.0](https://cyberduck.io/changelog/) or later required +::: + +Keys of type `sk-ecdsa-sha2-nistp256@openssh.com` and `sk-ssh-ed25519@openssh.com` created with `ssh-keygen -t ecdsa-sk` respectively `ssh-keygen -t ed25519-sk` are supported. The private key of such a key never leaves the authenticator, which is either the Secure Enclave of a Mac unlocked with _Touch ID_ or a hardware token such as a _YubiKey_ touched to confirm. The key file selected in the [Bookmark](../../cyberduck/bookmarks.md) holds the credential handle only. + +Signing a login is delegated to the middleware library of the authenticator, set with the [`SecurityKeyProvider`](#configuration-file) directive in `~/.ssh/config` or the [hidden configuration option](../../tutorials/hidden_properties.md) `ssh.authentication.securitykey.provider`. It defaults to `/usr/lib/ssh-keychain.dylib` for keys in the Secure Enclave on macOS. Alternatively add the key to an [SSH agent](#public-key-authentication-using-ssh-agent) which then prompts to confirm the login. + +:::{important} +The server must run _OpenSSH 8.2_ or later. Earlier versions do not know the `sk-*` key types and ignore the entry in `authorized_keys`. +::: + +:::{admonition} Tutorial +:class: tip + +Follow the [step-by-step instructions](../../tutorials/sftp_publickeyauth_securitykey.md) to create a key in the Secure Enclave or on a hardware token and connect with it. +::: + +#### Smartcard (PKCS#11) Authentication + +:::{important} +* Cyberduck [9.6.0](https://cyberduck.io/changelog/) or later required +::: + +Private keys kept on a smartcard are read with the _PKCS#11_ module of the card, the equivalent of `ssh -I`. Every key on the card with a matching certificate is offered to the server in turn and the PIN is prompted for when required by the card. A key on a card without a certificate is not found. + +Set the module with the [`PKCS11Provider`](#configuration-file) directive in `~/.ssh/config` or the [hidden configuration option](../../tutorials/hidden_properties.md) `ssh.authentication.pkcs11.library`. Both an absolute path and the file name of the bundled _OpenSC_ module `opensc-pkcs11.so` are accepted. + +:::{admonition} Tutorial +:class: tip + +Follow the [step-by-step instructions](../../tutorials/sftp_publickeyauth_pkcs11.md) to authenticate with a key on a smartcard. +::: + #### Public Key Authentication Using SSH Agent When connecting to a SSH server, Cyberduck will lookup matching private keys from the SSH agent when attempting to authenticate with the server if no password is available and no explicit private key to use is configured in the bookmark. @@ -175,6 +213,22 @@ Host myhostname Alternatively you can select the public key file in the [bookmark](../../cyberduck/bookmarks.md#edit-bookmark) configuration. +### Kerberos (GSSAPI) Authentication + +:::{important} +* Cyberduck [9.6.0](https://cyberduck.io/changelog/) or later required +::: + +Authentication with the method `gssapi-with-mic` using a _Kerberos_ ticket obtained with `kinit` is supported. The method is attempted after public key authentication and before prompting for a password when no password is saved for the bookmark. Without a valid ticket the login continues with the next authentication method. Connect using the fully qualified hostname matching the service principal of the server. + +The Kerberos configuration is read from the default location such as `/etc/krb5.conf`. Use the [hidden configuration options](../../tutorials/hidden_properties.md) `java.security.krb5.conf` to set a different configuration file or `java.security.krb5.realm` and `java.security.krb5.kdc` to set the realm and KDC without a configuration file. + +:::{admonition} Tutorial +:class: tip + +Follow the [step-by-step instructions](../../tutorials/sftp_kerberos.md) to authenticate with a Kerberos ticket. +::: + ### One-Time Passcodes (2FA) Using a challenge-response authentication with one-time password generators such as [*DUO*](https://duo.com/product/multi-factor-authentication-mfa), [*SecurID*](https://www.rsa.com/products/securid/) or [*Google Authenticator*](https://github.com/google/google-authenticator) is supported. After the initial login prompt for the username and password, a second login prompt is displayed to enter the one-time passcode. @@ -368,7 +422,7 @@ You can set Cyberduck or a third-party application as the default application (p ### SSH Key Types -`ssh-rsa`, `ssh-dss`, `ecdsa-sha2-nistp256`, `ecdsa-sha2-nistp384`, `ecdsa-sha2-nistp521`, `ssh-ed25519`, `rsa-sha2-256`, `rsa-sha2-512` +`ssh-rsa`, `ssh-dss`, `ecdsa-sha2-nistp256`, `ecdsa-sha2-nistp384`, `ecdsa-sha2-nistp521`, `ssh-ed25519`, `rsa-sha2-256`, `rsa-sha2-512`, `sk-ecdsa-sha2-nistp256@openssh.com`, `sk-ssh-ed25519@openssh.com` ### SSH Certificate Key Types diff --git a/tutorials/index.md b/tutorials/index.md index d2a7deaa..95ddf96f 100644 --- a/tutorials/index.md +++ b/tutorials/index.md @@ -15,9 +15,12 @@ owncloud_opencloud_oidc iam vault_localdisk sftp_publickeyauth +sftp_publickeyauth_securitykey +sftp_publickeyauth_pkcs11 sftp_publickeyauth_1password sftp_publickeyauth_bitwarden sftp_publickeyauth_yubikey +sftp_kerberos cli_github_action ::: @@ -56,6 +59,12 @@ Both [Cyberduck](../cyberduck/index.md) and [Mountain Duck](../mountainduck/inde ## [Configure Public Key Authentication for SFTP](sftp_publickeyauth.md) Configure Public Key Authentication for SFTP using OpenSSH tools. +### [Use a FIDO2 Security Key](sftp_publickeyauth_securitykey.md) +Authenticate with a `sk-*` key in the Secure Enclave unlocked with Touch ID or on a hardware token such as a YubiKey. + +### [Use a PKCS#11 Smartcard](sftp_publickeyauth_pkcs11.md) +Authenticate with a private key kept on a smartcard read with a PKCS#11 module such as OpenSC. + ### [Configure 1Password SSH Agent](sftp_publickeyauth_1password.md) Authenticate with SSH private key saved in 1Password. @@ -65,5 +74,8 @@ Authenticate with SSH private key saved in Bitwarden. ### [Use YubiKey](sftp_publickeyauth_yubikey.md) Authenticate with SSH private key saved on YubiKey. +## [Configure Kerberos Authentication for SFTP](sftp_kerberos.md) +Authenticate with a Kerberos ticket obtained with `kinit` using GSSAPI. + ## [Use Cyberduck CLI GitHub Action](cli_github_action.md) Use Cyberduck CLI Docker Container in GitHub Actions \ No newline at end of file From c6c51e9afb3e056371909841f17d691dbdb7bc36 Mon Sep 17 00:00:00 2001 From: David Kocher Date: Tue, 29 Sep 2026 18:06:36 +0200 Subject: [PATCH 03/12] Fix SFTP documentation to match implementation of authentication methods, OpenSSH configuration directives, key formats and algorithms. --- protocols/sftp/index.md | 32 +++++++++++++++++++------------- tutorials/sftp_kerberos.md | 2 +- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/protocols/sftp/index.md b/protocols/sftp/index.md index 90630b8b..66ca25a5 100644 --- a/protocols/sftp/index.md +++ b/protocols/sftp/index.md @@ -9,6 +9,9 @@ providers ../../tutorials/sftp_publickeyauth_1password ../../tutorials/sftp_publickeyauth_bitwarden ../../tutorials/sftp_publickeyauth_yubikey +../../tutorials/sftp_publickeyauth_securitykey +../../tutorials/sftp_publickeyauth_pkcs11 +../../tutorials/sftp_kerberos ::: :::{image} ../_images/ftp.png @@ -32,7 +35,7 @@ If you have access to a server using a secure shell ([SSH2](http://en.wikipedia. #### Public Key Fingerprints -Public key fingerprints are checked against and written to `~/ssh/known_hosts` when accepted. This does not apply to the Mac App Store version which does store key fingerprints in the preferences. +Public key fingerprints are checked against and written to `~/.ssh/known_hosts` when accepted. This does not apply to the Mac App Store version which does store key fingerprints in the preferences. #### Configuration File @@ -41,10 +44,13 @@ The following configuration options from `~/.ssh/config` are supported for SFTP - *IdentityFile* for public key authentication. - *IdentityAgent* for public key authentication. Specifies the UNIX-domain socket used to communicate with the authentication agent. - *HostName* aliases. +- *Port* to connect to. - *User* preference for login credentials. - *ProxyJump* to connect via SSH tunnel through bastion server. -- *PreferredAuthentications* to limit authentication methods tried to login. -- *IdentitiesOnly*. Only try explicitly set private keys to authenticate but not all identities found in SSH agent. Resolves _Too many authentication failures_ errors with servers limiting the number of attempted authentication requests. +- *ProxyCommand* to connect through the standard input and output of a command. +- *PreferredAuthentications* to set the order of authentication methods tried to login. Methods not listed are still tried afterwards. +- *IdentitiesOnly*. Only try the private key set with *IdentityFile* in `~/.ssh/config` to authenticate but not all identities found in SSH agent. The key selected in the bookmark does not apply. With no *IdentityFile* set, no identity from the SSH agent is offered. Resolves _Too many authentication failures_ errors with servers limiting the number of attempted authentication requests. +- *Include* to read other configuration files and *Match* blocks with the criteria `host` and `user`. - *SecurityKeyProvider* for the middleware library signing with a [FIDO2 security key](../../tutorials/sftp_publickeyauth_securitykey.md) for `sk-ecdsa-sha2-nistp256@openssh.com` and `sk-ssh-ed25519@openssh.com` keys. - *PKCS11Provider* for the module reading keys from a [smartcard](../../tutorials/sftp_publickeyauth_pkcs11.md). - A [bookmark](../../cyberduck/bookmarks.md) will update its public key authentication setting from the *IdentityFile* configuration in `~/.ssh/config`. Also when opening a new [connection](../../cyberduck/connection.md#toolbar-button) using *File → Open Connection…, IdentityFile* and *User* parameters in the OpenSSH user config file are auto completed. @@ -99,11 +105,11 @@ Follow the [step-by-step instructions](../../tutorials/sftp_publickeyauth.md) to #### PuTTY Key Format Interoperability -PuTTY private keys (`.ppk`) are supported for `rsa` key types. `ed25519` is not supported. +PuTTY private keys (`.ppk`) are supported for `rsa`, `dsa`, `ecdsa` and `ed25519` key types. #### OpenSSH Key Format Interoperability -OpenSSH private keys of type `rsa`, `dsa`, `ecdsa` and `ed25519` (in OpenSSL `PEM` format) are supported. The new OpenSSH format (`openssh-key-v1`) is only supported for `ecdsa` and `ed25519`. +OpenSSH private keys of type `rsa`, `dsa`, `ecdsa` and `ed25519` (in OpenSSL `PEM` format) are supported. The new OpenSSH format (`openssh-key-v1`) is supported for `rsa`, `ecdsa` and `ed25519` but not for `dsa`. ##### OpenSSH User Certificate Authentication @@ -122,7 +128,7 @@ Applies to SSH servers, which are configured with [`TrustedUserCAKeys`](https:// Keys of type `sk-ecdsa-sha2-nistp256@openssh.com` and `sk-ssh-ed25519@openssh.com` created with `ssh-keygen -t ecdsa-sk` respectively `ssh-keygen -t ed25519-sk` are supported. The private key of such a key never leaves the authenticator, which is either the Secure Enclave of a Mac unlocked with _Touch ID_ or a hardware token such as a _YubiKey_ touched to confirm. The key file selected in the [Bookmark](../../cyberduck/bookmarks.md) holds the credential handle only. -Signing a login is delegated to the middleware library of the authenticator, set with the [`SecurityKeyProvider`](#configuration-file) directive in `~/.ssh/config` or the [hidden configuration option](../../tutorials/hidden_properties.md) `ssh.authentication.securitykey.provider`. It defaults to `/usr/lib/ssh-keychain.dylib` for keys in the Secure Enclave on macOS. Alternatively add the key to an [SSH agent](#public-key-authentication-using-ssh-agent) which then prompts to confirm the login. +Signing a login is delegated to the middleware library of the authenticator, set with the [`SecurityKeyProvider`](#configuration-file) directive in `~/.ssh/config` or the [hidden configuration option](../../tutorials/hidden_properties.md) `ssh.authentication.securitykey.provider`. It defaults to `/usr/lib/ssh-keychain.dylib` for keys in the Secure Enclave on macOS. This library is not available on other platforms, where the directive or option must be set to the middleware library of the authenticator. Alternatively add the key to an [SSH agent](#public-key-authentication-using-ssh-agent) which then prompts to confirm the login. :::{important} The server must run _OpenSSH 8.2_ or later. Earlier versions do not know the `sk-*` key types and ignore the entry in `authorized_keys`. @@ -142,7 +148,7 @@ Follow the [step-by-step instructions](../../tutorials/sftp_publickeyauth_securi Private keys kept on a smartcard are read with the _PKCS#11_ module of the card, the equivalent of `ssh -I`. Every key on the card with a matching certificate is offered to the server in turn and the PIN is prompted for when required by the card. A key on a card without a certificate is not found. -Set the module with the [`PKCS11Provider`](#configuration-file) directive in `~/.ssh/config` or the [hidden configuration option](../../tutorials/hidden_properties.md) `ssh.authentication.pkcs11.library`. Both an absolute path and the file name of the bundled _OpenSC_ module `opensc-pkcs11.so` are accepted. +Set the module with the [`PKCS11Provider`](#configuration-file) directive in `~/.ssh/config` or the [hidden configuration option](../../tutorials/hidden_properties.md) `ssh.authentication.pkcs11.library`. Set an absolute path to the module. On macOS, the file name `opensc-pkcs11.so` of the _OpenSC_ module bundled with the application is accepted as well. Set the [hidden configuration option](../../tutorials/hidden_properties.md) `ssh.authentication.pkcs11.enable` to `false` to disable authentication with a smartcard. :::{admonition} Tutorial :class: tip @@ -151,7 +157,7 @@ Follow the [step-by-step instructions](../../tutorials/sftp_publickeyauth_pkcs11 ::: #### Public Key Authentication Using SSH Agent -When connecting to a SSH server, Cyberduck will lookup matching private keys from the SSH agent when attempting to authenticate with the server if no password is available and no explicit private key to use is configured in the bookmark. +When connecting to a SSH server, Cyberduck will try the identities from the SSH agent to authenticate with the server. When a password is saved for the bookmark, password authentication is attempted first. When a private or public key is selected in the bookmark, only the identity in the agent matching this key is offered. If no identity matches, all identities are offered. Disable the use of the SSH agent with the [hidden configuration option](../../tutorials/hidden_properties.md) `ssh.authentication.agent.enable=false`. :::{admonition} Mac App Store :class: attention @@ -308,7 +314,7 @@ Use *View → Customize Toolbar...* to add the *Terminal.app* toolbar icon to yo You can change the SSH command using the [hidden configuration option](../../tutorials/hidden_properties.md) ``` -terminal.command.ssh=\"ssh\ -t\ {0}\ {1}@{2}\ -p\ {3}\ \\\"cd\ {4}\ \&\&\ exec\ \\\\\$SHELL\\\"\" +terminal.command.ssh=\"ssh\ -t\ {0}\ {1}@{2}\ -p\ {3}\ \\\"cd\ {4}\ \&\&\ exec\ \\\\\$SHELL\ -l\\\"\" ``` where @@ -319,7 +325,7 @@ where - {3} is the port number of the remote host - {4} is the current working directory in the browser -Because of all the escaping of characters, it might be easier to edit the key using *Property List Editor* if you have the developer tools installed. You can then set the string for the key `terminal.command.ssh to ssh -t {0} {1}@{2} -p {3} "cd {4} && exec \$SHELL"`. Test the string in *Terminal.app* first if it is valid. +Because of all the escaping of characters, it might be easier to edit the key using *Property List Editor* if you have the developer tools installed. You can then set the string for the key `terminal.command.ssh` to `ssh -t {0} {1}@{2} -p {3} "cd {4} && exec \$SHELL -l"`. Test the string in *Terminal.app* first if it is valid. **Using [iTerm2](https://www.iterm2.com/)** @@ -418,7 +424,7 @@ You can set Cyberduck or a third-party application as the default application (p ### Key Exchange -`diffie-hellman-group1-sha1`, `diffie-hellman-group14-sha1`, `diffie-hellman-group14-sha256`, `diffie-hellman-group15-sha512`, `diffie-hellman-group16-sha512`, `diffie-hellman-group17-sha512`, `diffie-hellman-group18-sha512 diffie-hellman-group-exchange-sha1`, `diffie-hellman-group-exchange-sha256`, `ecdh-sha2-nistp256`, `ecdh-sha2-nistp384`, `ecdh-sha2-nistp521`, `curve25519-sha256@libssh.org` +`curve25519-sha256`, `curve25519-sha256@libssh.org`, `diffie-hellman-group-exchange-sha256`, `ecdh-sha2-nistp521`, `ecdh-sha2-nistp384`, `ecdh-sha2-nistp256`, `diffie-hellman-group-exchange-sha1`, `diffie-hellman-group1-sha1`, `diffie-hellman-group14-sha1`, `diffie-hellman-group14-sha256`, `diffie-hellman-group15-sha512`, `diffie-hellman-group16-sha512`, `diffie-hellman-group17-sha512`, `diffie-hellman-group18-sha512`, `diffie-hellman-group14-sha256@ssh.com`, `diffie-hellman-group15-sha256`, `diffie-hellman-group15-sha256@ssh.com`, `diffie-hellman-group15-sha384@ssh.com`, `diffie-hellman-group16-sha256`, `diffie-hellman-group16-sha384@ssh.com`, `diffie-hellman-group16-sha512@ssh.com`, `diffie-hellman-group18-sha512@ssh.com` ### SSH Key Types @@ -434,7 +440,7 @@ Compression with `zlib` and `zlib@openssh.com` is supported. ### Private Key Files -`pkcs5`, `pkcs8`, `openssh-key-v1` +`pkcs5`, `pkcs8`, `openssh-key-v1`, PuTTY `.ppk` ## Incompatibilities @@ -453,7 +459,7 @@ Running an SSH agent with many added identities can lead to the server error _To Possible remedies using configuration in [OpenSSH configuration file](#openssh-configuration-interoperability): - [`IdentitiesOnly`](https://man.openbsd.org/ssh_config.5#IdentitiesOnly) in client configuration file `~/.ssh/config`. Only try to authenticate with explicitly set private key instead of all identities retrieved from SSH agent. -- Set [`PreferredAuthentications`](https://man.openbsd.org/ssh_config.5#PreferredAuthentications) in client configuration file `~/.ssh/config` to disable public key authentication for example. +- Set [`PreferredAuthentications`](https://man.openbsd.org/ssh_config.5#PreferredAuthentications) in client configuration file `~/.ssh/config` to try another method such as `password` before public key authentication. Methods not listed are still tried afterwards. ### Illegal SFTP Packet Length: `Invalid packet: indicated length 1114795883 too large` diff --git a/tutorials/sftp_kerberos.md b/tutorials/sftp_kerberos.md index 661cd1d2..1e57ccac 100644 --- a/tutorials/sftp_kerberos.md +++ b/tutorials/sftp_kerberos.md @@ -109,7 +109,7 @@ Authentication fails when the clock of your computer differs by more than five m ::: :::{note} -The `GSSAPIAuthentication` directive in `~/.ssh/config` is not required. The authentication method is always attempted when offered by the server. Limit the methods tried with [`PreferredAuthentications`](../protocols/sftp/index.md#configuration-file) instead. +The `GSSAPIAuthentication` directive in `~/.ssh/config` is not required. The authentication method is always attempted when offered by the server. Change the order in which methods are tried with [`PreferredAuthentications`](../protocols/sftp/index.md#configuration-file) instead. Methods not listed are still tried afterwards. ::: ## References From 21cf920f6d6f9aa6e7fc8db9a925778503a5433c Mon Sep 17 00:00:00 2001 From: AliveDevil Date: Thu, 8 Oct 2026 15:53:40 +0200 Subject: [PATCH 04/12] Update SFTP protocol with Pageant requirements --- protocols/sftp/index.md | 8 ++-- tutorials/index.md | 4 ++ tutorials/sftp_publickeyauth_pageant.md | 49 +++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 tutorials/sftp_publickeyauth_pageant.md diff --git a/protocols/sftp/index.md b/protocols/sftp/index.md index a70650e1..daa6d345 100644 --- a/protocols/sftp/index.md +++ b/protocols/sftp/index.md @@ -9,6 +9,7 @@ providers ../../tutorials/sftp_publickeyauth_1password ../../tutorials/sftp_publickeyauth_bitwarden ../../tutorials/sftp_publickeyauth_yubikey +../../tutorials/sftp_publickeyauth_pageant ::: :::{image} ../_images/ftp.png @@ -45,6 +46,7 @@ The following configuration options from `~/.ssh/config` are supported for SFTP - *ProxyJump* to connect via SSH tunnel through bastion server. - *PreferredAuthentications* to limit authentication methods tried to login. - *IdentitiesOnly*. Only try explicitly set private keys to authenticate but not all identities found in SSH agent. Resolves _Too many authentication failures_ errors with servers limiting the number of attempted authentication requests. +- *Include* to compose the configuration from multiple files, e.g. to keep settings written by other applications in a separate file. - A [bookmark](../../cyberduck/bookmarks.md) will update its public key authentication setting from the *IdentityFile* configuration in `~/.ssh/config`. Also when opening a new [connection](../../cyberduck/connection.md#toolbar-button) using *File → Open Connection…, IdentityFile* and *User* parameters in the OpenSSH user config file are auto completed. Example `~/.ssh/config` configuration: @@ -146,14 +148,10 @@ Host myhostname IdentityAgent ~/.bitwarden-ssh-agent.sock ``` - ::: :::{group-tab} Windows -The following agents are supported: - * [Pageant](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html). Refer to [How To Use Pageant to Streamline SSH Key Authentication with PuTTY](https://www.digitalocean.com/community/tutorials/how-to-use-pageant-to-streamline-ssh-key-authentication-with-putty). - * OpenSSH for Windows using the pipe (`\\.\pipe\openssh-ssh-agent`) by default. Use `IdentityAgent` to set a custom socket path for any other compatible agent if needed. - * [1Password SSH agent](https://developer.1password.com/docs/ssh/agent/compatibility/#cyberduck) +SSH agents that provide a named pipe are supported, such as the OpenSSH agent, the [1Password SSH agent](https://developer.1password.com/docs/ssh/agent/compatibility/#cyberduck) and [Pageant](../../tutorials/sftp_publickeyauth_pageant.md). The OpenSSH agent pipe (`\\.\pipe\openssh-ssh-agent`) is used by default. Use `IdentityAgent` to set a different pipe if needed. ::: :::: diff --git a/tutorials/index.md b/tutorials/index.md index d2a7deaa..aabc48fb 100644 --- a/tutorials/index.md +++ b/tutorials/index.md @@ -18,6 +18,7 @@ sftp_publickeyauth sftp_publickeyauth_1password sftp_publickeyauth_bitwarden sftp_publickeyauth_yubikey +sftp_publickeyauth_pageant cli_github_action ::: @@ -65,5 +66,8 @@ Authenticate with SSH private key saved in Bitwarden. ### [Use YubiKey](sftp_publickeyauth_yubikey.md) Authenticate with SSH private key saved on YubiKey. +### [Configure Pageant](sftp_publickeyauth_pageant.md) +Authenticate with SSH private key loaded in Pageant. + ## [Use Cyberduck CLI GitHub Action](cli_github_action.md) Use Cyberduck CLI Docker Container in GitHub Actions \ No newline at end of file diff --git a/tutorials/sftp_publickeyauth_pageant.md b/tutorials/sftp_publickeyauth_pageant.md new file mode 100644 index 00000000..75468ecf --- /dev/null +++ b/tutorials/sftp_publickeyauth_pageant.md @@ -0,0 +1,49 @@ +Configure Public Key Authentication for SFTP using Pageant +==== + +> Public-key authentication using _Pageant_ SSH Agent allows you to connect to a remote server without a password. Instead of passwords, you use a pair of keys (private and public) for authentication. The private key is kept secret, while the public key is shared with the server. + +:::{important} +* Cyberduck [9.6](https://cyberduck.io/changelog/) or later required +* PuTTY/Pageant [0.77](https://www.chiark.greenend.org.uk/~sgtatham/putty/changes.html) or later required + +The previous built-in Pageant integration has been removed in Cyberduck 9.6. Refer to [#18479](https://github.com/iterate-ch/cyberduck/issues/18479). +::: + +Refer to [How To Use Pageant to Streamline SSH Key Authentication with PuTTY](https://www.digitalocean.com/community/tutorials/how-to-use-pageant-to-streamline-ssh-key-authentication-with-putty) for general usage of Pageant. Pageant supports writing the `IdentityAgent`-option into an OpenSSH configuration file on startup. + +1. Install [PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html), which includes _Pageant_ and _PuTTYgen_. + +2. Start Pageant with the `--openssh-config` option, e.g. in the shortcut used to launch Pageant at login. Private key files to load can be appended to the command line. + + ``` + pageant.exe --openssh-config %USERPROFILE%\.ssh\pageant.conf + ``` + +3. Add an `Include` directive at the top of `%USERPROFILE%\.ssh\config` before any `Host` entry to apply it to all hosts. + + ``` + Include ~/.ssh/pageant.conf + ``` + +4. Open your private key in _PuTTYgen_ and copy the public key shown in _Public key for pasting into OpenSSH authorized_keys file_. Add it to the `authorized_keys` in your `~/.ssh` directory on the server running OpenSSH. + +5. Add a new [Bookmark](../cyberduck/bookmarks.md) in Cyberduck. Enter the alias from your OpenSSH configuration or the hostname in _Server_. You do **not** need to set a value for _Password_. + + :::{tip} + The server may respond with _[Too many authentication failures](../protocols/sftp/index.md#too-many-authentication-failures)_ when trying to authenticate with all keys loaded in _Pageant_. In the [Bookmark](../cyberduck/bookmarks.md) panel, select the public key corresponding to your private key loaded in _Pageant_ for *SSH Private Key*. The public key must be available as a file, e.g. saved from _PuTTYgen_ to `%USERPROFILE%\.ssh\mykey.pub`. + + Alternatively, add the public key to the OpenSSH configuration file `~/.ssh/config` with the `IdentityFile` directive + + ``` + # Public Key File used to filter identities from SSH agent + IdentityFile ~/.ssh/mykey.pub + ``` + ::: + +6. Connect to the server. The private key loaded in _Pageant_ is used to authenticate. + +## References + +* [PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html) +* [How To Use Pageant to Streamline SSH Key Authentication with PuTTY](https://www.digitalocean.com/community/tutorials/how-to-use-pageant-to-streamline-ssh-key-authentication-with-putty) From c0a39a25f79355bd2c094d4f099212f4a70c897d Mon Sep 17 00:00:00 2001 From: David Kocher Date: Mon, 12 Oct 2026 13:05:07 +0200 Subject: [PATCH 05/12] Add documentation for Kerberos realm configuration per bookmark and Windows-specific setup steps for SFTP connections. --- cyberduck/bookmarks.md | 1 + protocols/profiles/index.md | 1 + protocols/sftp/index.md | 3 ++ tutorials/sftp_kerberos.md | 57 +++++++++++++++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/cyberduck/bookmarks.md b/cyberduck/bookmarks.md index 0f29b5e7..a96a7768 100644 --- a/cyberduck/bookmarks.md +++ b/cyberduck/bookmarks.md @@ -114,6 +114,7 @@ Select *Bookmark → Edit Bookmark (macOS `⌘E` Windows `Strg+E`)*. A panel whe | Connect
Mode | For [FTP](../protocols/ftp.md) connections only. Refer to [FTP Connect Mode](../protocols/ftp.md#ftp-connect-mode). | | Encoding | For [FTP](../protocols/ftp.md) connections only. Character encoding of filenames on the server. You can also change
the encoding used when the connection is open using *View → Text Encoding* if characters
are not displayed properly. Try `UTF-8` (the default), `ISO-8859-1`, and `Windows-1252`.
Refer to [Character Encoding](../protocols/ftp.md#character-encoding). | | Timezone | For all protocols except [FTP](../protocols/ftp.md), timestamps are reported in [UTC](http://en.wikipedia.org/wiki/Coordinated_Universal_Time) from the server and there is no
need for configuration. All timestamps in the browser are automatically converted to the timezone
you have configured in the *System Preferences* and displayed in local time. For [FTP](../protocols/ftp.md)
however, the local timezone is assumed for timestamps in directory listings If the server
is configured with a different timezone that your Mac and returning the local time for
modification dates, there will be an offset by the timezone difference. To get the correct local
time for modification dates in the browser, you can choose the timezone of the server in the
bookmark settings. Select *Bookmark → Edit Bookmark*. | +| Kerberos
Realm | For [SFTP](../protocols/sftp/index.md) connections only. Default realm for [Kerberos authentication](../tutorials/sftp_kerberos.md#kerberos-realm-per-bookmark).
Leave empty to use the default realm from the Kerberos configuration. | ### Passwords diff --git a/protocols/profiles/index.md b/protocols/profiles/index.md index 7e633199..5696d28f 100644 --- a/protocols/profiles/index.md +++ b/protocols/profiles/index.md @@ -70,6 +70,7 @@ The value of `Vendor` must be unique among all installed connection profiles. - `Anonymous Configurable` Boolean if anonymous access is configurable. - `Path Configurable` Boolean if default path is configurable. - `Certificate Configurable` Boolean if client certificate is configurable. +- `Kerberos Configurable` Boolean if the Kerberos realm is configurable in the bookmark. Defaults to `true` for [SFTP](../sftp/index.md) profiles. - `Role Configurable`. Boolean if role is configurable. Typically an ARN referencing the AWS IAM role to assume using AWS STS API. - `Region` Location constraint for [OpenStack Swift](../openstack/index.md) and [S3](../s3/index.md) profiles. :::{admonition} S3 diff --git a/protocols/sftp/index.md b/protocols/sftp/index.md index 66ca25a5..f82e895e 100644 --- a/protocols/sftp/index.md +++ b/protocols/sftp/index.md @@ -12,6 +12,7 @@ providers ../../tutorials/sftp_publickeyauth_securitykey ../../tutorials/sftp_publickeyauth_pkcs11 ../../tutorials/sftp_kerberos +../../tutorials/sftp_azure_blob_storage ::: :::{image} ../_images/ftp.png @@ -229,6 +230,8 @@ Authentication with the method `gssapi-with-mic` using a _Kerberos_ ticket obtai The Kerberos configuration is read from the default location such as `/etc/krb5.conf`. Use the [hidden configuration options](../../tutorials/hidden_properties.md) `java.security.krb5.conf` to set a different configuration file or `java.security.krb5.realm` and `java.security.krb5.kdc` to set the realm and KDC without a configuration file. +Set the realm of the server in _Kerberos Realm_ of the [bookmark](../../cyberduck/bookmarks.md#bookmark-options) when no default realm is configured or the server belongs to a different realm. + :::{admonition} Tutorial :class: tip diff --git a/tutorials/sftp_kerberos.md b/tutorials/sftp_kerberos.md index 1e57ccac..8fbe8843 100644 --- a/tutorials/sftp_kerberos.md +++ b/tutorials/sftp_kerberos.md @@ -14,7 +14,8 @@ Authentication with Kerberos is attempted after public key authentication and be - The server running OpenSSH is configured with `GSSAPIAuthentication yes` in `sshd_config` and has a keytab with the service principal `host/server.example.com@EXAMPLE.COM` for its fully qualified hostname. Refer to your administrator. - Your principal such as `user@EXAMPLE.COM` is allowed to log in to the account on the server. By default the principal `user@EXAMPLE.COM` maps to the account `user`. Additional principals are listed in `~/.k5login` of the account on the server. -- The Kerberos configuration with the default realm and the Key Distribution Center (KDC) of your organization is found in `/etc/krb5.conf` or can be looked up in DNS. +- The Kerberos configuration with the default realm and the Key Distribution Center (KDC) of your organization is found in `/etc/krb5.conf` or can be looked up in DNS. Alternatively set the [realm in the bookmark](#kerberos-realm-per-bookmark). +- On Windows, [MIT Kerberos for Windows](https://web.mit.edu/kerberos/dist/) is installed to obtain the ticket. ## Setup @@ -48,11 +49,50 @@ Authentication with Kerberos is attempted after public key authentication and be The hostname must match the service principal in the keytab of the server. Connecting using an IP address or a short hostname may fail when it cannot be resolved to the fully qualified name. ::: -5. Connect to the server. No prompt is displayed when the ticket is accepted. +5. Optionally enter the realm such as `EXAMPLE.COM` in _Kerberos Realm_ in the _More Options_ tab of the bookmark when no default realm is configured or the server belongs to a [different realm](#kerberos-realm-per-bookmark). + +6. Connect to the server. No prompt is displayed when the ticket is accepted. + +:::: +::::{group-tab} Windows + +The ticket of _MIT Kerberos for Windows_ is kept in memory by its credentials cache server and cannot be read directly.The ticket granting ticket is copied to a temporary credentials cache file for the login using the `klist.exe` and `kcpytkt.exe` tools of MIT Kerberos for Windows. The temporary file is deleted afterwards. + +1. Install [MIT Kerberos for Windows](https://web.mit.edu/kerberos/dist/). The tools are looked up in `%ProgramFiles%\MIT\Kerberos\bin`. + +2. Obtain a ticket for your principal with _MIT Kerberos Ticket Manager_ or from the command line. Enter the password of your Kerberos account when prompted. + ``` + "%ProgramFiles%\MIT\Kerberos\bin\kinit.exe" user@EXAMPLE.COM + ``` + +3. Verify a ticket for the realm is listed and has not expired. + ``` + "%ProgramFiles%\MIT\Kerberos\bin\klist.exe" + ``` + +4. Add a new [Bookmark](../cyberduck/bookmarks.md). Enter the fully qualified hostname `server.example.com` in _Server_ and your account in _Username_. You do **not** need to set a value for _Password_ or select a _SSH Private Key_. + + :::{warning} + The hostname must match the service principal in the keytab of the server. Connecting using an IP address or a short hostname may fail when it cannot be resolved to the fully qualified name. + ::: + +5. Check _Use MIT Kerberos_ in the bookmark. + +6. Enter the realm such as `EXAMPLE.COM` in _Kerberos Realm_. This is required unless the [Kerberos configuration](#kerberos-configuration) is found. The configuration `krb5.ini` of MIT Kerberos for Windows in `%ProgramData%\MIT\Kerberos5` is not read. + +7. Connect to the server. No prompt is displayed when the ticket is accepted. :::: ::::: +## Kerberos Realm per Bookmark + +Set the realm of the server such as `EXAMPLE.COM` in _Kerberos Realm_ of the [bookmark](../cyberduck/bookmarks.md#bookmark-options) when no default realm is configured on your computer or the server belongs to a different realm than the default realm. The field is found in the _More Options_ tab on macOS. + +For a connection with a realm set in the bookmark, a temporary Kerberos configuration with this default realm replaces any [configuration file](#kerberos-configuration). The KDC of the realm is looked up from DNS SRV records unless set with the hidden configuration option `java.security.krb5.kdc`. Other settings from your configuration file such as `[domain_realm]` mappings do not apply to this connection. + +The realm is saved in the bookmark as the property `ssh.authentication.gssapi.realm` and can also be set in a [`.duck` bookmark file](hidden_properties.md#in-duck-bookmark-files). + ## Kerberos Configuration The Kerberos configuration is read from `/etc/krb5.conf` or on macOS from `~/Library/Preferences/edu.mit.Kerberos` and `/Library/Preferences/edu.mit.Kerberos` first when found. A minimal configuration for the realm `EXAMPLE.COM` looks like @@ -71,7 +111,7 @@ The Kerberos configuration is read from `/etc/krb5.conf` or on macOS from `~/Lib Omit the `[realms]` section and add `dns_lookup_kdc = true` to `[libdefaults]` to look up the KDC from `_kerberos._tcp` and `_kerberos._udp` DNS SRV records of the realm instead. -The following [hidden configuration options](hidden_properties.md) apply to all connections. +The following [hidden configuration options](hidden_properties.md) apply to all connections. Options marked as per bookmark can be set for a single bookmark as well. | Option | Description | |-----------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -79,6 +119,9 @@ The following [hidden configuration options](hidden_properties.md) apply to all | `java.security.krb5.realm` | Default realm such as `EXAMPLE.COM` overriding the configuration file. Must be set together with `java.security.krb5.kdc`. | | `java.security.krb5.kdc` | Hostname of the KDC for the default realm overriding the configuration file. Must be set together with `java.security.krb5.realm`. Separate multiple KDCs with `:`. | | `ssh.authentication.gssapi.ticketcache` | Path to a credentials cache file to read the ticket from instead of the default cache. Obtain a ticket written to the file with `kinit -c /path/to/file user@EXAMPLE.COM`. | +| `ssh.authentication.gssapi.realm` | Per bookmark. Default realm for the connection set with _Kerberos Realm_ in the bookmark. Refer to [Kerberos Realm per Bookmark](#kerberos-realm-per-bookmark). | +| `ssh.authentication.gssapi.mit` | Per bookmark. Windows only. Set to `true` to copy the ticket from the credentials cache of MIT Kerberos for Windows. Set with _Use MIT Kerberos_ in the bookmark. | +| `ssh.authentication.gssapi.mit.path` | Windows only. Folder with `klist.exe` and `kcpytkt.exe` of MIT Kerberos for Windows when not installed in `%ProgramFiles%\MIT\Kerberos\bin`. | Example to set the realm and KDC for Cyberduck on macOS. ``` @@ -90,6 +133,10 @@ defaults write ch.sudo.cyberduck java.security.krb5.kdc kdc.example.com A KDC set with `java.security.krb5.kdc` is always contacted on the default port `88`. Use a configuration file with `kdc = kdc.example.com:port` for a KDC listening on a different port. ::: +## Connection Profiles + +The _Kerberos Realm_ field is shown in the bookmark for SFTP connections. Hide it for a [connection profile](../protocols/profiles/index.md) based on SFTP by setting `Kerberos Configurable` to `false`. + ## Require Public Key and Kerberos Authentication Servers can require authentication with both a private key and a Kerberos ticket with `AuthenticationMethods publickey,gssapi-with-mic` in `sshd_config`. Select the private key in _SSH Private Key_ of the bookmark. After the key has been accepted, login completes with the Kerberos ticket. @@ -108,6 +155,10 @@ The message _Server not found in Kerberos database_ printed by `ssh -v` indicate Authentication fails when the clock of your computer differs by more than five minutes from the KDC or the server. Enable _Set time and date automatically_ in _System Settings → General → Date & Time_. ::: +:::{warning} +On Windows, when you are prompted for a password, verify `klist.exe` of MIT Kerberos for Windows lists a ticket granting ticket `krbtgt/EXAMPLE.COM@EXAMPLE.COM` for your realm. When MIT Kerberos for Windows is installed in a different folder, set the hidden configuration option `ssh.authentication.gssapi.mit.path` to the folder containing `klist.exe` and `kcpytkt.exe`. +::: + :::{note} The `GSSAPIAuthentication` directive in `~/.ssh/config` is not required. The authentication method is always attempted when offered by the server. Change the order in which methods are tried with [`PreferredAuthentications`](../protocols/sftp/index.md#configuration-file) instead. Methods not listed are still tried afterwards. ::: From 3575fd26a8a10c24224a1eb1319eaa3077e4e9ea Mon Sep 17 00:00:00 2001 From: David Kocher Date: Mon, 12 Oct 2026 13:09:14 +0200 Subject: [PATCH 06/12] Add tutorial for Azure Blob Storage with SFTP --- tutorials/index.md | 4 + tutorials/sftp_azure_blob_storage.md | 170 +++++++++++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 tutorials/sftp_azure_blob_storage.md diff --git a/tutorials/index.md b/tutorials/index.md index 95ddf96f..f2997cbd 100644 --- a/tutorials/index.md +++ b/tutorials/index.md @@ -21,6 +21,7 @@ sftp_publickeyauth_1password sftp_publickeyauth_bitwarden sftp_publickeyauth_yubikey sftp_kerberos +sftp_azure_blob_storage cli_github_action ::: @@ -77,5 +78,8 @@ Authenticate with SSH private key saved on YubiKey. ## [Configure Kerberos Authentication for SFTP](sftp_kerberos.md) Authenticate with a Kerberos ticket obtained with `kinit` using GSSAPI. +## [Connect to Azure Blob Storage with SFTP](sftp_azure_blob_storage.md) +Authenticate with a local user using a password or private key, or with an SSH certificate issued by Microsoft Entra ID. + ## [Use Cyberduck CLI GitHub Action](cli_github_action.md) Use Cyberduck CLI Docker Container in GitHub Actions \ No newline at end of file diff --git a/tutorials/sftp_azure_blob_storage.md b/tutorials/sftp_azure_blob_storage.md new file mode 100644 index 00000000..9ca23cf3 --- /dev/null +++ b/tutorials/sftp_azure_blob_storage.md @@ -0,0 +1,170 @@ +Connect to Azure Blob Storage with SFTP +==== + +> Azure Blob Storage provides an [SFTP endpoint](https://learn.microsoft.com/en-us/azure/storage/blobs/secure-file-transfer-protocol-support) for storage accounts with the hierarchical namespace enabled. This tutorial describes how to enable SFTP in the Azure Portal and connect with Cyberduck or Mountain Duck, either with a [local user](#local-user-with-password-or-private-key) authenticating with a password or an SSH private key, or with a [Microsoft Entra ID](#ssh-certificate-with-microsoft-entra-id) account authenticating with an SSH certificate and no local users. + +:::{admonition} Authentication with an SSH certificate +:class: important + +- Cyberduck [8.9.0](https://cyberduck.io/changelog/) or later required +- Mountain Duck [4.16.0](https://mountainduck.io/changelog/) or later required +::: + +## Prerequisites + +- A *standard general-purpose v2* or *premium block blob* storage account with the [hierarchical namespace](https://learn.microsoft.com/en-us/azure/storage/blobs/upgrade-to-data-lake-storage-gen2-how-to) (Azure Data Lake Storage Gen2) enabled. The *SFTP* setting is not shown for other accounts. +- Permission to change the storage account in the [Azure Portal](https://portal.azure.com/). + +:::{note} +SFTP support is billed hourly for as long as it is enabled on the storage account. Select _Disable SFTP_ in the _SFTP_ settings of the storage account when not in use. +::: + +## Enable SFTP + +1. Sign in to the [Azure Portal](https://portal.azure.com/) and open your **Storage account**. +2. Under _Settings_, select **SFTP**. +3. Select **Enable SFTP**. + +The endpoint for SFTP is the Blob Storage endpoint `.blob.core.windows.net`. The Data Lake Storage endpoint `.dfs.core.windows.net` is *not* supported. + +## Local User with Password or Private Key + +Azure does not accept shared access signatures (SAS) for SFTP. A *local user* in the storage account is the identity to authenticate with a password or an SSH key pair. Password and key can both be enabled for a user but the client authenticates with only one of them. Requiring both is not supported. + +### Azure Portal + +1. Open the storage account, select **SFTP** under _Settings_ and select **Add local user**. +2. Enter a _Username_ such as `sftpuser`. +3. Select the authentication method. Select **SSH Password**, **SSH Key pair** or both. + - For *SSH Key pair* choose a _Public key source_: + - **Generate a new key pair**. Enter a key name. The private key is offered for download after you add the user. + - **Use existing public key**. Paste the public key in OpenSSH format such as `ssh-rsa AAAAB3N...` generated with `ssh-keygen`. Other formats such as PuTTY `.ppk` must be converted first. + - **Use existing key stored in Azure**. +4. Select **Next**. On the _Permissions_ tab choose the **Container** to make available and the permissions *Read*, *Write*, *List*, *Delete*, *Create*, *Modify Ownership* and *Modify Permissions*. Grant at least *Read* and *List* for browsing and *Write*, *Create* and *Delete* for upload and removal. +5. Enter a _Home directory_ such as `mycontainer` or `mycontainer/mydirectory`. Optionally select **Allow ACL authorization** to authorize with POSIX ACLs of files and directories in the container. +6. Select **Add**. + - For *SSH Password*, a generated password of at least 32 characters is shown **once**. Copy it. It cannot be retrieved later but only regenerated with _Reset password_ in the local user. + - For a new key pair, select **Download** to save the private key such as `sftpuser.pem`. Move it to `~/.ssh/` and restrict its permissions on macOS with `chmod 600 ~/.ssh/sftpuser.pem`. + +:::{important} +The local user must be granted at least one permission on the container it connects to. Otherwise the login fails. +::: + +### Cyberduck or Mountain Duck + +1. Add a new [Bookmark](../cyberduck/bookmarks.md) (_Bookmark → New Bookmark_ in Cyberduck) or connection in Mountain Duck and choose **SFTP (SSH File Transfer Protocol)**. +2. Enter the following. + + | Field | Value | + |----------|--------------------------------------------------------------------------------------------| + | Server | `.blob.core.windows.net` | + | Port | `22` | + | Username | `.` such as `contoso4.sftpuser` | + + :::{note} + If you did not set a home directory for the user, include the container in the username as `..` such as `contoso4.mycontainer.sftpuser`. + ::: + +3. Choose the authentication method. + - **Password**. Paste the generated password in _Password_ and leave _SSH Private Key_ set to _None_. Alternatively leave _Password_ empty and enter it when prompted, then choose _Save Password_ to store it in the keychain. + - **Private key**. Leave _Password_ empty and in _SSH Private Key_ choose _Choose…_ and select the downloaded private key such as `~/.ssh/sftpuser.pem`. For a key protected with a passphrase, enter the passphrase when prompted. Refer to [Configure Public Key Authentication](sftp_publickeyauth.md) for details. + +4. Close the bookmark and connect. Verify the host key presented by the server against the [published host keys](https://learn.microsoft.com/en-us/azure/storage/blobs/secure-file-transfer-protocol-host-keys) before choosing _Allow_. + +:::{tip} +The container is displayed at the root of the connection if no home directory is set for the local user and not part of the username. Navigate into it to see the blobs. +::: + +## SSH Certificate with Microsoft Entra ID + +Authenticating with Microsoft Entra ID replaces local users with your existing identities including multi-factor authentication, [Azure RBAC](https://learn.microsoft.com/en-us/azure/storage/blobs/data-lake-storage-access-control-model) and ACLs. You sign in to Entra ID, obtain a short-lived OpenSSH certificate signed for your account and present the certificate with its private key to the SFTP endpoint. No local user is required and none is used. Passwords are not supported with Entra ID. + +:::{important} +* Only **RSA** keys and certificates are supported. ECDSA and Ed25519 keys cannot be used. +* The certificate is valid for only **65 minutes**. Request a new certificate when it expires. +* Managed identities, a home directory and the container name in the username are not supported. +::: + +### Azure Portal + +1. Open the storage account and make sure **SFTP** is enabled as described [above](#enable-sftp). +2. To disable password and key access with local users, remove every local user: select **SFTP** under _Settings_, select the local users and choose **Delete**. Without local users the SFTP endpoint accepts only Entra ID certificates. +3. Grant the Entra ID user, group or service principal a data role on the storage account or the container. Select **Access Control (IAM) → Add → Add role assignment** and choose **Storage Blob Data Contributor** (read and write), **Storage Blob Data Owner** (additionally required to change ownership) or **Storage Blob Data Reader** (read only). On the _Members_ tab select the user. Role assignments can take a few minutes to apply. + +:::{note} +The permission *Storage Blob Data Contributor* is required even for the account owner. The Azure roles *Owner* or *Contributor* do not grant access to data. +::: + +### Obtain the Certificate + +Install the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) and sign in. + +1. Generate an RSA key pair in PEM format unless you already have one. Use the `-m PEM` option to create the private key in a format supported by Cyberduck. + ``` + ssh-keygen -m PEM -t rsa -b 4096 -f ~/.ssh/azure_sftp + ``` +2. Sign in to Entra ID. + ``` + az login + ``` +3. Request the certificate for the public key. Save the certificate next to the private key and suffixed with `-cert.pub`, the filename Cyberduck and Mountain Duck look for. + ``` + az sftp cert --public-key-file ~/.ssh/azure_sftp.pub --file ~/.ssh/azure_sftp-cert.pub + ``` + + On Windows, the equivalent with Azure PowerShell and the module [Az.Sftp](https://www.powershellgallery.com/packages/Az.Sftp) is + ``` + Connect-AzAccount + New-AzSftpCertificate -PublicKeyFile "$HOME\.ssh\azure_sftp.pub" -CertificatePath "$HOME\.ssh\azure_sftp-cert.pub" + ``` + +### Cyberduck or Mountain Duck + +1. Add a new [Bookmark](../cyberduck/bookmarks.md) or connection and choose **SFTP (SSH File Transfer Protocol)** with the following settings. + + | Field | Value | + |----------|-------------------------------------------------------| + | Server | `.blob.core.windows.net` | + | Username | `.` such as `contoso4.jdoe` | + + Use the username from the _Principals_ of the certificate **without** the domain. For the account `jdoe@example.com` the username is `jdoe`. For a service principal use its ID in place of the username. Do not add the container name. + + :::{tip} + The _Principals_ section lists the username to connect with and _Valid_ the expiration. + ``` + ssh-keygen -L -f ~/.ssh/azure_sftp-cert.pub + ``` + ::: + +2. In _SSH Private Key_ choose _Choose…_ and select the private key `~/.ssh/azure_sftp`. Leave _Password_ empty. The signed certificate `~/.ssh/azure_sftp-cert.pub` is picked up from the folder of the private key and sent to the server with the key. +3. Choose _Connect_. The root of the connection lists all containers you have access to. + +:::{warning} +The `CertificateFile` directive in `~/.ssh/config` is not supported. The certificate *must* reside next to the private key. Refer to [OpenSSH User Certificate Authentication](../protocols/sftp/index.md#openssh-user-certificate-authentication). +::: + +:::{tip} +After 65 minutes the certificate expires and the login fails with an authentication error. Repeat step 3 of [Obtain the Certificate](#obtain-the-certificate) to replace the file `azure_sftp-cert.pub`; the bookmark does not need to be changed. Reconnect open connections afterwards. +::: + +## Troubleshooting + +Verify the login with OpenSSH to inspect the reason for the failure. + +* For a local user, run +``` +sftp -v contoso4.sftpuser@contoso4.blob.core.windows.net +``` + +* For an Entra ID certificate, run +``` +sftp -v -o PubkeyAcceptedAlgorithms=rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-256 -o IdentityFile=~/.ssh/azure_sftp -o CertificateFile=~/.ssh/azure_sftp-cert.pub contoso4.jdoe@contoso4.blob.core.windows.net +``` + +## References + +- [SSH File Transfer Protocol (SFTP) in Azure Blob Storage](https://learn.microsoft.com/en-us/azure/storage/blobs/secure-file-transfer-protocol-support) +- [Enable or disable SFTP in Azure Blob Storage](https://learn.microsoft.com/en-us/azure/storage/blobs/secure-file-transfer-protocol-support-how-to) +- [Authorize SFTP access to Azure Blob Storage with local users](https://learn.microsoft.com/en-us/azure/storage/blobs/secure-file-transfer-protocol-support-authorize-access) +- [Authorize SFTP access to blobs using Microsoft Entra ID](https://learn.microsoft.com/en-us/azure/storage/blobs/secure-file-transfer-protocol-support-entra-id-based-access) +- [Connect to Azure Blob Storage from an SFTP client](https://learn.microsoft.com/en-us/azure/storage/blobs/secure-file-transfer-protocol-support-connect) From 142a0412560ba00b4c4e9d9411e1225f05895467 Mon Sep 17 00:00:00 2001 From: David Kocher Date: Tue, 13 Oct 2026 18:45:52 +0200 Subject: [PATCH 07/12] Document security key provider library configured by default on macOS only. --- protocols/sftp/index.md | 2 +- tutorials/sftp_publickeyauth_securitykey.md | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/protocols/sftp/index.md b/protocols/sftp/index.md index ca552184..89c5a380 100644 --- a/protocols/sftp/index.md +++ b/protocols/sftp/index.md @@ -130,7 +130,7 @@ Applies to SSH servers, which are configured with [`TrustedUserCAKeys`](https:// Keys of type `sk-ecdsa-sha2-nistp256@openssh.com` and `sk-ssh-ed25519@openssh.com` created with `ssh-keygen -t ecdsa-sk` respectively `ssh-keygen -t ed25519-sk` are supported. The private key of such a key never leaves the authenticator, which is either the Secure Enclave of a Mac unlocked with _Touch ID_ or a hardware token such as a _YubiKey_ touched to confirm. The key file selected in the [Bookmark](../../cyberduck/bookmarks.md) holds the credential handle only. -Signing a login is delegated to the middleware library of the authenticator, set with the [`SecurityKeyProvider`](#configuration-file) directive in `~/.ssh/config` or the [hidden configuration option](../../tutorials/hidden_properties.md) `ssh.authentication.securitykey.provider`. It defaults to `/usr/lib/ssh-keychain.dylib` for keys in the Secure Enclave on macOS. This library is not available on other platforms, where the directive or option must be set to the middleware library of the authenticator. Alternatively add the key to an [SSH agent](#public-key-authentication-using-ssh-agent) which then prompts to confirm the login. +Signing a login is delegated to the middleware library of the authenticator, set with the [`SecurityKeyProvider`](#configuration-file) directive in `~/.ssh/config`, the `SSH_SK_PROVIDER` environment variable or the [hidden configuration option](../../tutorials/hidden_properties.md) `ssh.authentication.securitykey.provider`. A value of the configuration directive beginning with `$` is read from the environment variable of that name. It defaults to `/usr/lib/ssh-keychain.dylib` for keys in the Secure Enclave on macOS. There is no default on other platforms, where OpenSSH talks to a token with built-in USB HID support instead of a library that could be loaded. Add the key to an [SSH agent](#public-key-authentication-using-ssh-agent) there, which prompts to confirm the login and works with any token supported by OpenSSH, or set the directive or option to a middleware library for the token. :::{important} The server must run _OpenSSH 8.2_ or later. Earlier versions do not know the `sk-*` key types and ignore the entry in `authorized_keys`. diff --git a/tutorials/sftp_publickeyauth_securitykey.md b/tutorials/sftp_publickeyauth_securitykey.md index c9b6bccf..32b95ae9 100644 --- a/tutorials/sftp_publickeyauth_securitykey.md +++ b/tutorials/sftp_publickeyauth_securitykey.md @@ -10,6 +10,10 @@ Configure Public Key Authentication for SFTP using a FIDO2 Security Key The key file in `~/.ssh` holds a reference to the credential on the authenticator but no private key. Signing a login is therefore delegated either to a _security key provider_ library talking to the authenticator or to an [SSH agent](#let-an-ssh-agent-handle-the-security-key) holding the key. +:::{note} +A security key provider library is configured by default on macOS only, serving keys in the Secure Enclave. On Windows and Linux OpenSSH talks to a token with built-in USB HID support instead of a library, which Cyberduck cannot load. Leave the key to an [SSH agent](#let-an-ssh-agent-handle-the-security-key) there, or set `SecurityKeyProvider` to a middleware library for your token. +::: + :::{important} The server must run _OpenSSH 8.2_ or later. Earlier versions do not know the `sk-*` key types and ignore the entry in `authorized_keys`. Verify the version of the server with `ssh -v user@remotehost` and look for the line `remote software version`. ::: @@ -67,7 +71,7 @@ The server must run _OpenSSH 8.2_ or later. Earlier versions do not know the `sk ::: :::{note} - If `ssh-keygen` reports it cannot find a library to use the security key, install [libfido2](https://github.com/Yubico/libfido2) with `brew install libfido2` and repeat the command with the option `-w /opt/homebrew/lib/libsk-libfido2.dylib`. + `ssh-keygen` talks to the token with the USB HID support built into OpenSSH. No middleware library is required to create the key. Pass `-w ` only to use a middleware library of your own instead. ::: 2. Add the public key to the `authorized_keys` in your `~/.ssh` directory on the server running OpenSSH. @@ -75,13 +79,17 @@ The server must run _OpenSSH 8.2_ or later. Earlier versions do not know the `sk ssh-copy-id -fi ~/.ssh/id_ed25519_sk.pub user@remotehost ``` -3. Refer to the middleware library of the token in your OpenSSH configuration file `~/.ssh/config` when it is not the default `/usr/lib/ssh-keychain.dylib` used for keys in the Secure Enclave. +3. Refer to the middleware library for the token in your OpenSSH configuration file `~/.ssh/config`. The default `/usr/lib/ssh-keychain.dylib` set on macOS serves keys in the Secure Enclave only. ``` Host * - SecurityKeyProvider /opt/homebrew/lib/libsk-libfido2.dylib + SecurityKeyProvider /path/to/middleware.so ``` - This [configuration](https://docs.cyberduck.io/protocols/sftp/#openssh-configuration-interoperability) directive is supported by Cyberduck and Mountain Duck. Alternatively set the [hidden configuration option](hidden_properties.md) `ssh.authentication.securitykey.provider` to the path of the library. + This [configuration](https://docs.cyberduck.io/protocols/sftp/#openssh-configuration-interoperability) directive is supported by Cyberduck and Mountain Duck. A value beginning with `$` is read from the environment variable of that name. Alternatively set the [hidden configuration option](hidden_properties.md) `ssh.authentication.securitykey.provider` to the path of the library. + + :::{important} + The USB HID support built into OpenSSH is not a library and cannot be loaded. Unless the token comes with a middleware library implementing the OpenSSH security key API, leave the security key to an [SSH agent](#let-an-ssh-agent-handle-the-security-key) instead, which works with any token supported by OpenSSH. + ::: 4. In the [Bookmark](../cyberduck/bookmarks.md) or [Connection](../cyberduck/connection.md) window, in _SSH Private Key_ select `id_ed25519_sk` in your `~/.ssh` directory. @@ -121,7 +129,7 @@ Other SSH agents manage keys of their own instead of a credential on a security ## Troubleshooting :::{warning} -When the connection fails with the message _Add the security key … to the SSH authentication agent_, the middleware library of the authenticator could not be loaded. Verify the path set with `SecurityKeyProvider` or add the key to an SSH agent instead. +When the connection fails with the message _No security key provider configured_, no middleware library is set for your platform. A library is configured by default on macOS only. Set `SecurityKeyProvider` in `~/.ssh/config` or add the key to an SSH agent instead. A failure naming the library instead means it could not be loaded, in which case verify the path. ::: :::{warning} From eccc30174be3a545ccde2913eb65e00e6d7cf435 Mon Sep 17 00:00:00 2001 From: David Kocher Date: Sun, 25 Oct 2026 12:02:34 +0100 Subject: [PATCH 08/12] Fix requirements. --- tutorials/sftp_azure_blob_storage.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorials/sftp_azure_blob_storage.md b/tutorials/sftp_azure_blob_storage.md index 9ca23cf3..d5b2f232 100644 --- a/tutorials/sftp_azure_blob_storage.md +++ b/tutorials/sftp_azure_blob_storage.md @@ -6,8 +6,8 @@ Connect to Azure Blob Storage with SFTP :::{admonition} Authentication with an SSH certificate :class: important -- Cyberduck [8.9.0](https://cyberduck.io/changelog/) or later required -- Mountain Duck [4.16.0](https://mountainduck.io/changelog/) or later required +- Cyberduck [9.6.0](https://cyberduck.io/changelog/) or later required +- Mountain Duck [5.4.0](https://mountainduck.io/changelog/) or later required ::: ## Prerequisites From f743e53c720c0cdd84a9887185bd8e14e88cbcce Mon Sep 17 00:00:00 2001 From: David Kocher Date: Tue, 27 Oct 2026 14:52:27 +0100 Subject: [PATCH 09/12] Note empty PIN prompt when writing key file for Secure Enclave. --- tutorials/sftp_publickeyauth_securitykey.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tutorials/sftp_publickeyauth_securitykey.md b/tutorials/sftp_publickeyauth_securitykey.md index 32b95ae9..ddc058d9 100644 --- a/tutorials/sftp_publickeyauth_securitykey.md +++ b/tutorials/sftp_publickeyauth_securitykey.md @@ -37,6 +37,10 @@ The server must run _OpenSSH 8.2_ or later. Earlier versions do not know the `sk cd ~/.ssh && ssh-keygen -w /usr/lib/ssh-keychain.dylib -K ``` + :::{note} + When prompted with `Enter PIN for authenticator:`, press _Enter_ to leave the PIN empty. A key in the Secure Enclave has no PIN and is protected by _Touch ID_ instead. The prompt is shown by OpenSSH for any authenticator. + ::: + This writes `id_ecdsa_sk_rk` and `id_ecdsa_sk_rk.pub`. Repeat the command with `-K` whenever you need the files again on another Mac with access to the same identity. 3. Add the public key to the `authorized_keys` in your `~/.ssh` directory on the server running OpenSSH. From c333c817ecbb6689c911d0f5b55a3ba665f7e852 Mon Sep 17 00:00:00 2001 From: David Kocher Date: Wed, 28 Oct 2026 12:58:27 +0100 Subject: [PATCH 10/12] Add tip for `openssh` configuration. --- tutorials/sftp_publickeyauth_securitykey.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tutorials/sftp_publickeyauth_securitykey.md b/tutorials/sftp_publickeyauth_securitykey.md index ddc058d9..4c7150e9 100644 --- a/tutorials/sftp_publickeyauth_securitykey.md +++ b/tutorials/sftp_publickeyauth_securitykey.md @@ -53,6 +53,17 @@ The server must run _OpenSSH 8.2_ or later. Earlier versions do not know the `sk ssh -o SecurityKeyProvider=/usr/lib/ssh-keychain.dylib -i ~/.ssh/id_ecdsa_sk_rk user@remotehost ``` + :::{tip} + Set the provider in `~/.ssh/config` to omit the `-o` option and the `-i` option. + ``` + Host remotehost + User user + IdentityFile ~/.ssh/id_ecdsa_sk_rk + SecurityKeyProvider /usr/lib/ssh-keychain.dylib + ``` + Cyberduck and Mountain Duck use `/usr/lib/ssh-keychain.dylib` by default on macOS and do not require this directive. + ::: + 5. In the [Bookmark](../cyberduck/bookmarks.md) or [Connection](../cyberduck/connection.md) window, in _SSH Private Key_ select `id_ecdsa_sk_rk` in your `~/.ssh` directory. You do **not** need to set a value for _Password_. 6. Connect to the server and confirm the prompt with _Touch ID_ to allow the Secure Enclave to sign the login. From e2b0c3fd7a25bc43812655ff6aa72c4f079c4d66 Mon Sep 17 00:00:00 2001 From: David Kocher Date: Sat, 7 Nov 2026 15:55:23 +0100 Subject: [PATCH 11/12] Update requirements. --- tutorials/sftp_kerberos.md | 2 +- tutorials/sftp_publickeyauth_pkcs11.md | 2 +- tutorials/sftp_publickeyauth_securitykey.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tutorials/sftp_kerberos.md b/tutorials/sftp_kerberos.md index 8fbe8843..2e56d8ba 100644 --- a/tutorials/sftp_kerberos.md +++ b/tutorials/sftp_kerberos.md @@ -4,7 +4,7 @@ Configure Kerberos Authentication for SFTP > Authentication with _Kerberos_ allows you to connect to a remote server without a password using the ticket you already obtained when logging in to your organization's realm with `kinit` or with your account on the Mac. The ticket is presented to the server using the SSH authentication method `gssapi-with-mic`, the equivalent of `ssh -o GSSAPIAuthentication=yes`. :::{important} -* Cyberduck [9.6.0](https://cyberduck.io/changelog/) or later required +* Cyberduck [9.7.0](https://cyberduck.io/changelog/) or later required * Mountain Duck [6.0.0](https://mountainduck.io/changelog/) or later required ::: diff --git a/tutorials/sftp_publickeyauth_pkcs11.md b/tutorials/sftp_publickeyauth_pkcs11.md index e43612e6..2794288d 100644 --- a/tutorials/sftp_publickeyauth_pkcs11.md +++ b/tutorials/sftp_publickeyauth_pkcs11.md @@ -4,7 +4,7 @@ Configure Public Key Authentication for SFTP using a PKCS#11 Smartcard > Public-key authentication with a smartcard allows you to connect to a remote server without a password. The private key is kept on the card and never leaves it. A _PKCS#11_ module, the native library shipped with the driver of your card, is used to read the public keys from the card and to sign the login with the corresponding private key protected by a PIN. This is the equivalent of `ssh -I /path/to/module.so`. :::{important} -* Cyberduck [9.6.0](https://cyberduck.io/changelog/) or later required +* Cyberduck [9.7.0](https://cyberduck.io/changelog/) or later required * Mountain Duck [6.0.0](https://mountainduck.io/changelog/) or later required ::: diff --git a/tutorials/sftp_publickeyauth_securitykey.md b/tutorials/sftp_publickeyauth_securitykey.md index 4c7150e9..8589dca7 100644 --- a/tutorials/sftp_publickeyauth_securitykey.md +++ b/tutorials/sftp_publickeyauth_securitykey.md @@ -4,7 +4,7 @@ Configure Public Key Authentication for SFTP using a FIDO2 Security Key > Public-key authentication with a _FIDO2_ security key allows you to connect to a remote server without a password. The private key never leaves the authenticator, which is either the Secure Enclave of your Mac unlocked with _Touch ID_ or a hardware token such as a _YubiKey_ you touch to confirm. OpenSSH calls these keys `sk-ecdsa-sha2-nistp256@openssh.com` and `sk-ssh-ed25519@openssh.com`. :::{important} -* Cyberduck [9.6.0](https://cyberduck.io/changelog/) or later required +* Cyberduck [9.7.0](https://cyberduck.io/changelog/) or later required * Mountain Duck [6.0.0](https://mountainduck.io/changelog/) or later required ::: From 6d444a0543a75522772e7b7c6e1e33c92ab247a4 Mon Sep 17 00:00:00 2001 From: David Kocher Date: Sun, 8 Nov 2026 16:39:42 +0100 Subject: [PATCH 12/12] Delete requirements. --- protocols/sftp/index.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/protocols/sftp/index.md b/protocols/sftp/index.md index 89c5a380..a947f0c5 100644 --- a/protocols/sftp/index.md +++ b/protocols/sftp/index.md @@ -115,11 +115,6 @@ OpenSSH private keys of type `rsa`, `dsa`, `ecdsa` and `ed25519` (in OpenSSL `PE ##### OpenSSH User Certificate Authentication -:::{important} -* Cyberduck [8.9.0](https://cyberduck.io/changelog/) or later required -* Mountain Duck [4.16.0](https://mountainduck.io/changelog/) or later required -::: - Applies to SSH servers, which are configured with [`TrustedUserCAKeys`](https://man.openbsd.org/sshd_config#TrustedUserCAKeys), refer to your software vendor for configuration. To configure authentication with a User CA signed private key, configure the private key as described in [Configure Public Key Authentication](#public-key-authentication) step 3. The signed public key file _must_ reside next to the private key file, suffixed `-cert.pub` or `.pub`. The [`CertificateFile`](https://man.openbsd.org/ssh_config#CertificateFile) configuration directive in `~/.ssh/config` is not supported. Pay attention to the server configuration and [`PubkeyAcceptedAlgorithms`](https://man.openbsd.org/sshd_config#PubkeyAcceptedAlgorithms) specifically which determines the allowed private key algorithms to authenticate with. #### Security Key (FIDO2) Authentication