简介
SFTPGo是一款基于Go语言开发的简单易用的sftp server软件,支持Linux、MacOS及Windows平台。本文以Win10系统为例。
摘自网络:
FTP与SFTP区别:
ftp协议设计之初,分为了主动工作模式和被动工作模式,这两种工作模式一个是需要在服务器端随机开一个端口,让客户端连接这个新开的端口进行数据传输,一个是在ftp客户端随机开一个端口供服务器端主动连过来进行通讯,不管是哪一种对于有防火墙或者nat代理的网络都是极其不友好的,而且ftp通讯协议可以被wireshark等抓包工具轻易的抓出来登录ftp的用户名和密码,属于很不安全的一种通讯协议。
sftp协议基于tcp协议,只需要一个tcp端口即可完成全部的数据传输工作,对防火墙友好,通讯过程加密,不会被人轻易发现sftp的登录账户和密码信息,很适合作为ftp的替代品。
步骤:
如果是exe方式安装,按向导安装后可直接访问(服务自启动):
http://localhost:8080/web/admin/setup
sftpgo.exe service start --config-dir C:ProgramDataSFTPGo --log-file-path logssftpgo.log
1 安装
winget install SFTPGo
http://localhost:8080/web/admin
配置
方式一:命令行配置
Usage:
sftpgo [command]
Available Commands:
acme Obtain TLS certificates from ACME-based CAs like Let's Encrypt
gen A collection of useful generators
help Help about any command
initprovider Initialize and/or updates the configured data provider
ping Issues an health check to SFTPGo
portable Serve a single directory/account
resetprovider Reset the configured provider, any data will be lost
resetpwd Reset the password for the specified administrator
revertprovider Revert the configured data provider to a previous version
serve Start the SFTPGo service
smtptest Test the SMTP configuration
startsubsys Use sftpgo as SFTP file transfer subsystem
Flags:
-h, --help help for sftpgo
-v, --version
Use "sftpgo [command] --help" for more information about a command.
The serve command supports the following flags:
-
—config–dir string. Location of the config dir. This directory is used as the base for files with a relative path, eg. the private keys for the SFTP server or the SQLite database if you use SQLite as data provider. The configuration file, if not explicitly set, is looked for in this dir. We support reading from JSON, TOML, YAML, HCL, envfile and Java properties config files. The default config file name is sftpgo and therefore sftpgo.json, sftpgo.yaml and so on are searched. The default value is the working directory (“.”) or the value of SFTPGO_CONFIG_DIR environment variable.
-
—config-file string. This flag explicitly defines the path, name and extension of the config file. If must be an absolute path or a path relative to the configuration directory. The specified file name must have a supported extension (JSON, YAML, TOML, HCL or Java properties). The default value is empty or the value of SFTPGO_CONFIG_FILE environment variable.
-
—grace-time, integer. Graceful shutdown is an option to initiate a shutdown without abrupt cancellation of the currently ongoing client–initiated transfer sessions. This grace time defines the number of seconds allowed for existing transfers to get completed before shutting down. 0 means disabled. The default value is 0 or the value of SFTPGO_GRACE_TIME environment variable. A graceful shutdown is triggered by an interrupt signal or by a service stop request on Windows, if a grace time is configured.
-
—loaddata-from string. Load users and folders from this file. The file must be specified as absolute path and it must contain a backup obtained using the dumpdata REST API or compatible content. The default value is empty or the value of SFTPGO_LOADDATA_FROM environment variable.
-
—loaddata–clean boolean. Determine if the loaddata-from file should be removed after a successful load. Default false or the value of SFTPGO_LOADDATA_CLEAN environment variable (1 or true, 0 or false).
-
—loaddata–mode, integer. Restore mode for data to load. 0 means new users are added, existing users are updated. 1 means new users are added, existing users are not modified. Default 1 or the value of SFTPGO_LOADDATA_MODE environment variable.
-
–loaddata-scan, integer. Quota scan mode after data load. 0 means no quota scan. 1 means quota scan. 2 means scan quota if the user has quota restrictions. Default 0 or the value of SFTPGO_LOADDATA_QUOTA_SCAN environment variable.
-
—log–compress boolean. Determine if the rotated log files should be compressed using gzip. Default false or the value of SFTPGO_LOG_COMPRESS environment variable (1 or true, 0 or false). It is unused if log-file-path is empty.
-
—log-file-path string. Location for the log file, default “sftpgo.log” or the value of SFTPGO_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 of SFTPGO_LOG_MAX_AGE environment variable. It is unused if log-file-path is empty.
-
–log-max-backups int. Maximum number of old log files to retain. Default 5 or the value of SFTPGO_LOG_MAX_BACKUPS environment variable. It is unused if log-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 of SFTPGO_LOG_MAX_SIZE environment variable. It is unused if log-file-path is empty.
-
–log-level string. Set the log level. Supported values: debug, info, warn, error. Default debug or the value of SFTPGO_LOG_LEVEL environment variable.
-
–log-utc–time boolean. Enable UTC time for logging. Default false or the value of SFTPGO_LOG_UTC_TIME environment variable (1 or true, 0 or false)
Log file can be rotated on demand sending a SIGUSR1 signal on Unix based systems and using the command sftpgo service rotatelogs on Windows.
If you don‘t configure any private host key, the daemon will use id_rsa, id_ecdsa and id_ed25519 in the configuration directory. If these files don‘t exist, the daemon will attempt to autogenerate them. The server supports any private key format supported by crypto/ssh.
The gen command allows to generate completion scripts for your shell and man pages.
sftpgo.exe service --help
Manage the SFTPGo Windows Service
Usage:
sftpgo service [command]
Available Commands:
install Install SFTPGo as Windows Service
reload Reload the SFTPGo Windows Service sending a "paramchange" request
rotatelogs Signal to the running service to rotate the logs
start Start the SFTPGo Windows Service
status Retrieve the status for the SFTPGo Windows Service
stop Stop the SFTPGo Windows Service
uninstall Uninstall the SFTPGo Windows Service
Flags:
-h, --help help for service
Use "sftpgo service [command] --help" for more information about a command.
方式二:配置文件sftpgo.json
{
"common": {
"idle_timeout": 15,
"upload_mode": 0,
"actions": {
"execute_on": [],
"execute_sync": [],
"hook": ""
},
"setstat_mode": 0,
"rename_mode": 0,
"temp_path": "",
"proxy_protocol": 0,
"proxy_allowed": [],
"proxy_skipped": [],
"startup_hook": "",
"post_connect_hook": "",
"post_disconnect_hook": "",
"data_retention_hook": "",
"max_total_connections": 0,
"max_per_host_connections": 20,
"allowlist_status": 0,
"allow_self_connections": 0,
"defender": {
"enabled": false,
"driver": "memory",
"ban_time": 30,
"ban_time_increment": 50,
"threshold": 15,
"score_invalid": 2,
"score_valid": 1,
"score_limit_exceeded": 3,
"score_no_auth": 0,
"observation_time": 30,
"entries_soft_limit": 100,
"entries_hard_limit": 150
},
"rate_limiters": [
{
"average": 0,
"period": 1000,
"burst": 1,
"type": 2,
"protocols": [
"SSH",
"FTP",
"DAV",
"HTTP"
],
"generate_defender_events": false,
"entries_soft_limit": 100,
"entries_hard_limit": 150
}
]
},
"acme": {
"domains": [],
"email": "",
"key_type": "4096",
"certs_path": "certs",
"ca_endpoint": "https://acme-v02.api.letsencrypt.org/directory",
"renew_days": 30,
"http01_challenge": {
"port": 80,
"proxy_header": "",
"webroot": ""
},
"tls_alpn01_challenge": {
"port": 0
}
},
"sftpd": {
"bindings": [
{
"port": 2022,
"address": "",
"apply_proxy_config": true
}
],
"max_auth_tries": 0,
"banner": "",
"host_keys": [],
"host_certificates": [],
"host_key_algorithms": [],
"moduli": [],
"kex_algorithms": [],
"ciphers": [],
"macs": [],
"trusted_user_ca_keys": [],
"revoked_user_certs_file": "",
"login_banner_file": "",
"enabled_ssh_commands": [
"md5sum",
"sha1sum",
"sha256sum",
"cd",
"pwd",
"scp"
],
"keyboard_interactive_authentication": true,
"keyboard_interactive_auth_hook": "",
"password_authentication": true,
"folder_prefix": ""
},
"ftpd": {
"bindings": [
{
"port": 0,
"address": "",
"apply_proxy_config": true,
"tls_mode": 0,
"certificate_file": "",
"certificate_key_file": "",
"min_tls_version": 12,
"force_passive_ip": "",
"passive_ip_overrides": [],
"passive_host": "",
"client_auth_type": 0,
"tls_cipher_suites": [],
"passive_connections_security": 0,
"active_connections_security": 0,
"debug": false
}
],
"banner": "",
"banner_file": "",
"active_transfers_port_non_20": true,
"passive_port_range": {
"start": 50000,
"end": 50100
},
"disable_active_mode": false,
"enable_site": false,
"hash_support": 0,
"combine_support": 0,
"certificate_file": "",
"certificate_key_file": "",
"ca_certificates": [],
"ca_revocation_lists": []
},
"webdavd": {
"bindings": [
{
"port": 0,
"address": "",
"enable_https": false,
"certificate_file": "",
"certificate_key_file": "",
"min_tls_version": 12,
"client_auth_type": 0,
"tls_cipher_suites": [],
"prefix": "",
"proxy_allowed": [],
"client_ip_proxy_header": "",
"client_ip_header_depth": 0,
"disable_www_auth_header": false
}
],
"certificate_file": "",
"certificate_key_file": "",
"ca_certificates": [],
"ca_revocation_lists": [],
"cors": {
"enabled": false,
"allowed_origins": [],
"allowed_methods": [],
"allowed_headers": [],
"exposed_headers": [],
"allow_credentials": false,
"max_age": 0,
"options_passthrough": false,
"options_success_status": 0,
"allow_private_network": false
},
"cache": {
"users": {
"expiration_time": 0,
"max_size": 50
},
"mime_types": {
"enabled": true,
"max_size": 1000,
"custom_mappings": []
}
}
},
"data_provider": {
"driver": "sqlite",
"name": "sftpgo.db",
"host": "",
"port": 0,
"username": "",
"password": "",
"sslmode": 0,
"disable_sni": false,
"target_session_attrs": "",
"root_cert": "",
"client_cert": "",
"client_key": "",
"connection_string": "",
"sql_tables_prefix": "",
"track_quota": 2,
"delayed_quota_update": 0,
"pool_size": 0,
"users_base_dir": "",
"actions": {
"execute_on": [],
"execute_for": [],
"hook": ""
},
"external_auth_hook": "",
"external_auth_scope": 0,
"pre_login_hook": "",
"post_login_hook": "",
"post_login_scope": 0,
"check_password_hook": "",
"check_password_scope": 0,
"password_hashing": {
"bcrypt_options": {
"cost": 10
},
"argon2_options": {
"memory": 65536,
"iterations": 1,
"parallelism": 2
},
"algo": "bcrypt"
},
"password_validation": {
"admins": {
"min_entropy": 0
},
"users": {
"min_entropy": 0
}
},
"password_caching": true,
"update_mode": 0,
"create_default_admin": false,
"naming_rules": 5,
"is_shared": 0,
"node": {
"host": "",
"port": 0,
"proto": "http"
},
"backups_path": "backups"
},
"httpd": {
"bindings": [
{
"port": 8080,
"address": "",
"enable_web_admin": true,
"enable_web_client": true,
"enable_rest_api": true,
"enabled_login_methods": 0,
"enable_https": false,
"certificate_file": "",
"certificate_key_file": "",
"min_tls_version": 12,
"client_auth_type": 0,
"tls_cipher_suites": [],
"proxy_allowed": [],
"client_ip_proxy_header": "",
"client_ip_header_depth": 0,
"hide_login_url": 0,
"render_openapi": true,
"web_client_integrations": [],
"oidc": {
"client_id": "",
"client_secret": "",
"config_url": "",
"redirect_base_url": "",
"scopes": [
"openid",
"profile",
"email"
],
"username_field": "",
"role_field": "",
"implicit_roles": false,
"custom_fields": [],
"insecure_skip_signature_check": false,
"debug": false
},
"security": {
"enabled": false,
"allowed_hosts": [],
"allowed_hosts_are_regex": false,
"hosts_proxy_headers": [],
"https_redirect": false,
"https_host": "",
"https_proxy_headers": [],
"sts_seconds": 0,
"sts_include_subdomains": false,
"sts_preload": false,
"content_type_nosniff": false,
"content_security_policy": "",
"permissions_policy": "",
"cross_origin_opener_policy": "",
"expect_ct_header": ""
},
"branding": {
"web_admin": {
"name": "",
"short_name": "",
"favicon_path": "",
"logo_path": "",
"login_image_path": "",
"disclaimer_name": "",
"disclaimer_path": "",
"default_css": "",
"extra_css": []
},
"web_client": {
"name": "",
"short_name": "",
"favicon_path": "",
"logo_path": "",
"login_image_path": "",
"disclaimer_name": "",
"disclaimer_path": "",
"default_css": "",
"extra_css": []
}
}
}
],
"templates_path": "templates",
"static_files_path": "static",
"openapi_path": "openapi",
"web_root": "",
"certificate_file": "",
"certificate_key_file": "",
"ca_certificates": [],
"ca_revocation_lists": [],
"signing_passphrase": "",
"token_validation": 0,
"max_upload_file_size": 0,
"cors": {
"enabled": false,
"allowed_origins": [],
"allowed_methods": [],
"allowed_headers": [],
"exposed_headers": [],
"allow_credentials": false,
"max_age": 0,
"options_passthrough": false,
"options_success_status": 0,
"allow_private_network": false
},
"setup": {
"installation_code": "",
"installation_code_hint": "Installation code"
},
"hide_support_link": false
},
"telemetry": {
"bind_port": 0,
"bind_address": "127.0.0.1",
"enable_profiler": false,
"auth_user_file": "",
"certificate_file": "",
"certificate_key_file": "",
"min_tls_version": 12,
"tls_cipher_suites": []
},
"http": {
"timeout": 20,
"retry_wait_min": 2,
"retry_wait_max": 30,
"retry_max": 3,
"ca_certificates": [],
"certificates": [],
"skip_tls_verify": false,
"headers": []
},
"command": {
"timeout": 30,
"env": [],
"commands": []
},
"kms": {
"secrets": {
"url": "",
"master_key": "",
"master_key_path": ""
}
},
"mfa": {
"totp": [
{
"name": "Default",
"issuer": "SFTPGo",
"algo": "sha1"
}
]
},
"smtp": {
"host": "",
"port": 25,
"from": "",
"user": "",
"password": "",
"auth_type": 0,
"encryption": 0,
"domain": "",
"templates_path": "templates",
"debug": 0,
"oauth2": {
"provider": 0,
"tenant": "",
"client_id": "",
"client_secret": "",
"refresh_token": ""
}
},
"plugins": []
}
方式三:环境变量
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.
-
To set the port for the first sftpd binding, you need to define the env var SFTPGO_SFTPD__BINDINGS__0__PORT
-
To set the execute_on actions, you need to define the env var SFTPGO_COMMON__ACTIONS__EXECUTE_ON. For example SFTPGO_COMMON__ACTIONS__EXECUTE_ON=upload,download
Telemetry Server
The telemetry server publishes the following endpoints:
-
/healthz, health information (for health checks)
-
/debug/pprof, if enabled via the enable_profiler configuration key, for profiling
客户端编码
maven依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.13</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
示例代码
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.extra.ssh.JschRuntimeException;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.Session;
import cn.hutool.extra.ssh.JschUtil;
import cn.hutool.extra.ssh.Sftp;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;
public static void handler(String host, Integer port, String user, String pwd) {
Session session = null;
Sftp sftp = null;
ChannelSftp channel = null;
try {
session = JschUtil.getSession(host, port, user, pwd);
sftp = JschUtil.createSftp(session);
channel = JschUtil.openSftp(session);
String pwd1 = channel.pwd();
Vector ls = channel.ls(pwd1);
channel.mkdir("MFTS");
channel.cd("MFTS");
String pwd2 = channel.pwd();
channel.mkdir("HQ_FMStoCRP_HQ");
channel.cd("HQ_FMStoCRP_HQ");
String pwd3 = channel.pwd();
channel.mkdir("MftXfePlanDataFilefoCMDCSrv");
channel.cd("MftXfePlanDataFilefoCMDCSrv");
String pwd4 = channel.pwd();
/*if (!destExist) {
// 使用hutool创建目录有bug
mkDirs(channel, destFtpUrl);
}*/
/*File zipFile = ZipUtil.zip("C:/Users/tianfl/Desktop/PlanData.json", "C:/Users/tianfl/Desktop/PlanData_new");
if (!sftp.exist("/MFTS/HQ_FMStoCRP_HQ/MftXfePlanDataFilefoCMDCSrv")) {
mkDirs(channel, "/MFTS/HQ_FMStoCRP_HQ/MftXfePlanDataFilefoCMDCSrv");
}
sftp.upload("/MFTS/HQ_FMStoCRP_HQ/MftXfePlanDataFilefoCMDCSrv", zipFile);
zipFile.delete();
System.out.println(">>>>>>>>>>>>>>>>>>>>>");*/
} catch (Exception e) {
e.printStackTrace();
} finally {
if (channel != null) {
channel.disconnect();
}
if (sftp != null) {
sftp.close();
}
if (session != null) {
session.disconnect();
}
}
}
public static void mkDirs(ChannelSftp channel, String dir) throws SftpException {
String[] dirs = StrUtil.trim(dir).split("[\\/]+");
String now = channel.pwd();
if (dirs.length > 0 && StrUtil.isEmpty(dirs[0])) {
channel.cd("/");
}
String[] var4 = dirs;
int var5 = dirs.length;
for(int var6 = 0; var6 < var5; ++var6) {
String s = var4[var6];
if (StrUtil.isNotEmpty(s)) {
boolean exist = true;
try {
channel.cd(s);
} catch (SftpException e) {
exist = false;
}
if (!exist) {
mkdir(channel, s);
channel.cd(s);
}
}
}
channel.cd(now);
}
public static boolean mkdir(ChannelSftp channel, String dir) throws SftpException {
if (isDir(channel, dir)) {
return true;
} else {
try {
channel.mkdir(dir);
return true;
} catch (SftpException e) {
throw new JschRuntimeException(e);
}
}
}
public static boolean isDir(ChannelSftp channel, String dir) throws SftpException {
SftpATTRS sftpATTRS;
try {
sftpATTRS = channel.stat(dir);
} catch (SftpException e) {
if (e.getMessage().toLowerCase().contains("no such file")) {
return false;
}
throw e;
}
return sftpATTRS.isDir();
}
常见异常
java.net.ConnectException: Connection refused: connect
JSchException: Auth fail
-
当连接数压到10000时,会抛出以下异常
session is down
Connection reset by peer: socket write error
channel is not opened
inputstream is closed
docker search sftpgo
docker pull drakkan/sftpgo:v2.5.4
# Start a sftpgo server instance
docker run --name some-sftpgo -p 8080:8080 -p 2022:2022 -d "drakkan/sftpgo:v2.5.4"
# Enable FTP service
# You can change the passive ports range (50000-50100 by default) by setting the environment variables SFTPGO_FTPD__PASSIVE_PORT_RANGE__START and SFTPGO_FTPD__PASSIVE_PORT_RANGE__END
docker run --name some-sftpgo
-p 8080:8080
-p 2022:2022
-p 2121:2121
-p 50000-50100:50000-50100
-e SFTPGO_FTPD__BINDINGS__0__PORT=2121
-e SFTPGO_FTPD__BINDINGS__0__FORCE_PASSIVE_IP=<your external ip here>
-d "drakkan/sftpgo:tag"
原文地址:https://blog.csdn.net/wsdhla/article/details/128628801
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_24034.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!