Simple authentication setup for SFTP server?

0 votes
asked Apr 10, 2016 by seamus (120 points)

Hi

I have a simple SFTP server running on Xamarin / Mono on OSX.
I can get the server running locally and connect via CyberDuck and ssh in the terminal. However in both cases the server ignores the root folder I have set and serves the root of the Xamarin project. The root folder is also read-only. Interestingly, when I list the command available at the Rebex Virtual Shell, there does not seem to be a 'put' command or similar.

I just need a simple user/password authentication system - this SFTP Server will only be connected to from localhost (and locked into a whitelist of IP addresses). Is there a way to get a simple read/write connection like this?

The server is written in F# but code in C# is also fine :)
I am using the trial product, but I will definitely buy if I can get this working.

Thanks

Seamus

Applies to: File Server

1 Answer

+1 vote
answered Apr 11, 2016 by Lukas Pokorny (86,950 points)

Hi,

  1. Could you please let us know how to reproduce the issue with a ignored root folder? This is working fine here, and none of our unit tests detected any similar issue on any of the supported platforms.

  2. What should this put command actually do? There is no put shell command in OS X, Linux or Windows. On the other hand, if you intend to upload files, you are supposed to use an SCP or SFTP client (which does provide a put command at the client side).

  3. You can easily limit the server to only accept connections from localhost by binding to the machine's loopback address. Just call server.Bind(new IPEndPoint(IPAddress.Loopback, port), FileServerProtocol.Sftp) instead of server.Bind(port, FileServerProtocol.Sftp) (where server is an instance of FileServer). Alternatively, if you would rather allow/reject connections based on
    an IP address whitelist, use FileServer object's Connecting event.

A simple code to achieve this (IP-address-based accept/reject event not included) might look like this:

        // create a server instance
        var server = new FileServer();

        // bind SFTP to port 2222 (all interfaces)
        server.Bind(2222, FileServerProtocol.Sftp);

        // bind shell to port 2222 (all interfaces)
        server.Bind(2222, FileServerProtocol.Shell);

        // bind SFTP to port 2222 of localhost
        //server.Bind(new IPEndPoint(IPAddress.Loopback, 2222), FileServerProtocol.Sftp);

        // bind shell to port 2222 of localhost
        //server.Bind(new IPEndPoint(IPAddress.Loopback, 2222), FileServerProtocol.Shell);

        // load a server private key from encrypted 'server-key.ppk' file
        if (!System.IO.File.Exists("server-key.ppk"))
        {
            // generate a 1024bit RSA key pair
            var privateKey = SshPrivateKey.Generate(SshHostKeyAlgorithm.RSA, 1024);

            // save the private key in PuTTY format
            privateKey.Save(@"server-key.ppk", "key_password", SshPrivateKeyFormat.Putty);
        }

        // specify a server key
        server.Keys.Add(new SshPrivateKey("server-key.ppk", "key_password"));

        // add a user (specify username, password and virtual root path)
        server.Users.Add("user01", "password", @"/Users/test/ServerRoot");

        Console.WriteLine("Starting server...");
        Console.WriteLine("Use user01/password to login to the server");
        Console.WriteLine();

        // start the server in the background
        server.Start();

        Console.WriteLine("To stop the server, press Enter.");
        Console.ReadLine();

        server.Stop();

You can download a whole solution here.

commented Apr 11, 2016 by seamus (120 points)
Thank you very much for that sample code - it actually helped me find out that the issue was a bug in my code. Sorry about that :)

Don't worry about the put command - I am using this with SSHFS and it seems to work well. So far so good.

Great customer service!

Thanks

Seamus
commented Apr 12, 2016 by Lukas Pokorny (86,950 points)
Thanks for letting us know! :-)
...