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

Add support for ssh_config for connection #23847

Merged
merged 3 commits into from
Oct 30, 2024

Conversation

afbjorklund
Copy link
Contributor

@afbjorklund afbjorklund commented Sep 3, 2024

Previously had to use podman system connection

Normal ssh://<alias> would fail to work properly

e.g. "default", podman --host ssh://default --ssh native ps

Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile $PWD/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL

Does this PR introduce a user-facing change?

ssh connection URL now supports regular ssh_config

Also adds support for default ssh user and path.


Tested manually with Lima. No unit tests found.

$ limactl start --name podman template://podman
$ ssh -F ~/.lima/podman/ssh.config lima-podman podman

$ limactl show-ssh --format=config podman >>~/.ssh/config
$ CONTAINER_HOST=ssh://lima-podman podman-remote version

Uses https://github.com/kevinburke/ssh_config

Closes #23831
Fixes #17452

Copy link

Ephemeral COPR build failed. @containers/packit-build please check.

@afbjorklund
Copy link
Contributor Author

afbjorklund commented Sep 3, 2024

Added required files to the "vendor" directory (by using go1.22.0 mod vendor)

bloat approved

***************************************************************************
* bin/podman grew by 110536 bytes; max allowed is 51200.
*
* Please investigate, and fix if possible.
*
* A repo admin can override by setting the bloat_approved label
***************************************************************************

no new tests

pr-should-include-tests: PR does not include changes in the 'tests' directory

Please write a regression test for what you're fixing. Even if it
seems trivial or obvious, try to add a test that will prevent
regressions.

If your change is minor, feel free to piggyback on already-written
tests, possibly just adding a small step to a similar existing test.
Every second counts in CI.

If your commit really, truly does not need tests, you can proceed
by asking a repo maintainer to set the 'No New Tests' github label.
This will only be done when there's no reasonable alternative.

BTW; There is no "tests" directory, but there is a "test" directory?

The "secure" parameter doesn't seem to do anything anymore?

ssh://<user>@<host>[:port]/run/podman/podman.sock?secure=True

@afbjorklund
Copy link
Contributor Author

afbjorklund commented Sep 3, 2024

This will fix trying to nslookup the alias, but it will not add support for ProxyJump

In order to support that, Podman needs to use more of containers/common SSHMode

Like it said in the original PR #15094 (that added --ssh=native):

Overall, this is a v1 of a long process of offering native ssh


     ProxyCommand
             Specifies the command to use to connect to the server.  The com‐
             mand string extends to the end of the line, and is executed using
             the user's shell ‘exec’ directive to avoid a lingering shell
             process.
             ...

     ProxyJump
             Specifies one or more jump proxies as either [user@]host[:port]
             or an ssh URI.  Multiple proxies may be separated by comma char‐
             acters and will be visited sequentially.  Setting this option
             will cause ssh(1) to connect to the target host by first making a
             ssh(1) connection to the specified ProxyJump host and then estab‐
             lishing a TCP forwarding to the ultimate target from there.
             ...

The current workaround is to tunnel a temporary unix: socket with a ssh -L command

@mheon
Copy link
Member

mheon commented Sep 5, 2024

* bin/podman grew by 110536 bytes; max allowed is 51200.

110kb from a 1700 line diffstat, ouch. Bloat approved label added still.

@mheon mheon added bloat_approved Approve a PR in which binary file size grows by over 50k No New Tests Allow PR to proceed without adding regression tests labels Sep 5, 2024
pkg/bindings/connection.go Outdated Show resolved Hide resolved
pkg/bindings/connection.go Outdated Show resolved Hide resolved
@mheon
Copy link
Member

mheon commented Sep 5, 2024

Few nits, looks fine overall. @baude PTAL when you get back.

@afbjorklund
Copy link
Contributor Author

afbjorklund commented Sep 5, 2024

* bin/podman grew by 110536 bytes; max allowed is 51200.

110kb from a 1700 line diffstat, ouch. Bloat approved label added still.

Not sure if there was any obvious culprit, it seemed to be evenly spread...

11714	runtime
1323	os
806	fmt
698	regexp
521	strings
501	strconv
437	unicode
430	bytes
429	sync
366	io
243	os/user
214	path/filepath
73	errors

EDIT: I take that back, the use of "runtime" seems suspicious and bloated

https://github.com/kevinburke/ssh_config/blob/v1.2.0/config.go#L312

                if r := recover(); r != nil {
                        if _, ok := r.(runtime.Error); ok {
                                panic(r)
                        }
                        if e, ok := r.(error); ok && e == ErrDepthExceeded {
                                err = e
                                return
                        }
                        err = errors.New(r.(string))
                }

https://go.dev/wiki/CodeReviewComments#dont-panic
https://go.dev/blog/defer-panic-and-recover

So maybe the bloat checker was onto something anyway?

pkg/bindings/connection.go Outdated Show resolved Hide resolved
cfg := ssh_config.DefaultUserSettings
if val := cfg.Get(alias, "User"); val != "" {
userinfo = url.User(val)
logrus.Debugf("User: %s", val)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These debug statements are not clear, they need to mention ssh config at least

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They could be removed altogether, they were mostly used during implementing...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is likely value in having them to see what the lib parsed in case of weird user configs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A compromise might be to log the new URL (once), once all the substitution (if any) is done.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes logging the final url once sounds good to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't so easy to log the information since _url is not the only source of information used...

But changed it so that it only outputs something, if an alias was actually found in ssh_config.

Comment on lines 176 to 179
if err := session.Run(
"podman info --format '{{.Host.RemoteSocket.Path}}'"); err != nil {
return nil, err
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a good idea for performance reasons, podman info is slow...
Also podman info has no actual knowledge of the actual API socket path and just guess the /run/podman/podman.sock or /run/user/xxx/podman/podman.sock as rootless so there is no reason to do that as you might as well guess on the client. Of course you would need to get the uid on the server to do this.

I mean alone the extra ssh connection is already slow but I think there is no need to avoid that if we need the uid on the server so maybe the podman info at this point is not to bad either?
Given that is is properly not a good idea to recommend leaving it the socket path if users care about performance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was more about compatibility/simplicity, and less about performance?

There is already the "system connection", that should be the preferred option...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it can hardcode the /run/user/$UID either, need to query for $XDG_RUNTIME_DIR.

Most systems with systemd will use the default, but other systems might use another directory...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I looked at this was like podman info isn't really great for this but thinking about this again given there is no way around opening an extra ssh connection for it so doing the podman info call should not be that big of a deal either.

Copy link
Contributor Author

@afbjorklund afbjorklund Sep 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually it might use the containers/common functionality for this (the "SSHMode").

Copy link
Contributor Author

@afbjorklund afbjorklund Sep 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@afbjorklund
Copy link
Contributor Author

afbjorklund commented Sep 6, 2024

Note that if providing a fully qualified URL, this will be a no-op (assuming an empty/small ~/.ssh/config)

export CONTAINER_HOST=ssh://[email protected]:2222/run/user/1000/podman/podman.sock
export CONTAINER_SSHKEY=$PWD/.vagrant/machines/default/virtualbox/private_key

It will only kick in, if there is an "alias" defined or if there are any parameters missing (like user or path)

@afbjorklund
Copy link
Contributor Author

There is more talk about performance in the issue, beyond using a legacy --host=ssh://

How to reuse the same ssh connection (and path), and how to choose a faster encryption...

For lima there is a "host agent" that sets up a persistent tunnel, and provides a unix socket

@afbjorklund afbjorklund force-pushed the ssh-config-main branch 2 times, most recently from 186b0ab to fe5df7e Compare September 11, 2024 16:50
@afbjorklund afbjorklund requested review from mheon and Luap99 September 11, 2024 16:50
Copy link
Member

@Luap99 Luap99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay, I have not forgotten this.

pkg/bindings/connection.go Outdated Show resolved Hide resolved
pkg/bindings/connection.go Outdated Show resolved Hide resolved
@Luap99
Copy link
Member

Luap99 commented Sep 24, 2024

Also can you squash your commits please.

Copy link

Cockpit tests failed for commit b174663c2f1354c5b3f32c234f780303b177a2ac. @martinpitt, @jelly, @mvollmer please check.

Copy link
Member

@Luap99 Luap99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, sorry for the late reply this time it fell of my list.
Can you rebase this please? If you don't have time I can also do that.

@mheon PTAL so we can merge once rebased.

Copy link
Contributor

openshift-ci bot commented Oct 30, 2024

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: afbjorklund, Luap99

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 30, 2024
@mheon
Copy link
Member

mheon commented Oct 30, 2024

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Oct 30, 2024
@openshift-merge-bot openshift-merge-bot bot merged commit 5751154 into containers:main Oct 30, 2024
85 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. bloat_approved Approve a PR in which binary file size grows by over 50k lgtm Indicates that a PR is ready to be merged. No New Tests Allow PR to proceed without adding regression tests release-note
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Podman over SSH in native mode does not use custom config ~/.ssh/config podman --url ssh:// fails wierdly
3 participants