FTP and SFTP storage¶
Two built-in adapters keep a source in a directory on a file server:
ftp: FTP and FTPS (explicit TLS). It uses the standard library, so it needs no extra.sftp: SFTP over SSH, through paramiko. It needs thesftpextra:pip install "jodit-python[sftp]"(or[all]). Without it, requests to SFTP sources answer501and other sources keep working.
The editor loads files from baseurl, not through the connector. Point baseurl at the web server that publishes the same directory, for example https://www.example.com/uploads/ for /public_html/uploads.
Quick start¶
{
"sources": {
"site": {
"title": "Website files",
"baseurl": "https://www.example.com/uploads/",
"storageAdapter": "sftp",
"sftp": {
"host": "files.example.com",
"username": "editor",
"privateKeyFile": "/run/secrets/editor_ed25519",
"hostKey": "ssh-ed25519 AAAA...paste the line printed by ssh-keyscan",
"directory": "/var/www/uploads"
}
}
}
}
Get the host key for hostKey from the server itself:
Copy the whole line it prints (files.example.com ssh-ed25519 AAAA...) or just its ssh-ed25519 AAAA... part. Compare the fingerprint (ssh-keygen -lf) with the one your hosting provider publishes.
FTP options¶
All options live under sources.<name>.ftp.
| Option | Type | Default | Meaning |
|---|---|---|---|
host |
string |
required | Server name or address |
port |
integer |
21 |
Control connection port |
username |
string |
anonymous |
Login |
password |
string |
"" |
Password |
directory |
string |
login directory | Directory acting as the source root; absolute, or relative to the login directory |
tls |
boolean |
false |
Explicit FTPS (AUTH TLS): commands and data are encrypted |
verifyCertificate |
boolean |
true |
Check the server certificate and name with the system CAs; turn off only for self-signed certificates on a trusted network |
timeout |
number |
30 |
Seconds to wait for the server |
connections |
integer |
4 |
Most connections open at once (1–64) |
idleTimeout |
number |
60 |
Seconds an unused connection is kept before it is reopened |
encoding |
string |
utf-8 |
Encoding of file names |
SFTP options¶
All options live under sources.<name>.sftp.
| Option | Type | Default | Meaning |
|---|---|---|---|
host |
string |
required | Server name or address |
port |
integer |
22 |
SSH port |
username |
string |
required | Login |
password |
string |
none | Password |
privateKey |
string |
none | Private key text (OpenSSH or PEM; Ed25519, ECDSA or RSA) |
privateKeyFile |
string |
none | Path to a private key file; not together with privateKey |
passphrase |
string |
none | Passphrase of an encrypted private key |
hostKey |
string or string[] |
none | Accepted server keys, as printed by ssh-keyscan |
knownHostsFile |
string |
system known_hosts |
OpenSSH known_hosts file used when hostKey is not set |
directory |
string |
login directory | Directory acting as the source root; absolute, or relative to the login directory |
timeout |
number |
30 |
Seconds to wait for the server |
connections |
integer |
4 |
Most connections open at once (1–64) |
idleTimeout |
number |
300 |
Seconds an unused connection is kept before it is reopened |
The SSH agent and the keys in ~/.ssh are not used; the adapter authenticates only with what the options name.
Host keys¶
The server's key is always checked. It is compared, in this order, with hostKey, with the entries of knownHostsFile, or with the system known_hosts (~/.ssh/known_hosts of the user running the connector). A key that is missing or different fails the connection with Server '...' not found in known_hosts. Unknown keys are never accepted on first use: that would let anyone on the network path impersonate the server and receive the uploads and the password.
When the server's key changes (a reinstall, a key rotation), put the new key in hostKey. List both keys during the rotation.
Secrets¶
Passwords and keys in a configuration file are readable by anyone who can read the file. Keep the file private, or pass the credentials through a dynamic source that reads them from your secret store. privateKeyFile can point at a mounted secret, such as /run/secrets/... in Docker.
How files are handled¶
- Connections. Each source keeps up to
connectionsconnections open and shares them between requests. A connection that dropped while idle is reopened and the operation is retried once. - Writes. Uploads and generated files are written to a temporary
.<random>.tmpfile in the target folder and then renamed over the target. Readers never see a partial file, and a failed upload leaves the previous file in place. A server that refuses to rename over an existing file gets the old file moved aside first and put back if the rename fails. - Streaming. Downloads are streamed in 64 KiB chunks. Uploads are sent from the request's temporary file.
- Copies. FTP and SFTP have no server-side copy, so the connector downloads the file (at most 1 MB in memory, the rest in a temporary file) and uploads it again. Renames and moves are server-side.
- Links. Symbolic links and other special entries are skipped in listings, like on the local filesystem.
FTP specifics¶
MLST/MLSDare used when the server has them (pure-ftpd, ProFTPD, FileZilla Server, IIS). OtherwiseSIZE,MDTMandLISTare used (vsftpd), and Unix and Windows (IIS/DOS) listing formats are read.- Times are taken as UTC. Without
MLSD, listings of recent files carry minutes, not seconds, and folders have no time. - Passive mode is used. The address the server announces for data connections is ignored, and data connections go to
host. This helps servers behind NAT and prevents a server from redirecting the connector elsewhere. - FTPS data connections resume the TLS session of the control connection, which vsftpd requires by default (
require_ssl_reuse).
Limits¶
- Plain FTP sends the password and the files unencrypted. Use
tls: trueor SFTP outside a trusted network. - Implicit FTPS (a TLS-only port, usually 990) is not supported. Use explicit FTPS on port 21.
- On FTP servers without
MLSD, listing a folder that does not exist may return an empty list instead of an error. - Each open download holds one connection until it finishes, so
connectionslimits the number of simultaneous downloads per source.
Troubleshooting¶
Server '...' not found in known_hosts- Set
hostKeyto the output ofssh-keyscanfor that host and port. Keys inknown_hostsfor a non-standard port are stored as[host]:port. 530 Login incorrect/AuthenticationException- Check
usernameandpassword. For SFTP with a key, also check that the server has the public key inauthorized_keysand thatpassphraseis set for an encrypted key. 425 Can't open data connectionor timeouts on listings- The server's passive port range is blocked by a firewall. Open it, or check the server's passive-mode settings.
certificate verify failed- The server's certificate is not signed by a CA the system trusts, or the certificate name does not match
host. Use the name on the certificate, install the CA, or setverifyCertificate: falseon a trusted network.