Use in-memory file as argument in SFTP
문제
I need to open an SFTP connection in Perl and I need to use a dsa key file but I can't actually store the file on the hard disk for security reasons. I am trying to use Net::SFTP.
my $sftp = Net::SFTP->new(
$host, user=>"$userid",
ssh_args => {
identity_files => [ $pathToInMemoryKeyFile ]
}
);
I think I know how to get a string represented as an in memory file handle but I don't know how to get the path of that file handle such that I can pass it in as one of the ssh_args. Does anybody have any suggestions?
Thanks!
해결책
I've looked through the various options of doing SFTP (Net::SFTP hasn't been updated since 2005, Net::SFTP::Foreign is more up to date) and they all do key authentication via a file.
Net::SFTP is backed by Net::SSH::Perl which is a pure Perl SSH implementation. You can do some patching to make it do what you want. I'm going to sketch it out for you.
Patch or put a wrapper around Net::SSH::Perl::Auth::PublicKey->authenticate to look for a new configuration key. Let's call it identity_keys
.
sub authenticate {
my $auth = shift;
my $ssh = $auth->{ssh};
my $sent = 0;
if (my $agent = $auth->mgr->agent) {
do {
$sent = $auth->_auth_agent;
} until $sent || $agent->num_left <= 0;
}
return $sent if $sent;
##### This is the new bit which tries any keys passed in. ######
my $ik = $ssh->config->get('identity_keys') || [];
for my $key (@$ik) {
return 1 if $auth->_auth_key($key);
}
my $if = $ssh->config->get('identity_files') || [];
my $idx = $auth->{_identity_idx} || 0;
for my $f (@$if[$idx..$#$if]) {
$auth->{_identity_idx}++;
return 1 if $auth->_auth_identity($f);
}
}
auth_key
would be a copy of _auth_identity
but calling Net::SSH::Perl::Key->read_private_key which would be the guts of Net::SSH::Perl::Key->read_private_pem minus opening and reading the key from a file. read_private_pem
would then be gutted to use read_private_key
.
Alternatively, use an ssh-agent. It holds the decrypted private key in memory, so you can immediately wipe it from the disk.