I figured out to make it work with a behind-NAT connection.
I have to connect to the server with ssh like this - ssh -A -R 9999:localhost:22 urth.org
Now I've updated my script to assume that there's a reverse tunnel on port 9999:
#!/usr/bin/perl
use strict; use warnings;
use File::Temp qw(tempfile);
my ( $fh, $filename ) = tempfile();
print $fh $_ while <>;
seek $fh, 0, 0;
system( 'scp', '-P', 9999, '-o', 'StrictHostKeyChecking=no', $filename, 'localhost:' . $filename ); system( 'ssh', '-p', 9999, '-o', 'StrictHostKeyChecking=no', 'localhost', 'DISPLAY=:0.0 gnome-open ' . $filename );
I think the warnings are because the keys on your machine are for localhost:22 whereas you are connecting to localhost:9999. You should be able to retain host key checks by telling ssh that it’s connecting through a proxy. Here I used netcat.
Try this for extra evil (untested):
#!/usr/bin/perl
use strict;
use warnings;
open my $pipe, '|-', 'ssh', '-o', 'ProxyCommand=nc localhost 9999', 'localhost', 'perl';
die "Can't fork: $!\n" unless defined $pipe;
print $pipe <<'END_PERL';
use strict;
use warnings;
use File::Temp qw( tempfile );
my ( $fh, $filename ) = tempfile();
local $/ = \65536;
print $fh $_ while <DATA>;
$ENV{DISPLAY}=':0.0';
system 'gnome-open', $filename;
__DATA__
END_PERL
local $/ = \65536;
print $fh $_ while <>;
SSH over SSH is not very efficient though. You could write a script that forks and runs ssh then stays around while that process is running, accepting connections on some port (bound to localhost only for security reasons) and writing the data to a file which it invokes gnome-open
on it. Then on the remote side all you’d need to do is pipe the file to nc localhost 9999
.