My company has a web hosting service for which people sign up. After the sign up process is complete, we go in manually and create a test / dev environment for that client to use. Generally the process goes like this:

  1. create Linux user, switch to that user
  2. run scripts to install templated set of files and directories into their home directory
  3. create an Apache .conf file
  4. restart apache
  5. Send an email to let them know the server is setup and ready for access
  6. Finally, the client can access their site as somerandomstring.devserver.com

Even though we use scripts to do this, volume dictates that manually having to log in and run them is now inconvenient. So, we want to automate this process to be triggered immediately after the client sign up process is complete.

I've thought of a couple ways to handle this.

1) Give a user the addusercapability and use PHP exec() function to create said user. I'd have to give that capability to www-data though, right? With PHP running in safe mode, commands for exec() are restricted to a specified directory. So, if I were to copy /usr/sbin/adduser to /my/custom/dir where only that command is available, what would be the lingering security concerns? I'm still at a loss though how I'd update the sites-available folder with the new site, since those are owned by root.

2) Let cron do it: A person has to sign up for the service, so by default they have a username and other client data stored in mysql. From an account that has adduser capabilities, have cron run a routine script that checks for new accounts (maybe every 30 to 60 seconds). If found, create a linux account for them, populate the home directories, write the apache conf virtualhost file, and reload apache.

Option 2 feels like the most secure way in that an isolated admin account handles this without www-data or the website having to execute system scripts and programs. The problem is the batch. Preferably, I'd like to find an option 1 solution so that a client is immediately signed up and they are redirected to their installed-and-ready-to-use server instance. I also don't like that I'm having to reload / restart apache so much.

Companies do this every day, especially web hosting companies. Bluehost, for example, once you've completed the sign up process, you immediately have access to /home/user/public_html with which you can interact. Because commercial solutions exist, I'm sure a lot of thought has been given to how to accomplish it securely and safely. What I'm trying to accomplish is identical, just on a much smaller scale.

  • 1
    I have a single question here: Why not just create dedicated web directories? Why create a whole user for this? If they're not going to be able to get into the home dir or ssh to the server or FTP into the server, you can do this without creating a brand new user on the system (which adds a huge can of worms of security risks). As an IT Security person, I'd rather not fuss with the user lists on the system itself, and just create individual directories and such for each user's locked site areas. Is there a reason you wouldn't want to take this approach?
    – Thomas Ward
    Commented Jan 20, 2017 at 18:11
  • If I'm understanding what you're advising, then the problem for us is malicious code. If I were to go this route, wouldn't all the files have to owned by the same user, like how Apache works by default with everything under /var/www/html owned by www-data? The problem we're fighting right now is that if Bob uploads a plugin to his dedicated folder and it contains malicious scripts, then, via www-data, it can overwrite and affect the files for Jane and Tom, even though despite them having separate directories. By having each person the owner of their own files, this has eliminated this for us.
    – user658182
    Commented Jan 20, 2017 at 18:24
  • If your core concern is malicious code, then having individual users doesn't solve your problem. They will still be able to go out into the drive if they have malicious code to recurse, and go back into other directories that aren't locked off. I would consider doing this as a manual process, not an automated PHP one, to prevent abuse and such. Writing PHP to do this can always introduce new evils that will make your 'system' completely insecure. Maybe a cron job can work, but you are delayed by the restrictions of Cron and need to set up a DB for all this.
    – Thomas Ward
    Commented Jan 20, 2017 at 18:27

2 Answers 2



This is an inherent security risk and has a lot of potential to go south at at any time. I'd highly advise against this setup, but oh well.

I'm not responsible for anything that happens as a result of you following anything given in this post, nor do I advise you to follow this system. This is mostly for educational/research purposes.

Linux has something known as setuid that allows any given program (like sudo) to run with privileges higher than the current executing user. You can write a shell script to do everything you need.

From there, because shell scripts can not be setuid, you need to convert this into a binary. You can use something like shc for this.

Once you have your shell pseudo-binary (example name: bootstrap_user) containing everything you need, you can do some fun alterations to get it ready. Namely, this:

  1. Set it owned by root, and group www-data.

     chown root:www-data ./bootstrap_user
  2. Assign RWX perms for owner (root), read and execute for group, none for anyone else:

     chmod 750 ./bootstrap_user
  3. Move the binary to somewhere PHP can exec() it.

  4. Finally, add the setuid bit to it, so that it's executed as root:

     chmod u+s ./bootstrap_user

In PHP, you can now call bootstrap_user as your executable, passing any required parameters. Be sure to take care to escape and sanitize input.


I think I'd be wary of anything that gives a browser user the ability to auto-generate a Unix user. If you did, it probably should incorporate both a queueing mechanism as well as a log or database so that the following doesn't occur:

  1. User presses the button to make it happen
  2. Your process kicks off
  3. The user presses F5 or clicks the reload button
  4. The user later presses the Backspace button to back up a page in their history
  5. The user creates a bookmark on this page and revisits it many times

So what happens when the user is re-initiating something that's either been done or is still occurring?

You must log in to answer this question.

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