Encrypted Files Transfers ?
Par jd le dimanche, octobre 3 2004, 14:06 - Naquadah Network - Lien permanent
Since a while, I am looking for a viable network transfer protocol with encryption support.
Let me explain.
Currently, I am using FTP with user accounts, but I am not happy because I hate plain text password auth. So, I decided to use a SSL way to communicate with my file server.
pure-ftpd offers me: log file (so I can make stats with webalizer or something else) and statuts information (pure-ftpwho).
So, what could I use ?
FTPs
You have to:
- Run the client on a non-NATed host or it will not work. That's not very easy for everyone.
or
- Open a range of port in your server's firewall to enable active connection, and that's not a good thing for me.
or
- Patch pure-ftpd (which I am currently using) for having it running iptables commands to open port when it need them. Berk.
SFTP/SCP
You do not have any log file (or you have to patch) and no statuts about who is doing what.
RSYNC over ssh
You do not have log files, and no statuts information too.
HTTPS
That's not a file transfer protocol.
So, any idea ?
Commentaires
WASTE (http://waste.sourceforge.net/) does exactly what you want. Sadly the only complete implementation is a Win32 app.
What about DAV? I don't have much experience with that, but you can run it over SSL (like HTTPS), you can transfer files, and you can get log files from Apache e.g.
Who says HTTPS is not a file transfer protocol? I assume you mean for upload, but even then you can upload stuff through HTTP (S or not S). There's a PUT method in HTTP that you can use, or you can use a POST request with a 50-line PHP script to manage permissions, logging, size limitations and so on.
What about mioga? Mioga (http://www.mioga2.org/) is a groupware application built on top of apache/modperl with a file manager which uses dav as transfer protocol. And with Mioga you've got users, groups and ACLs. You can acces your files through any dav client.
There's also ftp-ssl on debian...
Regards,
During my cleaning of my bookmarks I just found this :
http://sftplogging.sourceforge.net/
You can also use a plain rsync server with ssl tunneling (stunnel) instead of rsync over ssh. No shell, x509 control if you need it, good bandwith rate....usefull for backups, but need stunnel on the server and on the client.<br /> I don't agree with ftp-ssl and NAT, it's working quite well here with proftpd and nat/conntrack modules for ftp (just tcp:21 open and leave the conntrack track the related connections)
What about sftp? It works out of the box on any unix box with openssh's sshd (and probably others). It's also as secure as ssh and there are graphical explorers for it for various OSen (even Nautilus can browse them).
and of course the rest of my post was supposed to say that patching it to add logging support is probably a better solution than most other options.
Do it yourself
SSH allows arbitrary commands to execute, including a simple file transfer protocol tool. And it provides neatly a virtual chroot. Does not allow subdirs though (has security implications).
In ~user/.ssh/authorized_keys add the SSH key with the prefix:
command="/home/user/.ssh/restrict.py",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-f
orwarding ssh-dss <SSH keydata>
restrict.py (HTML might be garbled): <pre>
import sys, os, re
is_good_file = re.compile(r"^[0-9a-zA-Z][-a-zA-Z0-9. ]*$").match
datadir = "/home/user/pool/"
def handle_list ():
def handle_range (l, fname):
if is_good_file(fname): f = file(datadir+fname, 'rb') f.seek(l) data = f.read(1024) while data: sys.stdout.write(data) data = f.read(1024) sys.stdout.flush() else: print "Sorry."_logfile = open("/home/user/.ssh/connect.log", 'a') def log (msg):
_logfile.write(msg) _logfile.write(" ") _logfile.flush()def get_time ():
def main ():
arg = os.environ.get("SSH_ORIGINAL_COMMAND", "") log("user logged in on %s, cmd %s" % (get_time(), `arg`)) if arg=="list": handle_list() elif arg.startswith("get "): handle_range(0, arg[4:]) elif arg.startswith("range "): l, fname = arg[6:].split(" ", 1) handle_range(long(l), fname) else: print "Sorry."if __name__=='__main__':
try: main() except Exception: import traceback exctype, value, tb = sys.exc_info() traceback.print_exception(exctype, value, tb, None, _logfile) print "Sorry."</pre>