selinux and apache

Dear Lazyweb,

Apache won't start automatically on some (but not all) of my FC4 machines. I think this probably has something to do with SElinux?

In the default configuration, "service httpd start" doesn't seem to work at all: this is apparently because the init.d script has the wrong attributes:

    % ls -lZ /etc/rc.d/init.d/httpd
    -rwxr-xr-x root root system_u:object_r:initrc_exec_t /etc/rc.d/init.d/httpd
    % service httpd start
    Starting httpd: FAILED
If I change it, then it starts working when run manually:

    % chcon root:object_r:etc_t /etc/rc.d/init.d/httpd
    % service httpd start
    Starting httpd: OK
But the next time I reboot, still no httpd. I have to start it manually. Nothing obvious in dmesg, /var/log/messages, /var/log/secure, or /var/log/httpd/error_log.

I guess I could just turn off SElinux, but that doesn't seem like such a good idea. These machines are all very minimal, default-ish installations.

Any suggestions?

Tags: , , ,

22 Responses:

  1. bodyfour says:

    That's really bizarre... If I had to guess I'd say that some other object in the filesystem (like "/etc/httpd" or something) got its attributes set to something wrong.

    Have you verified that it's really an SElinux problem... does the init script work if you boot with "selinux=0" on the kernel boot line

    • bodyfour says:

      Also — try booting with "audit=1" which hopefully will give you some interesting log messages about what SElinux is unhappy with

  2. violentbloom says:

    you running rh3 or rh4?
    I have a clean installed server, and works for me by default... it's not the barebones config and I would guess something you need is missing if you have nothing else.

    so when you start it manually can you actually get to it with a browser or is it just saying it starts okay and then not actually working?
    I don't think you want to delete selinux... you could rename the folder and test it anyway and see if that fixes the issue.

    I can send you the clean copy of that init.d/httpd file if that helps?
    and httpd is set up to run for the level you're restarting in?

  3. otterley says:

    Are there appropriate symlinks to the script in /etc/rc3.d or /etc/rc5.d? (Depending on the default runlevel specified in /etc/inittab). Even if the init script is in /etc/rc.d/init.d, Apache won't start at boot unless the symlinks are in the right place(s).

    You can also run /sbin/chkconfig httpd to see what's going on.

    • otterley says:

      Sorry, that's /sbin/chkconfig --list httpd.

      You can find the default init level by running grep initdefault /etc/inittab.

      • bodyfour says:

        > You can find the default init level by running grep initdefault /etc/inittab.

        .. or just run "/sbin/runlevel" to see what runlevel you're in.

        % /sbin/runlevel
        N 3

        This means that the previous runlevel was "none" and the current runlevel is "3".

  4. mstyne says:

    I disabled SELinux on my FC4 box for this exact reason. Maybe see if there's an updated ruleset (selinux-policy-{targeted,strict}, I think) that fixes it.

  5. bitwise says:

    Yes, this is because there are no SElinux tags on whatever directory apache wants to access. When the redhat script starts apache, it starts it in a paranoid "I can only touch my own things" mode, so when it goes to access your directories (untagged), it barfs. But when you start it by hand, it hasn't been started in paranoid mode so it can access everything normally.

    You have two ways to fix it:

    1. Shut off SELinux,
    2. Properly tag the files with whatever ACL magic is needed. For example, if redhat expected you to use /var/www and you're using /home/httpd/, you need to go and look at the ACLs on /var/www and apply similar ones to /home/httpd/.

    • jwz says:

      Well, everything under /var/www/ is root:object_r:httpd_sys_content_t.

      Anyway, if the problem was that apache couldn't read its files, wouldn't it log an error message somewhere? I find the complete lack of diagnostics here especially helpful.

      Is there some way to run the init script in "paranoid mode" so that I can test it without having to actually reboot over and over again?

      • bodyfour says:

        You could do "init 1" and "init 3" to bounce the machine between single-user and multi-user modes. Still disruptive but probably quicker than a reboot.

      • bitwise says:

        Yes, there's a way to run the script in what I called "paranoid mode"-- put back the file permissions you messed with (in your original description).

        Presumably on reboot it automatically inherits the correct security context bits, and that's why it breaks then.

        My last guess is to look for error messages in /var/log/audit/audit.log .

    • bodyfour says:

      It's probably not something like "/var/www" since it's not even startnig up or printing anything in error_log. It's probably something called from the init scripts or the access on the httpd log files themselves.

  6. vordark says:

    While I abandoned Fedora before they started pushing SElinux hard, my friend did not, and he has this to say: "Disable it and never run it until you have a specific reason to do so."

    If they're really "very minimal" then maybe disabling it makes sense for you. I don't know.

    • bodyfour says:

      Running a public httpd is a very specific reason for doing so, at least if you want to run CGI/PHP/etc scripts. The other option is chroot apache which can be a pain depending on what the scripts actually need to do.

  7. omnifarious says:

    Calling them ACLs isn't quite right. The real ACLs are in the SELinux config. You're just categorizing the files when you change how they're tagged.

    Yeah, I'm being pedantic. But, computers are the ultimate pedants. It's often good to be really exacting in your terminology when dealing with them.

  8. Some random thoughts:

    By default, all SELinux-related errors should be logged to /var/log/messages. A sample selinux message looks like:

      Nov 22 20:49:14 cthulhu kernel: audit(1132710541.520:4): avc: denied { associate } for pid=1765 comm="ln" name="modem" scontext=system_u:object_r:cardmgr_lnk_t tcontext=system_u:object_r:tmpfs_t tclass=filesystem

    Are the httpd-related SElinux booleans the same on the systems which can and can't start httpd automatically? IIRC, I haven't modified any on this system and they look like:

      allow_httpd_anon_write inactive
      allow_httpd_sys_script_anon_write inactive
      httpd_builtin_scripting active
      httpd_can_network_connect inactive
      httpd_disable_trans inactive
      httpd_enable_cgi active
      httpd_enable_homedirs active
      httpd_ssi_exec active
      httpd_suexec_disable_trans inactive
      httpd_tty_comm inactive
      httpd_unified active

    Also might be worth checking/comparing the contexts on /var, /var/www, and anything under /var/www. If you wanted to just hit it with a very big hammer, touch /.autorelabel, reboot, and wait. Alternatively, use the restorecon utility.

  9. nirik says:

    when running init.d scripts from the command line, you might need to use the lovely selinux 'run_init' command, ie:

    run_init /etc/init.d/httpd start

    I think your default permissions are correct.
    As to why it's not starting up automatically, does it even try on boot? (might need 'chkconfig httpd on')

    If it tries and fails, is there anything in the /var/log/httpd/error_log about why? or /var/log/messages about a selinux denial?

    • jwz says:

      When I run it under run_init, it starts properly.
      Yes, the chkconfig links are all in the right places.
      Like I said, at boot, nothing about a failure is ever logged anywhere.