Trouble getting a cgi script to run

hi -

i have a very simple test script:

# cat  /home/MYDOMAIN/cgi-bin/test.cgi ;
#! /bin/sh -w
echo content-type: text/plain
echo
date

but the log keeps giving me this error:

End of script output before headers:

# ls -l ;
-rwxr-xr-x 1 MYDOMAIN MYDOMAIN 53 Mar 23 14:59 test.cgi

after much research, i was told to look here:

# journalctl -b | grep “suexec” | tail -10 ;
Mar 23 16:00:34 MYDOMAIN suexec[3925478]: uid: (1018/MYDOMAIN) gid: (1018/MYDOMAIN) cmd: test.cgi
Mar 23 16:00:34 MYDOMAIN suexec[3925478]: command not in docroot (/home/MYDOMAIN/cgi-bin/test.cgi)

and this:

# suexec -V ;
-D AP_DOC_ROOT="/var/www"
-D AP_GID_MIN=1000
-D AP_HTTPD_USER=“apache”
-D AP_LOG_SYSLOG
-D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
-D AP_UID_MIN=1000
-D AP_USERDIR_SUFFIX=“public_html”

what should i do to get this test script running? it works fine on Centos-7 but not Centos-8.

the httpd.conf file contains just default stuff:

<Directory /home/MYDOMAIN/cgi-bin>
allow from all
AllowOverride All Options=ExecCGI,Includes,IncludesNOEXEC,Indexes,MultiViews,SymLinksIfOwnerMatch
Require all granted

Webmin version 1.973
Usermin version 1.823
Virtualmin version 6.15
Operating system CentOS Linux 8.3.2011

You can’t run CGI scripts on CentOS 8, because suexec doesn’t work with /home.

There are workarounds. You can bind mount /var/www to home, and set the cgi-bin path to /var/www/domain/cgi-bin (instead of /home/domain/cgi-bin).

Or, just don’t use CGI scripts. There are wrappers for most languages to convert CGIs to run under an app server model, which you then proxy to with the web server (because nginx has never supported CGI scripts, it’s very common to need to “port” CGI scripts to run without a CGI interface).

For the foreseeable future, we’ll keep supporting CGI on systems that have suexec-custom packages (Debian/Ubuntu), but it’s not a great way to run applications.

thanks Joe -

what i really need to run is the perl scripts. any suggestions?

what is confusing me is that Virtualmin continues to create cgi-bin directories. or is there some way allow apache to execute these? i feel like i am missing something.

or is the solution to use mod_perl?

You’re not missing anything. It really isn’t supported anymore on CentOS 8, because we no longer ship a custom Apache build with suexec docroot set to /home (this was a source of ongoing maintenance troubles and also a lot of users didn’t like that the Apache was not provided by CentOS/RHEL, due to trust/auditing/etc. issues, which is a valid concern).

Suggestions were provided above: Bind mount /home over /var/www and update cgi-bin path in the configuration (can do it in Server Templates if you want it to be for every new site) so suexec will be happy, or run the apps with a wrapper in an app server, e.g. Plack::App::WrapCGI and proxy to them with ProxyPass rules.

e.g. to bind mount:

# mount --bind /home /var/www

Note that if you choose this option, you definitely can’t have any websites living in /var/www, because they’ll be hidden by the mount. You shouldn’t, anyway, as it’s confusing to mix and match like that. And, then update your ScriptAlias to point to the right place.

It’s an oversight, I guess, that the cgi-bin directories are still created.

The solution is definitely not using mod_perl. The solution is never mod_perl.

ok got a little further by changing my httpd.conf:

<Directory /home/MYDOMAIN/cgi-bin>

to:

<Directory /var/www/MYDOMAIN/cgi-bin>

and also issuing the following command:

mkdir /var/www/html ; ## /var/www now points to /home/

now i am seeing this error in my log:

AH01630: client denied by server configuration: /home/MYDOMAIN/cgi-bin/test.sh

my httpd.conf looks like this: (i have tried MANY options now)

<Directory /var/www/MYDOMAIN/cgi-bin>
AllowOverride All Options=ExecCGI,Includes,IncludesNOEXEC,Indexes,MultiViews,SymLinksIfOwnerMatch
Require all granted
</Directory>

also, i am also wondering why Virtualmin includes this when i create a new VM:

Options=ExecCGI

is this now unnecessary in Centos-8?

I apologize for all these questions.

There doesn’t need to be a /var/www/html directory as long as you don’t have any sites configured in /var/www.

Are the CGIs owned by the same user found in SuexecGroup and SuexecUser? Are the permissions reasonable? (777 is not reasonable. Never do that. suexec will refuse to run it.)

Just because that’s what is included on all distros. Same reason cgi-bin still gets created.

CentOS 8 is irrelevant. The same default Server Templates are used on all distros and versions. CentOS 8 just can’t run CGI scripts without some extra effort.

Oh, wait. I just noticed this. Did you add an AddHandler for .sh? Because, by default, that isn’t gonna be executed no matter what. .cgi is the only default executable file extension for cgi-bin, I think.

when i ran your suggested:
mount --bind /home /var/www;
command, suddenly line 122 of httpd.conf :
DocumentRoot "/var/www/html"
started to fail when i tried:

apachectl configtest ;

so i saw three solutions:

  1. comment out httpd.conf line 122 – DocumentRoot "/var/www/html"
  2. mkdir /var/www/html ; ## /var/www now points to /home/
  3. Find a wealthy spouse & forget all this technology crap

the second option seemed like the least ‘invasive’.

i wondered about this too, but that did not seem to matter.

i did FINALLY get it working, after having my ass[et] kicked a dozen different ways. this has been one of the most difficult issues i have ran into in a long time.

the secret apparently is to change both /home/DOMAIN/cgi-bin/ references to /var/www/DOMAIN/ in ScriptAlias as well as <Directory:

(need to do this for BOTH 80 & 443 VM)

ScriptAlias /cgi-bin/ /var/www/MYDOMAIN/cgi-bin/

        <Directory /var/www/MYDOMAIN/cgi-bin>
                AllowOverride All Options=ExecCGI,Includes,IncludesNOEXEC,Indexes,MultiViews,SymLinksIfOwnerMatch
                AddHandler cgi-script .cgi  .sh  .pl
                Require all granted
        </Directory>

And in a week from today, hopefully, it will be even more irrelevant when RockyLinux is released.

Joe, i cannot thank you enough for your extraordinary patience with me.

Oops, sorry I didn’t spell that out. I was working from memory, but yes, the paths that suexec checks have to be pointing to some subdirectory within its allowed directory (so, /var/www).

And, yeah, however you want to solve the /var/www/html thing is fine. I would just disable that DocumentRoot, personally. It shouldn’t be in play once there are name-based VirtualHosts in play.

i feel as if i owe you a big steak dinner for your assistance and your extraordinary patience.

THANK YOU Joe Cooper!

(…seven days until Rocky-Linux is released)

EDIT: kudos to Joe for saying:
mount --bind
rather than assuming the world knows what -B stand for. i say if you are going to document a command and you dont use it every hour, use the LONG form. it makes life so much simpler.

Yeah, I tend to encourage long form when checking shell scripts into git, as well, unless it’s a super common flag (e.g. -q, -y, etc.) as it helps people reading the code later understand what’s going on.

I don’t eat steak, as I’ve been vegetarian for 27 years. But, I appreciate the sentiment. :wink:

This topic was automatically closed 8 days after the last reply. New replies are no longer allowed.