.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" ======================================================================== .\" .IX Title "Net::SFTP::SftpServer 3pm" .TH Net::SFTP::SftpServer 3pm "2018-09-03" "perl v5.26.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Net::SFTP::SftpServer \- A Perl implementation of the SFTP subsystem with user access controls .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Net::SFTP::SftpServer; \& \& my $sftp = Net::SFTP::SftpServer\->new(); \& \& $sftp\->run(); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" A Perl port of sftp-server from openssh providing access control on a per user per command basis and improved logging via syslog .PP The limitations compared with the openssh implementation are as follows: .IP "\(bu" 4 Only files and directories are dealt with \- other types are not returned on readdir .IP "\(bu" 4 a virtual chroot is performed \- / is treated as the users home directory from the client perspective and all file access to / will be in // home_path is defined on object initialisation not accessed from /etc/passwd The script \s-1DOES NOT\s0 run under chroot \- this prevents it needing \s-1SUID\s0 to start. The virtual chroot is enforced by the objects and prevent opperations outside the home area .IP "\(bu" 4 all sym linked files or directories are hidden and not accessible on request .IP "\(bu" 4 symlink returns permission denied. Please contact me if you need this functionaility implementing .IP "\(bu" 4 readlink returns file does not exist. Please contact me if you need this functionaility implementing .IP "\(bu" 4 setting of stats (set_stat or set_fstat) is disabled \- client will receive permission denied. Please contact me if you need this functionaility implementing .IP "\(bu" 4 permissions for file or dir is defaulted \- default set on object initialisation .SH "USAGE" .IX Header "USAGE" Basic usage: .PP .Vb 1 \& use Net::SFTP::SftpServer; .Ve .PP Import options: .PP .Vb 2 \& :LOG \- Import logging functions for use in callbacks \& :ACTION \- Import constants for Allow/Deny of actions .Ve .PP Configuring syslog: .PP Syslog output mode must be configured in the use statement of the module as follows: .PP .Vb 1 \& use Net::SFTP::SftpServer ( { log => \*(Aqlocal5\*(Aq }, qw ( :LOG :ACTIONS ) ); .Ve .PP Net::SFTP::SftpServer will default to using \f(CW\*(C`daemon\*(C'\fR see your system's syslog documentation for more details .PP Options for object initialisation: .IP "\(bu" 4 debug .Sp Log debug level information. Deault=0 (note this will create very large log files \- use with caution) .IP "\(bu" 4 home .Sp Filesystem location of user home directories. default=/home .IP "\(bu" 4 file_perms .Sp Octal file permissions to force on creation of files. Default=0666 or permissions specified by file open command from client .IP "\(bu" 4 dir_perms .Sp Octal dir permissions to force on creation of directories. Default=0777 or permissions specified by mkdir command from client .IP "\(bu" 4 on_file_sent, on_file_received .Sp References to callback functions to be called on complete file sent or received. Function will be passed the full path and filename on the filesystem as a single argument .IP "\(bu" 4 use_tmp_upload .Sp Use temporary upload filenames while a file is being uploaded \- this allows a monitoring script to know which files are in transit without having to watch file size. Will be done transparently to the user, the file will be renamed to the original file name when close. The temportary extension is \*(L".SftpXFR.$$\*(R". Default=0 .IP "\(bu" 4 max_file_size .Sp Maximum file size (in bytes) which can be uploaded. Default=0 (no limit) .IP "\(bu" 4 valid_filename_char .Sp Array of valid characters for filenames .IP "\(bu" 4 allow, deny .Sp Actions allowed or denied \- see \*(L"\s-1PERMISSIONS\*(R"\s0 for details, Default is to allow \s-1ALL.\s0 .IP "\(bu" 4 fake_ok .Sp Array of actions (see action contants in \*(L"\s-1PERMISSIONS\*(R"\s0) which will be given response \s-1SSH2_FX_OK\s0 instead of \s-1SSH2_FX_PERMISSION_DENIED\s0 when denied by above deny options. Default=[] .IP "\(bu" 4 log_action_supress .Sp Array of actions to log quietly (logDetail \- syslog debug level), logs messages whenever this action is performed. Default is quiet for \s-1SSH2_FXP_READ, SSH2_FXP_WRITE, SSH2_FX_OPENDIR, SSH2_FXP_READDIR, SSH2_FXP_CLOSE, SSH2_FXP_STAT SSH2_FXP_FSTAT\s0 and \s-1SSH2_FXP_LSTAT\s0 override with log_action, see below. .IP "\(bu" 4 log_action .Sp Array of actions to log loudly (logGeneral \- syslog info level), logs messages whenever this action is performed. .IP "\(bu" 4 log_all_status .Sp Log all status messages at info level. By default \s-1SSH2_FX_OK\s0 and \s-1SSH2_FX_EOF\s0 will be logged at debug level. .SH "PERMISSIONS" .IX Header "PERMISSIONS" .Vb 10 \& ALL \- All actions \& NET_SFTP_SYMLINKS \- Symlinks in paths to files (recommended deny to enforce chroot) \& NET_SFTP_RENAME_DIR \- Rename directories (recommended deny if also denying SSH2_FXP_MKDIR) \& SSH2_FXP_OPEN \& SSH2_FXP_CLOSE \& SSH2_FXP_READ \& SSH2_FXP_WRITE \& SSH2_FXP_LSTAT \& SSH2_FXP_STAT_VERSION_0 \& SSH2_FXP_FSTAT \& SSH2_FXP_SETSTAT \- Automatically denied, not implemented in module \& SSH2_FXP_FSETSTAT \- Automatically denied, not implemented in module \& SSH2_FXP_OPENDIR \& SSH2_FXP_READDIR \& SSH2_FXP_REMOVE \& SSH2_FXP_MKDIR \& SSH2_FXP_RMDIR \& SSH2_FXP_STAT \& SSH2_FXP_RENAME \& SSH2_FXP_READLINK \- Automatically denied, not implemented in module \& SSH2_FXP_SYMLINK \- Automatically denied, not implemented in module .Ve .SH "CALLBACKS" .IX Header "CALLBACKS" Callback functions can be used to perform actions when files are sent or received, for example move a fully downloaded file to a processed directory or move a received file into an input directory. The callback is proided with a Net::SFTP::SftpServer::File object. This object allows access to the file within the virtual chroot environment. It will also return the full filename, or move the file to an explicit location on the full filesystem. Either of these actions will break the chroot and the methods on the object will no longer be available. .PP The following methods are provided .IP "\(bu" 4 read .Sp Read the data from the file \- as the IO::File\->read. Will open the file for reading if it is not already open and read back the data. .IP "\(bu" 4 open .Sp Will open the file \- as IO::File\->open but the filename is not supplied. .IP "\(bu" 4 getFilename .Sp Will return the filename as within the virtual chroot .IP "\(bu" 4 getFullFilenameBREAKCHROOT .Sp Will return the full filename on the real file system and break the virtual chroot .IP "\(bu" 4 renameBREAKCHROOT .Sp Takes a single argument of the new filename, will rename the file to that location and break the virtual chroot .SH "LOGGING" .IX Header "LOGGING" If :LOG is used when including Net::SFTP::SftpServer the following logging functions will be available: .PP .Vb 4 \& logError \- syslog with a log level of error \& logWarning \- syslog with a log level of warning \& logGeneral \- syslog with a log level of info \& logDetail \- syslog with a log level of debug, unless object was created with debug=>1 then syslog with a level of info .Ve .SH "HARDENED EXAMPLE SCRIPT" .IX Header "HARDENED EXAMPLE SCRIPT" The following example script shows how this module can be used to give far greater control over what is allowed on your \s-1SFTP\s0 server. .PP This setup is aimed at admins which want to user \s-1SFTP\s0 uploads but do not wish to grant users a system account. You will also need to set both the \s-1SFTP\s0 subsystem and the user's shell to the sftp script, eg /usr/local/bin/sftp\-server.pl .PP This configuration: .IP "\(bu" 4 Enforces that users can only access the sftp script, not an ssh shell. .IP "\(bu" 4 Chroots them into their home directory in /var/upload/sftp .IP "\(bu" 4 Sets all file permissions to 0660 and does not permit users to change them. .IP "\(bu" 4 Does not allow symlinks, making directories or renaming directories, but allows all other normal actions. .IP "\(bu" 4 Has a max upload filesize of 200Mb .IP "\(bu" 4 Has a script memory limit of 100Mb for safety .IP "\(bu" 4 Will log actions by user sftptest in debug mode .IP "\(bu" 4 Will only allow alphanumeric plus _ . and \- in filenames .IP "\(bu" 4 Will call ActionOnSent and ActionOnReceived respectively when files have been sent or received. .PP .Vb 1 \& #!/usr/local/bin/perl \& \& use strict; \& use warnings; \& use Net::SFTP::SftpServer ( { log => \*(Aqlocal5\*(Aq }, qw ( :LOG :ACTIONS ) ); \& use BSD::Resource; # for setrlimit \& \& use constant DEBUG_USER => { \& SFTPTEST => 1, \& }; \& \& \& # Security \- make sure we have started this as sftp not ssh \& unless ( scalar @ARGV == 2 and \& $ARGV[0] eq \*(Aq\-c\*(Aq and \& ($ARGV[1] eq \*(Aq/usr/local/bin/sftp\-server.pl\*(Aq) ){ \& \& logError "SFTP connection attempted for application $ARGV[0] \- exiting"; \& print "\en\erYou do not have permission to login interactively to this host.\en\er\en\erPlease contact the system administrator if you believe this to be a configuration error.\en\er"; \& exit 1; \& } \& \& my $MEMLIMIT = 100 * 1024 * 1024; # 100 Mb \& \& # hard limits on process memory usage; \& setrlimit( RLIMIT_RSS, $MEMLIMIT, $MEMLIMIT ); \& setrlimit( RLIMIT_VMEM, $MEMLIMIT, $MEMLIMIT ); \& \& my $debug = (defined DEBUG_USER\->{uc(getpwuid($>))} and DEBUG_USER\->{uc(getpwuid($>))}) ? 1 : 0; \& \& my $sftp = Net::SFTP::SftpServer\->new( \& debug => $debug, \& home => \*(Aq/var/upload/sftp\*(Aq, \& file_perms => 0660, \& on_file_sent => \e&ActionOnSent, \& on_file_received => \e&ActionOnReceived, \& use_tmp_upload => 1, \& max_file_size => 200 * 1024 * 1024, \& valid_filename_char => [ \*(Aqa\*(Aq .. \*(Aqz\*(Aq, \*(AqA\*(Aq .. \*(AqZ\*(Aq, \*(Aq0\*(Aq .. \*(Aq9\*(Aq, \*(Aq_\*(Aq, \*(Aq.\*(Aq, \*(Aq\-\*(Aq ], \& deny => ALL, \& allow => [ ( \& SSH2_FXP_OPEN, \& SSH2_FXP_CLOSE, \& SSH2_FXP_READ, \& SSH2_FXP_WRITE, \& SSH2_FXP_LSTAT, \& SSH2_FXP_STAT_VERSION_0, \& SSH2_FXP_FSTAT, \& SSH2_FXP_OPENDIR, \& SSH2_FXP_READDIR, \& SSH2_FXP_REMOVE, \& SSH2_FXP_STAT, \& SSH2_FXP_RENAME, \& )], \& fake_ok => [ ( \& SSH2_FXP_SETSTAT, \& SSH2_FXP_FSETSTAT, \& )], \& ); \& \& $sftp\->run(); \& \& sub ActionOnSent { \& my $fileObject = shift; \& ## Do Stuff \& } \& \& sub ActionOnReceived { \& my $fileObject = shift; \& ## Do Stuff \& } .Ve .SH "DEPENDENCIES" .IX Header "DEPENDENCIES" .Vb 5 \& Stat::lsMode \& Fcntl \& POSIX \& Sys::Syslog \& Errno .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" Sftp protocol .SH "AUTHOR" .IX Header "AUTHOR" .Vb 2 \& Simon Day, Pirum Systems Ltd \& cpan simonday.info .Ve .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" Based on sftp\-server.c Copyright (c) 2000\-2004 Markus Friedl. All rights reserved. .PP Ported to Perl and extended by Simon Day Copyright (c) 2009 Pirum Systems Ltd. All rights reserved. .PP Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. .PP \&\s-1THE SOFTWARE IS PROVIDED \*(L"AS IS\*(R" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\s0