2

I know the title is just baiting the "your setup is insecure", but allow me to explain.

I'm working on an application which aims to allow clients to rsync over SSH to our server. We need a web application from which we can create/rotate SSH keys for our users. This application will return a private SSH key to the user for their future use and will store the public key user's authorized_keys file.

Upon registration, we'll need to automatically create the user and initial .ssh directory and keys.

We're on CentOS 5 now, but we're flexible if there's sufficient reason to migrate. This server will be running only this web application in Apache (as apache:apache) and no data other than the synchronized user data will be stored on the system.

I've been thinking about the following solution, but have been running into trouble:

  1. Grant sudo useradd privileges to the apache user to allow them to create new users
  2. Call sudo useradd from the PHP script in the web application with a umask of 000 on the newly created home directory.
  3. chgrp the new home directory to apache so that apache will be able to create a new .ssh directory and write the keys.*
  4. chmod the new home directory to 770 so that only the user and apache have access.*
  5. mkdir .ssh in the new home directory and ssh-keygen to create the new key, storing the public key in authorized_keys and passing the private key back to the calling client.

The problems I'm encountering are with the *d points -- it seems that, even with chmod 777 I'm not able to chgrp or chmod the directory, as it's been created with the owner and group belonging to the new user.

I've looked at changing the user's default group to something that would allow apache to write to it, but I can't find a way to do that without having to grant apache usermod sudo privileges, which seems like a really bad idea.

Any thoughts would be appreciated!

2 Answers 2

4

Create a script that does all the privileged actions with tight validation and have it audited.

The script only gets the username as parameter and has to validate it:

  • only contains valid username characters
  • user with that name does not exist (is not an administrative account, etc.)

If you really need to generate the private key on the server (please look hard for alternatives), the script should output the private key to stdout.

Grant sudo permission to this script for the apache user. The script contains the chmod/chgrp commands but only after doing the validation. The apache user therefore does not need sudo permissions for those commands.

It is possible to execute the script as a third user who has sudo permission for the system commands instead of executing the script as root. Whether this extra step is useful depends on the risk assessment of the script.

Apache executes the script using sudo and collects stdout with the private key to send it to the web browser.

1
  • Thanks; that sounds like a pretty elegant solution and doesn't sacrifice the on-demand key generation, which is nice. Might I ask why you suggest that I "look hard for alternatives" to server-side key generation?
    – Jeff Allen
    Commented Apr 10, 2012 at 22:40
4

I'd probably suggest having cron fire a script that does nothing but edit those files with whatever is queued in the database to do.

Allow that part of the script to act entirely outside of the realm of the apache user and be able to lock down the account to only do that task.

That's just off the top of my head though as a simpler solution.

2
  • That sounds like a better idea, for sure. Can you help me think through the specifics of such a solution, though? I would essentially need to run that script as root, correct (or, at the least, a user with sudo privileges for chmod, chgrp, and useradd)? Is there a better approach by changing the user's default groups on useradd, for instance?
    – Jeff Allen
    Commented Apr 10, 2012 at 20:59
  • I'd maybe walk down the route of passing useradd -M so it doesn't create the home directory, and having your script create it, chown/chmod to user:app 770 (app being a group that your app user is in, user of course being the user that you just created), with the only issue being that you have to give it access to create files in /home/ (or move their home directories to another location). I however am not really a Linux permission buff so take my ideas as to actual sane setup with a grain of salt till someone else can chime in here on maybe a more "Unixy" setup. Commented Apr 10, 2012 at 21:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .