cloudflare / cloudflared

Cloudflare Tunnel client (formerly Argo Tunnel)
https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide
Apache License 2.0
9.28k stars 823 forks source link

Support user SSH keys for authentication #319

Open mbainter opened 3 years ago

mbainter commented 3 years ago

If I understand what I've seen so far correctly it appears that cloudflared only works with its own keypair. I would like to suggest supporting user keypairs. In particular, I'd like to see support for keypairs where the private key is stored on a hardware device (like a Yubikey). Instead of signing the internally generated key, you'd instead provide a short-lived certificate for the yubikey's public key, and then that certificate would be used to authenticate.

For an example of how this works, see Pritunl Zero's implementation.

TownLake commented 3 years ago

Thanks for the request; we'll review it on our side.

gcochard commented 2 years ago

A hardware backed rsa, ecdsa or ed25519 key should be easy to implement as long as the yubikey can generate the public key in standard openssh format. You can send a request to the cloudflare access cert signing endpoint with any public key you'd like, I've done this via the following:

curl https://${subdomain}.cloudflareaccess.com/cdn-cgi/access/cert_sign \
-H 'content-type: application/json' \
-d '{"issuer":"https://${subdomain}.cloudflareaccess.com",
"jwt":"<contents of ~/.cloudflared/$host-$uuid-token>",
"public_key":"<any rsa/ecdsa/ed25519 public key>"}'

{"id":"<jwt filename uuid>",
"certificate":"ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlz...",
"expires_at":"2022-05-05T19:23:48.299333798Z"}

Once you generate the cloudflared access config, you can just swap out the cloudflare-generated public key for the yubikey-backed public key, run cloudflared access ssh-config --hostname $host --short-lived-cert, add that output to your ~/.ssh/config and modify the IdentityFile line to point to the yubikey's public key instead, and it will just work.


I'd like to add to this: with the release of openssh 8.2, they added direct support for fido ssh keys, in the ecdsa-sk and ed25519-sk formats. The golang ssh library already supports these formats along with their certificate analogs, however when making a cert signing request with an ecdsa-sk formatted key, I am getting a 500 from cloudflare access.

<h2>Internal Server Error</h2>
<p>An internal issue is preventing us from connecting you to a protected site. 
This error has generated an alert for our team to start reviewing the issue. 
Check the <a href="https://www.cloudflarestatus.com/">Cloudflare status page</a> for more info.</p>

I'm guessing the server-side code has an allow-list but has not explicitly allowed-listed these key types.

milindpatel63 commented 2 years ago

I don't know if this is the right place for my issue. I can successfully connect using my own generated ssh key pair via cloudflare access using command line. But the browser rendered ssh page always gives error if I use my private key with it.

It says "Wrong passphrase or invalid/unrecognized private key file format".

Even though, it's the same private key that I am using via the command line.

It's "ED25519" type key with a password. Does browser rendered ssh support this?

milindpatel63 commented 2 years ago

I don't know if this is the right place for my issue. I can successfully connect using my own generated ssh key pair via cloudflare access using command line. But the browser rendered ssh page always gives error if I use my private key with it.

It says "Wrong passphrase or invalid/unrecognized private key file format".

Even though, it's the same private key that I am using via the command line.

It's "ED25519" type key with a password. Does browser rendered ssh support this?

Turn's out, the web rendered ssh doesn't support "ed25519" WITH "password" keys. "ed25519" without password works fine. And also "ECDSA" and "RSA" WITH "password" also works fine.

arnavpraneet commented 1 year ago

Hey, any update on this @milindpatel63? Currently ed25519 keys without password not working for me, nor is RSA with password or without on the CloudFlare Web Terminal

demiGod095 commented 1 year ago

ed25519 WITHOUT password not working for me either. It just says "Wrong passphrase or invalid/unrecognized private key file format"

kevintwingstrom commented 1 year ago

Following. Same issue as @milindpatel63.

gainskills commented 12 months ago

to the error: Wrong passphrase or invalid/unrecognized private key file format ED25519 with/without passphrase works to me

  1. generate the key: ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519 -C ""
  2. update sshd_config sudo vi /etc/ssh/sshd_config
PubkeyAuthentication yes

# Expect .ssh/authorized_keys2 to be disregarded by default in future.
AuthorizedKeysFile     /home/%u/.ssh/id_ed25519.pub
  1. restart sshd service sudo systemctl restart sshd

I also executed the command ssh-add ~/.ssh/id_ed25519 but don't think it pull the trigger.


note: the key which is generated by ssh-keygen -t rsa -b 4096 doesn't work

mbainter commented 12 months ago

What you're doing there @gainskills is just authorzing ssh via that key directly on a permanent basis, that is not what I'm after. What I want is to still authorize based on short-lived certificates signed by Cloudflare, but I want to sign the user-provided cert, not one generated automatically by cloudflare.

gcoshard's solution is a DIY implementation of that, for reference.

gainskills commented 12 months ago

What you're doing there @gainskills is just authorzing ssh via that key directly on a permanent basis, that is not what I'm after. What I want is to still authorize based on short-lived certificates signed by Cloudflare, but I want to sign the user-provided cert, not one generated automatically by cloudflare.

gcoshard's solution is a DIY implementation of that, for reference.

got u. My one is to the error: Wrong passphrase or invalid/unrecognized private key file format