The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Net::Dropbear::SSHd - Embed and control a Dropbear SSH server inside of perl

SYNOPSIS

  use Net::Dropbear::SSHd;
  
  Net::Dropbear::XS::gen_key($key_filename);
  
  my $sshd = Net::Dropbear::SSHd->new(
    addrs      => '2222',
    keys       => $key_filename,
    hooks      => {
      on_log => sub
      {
        my $priority = shift;
        my $msg      = shift;
        warn( "$msg\n" );
        return HOOK_CONTINUE;
      },
    }
  );
  
  $sshd->run;
  $sshd->wait;

DESCRIPTION

Net::Dropbear::SSHd allows you to embed and control an SSH server (using Dropbear) from perl.

Motivation

Maybe you're asking yourself why you'd want to do that? Imagine that you want to run a service where you let users run remote commands over SSH, say SFTP or git. Also imagine that you'd like maintain the users or public keys in a database instead of in a file. A good example of this behavior would be Github and other cloud-based git-over-ssh solutions.

I'm pretty confident that one could get OpenSSH to do this, but I saw a couple problems:

The user must be a real user

Any user that wants to connect must be a real user at the OS level. Managing multiple users, let alone millions, is a nightmare.

OpenSSH really likes running as root

Until recently, running as non-root was even possible. It's now possible, but a lot of interesting features are restricted.

Authorized keys can be provided through a script owned by root

A continuation of the point above, but in order to enable OpenSSH to verify a key, a script can be provided. This script (and all directories leading to the script) must be owned by root.

OpenSSH (and SSH) have a lot of options

And while that is a good thing in general, in this particular case I was not confident that I could tune all the options correctly to make sure I wasn't completely securing the system.

I really didn't want to provide outside users with a clever way to gain access to my machine. That's where this module comes into play. The goal of Net::Dropbear::SSHd is that you can control the entire lifecycle of SSHd, including which usernames are accpeted, which public keys are authorized and what commands are ran.

CONSTRUCTOR

new

  my $sshd = Net::Dropbear::SSHd->new({ %params });

Returns a new Net::Dropbear::SSHd object.

Attributes

addrs

A string or an array of addresses to bind to. Default: Nothing

keys

An array of strings that are the server keys for Dropbear. Default: Generate keys automatically

hooks

A hashref of coderef's that get called during key points of the SSH server session. See "Hooks".

Dropbear options

debug

Default: off

If Dropbear is complied with trace debuging turned on (not the default), turning this on will enable Dropbear's debugging information to be dumped.

forkbg

Default: off

Turning the forkbg option on means that Dropbear will fork into the background. Since Net::Dropbear::SSHd forks to run the main Dropbear code, doing this second fork would seem redundant.

usingsyslog

Default: off

Turning the usingsyslog option on means Dropbear will use syslog to output it's logs. Regardless of this setting, the on_log hook will still be called.

norootlogin

Default: on

Turning the norootlogin option on means that root can not login.

noauthpass

Default: on

Turning the noauthpass option on means that password authentication is not allowed

norootpass

Default: on

Turning the norootpass option on means that root cannot authenticate using a password.

allowblankpass

Default: off

Turning the allowblankpass option on means that if the SSH client requests it, Dropbear will authenticate someone with a blank password.

delay_hostkey

Default: off

Turning the delay_hostkey option on tells Dropbear to not generate hostkey files until the first user connects. This allows for faster startup times the very first time in exchange for a delayed connection for the very first user.

domotd

Default: off

Turning on the domotd option means that when an interactive session is started, the message of the day is sent.

noremotetcp

Default: on

Turning on the noremotetcp option means that Dropbear will not create remote forwarded TCP tunnels.

nolocaltcp

Default: on

Turning on the nolocaltcp option means that Dropbear will not create locally forwarded TCP tunnels.

Hooks

During the run of Dropbear, Net::Dropbear::SSHd hooks into certain points of the processing. With these hooks, the outcome of Dropbear can be changed. Each hook can return one of the hook constants: "HOOK_COMPLETE", "HOOK_CONTINUE" or "HOOK_FAILURE". Unless otherwise noted, returning "HOOK_CONTINUE" will result in Dropbear continuing as though the hook hadn't been called. See the hooks attribute.

on_log(priority, message)

The on_log hook is called when Dropbear logs anything.

HOOK_COMPLETE - No more logging will take place

HOOK_FAILURE - Logging will continue as normal

on_start()

The on_start hook is called after Dropbear is done initalizing.

HOOK_COMPLETE - Identical to HOOK_CONTINUE

HOOK_FAILURE - Dropbear will exit

on_username(username)

The on_username hook is called when a username is given. Returning anything but HOOK_CONTINUE from this will prevent on_passwd_fill or on_shadow_fill from being called.

HOOK_COMPLETE - The username is acceptable and dummy entries are used for the password file

HOOK_FAILURE - The username is rejected

on_passwd_fill(AuthState, username)

The on_passwd_fill hook is called when Dropbear is filling in information for a user from the passwd file. The AuthState paramater is an object that can be manipulated to fill in information for Dropbear. See Net::Dropbear::XS::AuthState. If any AuthState data is left invalid, Dropbear will exit.

HOOK_COMPLETE - The AuthState object should be used as the passwd information.

HOOK_FAILURE - The passwd information is invalid and the user connection will be rejected.

on_shadow_fill(crypt_password, pw_name)

The on_shadow_fill hook is called when the shadow file is consulted for a users password. Note that this is called even if HOOK_COMPLETE is returned from on_passwd_fill. The first paramter (crypt_password) is mutable and can be used to set what the user's crypted password is. If the crypt_password is invalid (null), Dropbear will exit.

HOOK_COMPLETE - The shadow file will not be consulted for the given user

HOOK_FAILURE - Ignored

on_crypt_passwd(input_passwd, salt, pw_name)

The on_crypt_passwd hook is used as an opportunity to crypt the password given by the connection yourself. It will give you the password as it was entered, and you are expected to change $_[0] in place to a crypted version that will match the value given in either on_passwd_fill or on_shadow_fill.

HOOK_COMPLETE - The crypt function doesn't need to be ran, and Dropbear can check the value of input_passwd directly.

HOOK_FAILURE - Ignored

on_check_pubkey(authkeys, pw_name)

The on_check_pubkey hook is called right before the the public keys for a user is checked. The first paramater, authkeys, is an string that can be populated with an authorized_keys(8) file and it will be used to authenticate the user given with pw_name.

HOOK_COMPLETE - Identical to HOOK_CONTINUE

HOOK_FAILURE - The public keys could not be retrieved and will not be checked.

on_new_channel(on_new_channel)

The on_new_channel hook is called when the client requests a new channel. The first paramater, on_new_channel, will contain the channel type as a string.

HOOK_COMPLETE - Identical to HOOK_CONTINUE

HOOK_FAILURE - The channel is denied with SSH_OPEN_ADMINISTRATIVELY_PROHIBITED

on_chansess_command(chansess)

The on_chansess_command hook is called when a new command is being requested by the client. The first paramater, chaness, is an object that should be used to let Dropbear know how to interact with the channel. See Net::Dropbear::XS::SessionAccept for more details.

HOOK_COMPLETE - No attempts will be made to start the command specified

HOOK_CONTINUE - The values from chansess will be copied into Dropbear and used in Dropbear's default operations

HOOK_FAILURE - The command session will behave as though the command had vailed

METHODS

run

Call $sshd->run to start Dropbear.

child

If Dropbear has been started, then this will return the Child::Link::Proc object of the child process. If Dropbear is not running, this will return undef. In the child process this will be undef as well.

comm

The comm method is a convience for both parent and child processes. This contains a two-way socket between the parent and child (and sub-children) processes. This is a AF_UNIX socket, which means you can pass new file handles between the processes.

is_running

Returns true if Dropbear is running, false if it's not.

stop

This will stop Dropbear.

wait

This waits for Dropbear to exit after it is sent the kill signal.

CONSTANTS

The constants below are exported by default.

HOOK_COMPLETE

This is used to indicate that a hook is done and not to use Dropbear's default operations.

HOOK_CONTINUE

This is used to indicate that the hook has decided not to do anything.

HOOK_FAILURE

This is used to indicate that the hook has failed and Dropbear should not continue.

CHILD PROCESSES

Since Dropbear is a program itself, it is ran as a child process. Each connection will also have it's own child process.

AUTHOR

Jon Gentle <atrodo@cpan.org>

COPYRIGHT

Copyright 2015-2016 Jon Gentle

LICENSE

This is free software. You may redistribute copies of it under the terms of the Artistic License 2 as published by The Perl Foundation.

This includes a complete copy of Dropbear that is patched and used. The majority of Dropbear is Copyright (c) 2002-2014 Matt Johnston under the MIT license. See https://matt.ucc.asn.au/dropbear/dropbear.html for details about Dropbear and it's license.