From 7986d8cfee8f32c191c916c2e4e35ecb9b8ac8f3 Mon Sep 17 00:00:00 2001 From: Nigel Kukard Date: Mon, 10 Oct 2016 17:55:00 +0000 Subject: [PATCH 1/2] Added support for --libvirt-vnc --- awit-ssh | 133 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 118 insertions(+), 15 deletions(-) diff --git a/awit-ssh b/awit-ssh index 778c3e3..ddae810 100755 --- a/awit-ssh +++ b/awit-ssh @@ -54,7 +54,7 @@ use User::pwent; my $NAME = "AWIT-SSH-Client"; -our $VERSION = "0.7.2"; +our $VERSION = "0.8.0"; print(STDERR "$NAME v$VERSION - Copyright (c) 2016, AllWorldIT\n\n"); @@ -73,6 +73,8 @@ GetOptions(\%optctl, "knock=s", "rsync", + + "libvirt-vnc=s", ) or exit 1; # Check for help @@ -88,12 +90,23 @@ if (defined($optctl{'version'})) { } # Check if we using rsync instead of SSH -my $useRsync = 0; +my $useRsync; my @rsyncParams; if (defined(my $rsyncHost = $optctl{'rsync'})) { $useRsync = $rsyncHost; } +# Check if we using libvirt vnc instead of SSH +my $libvirtVNC; +if (defined(my $vmName = $optctl{'libvirt-vnc'})) { + if (! -x '/usr/bin/ssvncviewer') { + logger('ERROR',color('magenta')."To use --libvirt-vnc you need to install ssvncviewer. Hint: apt-get install ssvnc". + color('reset')); + exit 1; + } + $libvirtVNC = $vmName; +} + # Check if we should be doing port knocking my ($knockHost,$knockPort); if (defined(my $knock = $optctl{'knock'})) { @@ -106,12 +119,19 @@ if (defined(my $knock = $optctl{'knock'})) { } +# Check for option combinations +if (defined($useRsync) && defined($libvirtVNC)) { + logger('ERROR',color('magenta')."Options --rsync and --libvirt-monitor cannot be used together".color('reset')); + exit 1; +} + + # Variables we may set below my $loginUsername; # Pull in hostname my $hostSpec; -if ($useRsync) { +if (defined($useRsync)) { foreach my $param (@ARGV) { # Look for the remote:// param if ($param =~ /remote:\/\//) { @@ -523,10 +543,12 @@ delete($ENV{'LC_CTYPE'}); my $TMPDIR = $ENV{'XDG_RUNTIME_DIR'} // $ENV{'TMPDIR'} // '/tmp'; -# Setup our forward port name +# Sockets we may use our $forwardSocket; -# Forward child PID +our $libvirtSocket; +# Children PID's we may create our $forwardChild; +our $libvirtChild; # Check if we're forwarding, we need to work a few things out... if (defined($forwardHost)) { @@ -610,7 +632,7 @@ if (defined($forwardSocket)) { (defined($forwardPort) ? " on port '".color('green')."$forwardPort".color('reset')."'" : "") . "...\n\n\n"); # Check what operation we're doing - if ($useRsync) { + if (defined($useRsync)) { # Build SSH command my $sshCmd = join(' ','/usr/bin/ssh', @sshArgs, @@ -625,7 +647,6 @@ if (defined($forwardSocket)) { @rsyncParams ); - # Normal SSH } else { # Fire up SSH system('/usr/bin/ssh', @@ -644,7 +665,7 @@ if (defined($forwardSocket)) { undef($forwardSocket); } else { - logger('ERROR',color('magenta')."Socket not connected, aborting!".color('reset')); + logger('ERROR',color('magenta')."Forward socket not connected, aborting!".color('reset')); } @@ -668,8 +689,8 @@ if (defined($forwardSocket)) { push(@sshArgs,'-p',$loginPort); } - # Check what operation we're doing - if ($useRsync) { + # Check if we're doing rsync... + if (defined($useRsync)) { # Build SSH command my $sshCmd = join(' ','/usr/bin/ssh', @sshArgs, @@ -683,6 +704,72 @@ if (defined($forwardSocket)) { @rsyncParams ); + # Check if we're doing libvirt monitor port forwarding... + } elsif (defined($libvirtVNC)) { + # Split off host and port + my ($vncHost,$vncDisplay) = split(':',$libvirtVNC); + if (!defined($vncHost) || $vncHost ne "127.0.0.1" || !defined($vncDisplay)) { + logger('ERROR',color('magenta')."Libvirt VNC socket looks invalid '%s'".color('reset'),$libvirtVNC); + exit 1; + } + # VNC port is the display plus 5900 + my $vncPort = 5900 + $vncDisplay; + + # Add forward socket name + $libvirtSocket = "$TMPDIR/awit-ssh-vnc-".sha1_hex("$loginHost:$loginPort:$libvirtVNC $$").".sock"; + + my @libvirtArgs = (); + + # Add on port we're forwarding + push(@libvirtArgs,'-L',"$libvirtSocket:$vncHost:$vncPort"); + + # Fork off child to establish the main connection + $libvirtChild = fork(); + if (!$libvirtChild) { + # Don't use signals for this child + undef($SIG{'TERM'}); + undef($SIG{'INT'}); + + # Exec ssh + if (!exec('/usr/bin/ssh', + @sshArgs, + '-o','ControlMaster=no', + @libvirtArgs, + # Use basic compression + '-o','Compression=yes', + '-o','CompressionLevel=7', + # All we're doing here is forwarding the port... + '-N', + $loginHost + )) { + + logger('ERROR',color('magenta')."Libvirt VNC unix forwarding SSH process failed to start".color('reset')); + + exit 1; + } + } + + # Loop waiting for the socket to be created + my $delay = 30; + while (! -e $libvirtSocket && $delay > 0) { + $delay--; + sleep 1; + } + + # If we still have timeout ticks left, then we connected, hopefully successfully + if ($delay) { + system('/usr/bin/ssvncviewer', + '-encodings','copyrect tight hextile zlib corre rre raw', + '-quality','7', + # This is handled by ssh + '-compresslevel','0', + '-16bpp', + $libvirtSocket); + } else { + logger('ERROR',color('magenta')."Libvirt socket not connected, aborting!".color('reset')); + } + + # Normal SSH } else { system('/usr/bin/ssh', @@ -714,16 +801,27 @@ exit 0; # Cleanup function sub cleanup { - # Kill the child + # Kill the children if ($forwardChild && kill(0,$forwardChild)) { kill('TERM',$forwardChild); # Wait for it to die waitpid($forwardChild,-1); } + if ($libvirtChild && kill(0,$libvirtChild)) { + kill('TERM',$libvirtChild); + # Wait for it to die + waitpid($libvirtChild,-1); + } - # Unlink the socket + # Unlink sockets if ($forwardSocket) { unlink($forwardSocket); + } + if ($libvirtSocket) { + unlink($libvirtSocket); + } + # Check if we exiting abnormally... + if ($forwardSocket || $libvirtSocket) { print STDERR "\nExiting...\n"; exit 1; } @@ -760,19 +858,24 @@ sub displayHelp print(STDERR< [USER@]HOST $0 --rsync -- remote://[USER@]HOST/file.name /tmp + $0 --libvirt-vnc HOST:PORT General Options: --help What you're seeing now. --version Display version. + Port Knocking: + --knock HOST:PORT Port knock a host to get access. + Secure Copy: (using rsync) - --rsync Run rsync instead of ssh, passing all + --rsync ... Run rsync instead of ssh, passing all command line parameters after the host to it. HOST is used for searching LDAP. - Port Knocking: - --knock HOST:PORT Port knock a host to get access. + Libvirt: + --libvirt-vnc ... Connect to the qemu machines VNC. + EOF return; -- GitLab From bb5517317d3fe40776cb39c1f85795889668cba7 Mon Sep 17 00:00:00 2001 From: Nigel Kukard Date: Mon, 10 Oct 2016 21:01:48 +0000 Subject: [PATCH 2/2] Slight enhancement to rsync options Display progress and verbosity by default --- awit-ssh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/awit-ssh b/awit-ssh index ddae810..8f37d2b 100755 --- a/awit-ssh +++ b/awit-ssh @@ -696,10 +696,11 @@ if (defined($forwardSocket)) { @sshArgs, # Use basic compression '-o','Compression=yes', - '-o','CompressionLevel=1' + '-o','CompressionLevel=7' ); # Run rsync system('/usr/bin/rsync', + '-vP', '-e',$sshCmd, @rsyncParams ); -- GitLab