SFTPGo -- 急我所急的SFTP server

在很多場景下,我們有來自不同的用戶上傳文件的需求。并且在文件上傳到服務(wù)器后,該目錄還需以NFS方式共享給其他服務(wù)器、應(yīng)用使用。
很久之前,我們一直通過vsftp等FTP軟件來實現(xiàn)文件的上傳、下載,性能很好,功能、配置也很豐富。
后來,安全問題造成了sftp的崛起。單端口和便利的傳輸加密使sftp獲得了更多人的青睞。
但是vsftp和sftp都有各自的優(yōu)勢和缺點。

對比 vsftp (passive mode) sftp
端口加固 1個通訊端口,很多個數(shù)據(jù)端口 單端口
傳輸加密 支持ssl加密,配置麻煩 原生支持ssl傳輸加密,無需配置
虛擬賬戶 支持virtual user 不支持虛擬賬戶

我們希望結(jié)合sftp端口加固和傳輸加密的優(yōu)勢和vsftp虛擬賬戶的優(yōu)勢。

SFTPGo

sftpgo git 地址 https://github.com/drakkan/sftpgo

SFTPGo 基于 Linux 開發(fā)和測試。

安裝需求
  • Go 1.13 或更高版本。
  • 數(shù)據(jù)庫服務(wù)器:PostreSQL 9.4+ ,MySQL 5.6+ , SQLite 3.x , bbolt 1.3.x。用于作為data provider.
安裝
[sysadmin@VM_201_18_centos opt]$ sudo tar xvJf sftpgo_0.9.5_linux_x86_64.tar.xz  -C sftpgo/
[sysadmin@VM_201_18_centos opt]$ ls sftpgo
init  LICENSE  README.pdf  scripts  sftpgo  sftpgo.json  sql  static  templates
配置

sftpgo的用法如下:

[sysadmin@VM_201_18_centos sftpgo]$ ls
init  LICENSE  README.pdf  scripts  sftpgo  sftpgo.json  sql  static  templates
[sysadmin@VM_201_18_centos sftpgo]$ 
[sysadmin@VM_201_18_centos sftpgo]$ 
[sysadmin@VM_201_18_centos sftpgo]$ ./sftpgo -h
Full featured and highly configurable SFTP server

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.

serve命令支持如下flags:

  • --config-dir 字符串。指定config目錄。目錄應(yīng)該包含sftpgo的配置文件,并且作為一些使用相對路徑文件的base目錄(比如:SFTP server的私鑰, SQLite or bblot 數(shù)據(jù)庫)。 默認值是 "." ,或者由環(huán)境變量SFTPGO_CONFIG_DIR定義。
  • --config-file 字符串。 配置文件名。它應(yīng)該是保存在config-dir的一個文件名,而不是配置文件的絕對路徑。指定的文件名不含擴展名,自動加載JSON, YAML, TOML, HCL and Java properties。默認是 "sftpgo" (因此會檢索 sftpgo.json, sftpgo.yaml 等) ,或者由環(huán)境變量SFTPGO_CONFIG_FILE定義。
  • --log-compress 布爾值。 定義被輪值切割的日志是否使用gzip壓縮。默認 false,或由環(huán)境變量 SFTPGO_LOG_COMPRESS定義 (1 or true, 0 or false)。如果log-file-path留空,那么該配置無效。
  • --log-file-path 字符串。定義Log文件路徑,默認 "sftpgo.log" ,或者由環(huán)境變量SFTPGO_LOG_FILE_PATH定義。留空會將Log寫入到 standard error。
  • --log-max-age 整數(shù)。 日志保留的最長天數(shù)。默認 28 ,或由環(huán)境變量SFTPGO_LOG_MAX_AGE定義。如果log-file-path留空,那么該配置無效。
  • --log-max-backups 整數(shù)。日志保留的最大數(shù)量。默認 5 ,或由環(huán)境變量SFTPGO_LOG_MAX_BACKUPS定義。如果log-file-path留空,那么該配置無效。
  • --log-max-size 整數(shù)。 日志文件切割的最大尺寸。默認 10 ,或由環(huán)境變量SFTPGO_LOG_MAX_SIZE定義。如果log-file-path留空,那么該配置無效。
  • --log-verbose 布爾值。 開啟詳細日志。默認 true ,或由環(huán)境變量SFTPGO_LOG_VERBOSE定義 (1 or true, 0 or false)。

如果你沒有配置私鑰,daemon 會使用配置目錄下的id_rsaid_ecdsa文件。如果文件不存在,會自動創(chuàng)建 (SFTPGo的運行用戶需要有config-dir的寫入權(quán)限)。服務(wù)器支持基于 crypto/ssh的私鑰。

sftpgo 配置文件定義包含三部分:
sftpd , data provider , httpd

"sftpd", SFTP server的配置項

  • bind_port, integer。 SFTP的服務(wù)端口。默認: 2022
  • bind_address, string。留空來監(jiān)聽所有可用網(wǎng)卡接口。默認: ""
  • idle_timeout, integer??臻eclient多少分鐘后被中斷。0 disable。默認:15。
  • max_auth_tries integer。每個連接的最大認證嘗試次數(shù)。如果設(shè)置為負值,那么嘗試次數(shù)不受限。如果設(shè)置為0,嘗試次數(shù)限制為6。
  • umask, string。Umask值。Windows無效。 默認: "0022"。
  • banner, string。驗證通過的歡迎語。留空則使用默認。 默認 SFTPGo_<version>, 范例 SSH-2.0-SFTPGo_0.9.5。
  • upload_mode integer。上傳模式定義。
    0 標準模式,文件會被直接上傳到請求路徑。
    1 原子模式,文件被上傳到臨時路徑,然后在上傳結(jié)束的時候重命名為請求路徑。 原子模式避免了類似如下的情況,當文件還在上傳的時候,web server 使用未上傳完畢的文件(partial files)提供了服務(wù)。在原子模式下,如果上傳報錯,臨時文件會被刪除,所以請求路徑下不會存在未上傳完畢的文件(partial files)。
    2 帶續(xù)傳的原子模式,類似原子模式,但是如果有上傳報錯,臨時文件會被重命名到請求路徑而不是刪除,這樣客戶端可以重連續(xù)傳。
  • actions, struct。包含要執(zhí)行的命令,提醒的HTTP URL,觸發(fā)器條件。 參考 "Custom Actions" 后去更詳細的信息。
    * execute_on, list of strings. 可用 download, upload, delete, rename, ssh_cmd。留空則 disable actions。
    * command, string。執(zhí)行命令的絕對路徑。留空則 disable。
    * http_notification_url, a valid URL。觸發(fā)一個到該URL的HTTP GET 請求。留空則 disable。
  • keys, struct array。包含了daemon的私鑰。如果留空或缺失,daemon會在配置目錄查找或者創(chuàng)建 id_rsaid_ecdsa 。
    * private_key, 私鑰的文件路徑。可以是配置目錄的相對路徑,或絕對路徑。
  • enable_scp, boolean。默認 disabled。設(shè)置為true來開啟實驗性的SCP支持。這個配置項不建議使用,在后面的版本會移除。請在enabled_ssh_commands清單添加 scp來開啟。
  • kex_algorithms, list of strings??捎玫?KEX (Key Exchange密碼交換) 算法,按順序優(yōu)先。留空使用默認值。支持的算法參考: crypto/ssh
  • ciphers, list of strings。 允許的密鑰密碼。留空使用默認值。支持的算法參考:: crypto/ssh
  • macs, list of strings??捎玫腗AC (message authentication code) 算法,按順序優(yōu)先。留空使用默認值。支持的算法參考:crypto/ssh
  • login_banner_file, 登錄banner文件路徑。文件的內(nèi)容會在認證允許前發(fā)給遠程用戶??梢允桥渲媚夸浀南鄬β窂剑蛘呓^對路徑。留空則 disable login banner。
  • setstat_mode, integer。
    0 - "正常模式": 變更權(quán)限,屬組,訪問/修改時間的需求會被執(zhí)行
    1 - "忽略模式": 變更權(quán)限,屬組,訪問/修改時間的需求會被忽略
  • enabled_ssh_commands, 允許的SSH命令清單。如下的一些 SSH 命令默認是開啟的: md5sum, sha1sum, cd, pwd。* 開啟所有支持的命令。有些命令在SFTPGo中實現(xiàn)了,還有些我們使用系統(tǒng)命令,需要被安裝并被配置在system的'PATH'中。For system commands we have no direct control on file creation/deletion and so we cannot support remote filesystems, such as S3, and 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 use cd and pwd SSH commands to get the initial directory. Currently cd does nothing and pwd 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's PATH. Git commands are not allowed inside virtual folders and inside directories with file extensions filters.
    * rsync. The rsync command need to be installed and in your system's PATH. We cannot avoid that rsync creates 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). The rsync command interacts with the filesystem directly and it is not aware about virtual folders and file extensions filters, so it will be automatically disabled for users with these features enabled.
  • keyboard_interactive_auth_program, string。Keyboard interactive authentication使用的擴展程序的絕對路徑。參考 "Keyboard Interactive Authentication" 獲取更多信息。
  • proxy_protocol, integer。HAProxy PROXY protocol的支持。如果將SFTPGo運行在proxy server后面, 比如 HAProxy, AWS ELB or NGNIX,你可以開啟 proxy protocol。它提供了一個簡便方式來可靠的傳輸連接信息,比如一個客戶端的地址經(jīng)過多層網(wǎng)絡(luò)(NAT or TCP proxies)來獲取真實的client IP 而不是proxy IP。協(xié)議版本1 and 2 都是被支持的。如果proxy protocol在SFTPGo開啟了,那么需要在proxy配置內(nèi)開啟protocol,比如對于 HAProxy 增加 send-proxy or send-proxy-v2對每個服務(wù)器配置。支持如下的模式:
    * 0, disabled
    * 1, enabled. Proxy header 會被使用,不帶proxy header的requests會被接收。
    * 2, required. Proxy header 會被使用,不帶proxy header的requests會被拒絕。
  • proxy_allowed, 允許發(fā)送proxy heard的IP地址或IP地址段。
    * 如果 proxy_protocol 設(shè)置為1,并且從沒在list中的IP收到 proxy header。連接會被接收,header會被忽略。
    * 如果 proxy_protocol 設(shè)置為2,并且從沒在list中的IP收到 proxy header。連接會被拒絕。

"data_provider", data provider的配置文件

  • driver, string。支持的驅(qū)動 sqlite, mysql, postgresql, bolt, memory
  • name, string。數(shù)據(jù)庫庫名。 For driver sqlite this can be the database name relative to the config dir or the absolute path to the SQLite database. For driver memory this is the (optional) path relative to the config dir or the absolute path to the users dump to load.
  • host, string。數(shù)據(jù)庫主機。對于sqlite, bolt and memory設(shè)置為空。
  • port, integer。數(shù)據(jù)庫端口。對于 sqlite, bolt and memory設(shè)置為空。
  • username, string。數(shù)據(jù)庫用戶名。對于 sqlite, bolt and memory設(shè)置為空。
  • password, string。數(shù)據(jù)庫密碼。對于 sqlite, bolt and memory設(shè)置為空。
  • sslmode, integer。適用于 mysql and postgresql。
    0 disable SSL/TLS connections,
    1 require ssl
    2 對于 postgresql設(shè)置ssl mode 為 verify-ca ,對于mysql設(shè)置為skip-verify
    3 對于 postgresql設(shè)置ssl mode 為 verify-full,對于mysql設(shè)置為preferred
  • 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 drivers bolt and memory
  • users_table, string。SFTP users 的數(shù)據(jù)庫表。
  • manage_users, integer。設(shè)置為0關(guān)閉users management, 1 開啟。
  • track_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。設(shè)置mysql或postgresql的最大連接數(shù)。默認 0 (不限制)
  • users_base_dir, string。用戶目錄。如果在創(chuàng)建用戶的時候沒有定義Home目錄,并且該值配置為絕對路徑,那么該目錄作為用戶的Home目錄。
  • actions, struct。包含了執(zhí)行的命令,HTTP URL,觸發(fā)條件。參見 "Custom Actions"獲取更多詳細信息。
    * execute_on, list of strings。Valid values are add, 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.
    * http_notification_url, a valid URL. Leave empty to disable.
  • external_auth_program, string。外部擴展認證程序的絕對路徑。參見 "External Authentication" 后去更詳細信息。留空關(guān)閉。
  • external_auth_scope, integer。
    0 所有認證方式 (密碼,公鑰 , keyboard interactive).
    1 僅密碼
    2 僅公鑰
    4 僅keyboard interactive。這個可以被綁定使用。
    6 公鑰和keyboard interactive
  • credentials_path, string。定義了用戶提供的認證文件的目錄,比如Google Cloud Storage credentials??梢允桥渲媚夸浀南鄬β窂剑蛘呓^對路徑。
  • pre_login_program, string。 Absolute path to an external program to use to modify user details just before the login. See the "Dynamic user modification" paragraph for more details. Leave empty to disable.

"httpd", 提供REST API的HTTP server的配置
* bind_port, integer。提供HTTP請求的端口。設(shè)置為 0 禁用HTTP server。默認t: 8080
* bind_address, string。留空以監(jiān)聽所有網(wǎng)絡(luò)接口。默認: "127.0.0.1"
* templates_path, string。 HTML web templates路徑。 可以設(shè)置為config dir的相對路徑或者絕對路徑。
* static_files_path, string。靜態(tài)文件路徑。可以設(shè)置為config dir的相對路徑或者絕對路徑。
* backups_path, string。Backup 目錄路徑??梢栽O(shè)置為config dir的相對路徑或者絕對路徑?;诎踩紤],不允許備份在arbitrary paths(任意路徑?)。
* auth_user_file, string。認證文件路徑??梢栽O(shè)置為config dir的相對路徑或者絕對路徑。支持HTTP認證,文件格式匹配Apache htpasswd工具創(chuàng)建的格式。密碼格式支持bcrypt ($2y$ prefix) 和md5 crypt ($apr1$ prefix)。留空則關(guān)閉HTTP認證。
* certificate_file, string。HTTPS證書。 可以設(shè)置為config dir的相對路徑或者絕對路徑。
* certificate_key_file, string。適配如上證書的私鑰??梢栽O(shè)置為config dir的相對路徑或者絕對路徑。如果證書和私鑰文件都已經(jīng)確認,那么服務(wù)器可以接收HTTPS連接了。證書和私鑰文件可以根據(jù)需要被重新加載,在基于Unix的系統(tǒng)上發(fā)送SIGHUP信號,windows上則是paramchange請求。

Data provider 初始化

在啟動SFTPGo server前,請確認配置的data provider已經(jīng)被初始化。

基于SQL的 data providers (SQLite, MySQL, PostgreSQL) 需要創(chuàng)建數(shù)據(jù)庫、表?;贛emory 和bolt的 data providers不需要初始化。

在配置文件配置完畢 data provider 后,你可以使用initprovider命令創(chuàng)建需要的數(shù)據(jù)庫結(jié)構(gòu)了。如果是SQLite provider,initprovider命令會自動創(chuàng)建數(shù)據(jù)庫文件和表。對于PostgreSQL 和MySQL,你需要先創(chuàng)建數(shù)據(jù)庫,然后initprovider命令會創(chuàng)建表。

范例,在配置目錄執(zhí)行如下命令:

sftpgo initprovider

查看命令行幫助

sftpgo initprovider --help

對于新安裝系統(tǒng), initprovider命令可以很好的完成初始化任務(wù)。從現(xiàn)在起,數(shù)據(jù)庫結(jié)構(gòu)可以在啟動的時候自動的檢查和升級了。

Upgrading

如果你從0.9.5版本或者之前的版本升級,你需要手動執(zhí)行SQL腳本來創(chuàng)建數(shù)據(jù)庫結(jié)構(gòu)。腳本位于源碼 sql 目錄。 腳本的名字是以日期YYYYMMDD和后綴 .sql命名的。執(zhí)行需要按照時間順序。比如, 20190828.sql 需要在20191112.sql之前執(zhí)行。
對于 SQLite: find sql/sqlite/ -type f -iname '*.sql' -print | sort -n | xargs cat | sqlite3 sftpgo.db。
在升級完畢后,你的數(shù)據(jù)庫結(jié)構(gòu)就和使用 initprovider命令初始化的結(jié)構(gòu)一樣了,以后就不需要再手動升級了。

以sqlite為范例運行一個SFTPGo Demo

如下是范例 sftogo.json配置文件,相對于默認配置文件僅修改了http bind-address為留空:

[sysadmin@VM_201_18_centos sftpgo]$ cat sftpgo.json 
{
  "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": ""
    },
    "external_auth_program": "",
    "external_auth_scope": 0
  },
  "httpd": {
    "bind_port": 8080,
    "bind_address": "",
    "templates_path": "templates",
    "static_files_path": "static",
    "backups_path": "backups"
  }
}

初始化data provider

[sysadmin@VM_201_18_centos sftpgo]$ ls
init  LICENSE  README.pdf  scripts  sftpgo  sftpgo.json  sftpgo.log  sql  static  templates
[sysadmin@VM_201_18_centos sftpgo]$ find sql/sqlite/ -type f -iname '*.sql' -print | sort -n | xargs cat | sqlite3 sftpgo.db
[sysadmin@VM_201_18_centos sftpgo]$ ls
init  LICENSE  README.pdf  scripts  sftpgo  sftpgo.db  sftpgo.json  sftpgo.log  sql  static  templates
[sysadmin@VM_201_18_centos sftpgo]$ 

開啟服務(wù)

[sysadmin@VM_201_18_centos sftpgo]$ ./sftpgo serve
2020-03-05T10:48:10.454 INF No host keys configured and "id_rsa" does not exist; creating new private key for server

新開一個窗口,查看目錄結(jié)構(gòu),會發(fā)現(xiàn)多了id_rsa和sftpgo.log文件

[sysadmin@VM_201_18_centos sftpgo]$ ls
id_rsa  init  LICENSE  README.pdf  scripts  sftpgo  sftpgo.db  sftpgo.json  sftpgo.log  sql  static  templates

查看端口

[sysadmin@VM_201_18_centos sftpgo]$ ps axu |grep sftpgo
sysadmin 22506  1.6  1.2 300436 12664 pts/1    Sl+  10:48   0:03 ./sftpgo serve
sysadmin 23037  0.0  0.0 112660   972 pts/0    R+   10:51   0:00 grep --color=auto sftpgo
[sysadmin@VM_201_18_centos sftpgo]$ 
[sysadmin@VM_201_18_centos sftpgo]$ 
[sysadmin@VM_201_18_centos sftpgo]$ sudo netstat -anpl |grep 22506
[sudo] password for sysadmin: 
tcp6       0      0 :::8080                 :::*                    LISTEN      22506/./sftpgo      
tcp6       0      0 :::2022                 :::*                    LISTEN      22506/./sftpgo      
[sysadmin@VM_201_18_centos sftpgo]$ 

訪問web


微信截圖_20200305105311.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容