Re: [PATCH 2/4] tools: Introduce SSH proxy

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Apr 19, 2024 at 12:12:31PM +0200, Michal Privoznik wrote:
> This allows users to SSH into a domain with a VSOCK device:
> 
>   ssh user@qemu/machineName
> 
> So far, only QEMU domains are supported AND qemu:///system is
> looked for the first for 'machineName' followed by
> qemu:///session. I took an inspiration from SystemD's ssh proxy
> [1] [2].
> 
> To just work out of the box, it requires (yet unreleased) systemd
> to be running inside the guest to set up a socket activated SSHD
> on the VSOCK. Alternatively, users can set up the socket
> activation themselves, or just run a socat that'll forward vsock
> <-> TCP communication.
> 
> 1: https://github.com/systemd/systemd/blob/main/src/ssh-generator/ssh-proxy.c
> 2: https://github.com/systemd/systemd/blob/main/src/ssh-generator/20-systemd-ssh-proxy.conf.in
> 
> Resolves: https://gitlab.com/libvirt/libvirt/-/issues/579
> Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx>
> ---
>  libvirt.spec.in                              |  27 +++
>  meson.build                                  |  16 +-
>  meson_options.txt                            |   2 +
>  po/POTFILES                                  |   1 +
>  tools/meson.build                            |   2 +
>  tools/ssh-proxy/30-libvirt-ssh-proxy.conf.in |  10 +
>  tools/ssh-proxy/meson.build                  |  25 ++
>  tools/ssh-proxy/ssh-proxy.c                  | 233 +++++++++++++++++++
>  8 files changed, 315 insertions(+), 1 deletion(-)
>  create mode 100644 tools/ssh-proxy/30-libvirt-ssh-proxy.conf.in
>  create mode 100644 tools/ssh-proxy/meson.build
>  create mode 100644 tools/ssh-proxy/ssh-proxy.c


> @@ -1017,6 +1018,9 @@ Summary: Client side utilities of the libvirt library
>  Requires: libvirt-libs = %{version}-%{release}
>  # Needed by virt-pki-validate script.
>  Requires: gnutls-utils
> +    %if %{with_ssh_proxy}
> +Recommends: libvirt-ssh-proxy = %{version}-%{release}
> +    %endif

I wonder if we should also have this present as a stronger 'Requires'
in both  libvirt-daemon-kvm & libvirt-daemon-qemu, as those are
convenience RPMs intended to provide a set of RPMs to maxmimise the
featureset.


> diff --git a/meson.build b/meson.build
> index 1518afa1cb..b19f9b1ed1 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -113,6 +113,11 @@ endif
>  confdir = sysconfdir / meson.project_name()
>  pkgdatadir = datadir / meson.project_name()
>  
> +sshconfdir = get_option('sshconfdir')
> +if sshconfdir == ''
> +  sshconfdir = sysconfdir / 'ssh/ssh_config.d'

Lets use the / operator consistently there

 sshconfdir = sysconfdir / 'ssh' / 'ssh_config.d'

> diff --git a/tools/ssh-proxy/30-libvirt-ssh-proxy.conf.in b/tools/ssh-proxy/30-libvirt-ssh-proxy.conf.in
> new file mode 100644
> index 0000000000..9a022826f7
> --- /dev/null
> +++ b/tools/ssh-proxy/30-libvirt-ssh-proxy.conf.in
> @@ -0,0 +1,10 @@
> +# SPDX-License-Identifier: LGPL-2.1-or-later
> +
> +Host qemu/*
> +    ProxyCommand @libexecdir@/libvirt-ssh-proxy %h %p
> +    ProxyUseFdpass yes
> +    CheckHostIP no
> +
> +    # Disable all kinds of host identity checks, since these addresses are generally ephemeral.
> +    StrictHostKeyChecking no
> +    UserKnownHostsFile /dev/null

I know systemd did this too, but I'm somewhat on the fence over
whether turning this off is a good idea or not.

I would assume it is recording "qemu/guestname" as the entry in
the known hosts file, which is not that ephemeral for traditional
guests ?

I wonder if we should just let the user decide to turn this off
if they so wish rather than forcing a less secure config by
default.

> +static int
> +processVsock(const char *domname,
> +             unsigned int port)
> +{
> +    const char *uris[] = {"qemu:///system", "qemu:///session"};

We should be skipping the session driver, if running as
root.

> +    struct sockaddr_vm sa = {
> +        .svm_family = AF_VSOCK,
> +        .svm_port = port,
> +    };
> +    VIR_AUTOCLOSE fd = -1;
> +    unsigned long long cid = -1;
> +    size_t i;
> +
> +    for (i = 0; i < G_N_ELEMENTS(uris); i++) {
> +        g_autoptr(virConnect) conn = NULL;
> +        g_autoptr(virDomain) dom = NULL;
> +
> +        if (!(dom = lookupDomain(domname, uris[i], &conn)))
> +            continue;
> +
> +        if (extractCID(dom, &cid) >= 0)
> +            break;
> +    }
> +
> +    if (cid == -1) {
> +        ERROR(_("No usable vsock found"));
> +        return -1;
> +    }
> +
> +    sa.svm_cid = cid;
> +
> +    fd = socket(AF_VSOCK, SOCK_STREAM | SOCK_CLOEXEC, 0);
> +    if (fd < 0) {
> +        SYS_ERROR(_("Failed to allocate AF_VSOCK socket"));
> +        return -1;
> +    }
> +
> +    if (connect(fd, (const struct sockaddr *)&sa, sizeof(sa)) < 0) {
> +        SYS_ERROR(_("Failed to connect to vsock (cid=%1$llu port=%2$u)"),
> +                  cid, port);
> +        return -1;
> +    }
> +
> +    /* OpenSSH wants us to send a single byte along with the file descriptor,
> +     * hence do so. */
> +    if (virSocketSendFD(STDOUT_FILENO, fd) < 0) {
> +        SYS_ERROR(_("Failed to send file descriptor %1$d"), fd);
> +        return -1;
> +    }
> +
> +    return 0;
> +}

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
_______________________________________________
Devel mailing list -- devel@xxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux