0

Okay, so on a fresh ubuntu 12.04, I install the lamp stack via: sudo tasksel install lamp-server

The next thing I want to do is change the User and Group that apache runs as and restart. Should be easy, right? WRONG.

Apache is installed such that it gets the User and Group from /etc/apache2/envvars I edit this file and change the User and Group, then do "apachectl restart" and... nope, the old User and Group are still in use (as confirmed via phpinfo). But if I do "apachectl stop" followed by "apachectl start" THEN it works. However, this sucks because I'm trying to write a bootstrap.sh script for Vagrant, and neither of these methods work in that context (I guess stop/start happens too fast, so while "stop" works, "start" does not.

In a perfect world, "restart" would do its job and actually reload the new values from envvars. Any ideas??

3

In an ideal world people would read the documentation :-)

http://httpd.apache.org/docs/2.2/stopping.html#hup

Signal: HUP

apachectl -k restart

Sending the HUP or restart signal to the parent causes it to kill off its children like in TERM, but the parent doesn't exit. It re-reads its configuration files, and re-opens any log files. Then it spawns a new set of children and continues serving hits.

Since the parent is not restarted, you can't use a restart to change the user it is running under.

3
  • Hmm, so is there a way in a bash script to call "stop" and make sure it's fully stopped before calling "start" again? Calling them consecutively doesn't seem to wait for "stop" to finish.
    – Brade
    May 8 '13 at 20:46
  • You can easily check in a bash script for the existance of httpd processes using a combination of ps and grep and put this into a looping type of context to wait.
    – mdpc
    May 8 '13 at 20:54
  • Well, you cant actually change users as a normal user using 'setuid' which explains why this wouldn't work. As for checking a process is stopped, running kill -0 <pid> can be used to check for the pids existance. This sends SIGNULL to the kernel (the process never gets it), its a pretty assured way to ensure the process has stopped for definite. May 8 '13 at 23:22
1

You can use /etc/init.d/apache2 restart or service apache2 restart. Both of these indeed do a stop and a start, with some handling of possible errors.

0

Are you absolutely positive that there are no other User or Group directives hiding in any other Apache configuration files? Remember that the last one that gets encountered "wins".

1
  • Yes, I am 99% sure it's the only place they've been set. Like I said, the new User always takes effect when I do "stop" followed by "start" -- it's just that "restart" for some reason doesn't reload these values.
    – Brade
    May 8 '13 at 20:44
0

It's not Apache's fault if you think "things should be" that are simply not possible (at least not directly, within Apache). The user change is done by the syscall setuid(). After root has called this function there is no way back. Exactly this feature makes this syscall safe.

If your Apache is running as e.g. user www and you want it to run as wwwrun then Apache cannot fulfill your wish because of missing technical privilege to do so. If you restart Apache instead this problem does not occur because the running process is killed and a new one is started: as root. Being root it can change its user.

Of course, the kernel could decide to change the user of a process. I don't know if there is any official way to do that. But only a root process could make the kernel do that. Apache would (sudo-like) have to signal to a privileged process that it wants its user to be changed. But considering how seldom this is going to happen I doubt that the kernel people are interested in implementing such a security relevant feature.

4
  • I don't think that this answer is really correct.
    – mdpc
    May 8 '13 at 20:55
  • My ultimate goal is to be able to restart apache as the new user--even it means calling "stop" then "start". But somehow I have to be sure that "stop" has finished before calling "start" again.
    – Brade
    May 8 '13 at 20:57
  • @mdpc Is there anything more you have to offer than your thinking? Like a precise claim what is not correct? Or is that expected too much? May 8 '13 at 20:58
  • @Brade I read too fast and misunderstood your problem. Thus what I wrote in my answer does not affect your problem (but the reload case). May 8 '13 at 21:05
0

Okay, so the following works in my bash script for my needs:

sudo apachectl stop
sleep 5
sudo apachectl start

It is imperfect, because I'd rather have it based on whether the "stop" actually completed (instead of just pausing for 5 seconds), but since this is a bootstrap script to set up a new server environment, it should be pretty reliable. If someone has a better answer though, feel free to give it. (Be specific though.)

1
  • Replace your sleep 5 by a loop: while pgrep httpd2-prefork &>/dev/null; do sleep 0.1; done. Adapt it to the name of your Apache processes if that's not httpd2-prefork`. May 8 '13 at 21:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.