Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'wezterm ssh': Allow ssh options (like identity file) and reading .ssh/config #457

Closed
bew opened this issue Feb 5, 2021 · 16 comments
Closed
Assignees
Labels
enhancement New feature or request fixed-in-nightly This is (or is assumed to be) fixed in the nightly builds. ssh

Comments

@bew
Copy link
Contributor

bew commented Feb 5, 2021

Hello @wez!

Is your feature request related to a problem? Please describe.
I need to connect to a remote server using an ssh key, with the builtin ssh client (I'm on windows now).

Describe the solution you'd like
Allow: wezterm ssh -i /foo/bar user@host

What about passing arbitrary arguments? do you need to re-implement all the standard ssh options? or can you pass them (with something like --extra-ssh-arg -i ... or an env variable) to libssh2 for consumption?

Describe alternatives you've considered
none?

@bew bew added the enhancement New feature or request label Feb 5, 2021
@bew bew changed the title All -i <ssh_key_path> for 'wezterm ssh' Allow -i <ssh_key_path> for 'wezterm ssh' Feb 5, 2021
@wez
Copy link
Owner

wez commented Feb 5, 2021

Note that the integrated ssh support is based on libssh2 which doesn't have command line options the same as openssh (it's a library, so there are no command line options!) so it's not quite as simple as passing a list of extra arguments; each of them needs proper config and/or argument definitions and those need to be hooked up to the ssh session construction.

Until something like this is hooked up: If you're on a system with openssh installed, you can do: wezterm start -- ssh -i /foo/bar user@host to achieve the same end goal, but it won't involve the built-in ssh client.

@bew
Copy link
Contributor Author

bew commented Feb 5, 2021

Note that the integrated ssh support is based on libssh2 which doesn't have command line options the same as openssh (it's a library, so there are no command line options!) so it's not quite as simple as passing a list of extra arguments; each of them needs proper config and/or argument definitions and those need to be hooked up to the ssh session construction.

Argh, that's what I thought..

Until something like this is hooked up: If you're on a system with openssh installed, you can do: wezterm start -- ssh -i /foo/bar user@host to achieve the same end goal, but it won't involve the built-in ssh client.

In my case I can't, I'm using Windows (I finally have a recent version so I can use Wezterm on it \o/), I know mouse support isn't great because of microsoft/terminal#376, and have found your commit (127b2a5) adding the builtin ssh command to solve this for remote systems (if I understood correctly?).

@wez
Copy link
Owner

wez commented Feb 5, 2021

re: windows + mouse, wezterm ships a special build of openconsole.exe and conpty.dll that allows mouse to work; I use it with wsl running vim when I'm developing wezterm on windows.

@wez
Copy link
Owner

wez commented Feb 6, 2021

If you (or someone else!) feels motivated to hook this up, here's the general approach:

The mux crate has an async_ssh_connect function that currently accepts the host/port and username.
That info gets passed down through to ssh_connect_with_ui which then creates an ssh2::Session.

I'd propose introducing a struct something like:

pub struct SshConnectOptions {
   pub remote_address: String,
   pub username: String,
   pub pubkey_file: Option<PathBuf>,
}

to replace the remote_address and username parameters that are currently passed down, and instead pass SshConnectOptions.

Then in ssh_connect_with_ui, pull the values from the struct instead.

You can use Session::userauth_pubkey_file to set the key path.

Then on the other side of this, is teaching the rest of the code to set up that struct; these two places should be expanded to allow specifying the key file:

Then it's just a matter of taking those values and setting them into the newly added SshConnectOptions in the mux crate.

@wez wez added the PR-welcome Wez doesn't have plans to work on this, but will accept a PR if someone feels motivated! label Feb 6, 2021
@bew
Copy link
Contributor Author

bew commented Feb 7, 2021

Thanks a lot for the walk-through! I might try to do it next week

Tiny note: I think it shouldn't be pubkey_file in the struct, but private_key_file, the public key doesn't have to be known.

(I don't need this, but I'm speculating)
How would it work if the mux server is not on the local machine, would there need to be a file transfer to the mux so it an be used there?

@wez
Copy link
Owner

wez commented Feb 7, 2021

How would it work if the mux server is not on the local machine, would there need to be a file transfer to the mux so it an be used there?

If the mux server is on a different machine, then it will read a config on a remote machine.
If ssh is being used to bootstrap a connection to a remote mux server, then that ssh connection will be from the local machine to the remote machine and thus can access the local ssh key.
In short, I don't think there is a scenario where the local ssh options get forwarded to a remote mux and where we might run into that!

@bew
Copy link
Contributor Author

bew commented Mar 23, 2021

Something that could be interesting as well is to be able to read the file ~/.ssh/config and use the options defined there.

I've checked, libssh2 doesn't support this, but libssh does with the function ssh_options_parse_config (https://api.libssh.org/master/group__libssh__session.html#ga82371e723260c7572ea061edecc2e9f1)

Do you know about that other lib, did you tried it already?

@wez
Copy link
Owner

wez commented Mar 23, 2021

So, ssh is a complicated mess:

  • libssh2 seems broken on Windows 10 (I can't connect from my win10 box to my fedora box any more)
  • there's something potentially relatedly funky going on with win/linux: cross platform ssh session not working #507
  • libssh is something I'm looking at at work. It doesn't support reading all of the options from the ~/.ssh/config file
  • I have a local wezterm branch intended to make libssh2 work nicely async, but given the windows compat issues, I'm not sure if I should continue with that, or do something to get the libssh based stuff we're doing at work opensourced (timeline for that is a big unknown)
  • I also looked at thrussh, a pure rust ssh client/server implementation. It's hosted on pijul which is always down AFAICT, but I've been able to download the published crates and poke around. It has poor Windows support. I wouldn't mind contributing, but the service is always down :-/
  • In my local branch, I made a new crate that can parse the ~/.ssh/config file directly. I think that's fine to get pushed up to the main wezterm branch and use it as an additional data source for client options.

I still don't feel like the overall state of ssh clients in rust is great and that it would be good to do something to fix it :-/

wez added a commit that referenced this issue Mar 23, 2021
@wez
Copy link
Owner

wez commented Mar 23, 2021

I pushed the ssh config parser crate. If you wanted to apply it to this, then the steps are something like:

let mut ssh_config = wezterm_ssh::config::Config::new();
ssh_config.add_default_config_files();
let ssh_config = ssh_config.for_host(hostname_or_alias);
// Look up "IdentityFile" option for that host. Note that you must use
// the option name in lowercase
let key_file = ssh_config.get("identityfile")?;

// Do something here to apply that to the libssh2 session

@wez wez removed the PR-welcome Wez doesn't have plans to work on this, but will accept a PR if someone feels motivated! label Mar 27, 2021
@wez wez self-assigned this Mar 27, 2021
wez added a commit that referenced this issue Mar 28, 2021
I can't get this to succeed though; I suspect there may be a lingering
bug from libssh2 and/or trailing support for newer openssh features.

refs: #457
wez added a commit that referenced this issue Mar 28, 2021
There are a few notable changes as a result:

* A number of `.ssh/config` options are now respected; host matching
  and aliasing and identity file are the main things
* The authentication prompt is inline in the window, rather than
  popping up a separate authentication window

Refs: #457
@wez wez added the ssh label Mar 28, 2021
wez added a commit that referenced this issue Mar 28, 2021
Allow overriding ssh config options from the command line.

I don't want to replicate the many options that `ssh(1)` has;
this just exposes the `-oNAME=VALUE` syntax.  The config names
are those from `man ssh_config`; `IdentityFile` rather than `-i`.

refs: #457
@wez wez added the fixed-in-nightly This is (or is assumed to be) fixed in the nightly builds. label Mar 28, 2021
@xanderificnl
Copy link

Hi. I bumped into (almost) the same issue except I'm authenticating via Kerberos/GSSAPI. The workaround (wezterm start -- ssh) doesn't work for new tabs. I don't mean to hijack this thread, but the issue is in effect similar.

Are there plans for (optional) integration with openssh-client, so that GSSAPI works & $HOME/.ssh/config is used?

@wez
Copy link
Owner

wez commented Mar 28, 2021

@web-refinery:
There are no plans for gssapi support; the underlying libssh2 library doesn't support it.
Nightly builds do have support for reading options from .ssh/config though.

You can use wezterm start ssh somewhere to spawn a window running the openssh client, and create a launch menu item:

return {
  launch_menu = {
    {
      label = "ssh somewhere",
      args = {"ssh", "somewhere"},
      domain = {DomainName="local"},
    },
  }
}

or make an explicit key binding: https://wezfurlong.org/wezterm/config/lua/keyassignment/SpawnTab.html

@xanderificnl
Copy link

Thanks, wezterm's full of options that keep surprising me.

@bew
Copy link
Contributor Author

bew commented Mar 29, 2021

New ssh login works, the login in the same window is clearly a better UX!
I didn't test loading configs from ~/.ssh/config though. (using user/passwd in the meantime)

However I've noticed that after I'm connected to a machine, my first key input is eaten, so if I connect successfully and type abc, only bc reaches the server.

@bew bew changed the title Allow -i <ssh_key_path> for 'wezterm ssh' 'wezterm ssh': Allow ssh options (like identity file) and reading .ssh/config Mar 29, 2021
@wez
Copy link
Owner

wez commented Mar 29, 2021

I can't reproduce the input eating when connecting to localhost, both with agent auth (no need to type anything) and with pubkey auth (need to enter my key passphrase). Can you tell me more about the scenario where that triggers for you?

@wez
Copy link
Owner

wez commented Apr 3, 2021

I'm going to close this one; can you open a new issue for input eating that you saw? I feel like that may be a slightly different issue, but either way I think it will be easier for me to manage separately from this one!

@wez wez closed this as completed Apr 3, 2021
@github-actions
Copy link
Contributor

github-actions bot commented Feb 4, 2023

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 4, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request fixed-in-nightly This is (or is assumed to be) fixed in the nightly builds. ssh
Projects
None yet
Development

No branches or pull requests

3 participants