Score:3

Setting up sftp on Amazon Linux 2 with ssh keys, user segregation (sftp vs ssh), different ports, and user directory constraints

pk flag

TDLR: I have a Catch 22 where, depending on permissions on the user's home directory, I can get the SSH authentication to work, or the user directory constraints, but not both.

BTW, I really want to roll my own SFTP server. Please don't recommend I try AWS Transfer service or something alternative. Thanks.

Here is relevant (changed from default) content in /etc/ssh/sshd_config:

Subsystem sftp internal-sftp
Port 22
Port 2299
Match Group sftpusers LocalPort 2299
  ChrootDirectory /sftp-data/%u
  ForceCommand internal-sftp
Match Group sftpusers LocalPort 22
  DenyGroups sftpusers
Match LocalPort 2299  Group *,!sftpusers
  DenyUsers *

I want port 22 functioning as ssh typically does, but only for non-sftp users. For sftp users, in group "sftpusers", I want port 2299 to function as sftp only, and not ssh. For non-sftpusers, I want access to port 2299 denied.

Ok, so, I created a user "user1" with home directory /sftp-data/user1 and shell /sbin/nologin. I created /sftp-data/user1/.ssh/authorized_keys and populated that with the public ssh key. /sftp-data is owned by root with 700 permissions. /sftp-data/user1/.ssh and below are owned by user1, and /sftp-data/user1/.ssh/authorized_keys has permission 600. The ownership/permissions of /sftp-data/user1 are under question here. More below.

I created the user group sftpusers and added user1 to that group. The built-in ec2-user you get with AWS is not a member of that group, however. Testing with ec2-user worked great: access via ssh, port 22 worked as it always does, but no access to port 2299.

So, testing with user1 is where it got interesting. User1 has no access to port 22 - that's great! With user1 owning /sftp-data/user1, the ssh public key authentication succeeds on port 2299, but the user is immediately logged out, with this message saved in /var/log/secure:

Sep  2 19:21:38 ip-192-168-0-25 sshd[10369]: Accepted publickey for user1 from <ip-address redacted> port 61110 ssh2: ECDSA SHA256:<sha redacted>
Sep  2 19:13:23 ip-192-168-0-25 sshd[9803]: pam_unix(sshd:session): session opened for user user1 by (uid=0)
Sep  2 19:13:23 ip-192-168-0-25 sshd[9803]: fatal: bad ownership or modes for chroot directory "/sftp-data/user1" [postauth]
Sep  2 19:13:23 ip-192-168-0-25 sshd[9803]: pam_unix(sshd:session): session closed for user user1

Sure, that makes sense. Chroot requires /sftp-data/user1 to be owned by root, permissions 700. So, make that so, and now the sftp (ssh key) authentication fails.

Sep  2 19:41:00 ip-192-168-0-25 sshd[11693]: error: AuthorizedKeysCommand /opt/aws/bin/eic_run_authorized_keys user1 SHA256:<sha redacted> failed, status 22

BTW, eic_run_authorized_keys is a wrapper AWS puts around standard ssh authentication to enable AWS Instance Connect.

For extra credit... if the above problem is not challenging enough, can you come up with a scheme where I can give particular sftp users access to particular project directories, and only those, without creating a group for every project? Link from each user's home directory to a project directory would be awesome.

Additional info requested by @anx:

# getent passwd user1
user1:x:1001:1001::/sftp-data/user1:/sbin/nologin
# namei -l /sftp-data/user1/.ssh/authorized_keys
f: /sftp-data/user1/.ssh/authorized_keys
dr-xr-xr-x root  root      /
drwxr-xr-x root  root      sftp-data
drwx------ root  root      user1
drwx------ user1 sftpusers .ssh
-rw------- user1 sftpusers authorized_keys

I turned on DEBUG logging for sshd. Using the ChrootDirectory directive, with /sftp-data/user1 owned by root, and SSH authentication failing, I see this in /var/log/secure:

debug1: Could not open authorized keys '/sftp-data/user1/.ssh/authorized_keys': Permission denied

ps clearly shows me that root is running the sshd process.

pk flag
@anx thanks for the thoughts. The eic_run_authorized_keys script, by AWS, is trying to check for a key in the EC2 instance metadata, to see if EC2 Instance Connect is being used. That script is specified in the sshd_config file under AuthorizedKeysCommand. The man page on that says: "If a key supplied by AuthorizedKeysCommand does not successfully authenticate and authorize the user then public key authentication continues using the usual AuthorizedKeysFile files." So, it fails with 22 status on a curl command returning a 401 status. Then regular process with ~user1/.ssh/authorized_keys go
pk flag
Pursant to @anx's suggestion, I created a simpler case which works. The working scenario is to remove the ChrootDirectory directive from sshd_config and user1 having ownership of /sftp-data/user1. That, of course, does not do what I wish. To add in Chroot, root must own /sftp-data/user1, or an error is thrown on that. Once root owns that directory, SSH authentication fails.
Michael Hampton avatar
cz flag
Which error was logged by sshd for that specific set of permissions?
pk flag
updated question - with that detail @MichaelHampton
Michael Hampton avatar
cz flag
Your ChrootDirectory needs at minimum search permission (`a+x`) so that the unprivileged user can descend into lower level directories.
pk flag
@MichaelHampton you got it. Create an answer if you would like. I read too much into what the man page says about ChrootDirectory: "At session startup sshd(8) checks that all components of the pathname are root-owned directories which are not writable by any other user or group". So, apparently what we have learned is that sshd is checking for a authorized_keys file that can be read as the user attempting to authenticate. Thanks much!
Score:3
cz flag

Your ChrootDirectory is /sftp-data/user1, which must be owned by root. And it is:

# namei -l /sftp-data/user1/.ssh/authorized_keys
f: /sftp-data/user1/.ssh/authorized_keys
dr-xr-xr-x root  root      /
drwxr-xr-x root  root      sftp-data
drwx------ root  root      user1
drwx------ user1 sftpusers .ssh
-rw------- user1 sftpusers authorized_keys

However, at this point the sshd has already changed the user to user1 and dropped privileges, so user1 cannot descend into lower level directories. To do that the directory needs search permission (a+x).

chmod a+x /sftp-data/user1

Now user1 can descend to subdirectories and the .ssh directory should be readable.

Score:1
ve flag

I think this is primarily a folder permissions issue. I think that /sftp-data/user1/.ssh and the directories below it must be owned by user1, but it sounds like they are owned by root. Try the following as root:

Verify the public key in /sftp-data/user1/.ssh/authorized_keys is accurate. After that, I think these are the permissions you may need to change:

chmod 700 /sftp-data/user1/.ssh
chmod 600 /sftp-data/user1/.ssh/authorized_keys
chown root:sftpusers /sftp-data
chown -R user1:user1 /sftp-data/user1/.ssh

Restart SSH and I think you'll be good to go.

pk flag
Thanks for the answer. Unfortunately, I had already had tried those permissions. Just in case, I ran your suggested commands and found the same outcome. SSH authentication fails. I'm thinking, logically, what could be different from the alternative, where user1 owns /sftp-data/user1? Could it be that sshd (running as root) is not able to access the user's authorized keys because it is walking the directories?
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.