Server Wide Script Locations not Working

I am attempting to convert our system wide Perl application from Cpanel to Virtualmin Webmin.

We have been using apache2 on Centos and cpanel for over 10 years.

On cpanel Centos Servers, there are system wide scripts located in


We are able to place a directory of scripts and data in those directories, and run them system wide on any virtual host in the server using apache2.

Inside the cgi-sys directory are cgi scripts for cpanel that do redirections.

We are able to put our script aliases in those directories, and call them with a script alias in httpd.conf. ie: ScriptAlias /dwos-bin/ /usr/local/cpanel/cgi-sys/netstores/dwos-bin

Now in Virtualmin / webmin on UBUNTU there is the directory called: /usr/share/webmin which contains all the server wide scripts of webmin and virtualmin.

These are perl scripts running systemwide.

We need to do the same thing with our application so I put the perl application scripting directory in:


with the scripting diretories within directory.

/usr/share/netstores/dwos-bin [same as a cgi-bin]

and within that directory a which is just hello world.

now the same perlscript work under the normal cgi-bin of a virtual host, but I get a server misconfiguration and suexec error when I try to run as a system wide scripts.

ScriptAlias /dwos-bin/ /usr/share/netstores/dwos-bin/

Added this additional ScriptAlias for adding another location in the conf-available conf file.


	ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
	<Directory "/usr/lib/cgi-bin">
		AllowOverride None
		Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
		Require all granted
	ScriptAlias /dwos-bin/ /usr/share/netstores/dwos-bin/
	<Directory "/usr/share/netstores/dwos-bin">
		AllowOverride All
		Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
		Require all granted

This is the suexec error when attempting to run.

[2021-07-08 21:45:04]: uid: (1001/netstore) gid: (1001/netstore) cmd:
[2021-07-08 21:45:04]: command not in docroot (/usr/share/netstores/dwos-bin/

Where do I place custom system wide perl scripts?

What is the configuration to do?

This is working on CPanel, any assistance on making it work on Virtualmin/Webmin Apache2 Ubuntu will be helpful.

Please always include your OS and version.

suexec websites can’t live in /usr/share. Virtualmin configures suexec_custom to put domain homes in /home. Also, suexec websites never live in /usr/share on CentOS; that’s a Debianism. CentOS defaults to suexec docroot of /var/www. We recompile it for CentOS versions 7 and below.

On CentOS 8, we no longer support running CGI scripts in Virtualmin domains, as we no longer rebuild Apache. There is always a better way to run any application in any language. For Perl scripts, use an application server and the fcgid interface or standard proxying.

If you’d provided your OS version, I could give very specific advice about how to keep running your app mostly as-is. But, the best advice is to not do that. CGI is pretty much deprecated and no one recommends it anymore.

But, if you search for suexec and CentOS 8 (assuming that’s what you have), you may find some ideas tor try.

Edit…argh, now I see you’re on Ubuntu. Please always include your OS first in your posts. For Ubuntu, just put your sites in /home.

Edit2: And, there is no such thing as “serverwide” in an Apache virtual hosting configuration. Everything is a virtual host, always.

1 Like

Sorry Joe, forgot to put OS. Operating system
Ubuntu Linux 18.04.5

Unfortunately, the application cannot change. To much development, and if I can’t move to Virtualmin on Ubuntu or Centos (could not get perl script to work on Centos install)

Well, on Cpanel this is. As I explained, with the same apache2.4 using EasyApache4, I am able to place a 1 full directory of scripts, and data files the way the application was built.

so far the only difference I can see, is you run webmin from the /usr/share directory, the same way that cpanel runs their system wide cgi in /usr/local/src/cgi-sys . Except on Ubuntu the suexec is run with the
/etc/apache2/suexec/www-data file

which reads

more www-data



# The first two lines contain the suexec document root and the suexec userdir

# suffix. If one of them is disabled by prepending a # character, suexec will

# refuse the corresponding type of request.

# This config file is only used by the apache2-suexec-custom package. See the

# suexec man page included in the package for more details.

 sudo /usr/lib/apache2/suexec -V
 -D SUEXEC_CONFIG_DIR=/etc/apache2/suexec/
 -D AP_GID_MIN=100
 -D AP_LOG_EXEC="/var/log/apache2/suexec.log"
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=100

And cpanel with apache2 suexec is.

 /usr/sbin/suexec -V
 -D AP_GID_MIN=100
 -D AP_HTTPD_USER="nobody"
 -D AP_LOG_EXEC="/etc/apache2/logs/suexec_log"
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=100
 -D AP_USERDIR_SUFFIX="public_html"

And I don’t think it has the same file.

But I am not an expert on EasyApache4 on Cpanel.

Do you have any experts that can figure out how to make this work? It is similar to webmin that runs system wide scripts under username id.

Here is an example of the suexec log running scripts on Centos 8 with Cpanel, and the EasyApache config file.

[2021-04-05 00:38:44]: uid: (642/netstore) gid: (579/netstore) cmd:
[2021-07-08 02:51:28]: uid: (642/netstore) gid: (579/netstore) cmd:
[2021-07-08 02:52:34]: uid: (642/netstore) gid: (579/netstore) cmd:
[2021-07-08 05:27:07]: uid: (642/netstore) gid: (579/netstore) cmd:

Here is the suexec log of UBUNTU

[2021-07-08 22:42:15]: uid: (1001/netstore) gid: (1001/netstore) cmd:
[2021-07-08 22:42:15]: command not in docroot (/usr/share/netstores/dwos-bin/
[2021-07-08 22:42:17]: uid: (1001/netstore) gid: (1001/netstore) cmd:
[2021-07-08 22:42:17]: command not in docroot (/usr/share/netstores/dwos-bin/
[2021-07-08 22:42:18]: uid: (1001/netstore) gid: (1001/netstore) cmd:
[2021-07-08 22:42:18]: command not in docroot (/usr/share/netstores/dwos-bin/

I can not run the application in a virtual user directory for security purposes, since the data files for the application reside away from direct access in their directories.

Any ideas on how to make this work?

That’s crazy. But, you’re welcome to reproduce that config on your Virtualmin system.

1 Like

Here is more info.

In Cpanel Apache there are templates ie: /var/cpanel/templates/apache2_4/ea4_main.local

Where the template was changed to:

<IfModule alias_module>
    ScriptAliasMatch ^/?controlpanel/?$ /usr/local/cpanel/cgi-sys/redirect.cgi
    ScriptAliasMatch ^/?cpanel/?$ /usr/local/cpanel/cgi-sys/redirect.cgi
    ScriptAliasMatch ^/?kpanel/?$ /usr/local/cpanel/cgi-sys/redirect.cgi
    ScriptAliasMatch ^/?securecontrolpanel/?$ /usr/local/cpanel/cgi-sys/sredirect.cgi
    ScriptAliasMatch ^/?securecpanel/?$ /usr/local/cpanel/cgi-sys/sredirect.cgi
    ScriptAliasMatch ^/?securewhm/?$ /usr/local/cpanel/cgi-sys/swhmredirect.cgi
    ScriptAliasMatch ^/?webmail$ /usr/local/cpanel/cgi-sys/wredirect.cgi
    ScriptAliasMatch ^/?webmail/ /usr/local/cpanel/cgi-sys/wredirect.cgi
    ScriptAliasMatch ^/?whm/?$ /usr/local/cpanel/cgi-sys/whmredirect.cgi
[% IF autodiscover_proxy_subdomains -%]
    ScriptAliasMatch ^/Autodiscover/Autodiscover.xml /usr/local/cpanel/cgi-sys/autodiscover.cgi
    ScriptAliasMatch ^/autodiscover/autodiscover.xml /usr/local/cpanel/cgi-sys/autodiscover.cgi
[% END -%]

    Alias /bandwidth /usr/local/bandmin/htdocs/
    Alias /img-sys /usr/local/cpanel/img-sys/
    Alias /java-sys /usr/local/cpanel/java-sys/
[% IF !skipmailman -%]
    Alias /mailman/archives /usr/local/cpanel/3rdparty/mailman/archives/public/
    Alias /pipermail /usr/local/cpanel/3rdparty/mailman/archives/public/
[% END -%]
    Alias /sys_cpanel /usr/local/cpanel/sys_cpanel/

    ScriptAlias /cgi-sys /usr/local/cpanel/cgi-sys/
[% IF !skipmailman -%]
    ScriptAlias /mailman /usr/local/cpanel/3rdparty/mailman/cgi-bin/
[% END -%]
    [% IF file_test('f', '/usr/local/cpanel/cgi-sys/scgiwrap') %]ScriptAlias /scgi-bin /usr/local/cpanel/cgi-sys/scgiwrap[% END %]
    ScriptAlias /dwos-bin/ /usr/local/cpanel/cgi-sys/netstores/dwos-bin/


So the IfModule has all the systemwide scripts and wrappers.

Is there a way I can configure Apach2 on the UBUNTU 18 with virtualmin and work the same way?


I did not make that configuration, Cpanel did.

So, what is the difference in the Apache versions?

As you can see, that is all we had to do to make our script bin system wide, with also adding additional PERL modules from the base Perl Install.

What version of Apache does webin use? Is it another version?

Do you know how I can make this work the same?

Is it just changing the www-data file? or recompiling apache to not include the suexec data file?

You don’t need to recompile on Ubuntu. suexec-custom is how it is configured; you just change a file.

I tried Joe, making it to “/” and public_html but that does not work either.

Get Error command not in docroot (/usr/share/netstores/dwos-bin/

Did you restart Apache after making the change?

Also, it’s possible suexec-custom won’t allow you to do something entirely nuts like /. Try giving it, like /usr/share just to test. (You shouldn’t leave it like that since that means suexec won’t work for Virtualmin sites in /home, but it’s plausible cPanel has a hacky Apache, and the Debian/Ubuntu suexec-custom still has some rules for docroots.)

Actually, yes, from the suexec-custom docs:

Suexec does not allow to set the document root to the root directory / . 

Source: suexec-custom(8) — apache2-suexec-custom — Debian jessie — Debian Manpages

Note that the “like /home” bit from that page doesn’t apply to a system that must run apps from user-owned locations (or, if it applies, it applies to any user-inhabited directory and would mean suexec cannot be used in a shared hosting system).

So, anyway, I guess you can’t set it up exactly like cPanel, because even the wild and crazy Debian/Ubuntu variation that allows just about any directory to be suexec_docroot, will not allow the whole system to be suexec_docroot.

1 Like

But, I do see that you can do per-user suexec-custom configs; so, just do that. Leave the default to /home, and for the user that runs this one app, give it the path to its home.

I tried /usr/share in www-data, but still misconfiguration (no suexec log now), but error log says:

[Fri Jul 09 06:41:00.026887 2021] [cgi:error] [pid 29196:tid 140467595003648] [client] AH01215: suexec policy violation: see suexec log for more details: /home/netstore/cgi-bin/

[Fri Jul 09 06:41:00.027301 2021] [cgi:error] [pid 29196:tid 140467595003648] [client] End of script output before headers:

[Fri Jul 09 06:41:15.907489 2021] [cgi:error] [pid 29196:tid 140467586610944] [client] AH01215: suexec policy violation: see suexec log for more details: /usr/share/netstores/dwos-bin/

[Fri Jul 09 06:41:15.908018 2021] [cgi:error] [pid 29196:tid 140467586610944] [client] End of script output before headers:

[Fri Jul 09 06:41:19.703931 2021] [cgi:error] [pid 29196:tid 140467509393152] [client] AH01215: suexec policy violation: see suexec log for more details: /usr/share/netstores/dwos-bin/

[Fri Jul 09 06:41:19.704388 2021] [cgi:error] [pid 29196:tid 140467509393152] [client] End of script output before headers:

[Fri Jul 09 06:41:21.370530 2021] [cgi:error] [pid 29197:tid 140467509393152] [client] AH01215: suexec policy violation: see suexec log for more details: /usr/share/netstores/dwos-bin/

[Fri Jul 09 06:41:21.370825 2021] [cgi:error] [pid 29197:tid 140467509393152] [client] End of script output before headers:

[Fri Jul 09 06:41:39.145628 2021] [cgi:error] [pid 29196:tid 140467501000448] [client] AH01215: suexec policy violation: see suexec log for more details: /usr/share/netstores/dwos-bin/

[Fri Jul 09 06:41:39.146006 2021] [cgi:error] [pid 29196:tid 140467501000448] [client] End of script output before headers:

How would I test a per user configuration?

Do the files adhere to suexec rules?

Permissions too open (i.e. 777 or whatever) is often a culprit. No group write. User and group must match the SuexecUser/SuexecGroup. I don’t remember all of them.

And, looking in that suexec log would be useful.

[2021-07-09 06:56:47]: uid: (1001/netstore) gid: (1001/netstore) cmd:

[2021-07-09 06:56:47]: target uid/gid (1001/1001) mismatch with directory (0/10) or program (0/10)

[2021-07-09 06:57:19]: uid: (1001/netstore) gid: (1001/netstore) cmd:

[2021-07-09 06:57:19]: target uid/gid (1001/1001) mismatch with directory (0/10) or program (0/10)

Well, that was somewhat helpful. The directory of scripts when copied over were owned by root but group uucp, so I chmod and chgrp them all to be owned by root and group root.

that is how it is on the CENTOS Cpanel Apache.

Here are the permissions of the dwos-bin directory files

-rwxr-xr-x 1 root root 483 Nov 7 2019 dwos-bin/
-rwxr-xr-x 1 root root 566 Dec 7 2012 dwos-bin/
-rwxr-xr-x 1 root root 81 Mar 7 2011 dwos-bin/

Sorry Joe, lost internet.

So on the Centos Cpanel server, group is set to wheel, but there is no wheel group on the UBUNTU.