Re: [qubes-devel] non-tcp pipe or stream between VMs - now works

286 views
Skip to first unread message

Igor Bukanov

unread,
Sep 25, 2012, 7:10:19 PM9/25/12
to Marek Marczykowski, qubes...@googlegroups.com
Thanks, /usr/lib/qubes/qrexec_client_vm is what I needed. To implement
that I put into ~/.ssh/config in the workvm:

ProxyCommand /usr/lib/qubes/qrexec_client_vm netvm ssh.Proxy
/usr/local/bin/my_ssh_proxy.pl %h %p

Here /usr/local/bin/my_ssh_proxy.pl is a perl script that first writes
host and port to netvm and then proceeds to copy input from the netvm
to the local output and copy local input to remote ( see the source
below ).

Then I created /etc/qubes_rpc/polices/ssh.Proxy in dom0 VM with single line:
workvm netvm allow

Then in netvm I created a script in /usr/local/bin that prepare the
proxy setup and called that script from /rw/config/rc.local (after
making that executable) :

#!/bin/sh
cmd=/usr/bin/my_ssh_proxy
echo "$cmd" > /etc/qubes_rpc/ssh.Proxy
cat > "$cmd" <<'_eof_'
#!/bin/sh
read host port
exec echo /usr/bin/nc "$host" "$port"
_eof_

chmod 755 "$cmd"

Then I run the script and ssh from the work vm started to work even
after I disabled any networking there.

Here is that /usr/local/bin/my_ssh_proxy.pl script:

#!/usr/bin/perl -w

use strict;
use IO::Handle;


print "$ARGV[0] $ARGV[1]\n";

sub copy_fd {
my $input = shift;
my $output = shift;
my $buf = '';
my $length = 1 << 16;
for (;;) {
my $nread = $input->sysread($buf, $length);
die "failed to read: $!" unless defined $nread;
last unless $nread;
my $offset = 0;
for (;;) {
my $nwritten = $output->syswrite($buf, $nread, $offset);
die "failed to write: $!" unless defined $nwritten;
$nread -= $nwritten;
$offset += $nwritten;
last unless $nread;
}
}
}

my $local_input = IO::Handle->new_from_fd(int($ENV{SAVED_FD_0}), "r");
my $local_output = IO::Handle->new_from_fd(int($ENV{SAVED_FD_1}), "w");
my $remote_input = IO::Handle->new_from_fd(fileno(STDIN), "r");
my $remote_output = IO::Handle->new_from_fd(fileno(STDOUT), "w");

$SIG{CHLD} = "IGNORE";

my $kidpid = fork;
die "can't fork: $!" unless defined $kidpid;

$SIG{PIPE} = sub { exit 0; };

if ($kidpid) {
# parent proceess, copy from local to remote
$local_output->close;
$remote_input->close;
copy_fd($local_input, $remote_output);
kill($kidpid);
} else {
# child proceess, copy from remote to local
$local_input->close;
$remote_output->close;
copy_fd($remote_input, $local_output);
}

On 25 September 2012 14:50, Marek Marczykowski
<marm...@invisiblethingslab.com> wrote:
> On 25.09.2012 12:00, Igor Bukanov wrote:
>> For my work VM I just need a working SSH client connection. As openssh
>> client can establish connection over arbitrary pipe, I wonder if it is
>> possible to create non-tcp pipe-like connection between say, work VM
>> and firewall VM? Presumably such pipe should require significantly
>> less code than TCP-IP stack and would protect the work WM against bugs
>> in that stack as it would not face the outside world.
>
> Am I understand correctly that you want something like:
> work---(some-pipe)-->firewallvm---(tcp)-->destination host
> ?
>
> It can be easily done using Qrexec and socat, some details here:
> https://wiki.qubes-os.org/trac/wiki/Qrexec
>
> The only possible problem is how pass destination host address.
>
> --
> Best Regards / Pozdrawiam,
> Marek Marczykowski
> Invisible Things Lab
>
Reply all
Reply to author
Forward
0 new messages