Chrooted SFTP server with logging

Discussion in 'General Server' started by grim76, Jan 14, 2014.

  1. grim76

    grim76 Active Member Staff Writer

    Messages:
    177
    Likes Received:
    48
    Trophy Points:
    28
    Purpose:
    This forum post is to tell someone how to setup an SFTP server with logging. Sometimes you need a secure place to upload files and not allow everyone else to see the files that have been uploaded.

    I am assuming that you have an installed Linux OS of some flavor.

    First thing to do is to add two groups. To make it easier we are going to use sftpusers and sftpadmins

    Code:
    groupadd sftpadmins
    groupadd sftpusers
    We will use these groups to assign access, and permissions for some users.

    Now we need to prep our file location.

    NOTE: The permissions required are very specific. Not adhering to the permissions structure will cause the SFTP server to fail on connection.


    We have chosen /sftp as the mount point for the chroot environment. We have mounted about 2TB of disk there so that the users have space to upload their rather large files. You can do this without mounting new space, but make sure that the location that you are working with is mounted allowing ACLs

    Code:
    setfacl -m d:g:sftpadmins:rwx /sftp
    This will set up a default ACL that will apply to any new folder or file that is created in the /sftp location.

    Code:
    grim76@sftp001:/> getfacl sftp
    # file: sftp
    # owner: root
    # group: root
    user::rwx
    group::r-x
    group:sftpadmins:rwx
    mask::rwx
    other::r-x
    default:user::rwx
    default:group::r-x
    default:group:sftpadmins:rwx
    default:mask::rwx
    default:other::r-x
    
    Now we need to alter SSH to lock down certain users to only allow SFTP:

    Find the sftp-server line comment it out and add a new line with the internal-sftp.
    Code:
    # override default of no subsystems
    # Subsystem    sftp    /usr/lib64/ssh/sftp-server
    Subsystem      sftp    internal-sftp
    
    Now we use our sftpusers group:

    Code:
    Match Group sftpusers
            ChrootDirectory /sftp/%u
            AllowTCPForwarding no
            X11Forwarding no
            ForceCommand internal-sftp -l info
    
    Make sure to restart the service.

    Here we match the user group sftpusers and apply the constraints.
    ChrootDirectory - This is where the "home" folder for the user will be
    AllowTCPForwarding - we don't want tcp forwarding for security reasons.
    X11Forwarding - Some servers have a GUI and you don't want to allow access
    ForceCommand - this line forces the user into the internal-sftp setup and info is for logging purposes.

    Now we create our first user:

    Code:
    useradd -m -s /bin/bash -c "user001" -G sftpusers -u 50001 user001
    Adding a standard user with a uid of 50001 this is so they stand out as an SFTP only user when we do an audit.

    Now we create the users location:

    Code:
    mkdir /sftp/user001
    
    drwxr-xr-x+  5 root root  46 Dec 16 14:34 user001
    grim76@sftp001:/sftp> getfacl user001/
    # file: user001/
    # owner: root
    # group: root
    user::rwx
    group::r-x
    group:sftpadmins:rwx            #effective:r-x
    mask::r-x
    other::r-x
    default:user::rwx
    default:group::r-x
    default:group:sftpadmins:rwx
    default:mask::rwx
    default:other::r-x
    
    
    Ok now we have to create the other file locations that the user is going to need.

    Code:
    cd /sftp/user001
    mkdir dev incoming outgoing
    
    ls -alh
    
    grim76@sftp001:/sftp> ls -alh user001/
    total 16K
    drwxr-xr-x+ 5 root      root  46 Dec 16 14:34 .
    drwxr-xr-x+ 6 root      root  63 Dec 16 14:33 ..
    drwxrwxr-x+ 2 root      root  16 Dec 16 14:43 dev
    drwxrwxr-x+ 2 user001 users 27 Dec 16 15:06 incoming
    drwxrwxr-x+ 2 user001 users  6 Dec 16 14:48 outgoing
    Now you should be able to sftp in as that user and upload files. Now the problem is that we can't track what that user is really doing. So we need to setup logging.

    Syslog-ng is what the system is using so we have to add a few things:

    Code:
    source src {
            #
            # include internal syslog-ng messages
            # note: the internal() soure is required!
            #
            internal();
    
            #
            # the default log socket for local logging:
            #
            unix-dgram("/dev/log");
    
            #
            # uncomment to process log messages from network:
            #
            #udp(ip("0.0.0.0") port(514));
            unix-stream("/sftp/user001/dev/log");
    };
    
    destination sftp { file("/var/log/sftp.log"); };
    filter f_sftp { program("internal-sftp"); };
    log { source(src); filter(f_sftp); destination(sftp); };
    Make sure to reload the service

    Here we setup the socket for logging, and then we put that log into /var/log/sftp.log.

    Now we have a server that will do SFTP with logging. When adding new users you will need to create the locations for them and only add a new unix-stream line to your syslog-ng configuration.


    Sorry if this post looks messy, and please feel free to ask questions. Also if you notice a correction please let me know so that I can make it.

    DevynCJohnson likes this.
  2. DevynCJohnson

    DevynCJohnson Well-Known Member Staff Member Staff Writer

    Messages:
    1,331
    Likes Received:
    1,069
    Trophy Points:
    113
    Great article. Thanks!
    Haider92 likes this.
  3. grim76

    grim76 Active Member Staff Writer

    Messages:
    177
    Likes Received:
    48
    Trophy Points:
    28
    No problem. I am working on a write up as to how to protect this type of server with ipsets and iptables.

Share This Page