theRiver
By:
theRiver

Locked myself out of server - I think

April 24, 2017 793 views
Linux Commands CentOS

In attempt to create a new user and restrict its access to SFTP, and access only to a specified direction, I found the question referenced in the link on the next line. Following the solution posted to this question (https://www.digitalocean.com/community/questions/how-do-i-restrict-a-user-to-a-specific-directory) I successfully created a new user and group which I want to restrict to a specified "home" directory.

I followed each step carefully, including the second part of Step 5, which states, "If that line does not exist, ..." and since the line DOES exist, I did not include the below text in my SSHD config:

Subsystem sftp internal-sftp

Match group sftpusers
ChrootDirectory %h
ForceCommand internal-sftp

I continued following the step-by-step and restarted SSH. I checked to make sure the user existed in the correct directory with '/etc/passwd' and it all checked out. Created a new droplet for this user in my FTP program and it wouldn't log in. Went back to Terminal and my connection (from sudoer) was broken. Login with new user didn't work - as I had hoped; but then login from sudoer didn't work either - connection refused. Login with root returned same results.

I am really hoping this is not as bad as it seems, and hoping someone here can help out.

Thanks!
River

3 Answers

@theRiver

That's actually one of the mini-guides I wrote, so I'll do my best to help where possible :-).

The first thing to note is that spacing matters, so when you see:

Subsystem sftp internal-sftp
Match group sftpusers
    ChrootDirectory %h
    ForceCommand internal-sftp

You need to use the same spacing that I used in the guide. I use a standard tab, which is 4 spaces.

If you are using password-based authentication, I'd recommend using this instead (again, four spaces indent the second through sixth lines with four spaces).

Match group sftpusers
    Subsystem sftp internal-sftp
    ChrootDirectory %h
    ForceCommand internal-sftp
    X11Forwarding no
    AllowTCPForwarding no
    PasswordAuthentication yes

The above needs to go below:

UsePAM yes

So what you should end up with is something that looks like this:

Subsystem sftp internal-sftp

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin yes
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes

Match group sftpusers
    Subsystem sftp internal-sftp
    ChrootDirectory %h
    ForceCommand internal-sftp
    X11Forwarding no
    AllowTCPForwarding no
    PasswordAuthentication yes

Once the changes have been made, restart ssh using service ssh restart. You should be able to use password authentication on users that you've added to the sftpusers group as of now if the users have been configured correctly.

If you are trying to create an SFTP user who is also a sudo user (which I don't recommend, for the sake of security), you need to append the user to the group instead of add them as is shown in that guide.

...

For example, let's say we created a user named jtittle (my username here on the community)

useradd -d /home/jtittle jtittle

If I wanted to add that user to the sudo group, I'd append that group on so I don't change the main group (which would be jtittle).

usermod -aG sudo jtittle

Now if I wanted to add that user to the sftpusers group as well, I'd append that group using -aG again.

usermod -aG sftpusers jtittle

...

I'm active here in the community, so don't be afraid to @jtittle tag me if you see a post of mine and want to flag me with the question :-).

  • Hi @jtittle

    Thanks for the reply - I will definitely try that when I am back on the server. For now, my problem is that this modification (I believe the one I made to the SSH config) has locked me out all the way up to the root level. I have 0 access to my server :(

    Any ideas?

    Thanks,
    River

    • @theRiver

      This:

      Match group sftpusers
          Subsystem sftp internal-sftp
          ChrootDirectory %h
          ForceCommand internal-sftp
          X11Forwarding no
          AllowTCPForwarding no
          PasswordAuthentication yes
      

      Should be:

      Match group sftpusers
          ChrootDirectory %h
          ForceCommand internal-sftp
          X11Forwarding no
          AllowTCPForwarding no
          PasswordAuthentication yes
      

      It won't let me edit the other post for some reason.

      In regards to logging in, you'll probably need to use Console from the DigitalOcean control panel.

      DigitalOcean CP -> Droplet -> Access -> Console

      I'm going to rewrite the mini guide here soon and repost it in full so hopefully others will find it first when they start having issues like this.

Hi @jtittle

I managed to get back into my server via my sudoer. (Apparently it is just a temporary connection refusal for 15 minutes or so; perhaps a security protocol with my VPS provider.) Here is what my SSHD config file looks like now:

UsePAM yes

Subsystem sftp internal-sftp
    Match group sftpusers
    ChrootDirectory %h
    ForceCommand internal-sftp
    X11Forwarding no
    AllowTCPForwarding no
    PasswordAuthentication yes

After writing and quitting, and restarting the SSH service, I was able to login with root via SFTP. I then tried to login with the user I had created in the group sftpusers, with the specified root directory entered into the appropriate field in my FTP program. The password was not accepted, so I tried removing the root directory. The connection was refused and now I am completely blocked from my server again - kicking me out of my sudo SSH connection in Terminal as well.

What have I done wrong?

Thanks,
River

@theRiver

SFTP and FTP are entirely different protocols, so if you're attempting to login using FTP without FTP setup, the login will fail. Likewise, the same would apply if you were trying to login using SFTP when FTP was the only method available.

When you try to login using SFTP, you must use the same port that you use to login to SSH. If you've not changed that port, it'd be 22 (as 22 is the default port for SSH).

Depending on what you're using to login, you may also need to explicitly specific SFTP as the means of login. I know FileZilla differentiates between the two via a drop-down menu.

  • @theRiver

    To clarify on what the configuration for sshd_config should look like, in the event spacing has anything to do with why you're not able to login, it should actually look like:

    Subsystem sftp internal-sftp
    
    UsePAM yes
    
    Match group sftpusers
        ChrootDirectory %h
        ForceCommand internal-sftp
        X11Forwarding no
        AllowTCPForwarding no
        PasswordAuthentication yes
    
    • Ah, got it. OK I will correct this. Yes, by "FTP" I mean SFTP. I use Fetch for Mac and there is a dropdown as well ;-) Also, the port I am using I am consistently using across the board, so that shouldn't be the issue.

      Is it likely that my VPS provider has a firewall set up that does not like this specific type of connection - where a user has SFTP access but not SSH?

      • @theRiver

        SFTP and SSH communicate over the same port. If access to SFTP was being blocked, you wouldn't be able to SSH in to your server.

        I can't really comment on other providers as to what their setup would be, though with DigitalOcean, Linode, Vultr, Amazon, and Google Cloud (GCP), the only active firewall would be the one that you setup on your own or through a control panel, barring some network level firewall or IPS, though that wouldn't impact your ability to log in.

        Beyond software firewalls, such as ufw, you normally would pay extra for something such as a hardware firewall, unless it's baked in to the service offering.

    • @jtittle

      I made these changes (tried both spaces between words like "Subsystem" and "sftp", as well as tab spacing between them. Both cases are not accepting this user's password.

      To clarify, I am running CENTOS 6 on a LAMP setup. Not sure if that changes things here.

      River

      • @theRiver

        Something, somewhere is misconfigured, otherwise you'd be able to login. To test this, I deployed a fresh CentOS 6.9 64bit Droplet.

        I started by running these commands, in order:

        groupadd sftpusers
        
        mkdir -p /home/theriver/htdocs/public
        
        useradd -dM /home/theriver theriver
        
        usermod -aG sftpusers theriver
        
        chown -R theriver:theriver /home/theriver/*
        

        I then opened up /etc/ssh/sshd_config:

        nano /etc/ssh/sshd_config
        

        Found:

        Subsystem sftp        /usr/libexec/openssh/sftp-server
        

        Changed it to:

        Subsystem sftp internal-sftp
        

        The at the very end of the file, I added:

        Match group sftpusers
            ChrootDirectory %h
            ForceCommand internal-sftp
            X11Forwarding no
            AllowTCPForwarding no
            PasswordAuthentication yes
        

        It's important that the above configuration be the last thing in the file.

        With those changes made, I restarted SSH:

        service sshd restart
        

        I then ran:

        passwd theriver
        

        To set a password on the account.

        Once SSH was restarted, I was able to login with theriver via SFTP on port 22 and was bought to /home/theriver where I could see ./htdocs and move around, but not out.

        ...

        If the above doesn't work, there's something in ./sshd_config that is preventing you from logging in with SFTP or permissions are not correct -- either could be the issue.

        • @jtittle
          Thank you for spelling that out, that's awesome. I followed this basically verbatim, except mine wouldn't tolerate the 'M' in the useradd - it said "useradd: invalid home directory 'M'" despite the fact that my home directory immediately followed. I modified the sshd config to match yours, exactly. I noticed the "UsePAM" part wasn't in this. Not critical?

          Finally, restarted sshd service, and created a passwd for new user. Tried logging in through SFTP via my program and again, rejected password.

          SIDENOTE 1: The "AllowGroups root" line is #commented out. Should that but uncommented, and allow the sftpusers group?

          SIDENOTE 2: If my sudo user, logged into SFTP, has less/limited access than root, is that indicative of a bad setup? Perhaps I have a problem somewhere that I created a long time ago that is still persisting.

          Thank you for your ongoing patience. You're saving me a lot of headache.

          River

          • @theRiver

            The version of CentOS you're using may not allow you to combine the args, so you may need to use:

            useradd -M -d /home/theriver theriver
            

            The -M argument tells useradd not to create the home directory, or should. We don't need it to since we just created it prior.

            As for pam, there should be a line that already exists in your sshd_config file somewhere, so you don't was duplicate configuration.

            For example, this is part of the sshd_config file on a fresh CentOS 6.9 64bit Droplet:

            # Set this to 'yes' to enable PAM authentication, account processing,
            # and session processing. If this is enabled, PAM authentication will
            # be allowed through the ChallengeResponseAuthentication and
            # PasswordAuthentication.  Depending on your PAM configuration,
            # PAM authentication via ChallengeResponseAuthentication may bypass
            # the setting of "PermitRootLogin yes
            # If you just want the PAM account and session checks to run without
            # PAM authentication, then enable this but set PasswordAuthentication
            # and ChallengeResponseAuthentication to 'no'.
            #UsePAM no
            UsePAM yes
            
            # Accept locale-related environment variables
            AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
            AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
            AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
            AcceptEnv XMODIFIERS
            
            #AllowAgentForwarding yes
            #AllowTcpForwarding yes
            #GatewayPorts no
            #X11Forwarding no
            X11Forwarding yes
            #X11DisplayOffset 10
            #X11UseLocalhost yes
            #PrintMotd yes
            #PrintLastLog yes
            #TCPKeepAlive yes
            #UseLogin no
            #UsePrivilegeSeparation yes
            #PermitUserEnvironment no
            #Compression delayed
            #ClientAliveInterval 0
            #ClientAliveCountMax 3
            #ShowPatchLevel no
            #UseDNS yes
            #PidFile /var/run/sshd.pid
            #MaxStartups 10:30:100
            #PermitTunnel no
            #ChrootDirectory none
            
            # no default banner path
            #Banner none
            
            # override default of no subsystems
            Subsystem sftp  /usr/libexec/openssh/sftp-server
            
            # Example of overriding settings on a per-user basis
            #Match User anoncvs
            #   X11Forwarding no
            #   AllowTcpForwarding no
            #   ForceCommand cvs server
            
            # Added by DigitalOcean build process
            ClientAliveInterval 120
            ClientAliveCountMax 2
            

            As you can the, towards the top, pam already exists. So we only need to be concerned with changing the Subsystem line and adding our match to the very bottom of the configuration.

            ...

            That being said, in terms of security, the only time you should be logging in as a root or sudo user is when you need to login to SSH directly, not over SFTP.

            Ideally, you should create a sudo user, make sure you can login and sudo up to run commands, then lock the root user to prevent anyone from using it. You would then use your sudo user to login to SSH anytime you needed to.

            Once you have your sudo user, you should be creating a new user for each site you host, where possible. With Apache, this is a bit of a pain, though with NGINX, it's a non-issue as PHP-FPM controls the user permissions so each user can write only to that users directories and files.

            None of the users you use for SFTP should be root or sudo users.

Have another answer? Share your knowledge.