mirror of
https://github.com/systemd/systemd.git
synced 2025-01-07 21:18:41 +03:00
ssh-proxy: add support for connecting to VMs by AF_VSOCK via "machine/…" host specs
With this one can type "ssh machine/foobar" to connect to locally registered machine "foobar" via SSH-over-AF_VSOCK.
This commit is contained in:
parent
1c7642a3b7
commit
26b455d815
@ -1,8 +1,15 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
#
|
#
|
||||||
# Make sure unix/* and vsock/* can be used to connect to AF_UNIX and AF_VSOCK paths
|
# Allow connecting to the local host directly via ".host"
|
||||||
|
Host .host machine/.host
|
||||||
|
ProxyCommand {{LIBEXECDIR}}/systemd-ssh-proxy unix/run/ssh-unix-local/socket %p
|
||||||
|
ProxyUseFdpass yes
|
||||||
|
CheckHostIP no
|
||||||
|
|
||||||
|
# Make sure unix/* and vsock/* can be used to connect to AF_UNIX and AF_VSOCK paths.
|
||||||
|
# Make sure machine/* can be used to connect to local machines registered in machined.
|
||||||
#
|
#
|
||||||
Host unix/* vsock/*
|
Host unix/* vsock/* machine/*
|
||||||
ProxyCommand {{LIBEXECDIR}}/systemd-ssh-proxy %h %p
|
ProxyCommand {{LIBEXECDIR}}/systemd-ssh-proxy %h %p
|
||||||
ProxyUseFdpass yes
|
ProxyUseFdpass yes
|
||||||
CheckHostIP no
|
CheckHostIP no
|
||||||
@ -10,9 +17,3 @@ Host unix/* vsock/*
|
|||||||
# Disable all kinds of host identity checks, since these addresses are generally ephemeral.
|
# Disable all kinds of host identity checks, since these addresses are generally ephemeral.
|
||||||
StrictHostKeyChecking no
|
StrictHostKeyChecking no
|
||||||
UserKnownHostsFile /dev/null
|
UserKnownHostsFile /dev/null
|
||||||
|
|
||||||
# Allow connecting to the local host directly via ".host"
|
|
||||||
Host .host
|
|
||||||
ProxyCommand {{LIBEXECDIR}}/systemd-ssh-proxy unix/run/ssh-unix-local/socket %p
|
|
||||||
ProxyUseFdpass yes
|
|
||||||
CheckHostIP no
|
|
||||||
|
@ -14,21 +14,19 @@
|
|||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
|
#include "varlink.h"
|
||||||
|
|
||||||
static int process_vsock(const char *host, const char *port) {
|
static int process_vsock_cid(unsigned cid, const char *port) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(host);
|
assert(cid != VMADDR_CID_ANY);
|
||||||
assert(port);
|
assert(port);
|
||||||
|
|
||||||
union sockaddr_union sa = {
|
union sockaddr_union sa = {
|
||||||
|
.vm.svm_cid = cid,
|
||||||
.vm.svm_family = AF_VSOCK,
|
.vm.svm_family = AF_VSOCK,
|
||||||
};
|
};
|
||||||
|
|
||||||
r = vsock_parse_cid(host, &sa.vm.svm_cid);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to parse vsock cid: %s", host);
|
|
||||||
|
|
||||||
r = vsock_parse_port(port, &sa.vm.svm_port);
|
r = vsock_parse_port(port, &sa.vm.svm_port);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to parse vsock port: %s", port);
|
return log_error_errno(r, "Failed to parse vsock port: %s", port);
|
||||||
@ -47,6 +45,21 @@ static int process_vsock(const char *host, const char *port) {
|
|||||||
|
|
||||||
log_debug("Successfully sent AF_VSOCK socket via STDOUT.");
|
log_debug("Successfully sent AF_VSOCK socket via STDOUT.");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int process_vsock_string(const char *host, const char *port) {
|
||||||
|
unsigned cid;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(host);
|
||||||
|
assert(port);
|
||||||
|
|
||||||
|
r = vsock_parse_cid(host, &cid);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse vsock cid: %s", host);
|
||||||
|
|
||||||
|
return process_vsock_cid(cid, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_unix(const char *path) {
|
static int process_unix(const char *path) {
|
||||||
@ -124,6 +137,43 @@ static int process_vsock_mux(const char *path, const char *port) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int process_machine(const char *machine, const char *port) {
|
||||||
|
_cleanup_(varlink_unrefp) Varlink *vl = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(machine);
|
||||||
|
assert(port);
|
||||||
|
|
||||||
|
r = varlink_connect_address(&vl, "/run/systemd/machine/io.systemd.Machine");
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to connect to machined on /run/systemd/machine/io.systemd.Machine: %m");
|
||||||
|
|
||||||
|
_cleanup_(sd_json_variant_unrefp) sd_json_variant *result = NULL;
|
||||||
|
r = varlink_callbo_and_log(
|
||||||
|
vl,
|
||||||
|
"io.systemd.Machine.List",
|
||||||
|
&result,
|
||||||
|
SD_JSON_BUILD_PAIR("name", SD_JSON_BUILD_STRING(machine)));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
uint32_t cid = VMADDR_CID_ANY;
|
||||||
|
|
||||||
|
const sd_json_dispatch_field dispatch_table[] = {
|
||||||
|
{ "vSockCid", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint32, PTR_TO_SIZE(&cid), 0 },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
r = sd_json_dispatch(result, dispatch_table, SD_JSON_ALLOW_EXTENSIONS, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse Varlink reply: %m");
|
||||||
|
|
||||||
|
if (cid == VMADDR_CID_ANY)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Machine has no AF_VSOCK CID assigned.");
|
||||||
|
|
||||||
|
return process_vsock_cid(cid, port);
|
||||||
|
}
|
||||||
|
|
||||||
static int run(int argc, char* argv[]) {
|
static int run(int argc, char* argv[]) {
|
||||||
|
|
||||||
log_setup();
|
log_setup();
|
||||||
@ -135,7 +185,7 @@ static int run(int argc, char* argv[]) {
|
|||||||
|
|
||||||
const char *p = startswith(host, "vsock/");
|
const char *p = startswith(host, "vsock/");
|
||||||
if (p)
|
if (p)
|
||||||
return process_vsock(p, port);
|
return process_vsock_string(p, port);
|
||||||
|
|
||||||
p = startswith(host, "unix/");
|
p = startswith(host, "unix/");
|
||||||
if (p)
|
if (p)
|
||||||
@ -145,6 +195,10 @@ static int run(int argc, char* argv[]) {
|
|||||||
if (p)
|
if (p)
|
||||||
return process_vsock_mux(p, port);
|
return process_vsock_mux(p, port);
|
||||||
|
|
||||||
|
p = startswith(host, "machine/");
|
||||||
|
if (p)
|
||||||
|
return process_machine(p, port);
|
||||||
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Don't know how to parse host name specification: %s", host);
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Don't know how to parse host name specification: %s", host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user