From nobody Sat Feb 7 11:05:19 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 207.211.31.81 as permitted sender) client-ip=207.211.31.81; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.81 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1594319846; cv=none; d=zohomail.com; s=zohoarc; b=bDtYabsjhv0HL7jhJTHwIpCmGMrzAH9gvKffrff28+g947hzShOke7f/uil3dUwFrUuHMwi0OmpTLhVxdA5FCMfJdlC0kDDNslnbK2/IOWVJdoQD/ToDIgi+EsPaw7uGeEP3MyYQ1aDuBeV2u9AwTLBa/ixCT16ovC80MDKYpAQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1594319846; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=mevR2rTpmI3I+bqKYMu3oEwim/fZrvT6VKZO1ILM5eo=; b=WmR/oCknICf9lYhfDozQW0uGCZh1S8menJLXuv3sYD/Q5YSkAbrtV1NNhkOkDCE7D04lGATUNRwqn5D/BA3o/tFpFQBbn/N4usnE0G7C8lOE6+3pS4gfz4uVrzgybeuzIZYULDgOKJPiOkxFDDSgbZuCyKYnfkfBA5wlUVN++sw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.81 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-1.mimecast.com (us-smtp-2.mimecast.com [207.211.31.81]) by mx.zohomail.com with SMTPS id 1594319845994549.7664566592036; Thu, 9 Jul 2020 11:37:25 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-281-JirGiKeOM1qq6zCMar7s5w-1; Thu, 09 Jul 2020 14:37:22 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D7908107BA59; Thu, 9 Jul 2020 18:37:15 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B67BC19D61; Thu, 9 Jul 2020 18:37:15 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 860D51809557; Thu, 9 Jul 2020 18:37:15 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 069IbEt9023594 for ; Thu, 9 Jul 2020 14:37:14 -0400 Received: by smtp.corp.redhat.com (Postfix) id B5B0F6111F; Thu, 9 Jul 2020 18:37:14 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.110.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id C1CAD610AF; Thu, 9 Jul 2020 18:37:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1594319844; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=mevR2rTpmI3I+bqKYMu3oEwim/fZrvT6VKZO1ILM5eo=; b=C/NHVFKtqe1N9Fc3FmuA52Af6G20z/DCMln51OrPLK9gF788x9vW/Eu8na6Lv5+1y2hyne TcDgMPPbRA7VraIo8vFOYFafM884N4vClM+uz8WgUJ1I2k+Pgjhla7ogDOE/5ISE9uU88I O6UxY5AgN8opjs9QmdPtBa1z62s9AVE= X-MC-Unique: JirGiKeOM1qq6zCMar7s5w-1 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Subject: [libvirt PATCH 9/9] rpc: use new virt-nc binary for remote tunnelling Date: Thu, 9 Jul 2020 19:36:46 +0100 Message-Id: <20200709183646.4016586-10-berrange@redhat.com> In-Reply-To: <20200709183646.4016586-1-berrange@redhat.com> References: <20200709183646.4016586-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) This wires up support for using the new virt-nc binary with the ssh, libssh and libssh2 protocols. The new binary will be used preferentially if it is available in $PATH, otherwise we fall back to traditional netcat. The "proxy" URI parameter can be used to force use of netcat e.g. qemu+ssh://host/system?proxy=3Dnetcat or the disable fallback e.g. qemu+ssh://host/system?proxy=3Dvirt-nc With use of virt-nc, we can now support remote session URIs qemu+ssh://host/session and this will only use virt-nc, with no fallback. This also lets the libvirtd process be auto-started. Signed-off-by: Daniel P. Berrang=C3=A9 --- docs/uri.html.in | 18 ++++++++++ src/remote/remote_driver.c | 30 +++++++++++++++- src/remote/remote_sockets.c | 8 ----- src/rpc/virnetclient.c | 70 ++++++++++++++++++++++++++++++------- src/rpc/virnetclient.h | 30 +++++++++++++--- tests/virnetsockettest.c | 7 ++-- 6 files changed, 136 insertions(+), 27 deletions(-) diff --git a/docs/uri.html.in b/docs/uri.html.in index 49f92773f8..5311579273 100644 --- a/docs/uri.html.in +++ b/docs/uri.html.in @@ -259,6 +259,24 @@ Note that parameter values must be Example: mode=3Ddirect + + + proxy + + auto, virt, generic + +
+
auto
try virt-nc, fallback to netcat<= /dd> +
netcat
only use netcat
+
virt-nc
only use virt-nc
+
+ Can also be set in libvirt.conf as remote_pro= xy + + + + + Example: proxy=3Dvirt-nc + command diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index c1f7a45aab..83789a86a9 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -761,12 +761,14 @@ doRemoteOpen(virConnectPtr conn, g_autofree char *knownHosts =3D NULL; g_autofree char *mode_str =3D NULL; g_autofree char *daemon_name =3D NULL; + g_autofree char *proxy_str =3D NULL; bool sanity =3D true; bool verify =3D true; #ifndef WIN32 bool tty =3D true; #endif int mode; + int proxy; =20 if (inside_daemon && !conn->uri->server) { mode =3D REMOTE_DRIVER_MODE_DIRECT; @@ -774,6 +776,14 @@ doRemoteOpen(virConnectPtr conn, mode =3D REMOTE_DRIVER_MODE_AUTO; } =20 + /* Historically we didn't allow ssh tunnel with session mode, + * since we can't construct the accurate path remotely, + * so we can default to modern virt-nc */ + if (flags & VIR_DRV_OPEN_REMOTE_USER) + proxy =3D VIR_NET_CLIENT_PROXY_VIRT_NC; + else + proxy =3D VIR_NET_CLIENT_PROXY_NETCAT; + /* We handle *ALL* URIs here. The caller has rejected any * URIs we don't care about */ =20 @@ -813,6 +823,7 @@ doRemoteOpen(virConnectPtr conn, EXTRACT_URI_ARG_STR("known_hosts_verify", knownHostsVerify); EXTRACT_URI_ARG_STR("tls_priority", tls_priority); EXTRACT_URI_ARG_STR("mode", mode_str); + EXTRACT_URI_ARG_STR("proxy", proxy_str); EXTRACT_URI_ARG_BOOL("no_sanity", sanity); EXTRACT_URI_ARG_BOOL("no_verify", verify); #ifndef WIN32 @@ -865,6 +876,14 @@ doRemoteOpen(virConnectPtr conn, (mode =3D remoteDriverModeTypeFromString(mode_str)) < 0) goto failed; =20 + if (conf && !proxy_str && + virConfGetValueString(conf, "remote_proxy", &proxy_str) < 0) + goto failed; + + if (proxy_str && + (proxy =3D virNetClientProxyTypeFromString(proxy_str)) < 0) + goto failed; + /* Sanity check that nothing requested !direct mode by mistake */ if (inside_daemon && !conn->uri->server && mode !=3D REMOTE_DRIVER_MOD= E_DIRECT) { virReportError(VIR_ERR_INVALID_ARG, "%s", @@ -949,8 +968,11 @@ doRemoteOpen(virConnectPtr conn, knownHosts, knownHostsVerify, sshauth, + proxy, netcat, sockname, + name, + flags & VIR_DRV_OPEN_REMOTE_= RO, auth, conn->uri); if (!priv->client) @@ -970,8 +992,11 @@ doRemoteOpen(virConnectPtr conn, knownHosts, knownHostsVerify, sshauth, + proxy, netcat, sockname, + name, + flags & VIR_DRV_OPEN_REMOTE_R= O, auth, conn->uri); if (!priv->client) @@ -1011,8 +1036,11 @@ doRemoteOpen(virConnectPtr conn, !tty, !verify, keyfile, + proxy, netcat ? netcat : "nc", - sockname))) + sockname, + name, + flags & VIR_DRV_OPEN_REMOT= E_RO))) goto failed; =20 priv->is_secure =3D 1; diff --git a/src/remote/remote_sockets.c b/src/remote/remote_sockets.c index 854775f401..7c69ed9e7f 100644 --- a/src/remote/remote_sockets.c +++ b/src/remote/remote_sockets.c @@ -108,14 +108,6 @@ remoteGetUNIXSocketHelper(remoteDriverTransport transp= ort, g_autofree char *userdir =3D NULL; =20 if (session) { - if (transport !=3D REMOTE_DRIVER_TRANSPORT_UNIX) { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, - _("Connecting to session instance without " - "socket path is not supported by the %s " - "transport"), - remoteDriverTransportTypeToString(transport)); - return NULL; - } userdir =3D virGetUserRuntimeDirectory(); =20 sockname =3D g_strdup_printf("%s/%s-sock", userdir, sock_prefix); diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c index cd1bcc3ab3..5939f74e62 100644 --- a/src/rpc/virnetclient.c +++ b/src/rpc/virnetclient.c @@ -50,6 +50,10 @@ enum { VIR_NET_CLIENT_MODE_COMPLETE, }; =20 +VIR_ENUM_IMPL(virNetClientProxy, + VIR_NET_CLIENT_PROXY_LAST, + "auto", "netcat", "virt-nc"); + struct _virNetClientCall { int mode; =20 @@ -414,20 +418,50 @@ virNetClientDoubleEscapeShell(const char *str) } =20 char * -virNetClientSSHHelperCommand(const char *netcatPath, - const char *socketPath) +virNetClientSSHHelperCommand(virNetClientProxy proxy, + const char *netcatPath, + const char *socketPath, + const char *driverURI, + bool readonly) { g_autofree char *netcatPathSafe =3D virNetClientDoubleEscapeShell(netc= atPath); + g_autofree char *driverURISafe =3D virNetClientDoubleEscapeShell(drive= rURI); + g_autofree char *nccmd =3D NULL; + g_autofree char *virtnccmd =3D NULL; =20 - return g_strdup_printf( - "sh -c " - "'if '%s' -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1;= then " - "ARG=3D-q0;" + nccmd =3D g_strdup_printf( + "if '%s' -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; = then " + "ARG=3D-q0;" "else " - "ARG=3D;" + "ARG=3D;" "fi;" - "'%s' $ARG -U %s'", + "'%s' $ARG -U %s", netcatPathSafe, netcatPathSafe, socketPath); + + virtnccmd =3D g_strdup_printf("%s '%s'", + readonly ? "virt-nc -r" : "virt-nc", + driverURISafe); + + switch (proxy) { + case VIR_NET_CLIENT_PROXY_AUTO: + return g_strdup_printf("sh -c 'which virt-nc 1>/dev/null 2>&1; " + "if test $? =3D 0; then " + " %s; " + "else" + " %s; " + "fi'", virtnccmd, nccmd); + + case VIR_NET_CLIENT_PROXY_NETCAT: + return g_strdup_printf("sh -c '%s'", nccmd); + + case VIR_NET_CLIENT_PROXY_VIRT_NC: + return g_strdup_printf("sh -c '%s'", virtnccmd); + + case VIR_NET_CLIENT_PROXY_LAST: + default: + virReportEnumRangeError(virNetClientProxy, proxy); + return NULL; + } } =20 =20 @@ -442,8 +476,11 @@ virNetClientPtr virNetClientNewSSH(const char *nodenam= e, bool noTTY, bool noVerify, const char *keyfile, + virNetClientProxy proxy, const char *netcatPath, - const char *socketPath) + const char *socketPath, + const char *driverURI, + bool readonly) { virNetSocketPtr sock; =20 @@ -451,7 +488,8 @@ virNetClientPtr virNetClientNewSSH(const char *nodename, =20 DEFAULT_VALUE(netcatPath, "nc"); =20 - command =3D virNetClientSSHHelperCommand(netcatPath, socketPath); + command =3D virNetClientSSHHelperCommand(proxy, netcatPath, socketPath, + driverURI, readonly); =20 if (virNetSocketNewConnectSSH(nodename, service, binary, username, noT= TY, noVerify, keyfile, command, &sock) < 0) @@ -468,8 +506,11 @@ virNetClientPtr virNetClientNewLibSSH2(const char *hos= t, const char *knownHostsPath, const char *knownHostsVerify, const char *authMethods, + virNetClientProxy proxy, const char *netcatPath, const char *socketPath, + const char *driverURI, + bool readonly, virConnectAuthPtr authPtr, virURIPtr uri) { @@ -511,7 +552,8 @@ virNetClientPtr virNetClientNewLibSSH2(const char *host, DEFAULT_VALUE(netcatPath, "nc"); DEFAULT_VALUE(knownHostsVerify, "normal"); =20 - command =3D virNetClientSSHHelperCommand(netcatPath, socketPath); + command =3D virNetClientSSHHelperCommand(proxy, netcatPath, socketPath, + driverURI, readonly); =20 if (virNetSocketNewConnectLibSSH2(host, port, family, @@ -531,8 +573,11 @@ virNetClientPtr virNetClientNewLibssh(const char *host, const char *knownHostsPath, const char *knownHostsVerify, const char *authMethods, + virNetClientProxy proxy, const char *netcatPath, const char *socketPath, + const char *driverURI, + bool readonly, virConnectAuthPtr authPtr, virURIPtr uri) { @@ -574,7 +619,8 @@ virNetClientPtr virNetClientNewLibssh(const char *host, DEFAULT_VALUE(netcatPath, "nc"); DEFAULT_VALUE(knownHostsVerify, "normal"); =20 - command =3D virNetClientSSHHelperCommand(netcatPath, socketPath); + command =3D virNetClientSSHHelperCommand(proxy, netcatPath, socketPath, + driverURI, readonly); =20 if (virNetSocketNewConnectLibssh(host, port, family, diff --git a/src/rpc/virnetclient.h b/src/rpc/virnetclient.h index 6fdc370083..76500e2c3f 100644 --- a/src/rpc/virnetclient.h +++ b/src/rpc/virnetclient.h @@ -30,9 +30,22 @@ #include "virobject.h" #include "viruri.h" =20 +typedef enum { + VIR_NET_CLIENT_PROXY_AUTO, + VIR_NET_CLIENT_PROXY_NETCAT, + VIR_NET_CLIENT_PROXY_VIRT_NC, + + VIR_NET_CLIENT_PROXY_LAST, +} virNetClientProxy; + +VIR_ENUM_DECL(virNetClientProxy); + char * -virNetClientSSHHelperCommand(const char *netcatPath, - const char *socketPath); +virNetClientSSHHelperCommand(virNetClientProxy proxy, + const char *netcatPath, + const char *socketPath, + const char *driverURI, + bool readonly); =20 virNetClientPtr virNetClientNewUNIX(const char *path, bool spawnDaemon, @@ -49,8 +62,11 @@ virNetClientPtr virNetClientNewSSH(const char *nodename, bool noTTY, bool noVerify, const char *keyfile, - const char *netcat, - const char *socketPath); + virNetClientProxy proxy, + const char *netcatPath, + const char *socketPath, + const char *driverURI, + bool readonly); =20 virNetClientPtr virNetClientNewLibSSH2(const char *host, const char *port, @@ -60,8 +76,11 @@ virNetClientPtr virNetClientNewLibSSH2(const char *host, const char *knownHostsPath, const char *knownHostsVerify, const char *authMethods, + virNetClientProxy proxy, const char *netcatPath, const char *socketPath, + const char *driverURI, + bool readonly, virConnectAuthPtr authPtr, virURIPtr uri); =20 @@ -73,8 +92,11 @@ virNetClientPtr virNetClientNewLibssh(const char *host, const char *knownHostsPath, const char *knownHostsVerify, const char *authMethods, + virNetClientProxy proxy, const char *netcatPath, const char *socketPath, + const char *driverURI, + bool readonly, virConnectAuthPtr authPtr, virURIPtr uri); =20 diff --git a/tests/virnetsockettest.c b/tests/virnetsockettest.c index 842eb1bcfc..c6fbe479d7 100644 --- a/tests/virnetsockettest.c +++ b/tests/virnetsockettest.c @@ -464,8 +464,11 @@ static int testSocketSSH(const void *opaque) virNetSocketPtr csock =3D NULL; /* Client socket */ int ret =3D -1; char buf[1024]; - g_autofree char *command =3D virNetClientSSHHelperCommand(data->netcat, - data->path); + g_autofree char *command =3D virNetClientSSHHelperCommand(VIR_NET_CLIE= NT_PROXY_AUTO, + data->netcat, + data->path, + "qemu:///sessi= on", + true); =20 if (virNetSocketNewConnectSSH(data->nodename, data->service, --=20 2.26.2