Cannot create upstream when client has multiple key pairs
Hi! I just saw this project today and wanted to try it out to reverse proxy my SSH servers. When using public key authentication, the server errors out if the incorrect private key is used by the client. I believe the normal behaviour seen in openssh server is either a "permission denied (publickey)" or allow the client to retry with a different key. Is there some kind of configuration I can use/enable to allow the normal behaviour?
Here is my YAML file
version: "1.0"
pipes:
- from:
- username: "user"
authorized_keys: /home/user/sshpiper/keys/authorized_c1
to:
host: 127.0.0.1:5522
username: "user"
password: "pass"
ignore_hostkey: true
- from:
- username: "user2"
authorized_keys: /home/user/sshpiper/keys/authorized_c2
to:
host: 127.0.0.1:5422
username: "user2"
password: "pass"
ignore_hostkey: true
and here is the command I used
./out/sshpiperd -i /tmp/sshpiperkey --server-key-generate-mode notexist --log-level=trace ./out/yaml --config config.yaml --no-check-perm
Thank you so much for this project by the way, it is the only functional SSH reverse proxy I've come across
server here is unclear
I believe you are looking for mapping something to key auth to upstream (real sshd)
to:
private_key: /path/to/host-publickey/id_rsa
reason TL;DR https://github.com/tg123/sshpiper?tab=readme-ov-file#public-key-authentication-when-using-sshpiper-private-key-remapping
I am currently attempting to have downstream connect to sshpiper via key auth, and sshpiper to upstream using password auth. Currently, a working configuration (please correct me if I'm missing something important) requires me to enable ignore_hostkey in the yaml and the --no-check-perm flag.
On my local machine, I have multiple SSH keys, and normally when connecting to an OpenSSH server my client can retry with a different key until either all keys have been tried or it succeeds. Under my current configuration, if the initial offered key matches, the connection works, but if the initial key offered does not match, my client hangs and sshpiper's logs are spammed with
ERRO[0136] cannot create upstream for mydownstreamip (username [user]) with public key auth: rpc error: code = Unknown desc = no matching pipe for username [user] found
if I remove the ignore_hostkey option in the yaml file, I get a Permission denied (publickey) response if the key matches, and the same issue as above if the key doesn't match.
if I remove --no-check-perm flag, I get a config.yaml's perm is too open error in sshpiper even though the configuration seems to be correct from the examples.
Thanks!
i assume you are running
ssh user@xxx -i key
could you please confirm if key.pub in /home/user/sshpiper/keys/authorized_c1
sshpiper will treat user as not matched if key.pub not found in authorized_keys
Yes, the public key is in /home/user/sshpiper/keys/authorized_c1. However, I have multiple key pairs on my machine so, for example, if the public key in that file is the second key pair on my device, and my SSH client offers the first one initially, then sshpiper spams the log and my client hangs (as opposed to normal ssh server where my client retries with second key). In this case, I must manually specify which key my client must use with the -i option, as opposed to just ssh user@xxx
Here is the version:
sshpiperd version (devel), 38be0fdd8, 2024-05-18T09:51:39Z, go1.22.3
built directly from master branch
got it, could you please test if last know stable v1.2.8 good for your case
also i am working on a fix to it
I just tried stable v1.2.8, I get Permission denied (publickey) if I don't specify which key client should use (as opposed to hanging + spamming logs from before). I'm still forced to use --no-check-perm and ignore-hostkey: true to make it work.
will support multiple key
--no-check-perm: you need to set yaml to 400 (chmod 400 xxx.yaml)
ignore-hostkey: true: to have secure connection, need to put upstream hostkey.pub to known_hosts_data
ah 600 is good too
see code here https://github.com/tg123/sshpiper/blob/38be0fdd814aa22486c3197fbba8577dfb3be3a9/plugin/yaml/yaml.go#L78
Thanks, setting 600 worked. As for known_hosts, I tried adding known_hosts and putting the public key in the file, and I also tried base64 encoding the public key and adding it inline as known_hosts_data, but I still get Permission denied (publickey) on downstream client side
(I pulled the SSH host public key from /etc/ssh/ssh_host_ed25519_key.pub, if that's what I'm supposed to use)
the known_hosts_data here is for sshpiper to verify upstream (real sshd)
if ignore-hostkey: true works, then you are putting wrong key
I feel like I'm doing things right, correct me if I did anything wrong:
- on upstream machine, I updated sshd to use
/etc/ssh/ssh_host_rsa_key(the autogenerated one), and copied the corresponding public key (ssh_host_rsa_key.pub) tosshpiper's directory - on sshpiper's machine, in
config.yaml, I added the path tossh_host_rsa_key.pubunderknown_hosts: /home/ubuntu/sshpiper/ssh_host_rsa_key.pub
Nevermind fixed it, I looked at the known hosts parsing and it needs to contain the host IP as well in addition to pubkey
hi @ApocalypseCalculator
i added testcase cover your scenario in #396
seems ssh client worked well (current sshpiper master 6fe67e3, with ssh client OpenSSH_9.2p1 Debian-2+deb12u2, OpenSSL 3.0.11 19 Sep 2023)
could you please review the testcase?
using multiple keyfile, first wrong, second right
ssh -v -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 33803 -l publickey_simple -i /tmp/3823507707/key -i /tmp/4237723506/id_rsa_simple
logs
debug1: Next authentication method: publickey
DEBU[0001] downstream 127.0.0.1:46118 (username [publickey_simple]) is sending public key auth
debug1: Offering public key: /tmp/3823507707/key RSA SHA256:wrUs0Z/BBZCbkp6ANbU4DlaNkld85eIDbCk2H0wFI9I explicit
ERRO[0001] cannot create upstream for 127.0.0.1:46118 (username [publickey_simple]) with public key auth: rpc error: code = Unknown desc = no matching pipe for username [publickey_simple] found
DEBU[0001] next auth methods [password publickey] for downstream 127.0.0.1:46118 (username [publickey_simple])
debug1: Authentications that can continue: password,publickey
debug1: Offering public key: /tmp/4237723506/id_rsa_simple RSA SHA256:BT5nRpf60kdFVV6fzDEvm0hYhmVx9wAHkT/Qk8MkOlg explicit
DEBU[0001] downstream 127.0.0.1:46118 (username [publickey_simple]) is sending public key auth
DEBU[0001] connecting to upstream 172.19.0.6:2222 with auth [privatekey]
debug1: Server accepts key: /tmp/4237723506/id_rsa_simple RSA SHA256:BT5nRpf60kdFVV6fzDEvm0hYhmVx9wAHkT/Qk8MkOlg explicit
Authenticated to 127.0.0.1 ([127.0.0.1]:33803) using "publickey".
Nice! It works 👍