cmd | ||
config | ||
dataprovider | ||
docker | ||
fail2ban | ||
httpd | ||
init | ||
logger | ||
metrics | ||
scripts | ||
service | ||
sftpd | ||
sql | ||
static | ||
templates | ||
utils | ||
.travis.yml | ||
go.mod | ||
go.sum | ||
LICENSE | ||
main.go | ||
README.md | ||
sftpgo.iss | ||
sftpgo.json |
SFTPGo
Full featured and highly configurable SFTP server
Features
- Each account is chrooted to his Home Dir.
- SFTP accounts are virtual accounts stored in a "data provider".
- SQLite, MySQL, PostgreSQL, bbolt (key/value store in pure Go) and in memory data providers are supported.
- Public key and password authentication. Multiple public keys per user are supported.
- Quota support: accounts can have individual quota expressed as max total size and/or max number of files.
- Bandwidth throttling is supported, with distinct settings for upload and download.
- Per user maximum concurrent sessions.
- Per user and per directory permissions: list directories content, upload, overwrite, download, delete, rename, create directories, create symlinks, changing owner/group and mode, changing access and modification times can be enabled or disabled.
- Per user files/folders ownership: you can map all the users to the system account that runs SFTPGo (all platforms are supported) or you can run SFTPGo as root user and map each user or group of users to a different system account (*NIX only).
- Per user IP filters are supported: login can be restricted to specific ranges of IP addresses or to a specific IP address.
- Configurable custom commands and/or HTTP notifications on file upload, download, delete, rename, on SSH commands and on user add, update and delete.
- Automatically terminating idle connections.
- Atomic uploads are configurable.
- Support for Git repositories over SSH.
- SCP and rsync are supported.
- Prometheus metrics are exposed.
- REST API for users management, backup, restore and real time reports of the active connections with possibility of forcibly closing a connection.
- Web based interface to easily manage users and connections.
- Easy migration from Unix system user accounts.
- Portable mode: a convenient way to share a single directory on demand.
- Configuration is a your choice: JSON, TOML, YAML, HCL, envfile are supported.
- Log files are accurate and they are saved in the easily parsable JSON format.
Platforms
SFTPGo is developed and tested on Linux. After each commit the code is automatically built and tested on Linux and macOS using Travis CI. Regularly the test cases are manually executed and pass on Windows. Other UNIX variants such as *BSD should work too.
Requirements
- Go 1.13 or higher as build only dependency.
- A suitable SQL server or key/value store to use as data provider: PostreSQL 9.4+ or MySQL 5.6+ or SQLite 3.x or bbolt 1.3.x
Installation
Binary releases for Linux, macOS and Windows are available, please visit the releases page.
Sample Dockerfiles for Debian and Alpine are available inside the source tree docker directory.
Some Linux distro packages are available:
- For Arch Linux via AUR:
- sftpgo. This package follow stable releases. It requires
git
,gcc
andgo
to build. - sftpgo-bin. This package follow stable releases downloading the prebuilt linux binary from GitHub. It does not require
git
,gcc
andgo
to build. - sftpgo-git. This package build and install the latest git master. It requires
git
,gcc
andgo
to build.
- sftpgo. This package follow stable releases. It requires
Alternately you can install the package to your $GOPATH with the go tool from shell:
$ go get -u github.com/drakkan/sftpgo
Make sure Git is installed on your machine and in your system's PATH
.
SFTPGo depends on go-sqlite3 that is a CGO package and so it requires a C
compiler at build time.
On Linux and macOS a compiler is easy to install or already installed, on Windows you need to download MinGW-w64 and build SFTPGo from its command prompt.
The compiler is a build time only dependency, it is not not required at runtime.
If you don't need SQLite, you can also get/build SFTPGo setting the environment variable GCO_ENABLED
to 0, this way SQLite support will be disabled but PostgreSQL, MySQL, bbolt and memory data providers will work and you don't need a C
compiler for building.
Version info, such as git commit and build date, can be embedded setting the following string variables at build time:
github.com/drakkan/sftpgo/utils.commit
github.com/drakkan/sftpgo/utils.date
For example you can build using the following command:
go build -i -ldflags "-s -w -X github.com/drakkan/sftpgo/utils.commit=`git describe --always --dirty` -X github.com/drakkan/sftpgo/utils.date=`date -u +%FT%TZ`" -o sftpgo
and you will get a version that includes git commit and build date like this one:
sftpgo -v
SFTPGo version: 0.9.0-dev-90607d4-dirty-2019-08-08T19:28:36Z
For Linux, a systemd
sample service can be found inside the source tree.
For macOS a launchd
sample service can be found inside the source tree. The launchd
plist assumes that sftpgo
has /usr/local/opt/sftpgo
as base directory.
On Windows you can run SFTPGo
as Windows Service, please read the "Configuration" section below for more details.
Configuration
The sftpgo
executable can be used this way:
Usage:
sftpgo [command]
Available Commands:
help Help about any command
portable Serve a single directory
serve Start the SFTP Server
Flags:
-h, --help help for sftpgo
-v, --version
Use "sftpgo [command] --help" for more information about a command
The serve
subcommand supports the following flags:
--config-dir
string. Location of the config dir. This directory should contain thesftpgo
configuration file and is used as the base for files with a relative path (eg. the private keys for the SFTP server, the SQLite or bblot database if you use SQLite or bbolt as data provider). The default value is "." or the value ofSFTPGO_CONFIG_DIR
environment variable.--config-file
string. Name of the configuration file. It must be the name of a file stored in config-dir not the absolute path to the configuration file. The specified file name must have no extension we automatically load JSON, YAML, TOML, HCL and Java properties. The default value is "sftpgo" (and thereforesftpgo.json
,sftpgo.yaml
and so on are searched) or the value ofSFTPGO_CONFIG_FILE
environment variable.--log-compress
boolean. Determine if the rotated log files should be compressed using gzip. Defaultfalse
or the value ofSFTPGO_LOG_COMPRESS
environment variable (1 ortrue
, 0 orfalse
). It is unused iflog-file-path
is empty.--log-file-path
string. Location for the log file, default "sftpgo.log" or the value ofSFTPGO_LOG_FILE_PATH
environment variable. Leave empty to write logs to the standard error.--log-max-age
int. Maximum number of days to retain old log files. Default 28 or the value ofSFTPGO_LOG_MAX_AGE
environment variable. It is unused iflog-file-path
is empty.--log-max-backups
int. Maximum number of old log files to retain. Default 5 or the value ofSFTPGO_LOG_MAX_BACKUPS
environment variable. It is unused iflog-file-path
is empty.--log-max-size
int. Maximum size in megabytes of the log file before it gets rotated. Default 10 or the value ofSFTPGO_LOG_MAX_SIZE
environment variable. It is unused iflog-file-path
is empty.--log-verbose
boolean. Enable verbose logs. Defaulttrue
or the value ofSFTPGO_LOG_VERBOSE
environment variable (1 ortrue
, 0 orfalse
).
If you don't configure any private host keys, the daemon will use id_rsa
in the configuration directory. If that file doesn't exist, the daemon will attempt to autogenerate it (if the user that executes SFTPGo has write access to the config-dir). The server supports any private key format supported by crypto/ssh
.
Before starting sftpgo
a dataprovider must be configured.
SQL scripts to create the required database structure can be found inside the source tree sql directory. The SQL scripts filename is, by convention, the date as YYYYMMDD
and the suffix .sql
. You need to apply all the SQL scripts for your database ordered by name, for example 20190828.sql
must be applied before 20191112.sql
and so on.
The sftpgo
configuration file contains the following sections:
- "sftpd", the configuration for the SFTP server
bind_port
, integer. The port used for serving SFTP requests. Default: 2022bind_address
, string. Leave blank to listen on all available network interfaces. Default: ""idle_timeout
, integer. Time in minutes after which an idle client will be disconnected. 0 menas disabled. Default: 15max_auth_tries
integer. Maximum number of authentication attempts permitted per connection. If set to a negative number, the number of attempts are unlimited. If set to zero, the number of attempts are limited to 6.umask
, string. Umask for the new files and directories. This setting has no effect on Windows. Default: "0022"banner
, string. Identification string used by the server. Leave empty to use the default banner. Default "SFTPGo_version"upload_mode
integer. 0 means standard, the files are uploaded directly to the requested path. 1 means atomic: files are uploaded to a temporary path and renamed to the requested path when the client ends the upload. Atomic mode avoids problems such as a web server that serves partial files when the files are being uploaded. In atomic mode if there is an upload error the temporary file is deleted and so the requested upload path will not contain a partial file. 2 means atomic with resume support: as atomic but if there is an upload error the temporary file is renamed to the requested path and not deleted, this way a client can reconnect and resume the upload.actions
, struct. It contains the command to execute and/or the HTTP URL to notify and the trigger conditionsexecute_on
, list of strings. Valid values aredownload
,upload
,delete
,rename
,ssh_cmd
. Actions will not be executed if an error is detected and so a partial file is uploaded or downloaded or an SSH command is not successfully completed. Theupload
condition includes both uploads to new files and overwrite of existing files. Thessh_cmd
condition will be triggered after a command is successfully executed via SSH.scp
will trigger thedownload
andupload
conditions and notssh_cmd
. Leave empty to disable actions.command
, string. Absolute path to the command to execute. Leave empty to disable. The command is invoked with the following arguments:action
, any validexecute_on
stringusername
, user who did the actionpath
to the affected file. Forrename
action this is the old file nametarget_path
, non empty forrename
action, this is the new file namessh_cmd
, non empty forssh_cmd
action
http_notification_url
, a valid URL. An HTTP GET request will be executed to this URL. Leave empty to disable. The query string will contain the following parameters that have the same meaning of the command's arguments:action
username
path
target_path
, added forrename
action onlyssh_cmd
, added forssh_cmd
action only
keys
, struct array. It contains the daemon's private keys. If empty or missing the daemon will search or try to generateid_rsa
in the configuration directory.private_key
, path to the private key file. It can be a path relative to the config dir or an absolute one.
enable_scp
, boolean. Default disabled. Set totrue
to enable the experimental SCP support. This setting is deprecated and will be removed in future versions, please addscp
to theenabled_ssh_commands
list to enable itkex_algorithms
, list of strings. Available KEX (Key Exchange) algorithms in preference order. Leave empty to use default values. The supported values can be found here:crypto/ssh
ciphers
, list of strings. Allowed ciphers. Leave empty to use default values. The supported values can be found here:crypto/ssh
macs
, list of strings. available MAC (message authentication code) algorithms in preference order. Leave empty to use default values. The supported values can be found here:crypto/ssh
login_banner_file
, path to the login banner file. The contents of the specified file, if any, are sent to the remote user before authentication is allowed. It can be a path relative to the config dir or an absolute one. Leave empty to send no login bannersetstat_mode
, integer. 0 means "normal mode": requests for changing permissions, owner/group and access/modification times are executed. 1 means "ignore mode": requests for changing permissions, owner/group and access/modification times are silently ignored.enabled_ssh_commands
, list of enabled SSH commands. These SSH commands are enabled by default:md5sum
,sha1sum
,cd
,pwd
.*
enables all supported commands. Some commands are implemented directly inside SFTPGo, while for other commands we use system commands that need to be installed and in your system'sPATH
. For system commands we have no direct control on file creation/deletion and so quota check is suboptimal: if quota is enabled, the number of files is checked at the command begin and not while new files are created. The allowed size is calculated as the difference between the max quota and the used one and it is checked against the bytes transferred via SSH. The command is aborted if it uploads more bytes than the remaining allowed size calculated at the command start. Anyway we see the bytes that the remote command send to the local command via SSH, these bytes contain both protocol commands and files and so the size of the files is different from the size trasferred via SSH: for example a command can send compressed files or a protocol command (few bytes) could delete a big file. To mitigate this issue quotas are recalculated at the command end with a full home directory scan, this could be heavy for big directories. If you need system commands and quotas you could consider to disable quota restrictions and periodically update quota usage yourself using the REST API. We support the following SSH commands:scp
, SCP is an experimental feature, we have our own SCP implementation since we can't rely on "scp" system command to proper handle quotas and user's home dir restrictions. The SCP protocol is quite simple but there is no official docs about it, so we need more testing and feedbacks before enabling it by default. We may not handle some borderline cases or have sneaky bugs. Please do accurate tests yourself before enabling SCP and let us known if something does not work as expected for your use cases. SCP between two remote hosts is supported using the-3
scp option.md5sum
,sha1sum
,sha256sum
,sha384sum
,sha512sum
. Useful to check message digests for uploaded files. These commands are implemented inside SFTPGo so they work even if the matching system commands are not available, for example on Windows.cd
,pwd
. Some SFTP clients does not support the SFTP SSH_FXP_REALPATH packet type and so they usecd
andpwd
SSH commands to get the initial directory. Currentlycd
do nothing andpwd
always returns the/
path.git-receive-pack
,git-upload-pack
,git-upload-archive
. These commands enable support for Git repositories over SSH, they need to be installed and in your system'sPATH
.rsync
. Thersync
command need to be installed and in your system'sPATH
. We cannot avoid that rsync create symlinks so if the user has the permission to create symlinks we add the option--safe-links
to the received rsync command if it is not already set. This should prevent to create symlinks that point outside the home dir. If the user cannot create symlinks we add the option--munge-links
, if it is not already set. This should make symlinks unusable (but manually recoverable)
- "data_provider", the configuration for the data provider
driver
, string. Supported drivers aresqlite
,mysql
,postgresql
,bolt
,memory
name
, string. Database name. For driversqlite
this can be the database name relative to the config dir or the absolute path to the SQLite database.host
, string. Database host. Leave empty for driverssqlite
,bolt
andmemory
port
, integer. Database port. Leave empty for driverssqlite
,bolt
andmemory
username
, string. Database user. Leave empty for driverssqlite
,bolt
andmemory
password
, string. Database password. Leave empty for driverssqlite
,bolt
andmemory
sslmode
, integer. Used for driversmysql
andpostgresql
. 0 disable SSL/TLS connections, 1 require ssl, 2 set ssl mode toverify-ca
for driverpostgresql
andskip-verify
for drivermysql
, 3 set ssl mode toverify-full
for driverpostgresql
andpreferred
for drivermysql
connectionstring
, string. Provide a custom database connection string. If not empty this connection string will be used instead of build one using the previous parameters. Leave empty for driversbolt
andmemory
users_table
, string. Database table for SFTP usersmanage_users
, integer. Set to 0 to disable users management, 1 to enabletrack_quota
, integer. Set the preferred mode to track users quota between the following choices:- 0, disable quota tracking. REST API to scan user dir and update quota will do nothing
- 1, quota is updated each time a user upload or delete a file even if the user has no quota restrictions
- 2, quota is updated each time a user upload or delete a file but only for users with quota restrictions. With this configuration the "quota scan" REST API can still be used to periodically update space usage for users without quota restrictions
pool_size
, integer. Sets the maximum number of open connections formysql
andpostgresql
driver. Default 0 (unlimited)users_base_dir
, string. Users' default base directory. If no home dir is defined while adding a new user, and this value is a valid absolute path, then the user home dir will be automatically defined as the path obtained joining the base dir and the usernameactions
, struct. It contains the command to execute and/or the HTTP URL to notify and the trigger conditionsexecute_on
, list of strings. Valid values areadd
,update
,delete
.update
action will not be fired for internal updates such as the last login or the user quota fields.command
, string. Absolute path to the command to execute. Leave empty to disable. The command is invoked with the following arguments that identify the user added, updated or deleted:action
, any validexecute_on
stringusername
ID
status
expiration_date
, as unix timestamp in millisecondshome_dir
uid
gid
http_notification_url
, a valid URL. The action is added to the query string. For example<http_notification_url>?action=update
. An HTTP POST request will be executed to this URL. The user is sent serialized as json inside the POST body. Leave empty to disable.
- "httpd", the configuration for the HTTP server used to serve REST API
bind_port
, integer. The port used for serving HTTP requests. Set to 0 to disable HTTP server. Default: 8080bind_address
, string. Leave blank to listen on all available network interfaces. Default: "127.0.0.1"templates_path
, string. Path to the HTML web templates. This can be an absolute path or a path relative to the config dirstatic_files_path
, string. Path to the static files for the web interface. This can be an absolute path or a path relative to the config dirbackups_path
, string. Path to the backup directory. This can be an absolute path or a path relative to the config dir. We don't allow backups in arbitrary paths for security reasons
Here is a full example showing the default config in JSON format:
{
"sftpd": {
"bind_port": 2022,
"bind_address": "",
"idle_timeout": 15,
"max_auth_tries": 0,
"umask": "0022",
"banner": "",
"upload_mode": 0,
"actions": {
"execute_on": [],
"command": "",
"http_notification_url": ""
},
"keys": [],
"enable_scp": false,
"kex_algorithms": [],
"ciphers": [],
"macs": [],
"login_banner_file": "",
"setstat_mode": 0,
"enabled_ssh_commands": ["md5sum", "sha1sum", "cd", "pwd"]
},
"data_provider": {
"driver": "sqlite",
"name": "sftpgo.db",
"host": "",
"port": 5432,
"username": "",
"password": "",
"sslmode": 0,
"connection_string": "",
"users_table": "users",
"manage_users": 1,
"track_quota": 2,
"pool_size": 0,
"users_base_dir": "",
"actions": {
"execute_on": [],
"command": "",
"http_notification_url": ""
}
},
"httpd": {
"bind_port": 8080,
"bind_address": "127.0.0.1",
"templates_path": "templates",
"static_files_path": "static",
"backups_path": "backups"
}
}
If you want to use a private key that use an algorithm different from RSA or more than one private key then replace the empty keys
array with something like this:
"keys": [
{
"private_key": "id_rsa"
},
{
"private_key": "id_ecdsa"
}
]
The configuration can be read from JSON, TOML, YAML, HCL, envfile and Java properties config files, if your config-file
flag is set to sftpgo
(default value) you need to create a configuration file called sftpgo.json
or sftpgo.yaml
and so on inside config-dir
.
You can also override all the available configuration options using environment variables, sftpgo will check for environment variables with a name matching the key uppercased and prefixed with the SFTPGO_
. You need to use __
to traverse a struct.
Let's see some examples:
- To set sftpd
bind_port
you need to define the env varSFTPGO_SFTPD__BIND_PORT
- To set the
execute_on
actions you need to define the env varSFTPGO_SFTPD__ACTIONS__EXECUTE_ON
for exampleSFTPGO_SFTPD__ACTIONS__EXECUTE_ON=upload,download
Please note that to override configuration options with environment variables a configuration file containing the options to override is required. You can, for example, deploy the default configuration file and then override the options you need to customize using environment variables.
To start the SFTP Server with the default values for the command line flags simply use:
sftpgo serve
On Windows you can register SFTPGo
as Windows Service, take a look at the CLI usage to learn how:
sftpgo.exe service --help
Install, Uninstall, Start, Stop and retrieve status for SFTPGo Windows Service
Usage:
sftpgo service [command]
Available Commands:
install Install SFTPGo as Windows Service
start Start SFTPGo Windows Service
status Retrieve the status for the SFTPGo Windows Service
stop Stop SFTPGo Windows Service
uninstall Uninstall SFTPGo Windows Service
Flags:
-h, --help help for service
Use "sftpgo service [command] --help" for more information about a command.
install
subcommand accepts the same flags valid for serve
.
After installing as Windows Service please remember to allow network access to the SFTPGo executable using something like this:
netsh advfirewall firewall add rule name="SFTPGo Service" dir=in action=allow program="C:\Program Files\SFTPGo\sftpgo.exe"
or through the Windows Firewall GUI.
Portable mode
SFTPGo allows to share a single directory on demand using the portable
subcommand:
sftpgo portable --help
To serve the current working directory with auto generated credentials simply use:
sftpgo portable
Please take a look at the usage below to customize the serving parameters
Usage:
sftpgo portable [flags]
Flags:
-C, --advertise-credentials If the SFTP service is advertised via multicast DNS this flag allows to put username/password inside the advertised TXT record
-S, --advertise-service Advertise SFTP service using multicast DNS (default true)
-d, --directory string Path to the directory to serve. This can be an absolute path or a path relative to the current directory (default ".")
-h, --help help for portable
-l, --log-file-path string Leave empty to disable logging
-p, --password string Leave empty to use an auto generated value
-g, --permissions strings User's permissions. "*" means any permission (default [list,download])
-k, --public-key strings
-s, --sftpd-port int 0 means a random non privileged port
-c, --ssh-commands strings SSH commands to enable. "*" means any supported SSH command including scp (default [md5sum,sha1sum,cd,pwd])
-u, --username string Leave empty to use an auto generated value
In portable mode SFTPGo can advertise the SFTP service and, optionally, the credentials via multicast DNS, so there is a standard way to discover the service and to automatically connect to it.
Here is an example of the advertised service including credentials as seen using avahi-browse
:
= enp0s31f6 IPv4 SFTPGo portable 53705 SFTP File Transfer local
hostname = [p1.local]
address = [192.168.1.230]
port = [53705]
txt = ["password=EWOo6pJe" "user=user" "version=0.9.3-dev-b409523-dirty-2019-10-26T13:43:32Z"]
Account's configuration properties
For each account the following properties can be configured:
username
password
used for password authentication. For users created using SFTPGo REST API if the password has no known hashing algo prefix it will be stored using argon2id. SFTPGo supports checking passwords stored with bcrypt, pbkdf2, md5crypt and sha512crypt too. For pbkdf2 the supported format is$<algo>$<iterations>$<salt>$<hashed pwd base64 encoded>
, where algo ispbkdf2-sha1
orpbkdf2-sha256
orpbkdf2-sha512
. For example thepbkdf2-sha256
of the wordpassword
using 150000 iterations andE86a9YMX3zC7
as salt must be stored as$pbkdf2-sha256$150000$E86a9YMX3zC7$R5J62hsSq+pYw00hLLPKBbcGXmq7fj5+/M0IFoYtZbo=
. For bcrypt the format must be the one supported by golang's crypto/bcrypt package, for example the passwordsecret
with cost14
must be stored as$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK
. For md5crypt and sha512crypt we support the format used in/etc/shadow
with the$1$
and$6$
prefix, this is useful if you are migrating from Unix system user accounts. Using the REST API you can send a password hashed as bcrypt, pbkdf2, md5crypt or sha512crypt and it will be stored as is.public_keys
array of public keys. At least one public key or the password is mandatory.status
1 means "active", 0 "inactive". An inactive account cannot login.expiration_date
expiration date as unix timestamp in milliseconds. An expired account cannot login. 0 means no expiration.home_dir
The user cannot upload or download files outside this directory. Must be an absolute path.uid
,gid
. If sftpgo runs as root system user then the created files and directories will be assigned to this system uid/gid. Ignored on windows and if sftpgo runs as non root user: in this case files and directories for all SFTP users will be owned by the system user that runs sftpgo.max_sessions
maximum concurrent sessions. 0 means unlimited.quota_size
maximum size allowed as bytes. 0 means unlimited.quota_files
maximum number of files allowed. 0 means unlimited.permissions
the following per directory permissions are supported:*
all permissions are grantedlist
list items is alloweddownload
download files is allowedupload
upload files is allowedoverwrite
overwrite an existing file, while uploading, is allowed.upload
permission is required to allow file overwritedelete
delete files or directories is allowedrename
rename files or directories is allowedcreate_dirs
create directories is allowedcreate_symlinks
create symbolic links is allowedchmod
changing file or directory permissions is allowed. On Windows, only the 0200 bit (owner writable) of mode is used; it controls whether the file's read-only attribute is set or cleared. The other bits are currently unused. Use mode 0400 for a read-only file and 0600 for a readable+writable file.chown
changing file or directory owner and group is allowed. Changing owner and group is not supported on Windows.chtimes
changing file or directory access and modification time is allowed
upload_bandwidth
maximum upload bandwidth as KB/s, 0 means unlimited.download_bandwidth
maximum download bandwidth as KB/s, 0 means unlimited.allowed_ip
, List of IP/Mask allowed to login. Any IP address not contained in this list cannot login. IP/Mask must be in CIDR notation as defined in RFC 4632 and RFC 4291, for example "192.0.2.0/24" or "2001:db8::/32"denied_ip
, List of IP/Mask not allowed to login. If an IP address is both allowed and denied then login will be denied
These properties are stored inside the data provider.
If you want to use your existing accounts you have two options:
- If your accounts are aleady stored inside a supported database, you can create a database view. Since a view is read only, you have to disable user management and quota tracking so SFTPGo will never try to write to the view
- you can import your users inside SFTPGo. Take a look at sftpgo_api_cli.py, it can convert and import users from Unix system users and Pure-FTPd/ProFTPD virtual users
REST API
SFTPGo exposes REST API to manage, backup and restore users and to get real time reports of the active connections with possibility of forcibly closing a connection.
If quota tracking is enabled in sftpgo
configuration file, then the used size and number of files are updated each time a file is added/removed. If files are added/removed not using SFTP/SCP or if you change track_quota
from 2
to 1
, you can rescan the users home dir and update the used quota using the REST API.
REST API is designed to run on localhost or on a trusted network, if you need HTTPS and/or authentication you can setup a reverse proxy using an HTTP Server such as Apache or NGNIX.
For example you can keep SFTPGo listening on localhost and expose it externally configuring a reverse proxy using Apache HTTP Server this way:
ProxyPass /api/v1 http://127.0.0.1:8080/api/v1
ProxyPassReverse /api/v1 http://127.0.0.1:8080/api/v1
and you can add authentication with something like this:
<Location /api/v1>
AuthType Digest
AuthName "Private"
AuthDigestDomain "/api/v1"
AuthDigestProvider file
AuthUserFile "/etc/httpd/conf/auth_digest"
Require valid-user
</Location>
and, of course, you can configure the web server to use HTTPS.
The OpenAPI 3 schema for the exposed API can be found inside the source tree: openapi.yaml.
A sample CLI client for the REST API can be found inside the source tree scripts directory.
You can also generate your own REST client, in your preferred programming language or even bash scripts, using an OpenAPI generator such as swagger-codegen or OpenAPI Generator
Metrics
SFTPGo exposes Prometheus metrics at the /metrics
HTTP endpoint.
Several counters and gauges are available, for example:
- Total uploads and downloads
- Total upload and download size
- Total upload and download errors
- Total executed SSH commands
- Total SSH command errors
- Number of active connections
- Data provider availability
- Total successful and failed logins using a password or a public key
- Total HTTP requests served and totals for response code
- Go's runtime details about GC, number of gouroutines and OS threads
- Process information like CPU, memory, file descriptor usage and start time
Please check the /metrics
page for more details.
Web Admin
You can easily build your own interface using the exposed REST API, anyway SFTPGo provides also a very basic builtin web interface that allows to manage users and connections.
With the default httpd
configuration, the web admin is available at the following URL:
If you need HTTPS and/or authentication you can setup a reverse proxy as explained for the REST API.
Logs
Inside the log file each line is a JSON struct, each struct has a sender
fields that identify the log type.
The logs can be divided into the following categories:
- "app logs", internal logs used to debug
sftpgo
:sender
string. This is generally the package name that emits the logtime
string. Date/time with millisecond precisionlevel
stringmessage
string
- "transfer logs", SFTP/SCP transfer logs:
sender
string.Upload
orDownload
time
string. Date/time with millisecond precisionlevel
stringelapsed_ms
, int64. Elapsed time, as milliseconds, for the upload/downloadsize_bytes
, int64. Size, as bytes, of the download/uploadusername
, stringfile_path
stringconnection_id
string. Unique connection identifierprotocol
string.SFTP
orSCP
- "command logs", SFTP/SCP command logs:
sender
string.Rename
,Rmdir
,Mkdir
,Symlink
,Remove
,Chmod
,Chown
,Chtimes
,SSHCommand
level
stringusername
, stringfile_path
stringtarget_path
stringfilemode
string. Valid for senderChmod
otherwise emptyuid
integer. Valid for senderChown
otherwise -1gid
integer. Valid for senderChown
otherwise -1access_time
datetime as YYYY-MM-DDTHH:MM:SS. Valid for senderChtimes
otherwise emptymodification_time
datetime as YYYY-MM-DDTHH:MM:SS. Valid for senderChtimes
otherwise emptyssh_command
, string. Valid for senderSSHCommand
otherwise emptyconnection_id
string. Unique connection identifierprotocol
string.SFTP
,SCP
orSSH
- "http logs", REST API logs:
sender
string.httpd
level
stringremote_addr
string. IP and port of the remote clientproto
string, for exampleHTTP/1.1
method
string. HTTP method (GET
,POST
,PUT
,DELETE
etc.)user_agent
stringuri
string. Full uriresp_status
integer. HTTP response status coderesp_size
integer. Size in bytes of the HTTP responseelapsed_ms
int64. Elapsed time, as milliseconds, to complete the requestrequest_id
string. Unique request identifier
- "connection failed logs", logs for failed attempts to initialize a connection. A connection can fail for an authentication error or other errors such as a client abort or a timeout if the login does not happen in two minutes
sender
string.connection_failed
level
stringusername
, string. Can be empty if the connection is closed before an authentication attemptclient_ip
string.login_type
string. Can bepublic_key
,password
orno_auth_tryed
error
string. Optional error description
Brute force protection
The connection failed logs can be used for integration in tools such as Fail2ban. Example of jails and filters working with systemd
/journald
are available in fail2ban directory.
Acknowledgements
- pkg/sftp
- go-chi
- zerolog
- lumberjack
- argon2id
- go-sqlite3
- go-sql-driver/mysql
- bbolt
- lib/pq
- viper
- cobra
- xid
- nathanaelle/password
- ZeroConf
- SB Admin 2
Some code was initially taken from Pterodactyl sftp server
License
GNU GPLv3