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

sshtunnel: support Dropbear #21263

Closed
wants to merge 9 commits into from
Closed

sshtunnel: support Dropbear #21263

wants to merge 9 commits into from

Conversation

stokito
Copy link
Contributor

@stokito stokito commented Jun 3, 2023

Maintainer: @nunojpg

Compile tested: OpenWrt 23
Run tested: tested in VirtualBox, works fine with OpenSSH server on Turris

Description:
The sshtunnel use the openssh-client which is quite big. The Dropbear can do the job.
Few years ago I already asked @nunojpg if it's possible to use the plain dbclient:

I think you are underestimating the amount of differences between openssh and dropbear. It will have a lot of different corner effects. Since this can be a remote access critical tool, testing for a major change like that would never be enough and in months or years we would be finding issues.

I don't see a reasonable way to make such change.

But the dropbear anyway is used today for sshtunnels so for those users it anyway makes sense to support it by the sshtunnel.

From the line we see what options are used:

ARGS="$ARGS_options -o ExitOnForwardFailure=yes -o BatchMode=yes -nN $ARGS_tunnels -p $port $user@$hostname"

Some ags are not supported by dropbear client:

  • Flag -n to disable stdin
  • Option BatchMode

The -n arguments seems unnecessary. We can leave it as is because the dbclient will just ignore unknown flags and options.

The BatchMode is not necessary because the tunnel works only by keys in non-interactive mode. Basically we have two interactions: ask to accept the host key on first setup and also a possible password prompt if the key auth failed.
I checked and with the dbclient when the password is asked it will just fail without hanging.
For the host key confirmation user should connect manually first but this makes not possible to configure the sshtunnel from GUI.
So I made the StrictHostKeyChecking=accept-new by default and this should solve the problem.

UPD mkj/dropbear#224

Please see commit comments for details.

I removed the openssh-client from dependencies. All existing users anyway have it installed so they shouldn't be affected on update.

On the wiki page I'll add a note to install the openssh-client for those who may need it. Also I'll mark all options that aren't supported by the dbclient.

If you feel bad about removing the dependency then I can drop the last two commits. Users may uninstal the openssh-client themselves after installation to use the plain dbclient.

I have a plan to add a luci-app for the sshtunnel. With the UI user should be able to generate a keypair because it's not so trivial. But also it should detect which ssh client is installed and hide extended options if they are not supported by the dbclient.

Also I'll send a letter to Dropbear author to ask to support the StrictHostKeyChecking option out of the box. UPD mkj/dropbear#226

See also luci-app-sshtunnel

Simplify comment and make it shorter.
Remove triling tab after retrydelay.
Use a full path for IdentityFile because otherwise the uci validation fails with the relative path ~/.ssh

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
Without the option the ssh will propt a user to accept the host key.
So a user should perform a connection manualy and accept before useing the sshtunnel.
The accept-new is a reasonable trade off.

Also the LogLevel is INFO by default.

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
This makes the sshtunnel compatible with Dropbear.

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
The dbclient doesn't support the -o StrictHostKeyChecking but it has it's own -y option:
-y    Always accept remote host key if unknown
-y -y Don't perform any remote host key checking (caution)

So we can add these options to make the StrictHostKeyChecking working.
The dbclient will ignore -o StrictHostKeyChecking but use the -y or -yy instead.

The only problem is that the -y flag is also used by the openssh-client:

-y Send log information using the syslog(3) system module.  By default this information is sent to stderr.

This is not critical and once the dbclient start to support the StrictHostKeyChecking we can remove the -y flag.

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
@nunojpg
Copy link
Member

nunojpg commented Jun 3, 2023

Hey. Dropbear has come a long way. In my company we now use it instead of openssh.
But I would be really carefull with this. What about keys in the device in a update scenario? Formats are not compatible.
Wouldn't create a new package name and deprecating this be the right thing to do?

But using by default Dropbear is the way to go at this time. We just need to think about a safe transition path.

@stokito
Copy link
Contributor Author

stokito commented Jun 3, 2023

Yes, but if anyone already have the sshtunnel then they have the opensh-cleint and nothing should break during an update. But maybe after a sysupgrade and manual installation of the sshtunnel package a user may not install the openssh-client.
This case should be described on Wiki with dbconvert command.

I hope that most users will jsut use a default location for keys and this should make it easier.

Also I think that for simplicity we may just generate a new default key id_rsa or id_dropbear if they not exists. Then an inexperienced user may just copy a public key without wasting time for googling. We can add a GUI to see the pub key.

@stokito
Copy link
Contributor Author

stokito commented Jun 3, 2023

One possible solution may be to make the dropbear to support the OpenSSH PEM keys and default locations. It shouldn't be that complicated and bloated.

But generally speaking I believe that current users are technically competent to understand the difference. And also it shouldn't be so many of them so even if it breaks anyone it should be fine.
The OpenWrt design goal is to be small and suckless so users should be ready for such changes.

@stokito
Copy link
Contributor Author

stokito commented Jun 3, 2023

You know, I think that the most convenient path would be to keep the dependency but on the wiki add an instruction how to remove the openssh-client if not needed and put a notice for a future removing of the dependency. That still will make a pain for those who builds own images

@stokito stokito changed the title sshtunnel: support sshtunnel: support Dropbear Jun 3, 2023
@stokito
Copy link
Contributor Author

stokito commented Jun 9, 2023

@nunojpg so should I drop the last commit with removing the dependency?
Also I wish to add "Enabled" option to tunnels. Will you accept the change?
Another one question: is it possible somehow to see a list of working tunnels?
I can make ps | grep ssh but anyway it would be better to know which config is used so I need to know pid of a tunnel config.
The ddns scripts can track the subtasks.

@nunojpg
Copy link
Member

nunojpg commented Jun 9, 2023

I can only come back to this next month, sorry

@stokito
Copy link
Contributor Author

stokito commented Jun 14, 2023

I also going to change validation and allow empty remote address because now it should be always specified or to be *:

By default, TCP listening sockets on the server will be bound to
the loopback interface only. This may be overridden by specify‐
ing a bind_address. An empty bind_address, or the address ‘*’,
indicates that the remote socket should listen on all interfaces.

This causes problems when I tried to use a service localhost.run. I can report a bug to author. But generally speaking it's a valid case if I want to establish a tunnel to a local port on a remote server.

Also the localhost.run and https://github.com/antoniomika/sish services have a command that may or should be executed.

Another one problem is that a user may have own hosts configuration in the .ssh/config. Maybe we should allow to use them. Will think about this.

@nunojpg
Copy link
Member

nunojpg commented Jun 20, 2023

@stokito don't you want to take maintainership for this package? I don't use it for about 10 years now.

Just empty or * may have some semantic difference on a server

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
A user may have some host configured in the .ssh/config with user and port.
But we anyway have to specify them in the sshtunnel.
The change fixes this

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
@stokito
Copy link
Contributor Author

stokito commented Jun 21, 2023

@nunojpg well, please just make at least some brief review. I think next time the packages will be changed in another 10 years :)

I removed the removing of dependency. Maybe in future we may back to this.

I added the enabled flag.

@stokito
Copy link
Contributor Author

stokito commented Jun 21, 2023

I removed the -nN flags from the ssh command. They cause some problem when an SSH server wants to print something into console. For example when connection to the https://docs.srv.us/ without this flags it will print a URL for the tunnel:

$ ssh srv.us -R 1:localhost:3000
1: https://3pier5xmjygganhcissqsapcsu.srv.us/

But when the -N flag is set then you won't see the URL:

$ ssh srv.us -R 1:localhost:3000 -N

With the -n flag it will be printed but with an additional message:

$ ssh srv.us -R 1:localhost:3000 -n
Pseudo-terminal will not be allocated because stdin is not a terminal.
1: https://3pier5xmjygganhcissqsapcsu.srv.us/

I need to the the url in logs to know how to access my Luci.

The flags seems like not add much value but also the -N is not supported by the dropbear.

Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
@stokito
Copy link
Contributor Author

stokito commented Jul 8, 2023

I removed my commit with removing the -N. This makes not possible to see a text from SSH server but there is no other options.

After testing I found that when connecting the plain OpenSSH server then the SSH just closes connection with 0 exit code without any details. Even DEBUG loglevel shows nothing. It closes when connecting from procd or systemd but never happens when connecting from shell. Maybe it's relates to stdin.

Also I created a clone of the sshtunnel package but for systemd based systems without UCI https://github.com/yurt-page/sshtunnel
It follows similar idea but differs in many places.

@stokito stokito closed this Sep 20, 2023
@stokito stokito deleted the sshtunnel branch September 20, 2023 13:26
@stokito stokito restored the sshtunnel branch September 20, 2023 13:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants