My CGI Perl scripts CentOS 7 are not running correctly, they are either showing up as plain text or I am getting a server error.

I've been placing my scripts into the default /var/www/cgi-bin directory with no luck.

I tried to place CGI scripts into /var/www/html/another-dir but they are just coming up as plain text.


This is how to get CGI Perl scripts executing correctly on CentOS 7.

I'm leaving this here as it seems a lot of the resources on the internet don't combine the steps and leave people like me very confused.

In short this, is what needs to be done.

  1. Install software.
  2. Create your test CGI file.
  3. Ensure the CGI module is loaded. Inside httpd.conf.
  4. Change the directory settings in httpd.conf.
  5. Change permissions to allow for CGI to execute.

Install and configure software

sudo yum update
sudo yum install httpd
sudo yum install perl perl-CGI
sudo systemctl start httpd.service
sudo systemctl enable httpd.service

Create your test CGI file

Even following these steps all the way through, I never once got a CGI script inside /var/www/cgi-bin to load without modifying the web root inside httpd.conf. Instead I decided to just activate CGI in another directory.

On my server, I want the web root html to hold my CGI files. This is /var/www/html/hello.cgi

print "Content-type: text/html\n\n"; # This is mandatory.
print "<h2>Hello world!</h2>";

Ensure the CGI module is loaded. Inside httpd.conf

You can do an easy check for this via the command.

grep -n "LoadModule" /etc/httpd/conf/httpd.conf

I could see that no CGI modules were specified and I confirmed their existence inside the modules folder via:

find /etc/httpd/modules/ -iname "*cgi*"

This is the one I am after:


Let's add that to the /etc/httpd/conf/httpd.conf file:

LoadModule cgi_module modules/mod_cgi.so

I believe that you need to load the module in a different way in Ubuntu, keep that in mind.

Change the directory settings in httpd.conf

Before restarting httpd we have to change one more thing inside /etc/httpd/conf/httpd.conf:

<Directory "var/www/html">
    Options +ExecCGI
    AddHandler cgi-script .cgi .pl

According to many Googlings, you may have to also modify this part of the httpd.conf file so that it points to the same directory as above "var/www/html":

ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

I didn't modify mine, it didn't seem to make a difference.

Change permissions to allow for CGI to execute

And this one got me stuck a lot! Don't overlook this!

You need to tell your server that these CGI scripts are allowed to be executed as programs.

chmod 705 *.cgi

Or you can target individual CGI scripts.

chmod 705 hello.cgi

(Some people on the internet have said that chmod 755 and 777 might also work.)

Now restart httpd like so:

sudo systemctl restart httpd.service

At this point my CGI scripts are rendering into HTML correctly.

They are being served from the web root like this: http://<IP>/hello.cgi

Please feel free to add any more information that might help others.

  • 2
    Making your whole DocRoot executable makes it easier on attackers. All they need to do is find a whole that let's them write a file in that tree. Only the smallest subset of things practical should be allowed to execute.
    – chicks
    Jan 28 '16 at 21:27
  • 3
    Better practice would be to put *.cgi into it's own dir and add that dir as <Directory> for CGI execution in httpd.conf, is that correct?
    – Joseph
    Jan 28 '16 at 23:38

(Some people on the internet have said that chmod 755 and 777 might also work.)

If you are sharing the server with anyone else, and in general because of possible attack, you should almost definitely not be using /any/ of 755, 705 or 777. These would give any other users logged onto your server the ability to execute your scripts with any arguments they choose. Instead, make sure that your scripts and all directories above it have nginx, apache, or whatever user/group runs your webserver and is supposed to execute your scripts, as owner or group (using the command chown or chgrp). Then set the third bit in chmod to 0 (You should never use something more permissive than 750), because other users on your server (except for you and nginx/apache, whether an intruder or a legitimate user), have /no/ business executing, reading or modifying your scripts from the shell.

You can read up on linux file permissions at e.g. https://www.digitalocean.com/community/tutorials/linux-permissions-basics-and-how-to-use-umask-on-a-vps#octal or https://www.digitalocean.com/community/tutorials/an-introduction-to-linux-permissions etc

Good luck!

EDIT: This is an explanation of what user chick wrote on Jan 28 - good call, the permissions are too permissive in the tutorial.

  • Great points! I made my previous answer a community wiki so that others can update it correctly. :)
    – Joseph
    Aug 8 '16 at 14:10

One more note to mention is that if you are writing your code in windows environment and then remotely uploading it to the server, make sure that you convert the file to Unix EOL (especially when using Notepad++, found under Edit menu); otherwise, you will get server error.

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.