NAME
Net::LibSSH - Perl binding for libssh — SSH without SFTP dependency
VERSION
version 0.003
SYNOPSIS
use Net::LibSSH;
my $ssh = Net::LibSSH->new;
$ssh->option(host => 'server.example.com');
$ssh->option(user => 'root');
$ssh->option(port => 22);
$ssh->connect or die "connect failed: " . $ssh->error;
$ssh->auth_agent or die "auth failed: " . $ssh->error;
my $ch = $ssh->channel;
$ch->exec("uname -r");
my $out = $ch->read;
print "Kernel: $out";
print "Exit: ", $ch->exit_status, "\n";
# Optional SFTP (returns undef if SFTP subsystem not available)
if (my $sftp = $ssh->sftp) {
my $attr = $sftp->stat('/etc/hostname');
print "size: $attr->{size}\n" if $attr;
}
DESCRIPTION
Net::LibSSH is a Perl XS binding for libssh.
Unlike Net::SSH2 (which wraps libssh2) and Net::OpenSSH (which wraps the system ssh binary), this module links directly against libssh — a separate, actively maintained C library. The key difference for automation use cases: what this module exposes are exec channels via Net::LibSSH::Channel, not a file transfer API. File operations are built on top of those channels — as Rex::LibSSH does — and therefore need no SFTP subsystem on the remote host.
SFTP is supported as an optional feature via "sftp": it returns undef gracefully when the remote server has no SFTP subsystem, rather than crashing.
Note: This module is not thread-safe and does not support fork. Use one connection per process.
METHODS
new
my $ssh = Net::LibSSH->new;
Creates a new session object.
option($key, $value)
$ssh->option(host => 'server.example.com');
$ssh->option(port => 22);
$ssh->option(user => 'root');
Set a session option before connecting. Supported keys: host, port, user, knownhosts, timeout, compression, log_verbosity, strict_hostkeycheck (set to 0 to disable host key verification).
Croaks if $key is not one of the keys above, or if libssh rejects the resulting value. $value is not validated on this side of the boundary — numeric options go through Perl's ordinary numeric conversion, so a non-numeric string silently becomes 0 — and whether that ends up croaking is entirely libssh's call, not something you can rely on uniformly. For example, port => 'nonsense' croaks (libssh rejects port 0), while timeout => 'nonsense' or log_verbosity => 'nonsense' are silently accepted as 0. Do not read the absence of a croak here as validation.
connect
$ssh->connect or die $ssh->error;
Connect to the host. Returns 1 on success, 0 on failure, and never dies — including when called on a session that has already been connected and disconnected, see "disconnect".
disconnect
$ssh->disconnect;
Disconnect from the host. Every Net::LibSSH::Channel and Net::LibSSH::SFTP object already opened on this session is invalidated by the same call — libssh frees the channels as part of disconnecting. From that point on, every method on such an object but close croaks with "session was disconnected", a message distinct from a channel's own "channel is closed" so a caller can tell its own teardown from this one; see "close" in Net::LibSSH::Channel. Closing such a channel, or simply letting it or an SFTP object go out of scope, is safe and does nothing.
$ssh->channel and $ssh->sftp called on a session that has already disconnected return undef rather than croaking — the same graceful-failure contract they already have for any other failure to open.
The session itself is not reusable once it has actually been connected and then disconnected: calling "connect" again on it returns 0 immediately, with error() reporting "session was disconnected and cannot be reconnected". This module refuses the call itself, without asking libssh — measured against libssh 0.10.6, ssh_connect() on such a session does not fail fast, it sits out the whole timeout option and only then reports a misleading "Timeout connecting to ...". Treat disconnect/connect as one-way — not a cycle you can repeat on the same session.
Calling disconnect on a session that was never successfully connected does not spend it: a later "connect" on it still works normally. Only a connect/disconnect pair is terminal, not the mere act of disconnecting.
error
my $msg = $ssh->error;
Return the last error message from libssh, or undef — not the empty string — when libssh has nothing to report. One message is this module's own rather than libssh's — the refusal described in "disconnect" — and takes precedence over whatever libssh has to say.
auth_password($password)
$ssh->auth_password('s3cr3t') or die $ssh->error;
auth_publickey($privkey_path)
$ssh->auth_publickey('/root/.ssh/id_ed25519') or die $ssh->error;
auth_agent
$ssh->auth_agent or die $ssh->error;
Authenticate via the SSH agent, falling back to the default key files (public-key auto-authentication) whenever the agent attempt does not succeed — not only when no agent is running, but also when a reachable agent's authentication is rejected. A true return therefore does not by itself prove that the agent was used; it only means one of the two methods succeeded.
channel
my $ch = $ssh->channel;
Open a new session channel. Returns a Net::LibSSH::Channel object, or undef on failure — including when called on a session that has already disconnected, see "disconnect". The returned channel keeps this session alive on its own; see Net::LibSSH::Channel for what that guarantees and what it does not.
sftp
my $sftp = $ssh->sftp; # returns undef if SFTP not available
Open an SFTP session. Returns a Net::LibSSH::SFTP object, or undef if the remote server does not support SFTP. This is the documented way to detect SFTP availability — sftp never throws for that reason, on this or any other failure to open the session, including being called on a session that has already disconnected, see "disconnect". Like "channel", the returned object keeps this session alive on its own.
SEE ALSO
Net::LibSSH::Channel, Net::LibSSH::SFTP, Alien::libssh, Net::SSH2
SUPPORT
Issues
Please report bugs and feature requests on GitHub at https://github.com/Getty/p5-net-libssh/issues.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <getty@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.