SFTPGo: A Full Featured SFTP Server in Go
github.com
github.com
Go has a really good set of crypto primitives, an excellent ssh implementation maintained by the core team, and a great sftp server and client library which makes this project possible.
I recently added an sftp server to rclone: https://rclone.org/commands/rclone_serve_sftp/ - this can serve any of the cloud providers rclone support as sftp (or local disk). This runs on windows/macOS/linux too.
It was a joy to add this as the Go libraries are very well thought out and easy to use.
Edit: just looked at the amalgamation again, it's huge... Still surprised no one has tried it yet that I know of. Pre-processor directives would probably make it even more difficult though.
Edit2: and it already works so what's the point, other than an extremely challenging problem
It's really not that hard. The code is clearly documented and everything works in roughly the same way. Easily achievable by a single developer in a few months.
Sqlite code is emulating classes with structs and methods (they're even called classes in the code). This it's pretty easy to translate into languages with reference and struct support.
Memory allocation is separated into an allocation provider, which is easy to implement in GC languages (just create the struct requested).
The parser and VM opcode file is tricky. The opcodes are parsed from comments in one big file. I'm not a fan of that. But once generated for a particular version, pretty easy to translate.
Testing is another can of worms. Translating the exact version of Tcl, too is the best course of action. This is required to run and pass the (hundreds of thousands of) base line tests. Other correctness tests (in sqlite because of branch coverage requirements for aircraft software) are harder to translate. The prerelease burn in test is also not publicly available.
Preprocessor directives are not used as macros. Rather they are used to enable features. In a port, you can for example choose to exclude WAL or specific optimizations. FTS can be left out if not needed. The different lock implementations can be deferred to the stdlib.
If you interested in the perf overhead, here's a small benchmark of a C# implementation I maintain:
https://drive.google.com/file/d/11Bgfh1WgEreDenosoEdWkYAOb6u...
Edit: Here it is: https://gitlab.com/cznic/sqlite
That being said if you really wanted to use sqlite for the database, you'd do the exact same thing, use a persistent volume.
There's only one table..."users". SQL seems like a bit of overkill for this. Maybe there are future plans to save more state.
This seems to fly in the face of that.
If you are willing to install more software, why not use a more feature filled file server?
because SSH and SFTP are so closely tied together, a configuration via PAM is pretty hard and inconvenient because creating fake users via PAM for SFTP will also create them for SSH and because there’s no easy way to map all such virtual users to the same user-id. Also, because OpenSSH has zero support for virtual users, aside of a PAM configuration, you also need an NSS configuration and now all your virtual users in some database have suddenly become system users on your box.
SFTP as a protocol on the other hand is very convenient over, say FTP over TLS because it’s using a single TCP port and it has been created this century.
So having this self-contained project is useful when you need to allow third parties access to files but you also don’t want to create system users for them or risk f’ing something up with PAM
Would the OpenSSH upstream accept patches for an unprivileged sshd/sftp-subsystem to make this easier to use their battle tested code?
https://github.com/sandreas/graft
graft serve ./*.txt
will serve every txt file in the current dir...
> graft will prompt for a password, run an sftp server and promote it via zeroconf.
Is that a one time password that will be used by the "receiver" to download the file?
I wrote graft to have a simple portable tool for transfering files in a network without shares - the main idea behind it was to run:
graft serve myfiles/*.txt
on the server side and then
graft receive
on the client side without having to remember the ip or hostname - because zeroconf / mdns is used, it will find the server automatically, if the network is not too big. If there is more than one server, it will prompt you to choose the right one.
I only used SFTP, because it is a secure way to transfer files over the network.
That means that there's no way to authenticate users if you use a password encryption scheme not supported by the bundled modules (like bcrypt for example)
Proftpd?
A lot of more advanced servers are either (1) proprietary (2) unmaintained (3) hard to use (4) require a Linux VM or all of the above.
This project looks to alleviate a lot of these problems.
It'd be great to be able to register webhooks so that it could send events to external systems. Ideally I'd like to know when a file is created/deleted etc without having to walk directories on the sftp server on a regular basis.
For me, in a previous system I uploaded as a .tmp file, then the uploaded renames to .zip at the end of the upload. The rename is atomic so no chance of the consumer reading a partial file.
I was dealing in CSV, TSV and XML files. I chose to upload them all in a zip wrapper not only because they compress well, but also because each file has a CRC and the file won’t be extracted if the file is damaged or truncated. It’s hard to tell if a raw CSV file has been truncated.
They way overcharge though. ($300/month)
I am asking, b/c I am currently working on a little document management system for home-use. It looks like the only sane way to integrate with document scanners is (S)FTP upload or Email (SMPT). I have tried to use off-the-shelf FTP servers for this and inotify to get notified of new uploads. The the solutions work OK, but are hard to setup and rather brittle (and limited to Linux).
Go seems to be the ideal language for this project, because its concurrency model and the ease of distribution (as single binary files).
- Has anyone here experience with building systems like this (integrating via FTP/SMTP)?
- Any recommendations for languages and libraries?
Don't ask why...
The configuration format it's a your choice