Solved How to build Apache with suexec enabled?

I have serious difficulties trying to compile/enable/configure suexec for apache24.
Whatever I try, the result is always the same:
Copypaste of the CGI output in the web browser said:

Hello World!​


getlogin says: Running as 'root'!
getpwuid says: Running as 'www'!
Perl says: Effective UID of the currently running Perl program: '80'!
Perl says: Real UID of the currently running Perl program: '80'!
Perl says: Effective GID of the currently running Perl program: '80 80'!
Perl says: Real GID of the currently running Perl program: '80 80'!

When I look, I cannot find a file 'suexec' anywhere.
I must be doing something seriously wrong.

The steps I tried to generate the apache24 port with suexec enabled+configured are these:
(executed directly after installing FreeBSD from ISO (using guided ZFS setup, and src + ports tree options enabled)

Code:
zfs snapshot -r wurstpool@bootie_snap_before_install_2021-01-21-18:09:56
env ASSUME_ALWAYS_YES=YES PAGER=cat freebsd-update fetch
[0 1 2]env ASSUME_ALWAYS_YES=YES PAGER=cat freebsd-update install
env ASSUME_ALWAYS_YES=YES pkg update
env ASSUME_ALWAYS_YES=YES pkg upgrade
env ASSUME_ALWAYS_YES= pkg install -y -A $(make -C /usr/ports/www/apache24 missing)
cd /usr/ports/www/apache24/
make -DWITH_SUEXEC -DSUEXEC_DOCROOT=\"/\" -DSUEXEC_USERDIR=\"/\" -DSUEXEC_UIDMIN=\"0\" -DSUEXEC_GIDMIN=\"0\"
-DSUEXEC_LOGFILE=\"/var/log/httpd/httpd-suexec.log\" -DBATCH fetch
make -DWITH_SUEXEC -DSUEXEC_DOCROOT=\"/\" -DSUEXEC_USERDIR=\"/\" -DSUEXEC_UIDMIN=\"0\" -DSUEXEC_GIDMIN=\"0\"
-DSUEXEC_LOGFILE=\"/var/log/httpd/httpd-suexec.log\" -DBATCH extract
make -DWITH_SUEXEC -DSUEXEC_DOCROOT=\"/\" -DSUEXEC_USERDIR=\"/\" -DSUEXEC_UIDMIN=\"0\" -DSUEXEC_GIDMIN=\"0\"
-DSUEXEC_LOGFILE=\"/var/log/httpd/httpd-suexec.log\" -DBATCH patch
_back_up_and_patch_suexec_c_
make -DWITH_SUEXEC -DSUEXEC_DOCROOT=\"/\" -DSUEXEC_USERDIR=\"/\" -DSUEXEC_UIDMIN=\"0\" -DSUEXEC_GIDMIN=\"0\"
-DSUEXEC_LOGFILE=\"/var/log/httpd/httpd-suexec.log\" -j12 -DBATCH build
make -DWITH_SUEXEC -DSUEXEC_DOCROOT=\"/\" -DSUEXEC_USERDIR=\"/\" -DSUEXEC_UIDMIN=\"0\" -DSUEXEC_GIDMIN=\"0\"
-DSUEXEC_LOGFILE=\"/var/log/httpd/httpd-suexec.log\" -DBATCH install
env ASSUME_ALWAYS_YES=YES pkg install ap24-mod_perl2
cp /usr/local/etc/apache24/httpd.conf /usr/local/etc/apache24/httpd.conf.orig
_write_httpd_conf_
mkdir -p /cgi-bin
_write_the_helloworld_cgi_
_update_rc_conf_for_apache_
env ASSUME_ALWAYS_YES=YES pkg autoremove
service apache24 onestart

This script is generated by my postinstaller bootstrap script 'bootie.pl' (see attached file).
It is intended to be run directly after FreeBSD installation.

The postinstaller bootstrapper opens dialog windows, the same blue ones we know from FreeBSD installer, and
1. asks whether to make a ZFS snapshot (for maybe reverting if fail)
2. asks whether to update/upgrade the system via internet
3. asks for IP4s which are to be allowed access to the "web console"
4. a messagebox showing the "script" generated
5. finally builds, installs, configures and runs the apache webserver

The last message says "Starting apache24".
At this point you can check the output with a webbrowser.

Here the reply from the now-running web server should not say "running as user www, uid/gid 80.
Instead it should say "running as root, uid and gid 0".

What did I do wrong?
What needs to be corrected?


I uploaded the script as file attachment, if anybody wants to take a look at it.



P.S.:
More details and background in this thread.

This is all very confusing, as you get some messages of the following sort.
But, doing as the text below indicates doesn't change anything.

Message from apr-1.7.0.1.6.1_1: said:
[...]
/!\ WARNING /!\

WITH_SUEXEC is unsupported, use WITH=SUEXEC on the command line, or one of
these in /etc/make.conf, OPTIONS_SET+=SUEXEC to set it globally, or
www_apache24_SET+=SUEXEC for only this port.
 

Attachments

  • bootie.pl.txt
    17.9 KB · Views: 103
from the Apache 2.4 docs, https://httpd.apache.org/docs/2.4/suexec.html

7. Is the target user NOT superuser?
suEXEC does not allow root to execute CGI/SSI programs.
8. Is the target userid ABOVE the minimum ID number?
The minimum user ID number is specified during configuration. This allows you to set the lowest possible userid that will be allowed to execute CGI/SSI programs. This is useful to block out "system" accounts.
9. Is the target group NOT the superuser group?
Presently, suEXEC does not allow the root group to execute CGI/SSI programs.
10. Is the target groupid ABOVE the minimum ID number?
The minimum group ID number is specified during configuration. This allows you to set the lowest possible groupid that will be allowed to execute CGI/SSI programs. This is useful to block out "system" groups.
 
Because of this my script patches two lines in suexec.c which do the above checks.
Code:
# now hack the suexec src
    # we need to disable two security checks to allow cgi run as root
    #     (uid == 0) || (uid < AP_UID_MIN)
    #     (gid == 0) || (gid < AP_GID_MIN)
    $$src =~ s/(\(\wid\s\=\=\s0\)\s\|\|\s\(\wid\s\<\sAP_\wID_MIN\))/\/\* $1 \*\/ 0/g;
These conditions are being commented out and replaced by 0, so the checks are being skipped.
This happens in the step _back_up_and_patch_suexec_c_ of the generated "script".
So this is not the problem.

The problem is that the additional executable 'suexec' is not being built, for some reason I do not yet understand.
 
It seems that the problem is the command-line suexec-enabling options.
The options I used (shown in the "batch" listing in the OP) seem to not work for some reason I do not understand.

Either I used incorrect options or there has been some change in the apache maker script that broke things, see the message about " -DWITH=SUEXEC" instead of " -DWITH_SUEXEC" from some apache build script that confused me so much (see end of OP).

Now I tried the make.conf-method described by SirDice here.
And it built the suexec executable :)

However, it got built with the default options which are of no use to me:

Code:
root@wurst:/var/log # suexec -V
-D AP_DOC_ROOT="/usr/local/www/data"
-D AP_GID_MIN=1000
-D AP_HTTPD_USER="www"
-D AP_LOG_EXEC="/var/log/httpd-suexec.log"
-D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
-D AP_UID_MIN=1000
-D AP_USERDIR_SUFFIX="public_html"
root@wurst:/var/log #

So I still need to find out how to set these options properly, as my previous attempts were unsuccessful.
There are very few threads about setting suexec options correctly (here, here), and none of them seems conclusively solved.
I guess I have to try some more using the hack-make.conf-method...
 
Finally it works :)
/etc/make.conf settings I used were:

Code:
OPTIONS_SET+=SUEXEC
SUEXEC_DOCROOT=/
SUEXEC_USERDIR=/
SUEXEC_UIDMIN=0
SUEXEC_GIDMIN=0
SUEXEC_LOGFILE=/tmp/httpd-suexec.log

As it is a postinstaller, the file just gets deleted after finish.
So it's ugly and unelegant, but it works 🐑

I still need to find out how to handle this correctly:
The suexec executable starts as user/group www:www, as inherited from apache.
At this stage I doubt it can write into there:
Code:
SUEXEC_LOGFILE=/var/log/httpd/httpd-suexec.log
So one needs to find some appropriate place where www:www can write at.

In httpd.conf one needs the suexec LoadModule and SuexecUserGroup directives to get things work:

Code:
LoadModule suexec_module /usr/local/libexec/apache24/mod_suexec.so
<VirtualHost ...>
SuexecUserGroup root wheel
</VirtualHost>

I also wonder why perl getppid returns apache and not the suexec executable.
But that's not a real problem, as long as the cgi runs under the intended UID/GID 👍
CGI output copypasted from browser said:

Hello World!​


getlogin says: Running as 'root'!
getpwuid says: Running as 'root'!
Perl says: Effective UID of the currently running Perl program: '0'!
Perl says: Real UID of the currently running Perl program: '0'!
Perl says: Effective GID of the currently running Perl program: '0 0 0 5'!
Perl says: Real GID of the currently running Perl program: '0 0 0 5'!
CGI parent PID: '41095'
CGI parent command line: ' /usr/local/sbin/httpd'

Thanks to all for your help!
 
/etc/make.conf settings I used were: [...]
The clean solution is to use ports-mgmt/portconf and not clutter make.conf(5)
I still need to find out how to handle this correctly:
The suexec executable starts as user/group www:www, as inherited from apache.
At this stage I doubt it can write into there:
Code:
SUEXEC_LOGFILE=/var/log/httpd/httpd-suexec.log
So one needs to find some appropriate place where www:www can write at.
sudo chown -vR www:www /var/log/httpd
Also, look into the service script /usr/local/etc/rc.d/apache24 and file a bug report. That should really be done from therein IMHO.
 
Back
Top