add -J proxyjump option (#15)

This commit is contained in:
Ryo Nakamura
2024-04-14 15:49:27 +09:00
parent e47d5b76e6
commit 4ce62079cf
7 changed files with 71 additions and 7 deletions

View File

@@ -56,6 +56,9 @@ mscp \- copy files over multiple SSH connections
.BI \-i \ IDENTITY\c
]
[\c
.BI \-J \ DESTINATION\c
]
[\c
.BI \-c \ CIPHER\c
]
[\c
@@ -270,6 +273,19 @@ supports.
.B \-i \fIIDENTITY\fR
Specifies the identity file for public key authentication.
.TP
.B \-J \fIDESTINATION\fR
A shortcut to define a
.B ProxyJump
configuration directive. Each SFTP session of
.B mscp
connects to the target host by first making an
.B ssh
connection to the jump host described by
.I destination.
.TP
.B \-c \fICIPHER\fR
Selects the cipher to use for encrypting the data transfer. See

View File

@@ -2,7 +2,7 @@
MSCP
====
:Date: v0.1.5-16-ga1ba6f1
:Date: v0.1.5-18-ge47d5b7
NAME
====
@@ -18,8 +18,8 @@ SYNOPSIS
**-S** *MAX_CHUNK_SIZE* ] [ **-a** *NR_AHEAD* ] [ **-b** *BUF_SIZE* ] [
**-L** *LIMIT_BITRATE* ] [ **-l** *LOGIN_NAME* ] [ **-P** *PORT* ] [
**-F** *SSH_CONFIG* ] [ **-o** *SSH_OPTION* ] [ **-i** *IDENTITY* ] [
**-c** *CIPHER* ] [ **-M** *HMAC* ] [ **-C** *COMPRESS* ] [ **-g**
*CONGESTION* ] *source ... target*
**-J** *DESTINATION* ] [ **-c** *CIPHER* ] [ **-M** *HMAC* ] [ **-C**
*COMPRESS* ] [ **-g** *CONGESTION* ] *source ... target*
DESCRIPTION
===========
@@ -159,6 +159,11 @@ OPTIONS
**-i IDENTITY**
Specifies the identity file for public key authentication.
**-J DESTINATION**
A shortcut to define a **ProxyJump** configuration directive. Each
SFTP session of **mscp** connects to the target host by first making
an **ssh** connection to the jump host described by *destination.*
**-c CIPHER**
Selects the cipher to use for encrypting the data transfer. See
`libssh features <https://www.libssh.org/features/>`__.

View File

@@ -63,6 +63,7 @@ struct mscp_ssh_opts {
char *config; /** path to ssh_config, default ~/.ssh/config*/
char **options; /** array of ssh_config options, terminated by NULL */
char *identity; /** path to private key */
char *proxyjump; /** ProxyJump configuration directive (shortcut) */
char *cipher; /** cipher spec */
char *hmac; /** hmacp spec */
char *compress; /** yes, no, zlib@openssh.com */

View File

@@ -12,6 +12,9 @@ set -x
echo "Port 22" >> /etc/ssh/sshd_config
echo "Port 8022" >> /etc/ssh/sshd_config
## Alpine default sshd disables TcpForwarding, which is required for proxyjump test
sed -i -e 's/AllowTcpForwarding no/AllowTcpForwarding yes/' /etc/ssh/sshd_config
# Run sshd
if [ ! -e /var/run/sshd.pid ]; then
/usr/sbin/sshd

View File

@@ -24,12 +24,12 @@ void usage(bool print_help)
{
printf("mscp " MSCP_BUILD_VERSION ": copy files over multiple SSH connections\n"
"\n"
"Usage: mscp [-46vqDpdNh] [-n nr_conns] [-m coremask]\n"
" [-u max_startups] [-I interval] [-W checkpoint] [-R checkpoint]\n"
"Usage: mscp [-46vqDpdNh] [-n nr_conns] [-m coremask] [-u max_startups]\n"
" [-I interval] [-W checkpoint] [-R checkpoint]\n"
" [-s min_chunk_sz] [-S max_chunk_sz] [-a nr_ahead]\n"
" [-b buf_sz] [-L limit_bitrate]\n"
" [-l login_name] [-P port] [-F ssh_config] [-o ssh_option]\n"
" [-i identity_file] [-c cipher_spec] [-M hmac_spec]\n"
" [-i identity_file] [-J destination] [-c cipher_spec] [-M hmac_spec]\n"
" [-C compress] [-g congestion]\n"
" source ... target\n"
"\n");
@@ -64,6 +64,7 @@ void usage(bool print_help)
" -F SSH_CONFIG path to user ssh config (default ~/.ssh/config)\n"
" -o SSH_OPTION ssh_config option\n"
" -i IDENTITY identity file for public key authentication\n"
" -J DESTINATION ProxyJump destination\n"
" -c CIPHER cipher spec\n"
" -M HMAC hmac spec\n"
" -C COMPRESS enable compression: "
@@ -277,7 +278,7 @@ int main(int argc, char **argv)
memset(&o, 0, sizeof(o));
o.severity = MSCP_SEVERITY_WARN;
#define mscpopts "n:m:u:I:W:R:s:S:a:b:L:46vqDrl:P:i:F:o:c:M:C:g:pdNh"
#define mscpopts "n:m:u:I:W:R:s:S:a:b:L:46vqDrl:P:F:o:i:J:c:M:C:g:pdNh"
while ((ch = getopt(argc, argv, mscpopts)) != -1) {
switch (ch) {
case 'n':
@@ -375,6 +376,9 @@ int main(int argc, char **argv)
case 'i':
s.identity = optarg;
break;
case 'J':
s.proxyjump = optarg;
break;
case 'c':
s.cipher = optarg;
break;

View File

@@ -88,6 +88,16 @@ static int ssh_set_opts(ssh_session ssh, struct mscp_ssh_opts *opts)
return -1;
}
if (opts->proxyjump) {
char buf[256];
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf), "proxyjump=%s", opts->proxyjump);
if (ssh_config_parse_string(ssh, buf) != SSH_OK) {
priv_set_errv("failed to set ssh option: %s", buf);
return -1;
}
}
if (opts->options) {
int n;
for (n = 0; opts->options[n]; n++) {

View File

@@ -530,6 +530,31 @@ def test_inline_option_ng(mscp, src_prefix, dst_prefix, option):
src.cleanup()
@pytest.mark.parametrize("src_prefix, dst_prefix", param_remote_prefix)
def test_porxyjump_ok(mscp, src_prefix, dst_prefix):
""" test -J proxyjump option"""
src = File("src", size = 10 * 1024 * 1024).make()
dst = File("dst")
# use small min-chunk-size to use multiple connections
run2ok([mscp, "-n", 4, "-s", 1024 * 1024, "-vvv",
"-J", "localhost:8022",
src_prefix + src.path, dst_prefix + dst.path])
assert check_same_md5sum(src, dst)
src.cleanup()
dst.cleanup()
@pytest.mark.parametrize("src_prefix, dst_prefix", param_remote_prefix)
def test_porxyjump_ng(mscp, src_prefix, dst_prefix):
""" test -J proxyjump option, invalid jump node causes fail"""
src = File("src", size = 10 * 1024 * 1024).make()
dst = File("dst")
# use small min-chunk-size to use multiple connections
run2ng([mscp, "-n", 4, "-s", 1024 * 1024, "-vvv",
"-J", "invaliduser@localhost:8022",
src_prefix + src.path, dst_prefix + dst.path])
src.cleanup()
# username test assumes that this test runs inside a container, see Dockerfiles
def test_specify_passphrase_via_env(mscp):
src = File(os.getcwd() + "/src", size = 1024).make()