Weird~Apache can not find the actually existing "bash" to execute my cgi file~ - apache

May be it's too easy for you to answer.
My problem is about cgi and apache web server.
Make it simple, I have a html "form.html" containing a form in it. To access it, typing "127.0.0.1/form.html" in browser.
After clicking "submit" in this html file, it is supposed to adress to "127.0.0.1\cgi-bin\cginame.cgi", the content of "cginame.cgi" is as below:
#!/bin/bash
if [ $REQUEST_METHOD="GET" ]
then
data=$QUERY_STRING
else
data='cat'
fi
java mortcal $data
"mortcal" is a java program calculating and return a HTML page containing results to user.
I'm using apache 2.2 and ubuntu 10.04.
The problem is when I click the "submit" button in "form.html", I got these in error log:
[Sat Sep 24 15:00:20 2011] [error] (2)No such file or directory: exec of '/usr/lib/cgi-bin/mortcgi.cgi' failed
[Sat Sep 24 15:00:20 2011] [error] [client 127.0.0.1] Premature end of script headers: mortcgi.cgi
I know it's because apache can not find "/bin/bash" to execute the cgi file. But I do have "/bin/bash".
It's so weird. Please help me out. Thank you in advance.

To execute CGI scripts, you need to configure Apache to allow this, and your script has to follow the HTTP protocol by sending back data in the right format, and right permissions, and on and on and on.
Here's a great tutorial with an example: http://httpd.apache.org/docs/2.2/howto/cgi.html
... however, I need to say: running a java program from within a shell script via Apache is a bad idea, in general. Each request loads the java runtime engine (JRE), runs the program, then unloads it. There are issues with environment, file ownership and so on -- all of this is why there are application servers like tomcat for java. So if you're just trying something, that's fine. If you're thinking this is a good way to get something done in a professional production environment, I would reconsider.

As noted, this seems like a poor way to do things, but:
Do the script file permissions allow execution for the web server user?
Are you using any security framework such as selinux which would apply additional restrictions?

I checked my configuration files. They are ok. So I kept searching on the web and finally I saw this:
"If you've copied over the script from a Windows machine, you may be being tripped up by ^M at end of line. You can use cat -v /usr/lib/cgi-bin/printenv.pl | head -1 to verify that there isn't a ^M at the end of the line. "
I did copy my cgi file from windows! I forgot to mention it because I did not think it's a big deal.
Now I have removed the ^M by typing this" :%s/^V^M//g in vi. This problem is resolved. Thanks very much for your answer, Mr.Harrison and Dark Falcon, Thank you all.

Related

How can I intentionally create a server error on apache to test error log

I'm on network solutions apache server. On their setup page I chose to enable error logging. Nothing ever seems to appear in the log folder though. I suppose that could be good if I really have no errors. How could I create an error that should show up in the log folder so I can test it.
If you have enabled dynamic scripts, how about a script that dies or won't compile?
#!/usr/bin/env perl
die "This script intentionally produces HTTP 500";

Serving a yesod application as a (Fast)CGI

I'm trying to serve a yesod application as a CGI (or FastCGI) program but Apache shows me a 500 error:
[Mon Sep 21 17:35:41.425565 2020] [http:error] [pid 2758] [client 10.0.2.2:43872] AH02429: Response header name '21/Sep/2020' contains invalid characters, aborting request
Starting with a new template with stack new project yesodweb/sqlite, I've tried to convert it to a CGI program by changing src/Application.hs.
I've imported the Wai CGI library with
import Network.Wai.Handler.CGI (run)
and changed the last line of appMain to run app:
-- | The #main# function for an executable running this site.
appMain :: IO ()
appMain = do
-- Get the settings from all relevant sources
settings <- loadYamlSettingsArgs
-- fall back to compile-time values, set to [] to require values at runtime
[configSettingsYmlValue]
-- allow environment variables to override
useEnv
-- Generate the foundation from the settings
foundation <- makeFoundation settings
-- Generate a WAI Application from the foundation
app <- makeApplication foundation
-- Run the application with Warp
--runSettings (warpSettings foundation) app
run app
I thought this was the minimal change to serve it as a CGI program but apparently is not working.
I've already looked into yesod's book chapter on deploying your Webapp which has been handy to write the apropriate Apache configuration so the server could ran the app. It says nothing about the nedded changes to the app code which I presume is where the problem is.
I've also checked this stackoverflow question but it's from almost 8 years ago so it's outdated now.
The problem is that the default makeFoundation logs to standard output, which is also where the CGI program is supposed to send its response, so you're getting intermingling of response headers with log output, and Apache tries to parse log lines as HTTP headers, etc.
If you replace newStdoutLoggerSet with newStderrLoggerSet, it should work, and the log output will end up in Apache's "error.log" or equivalent.

Centos server hanged due to postfix/sendmail spam emails

My centos server is running web applications in LAMP stack. A couple of days back, the server was not responding for about 10 mins and I got http response failure alert from my monitoring tool. When I checked the httpd error log I found a huge log entry (~12000 lines) related to sendmail.
14585 sendmail: fatal: open /etc/postfix/main.cf: Permission denied
The server ran out of memory and not responding.
14534 [Fri Aug 19 22:14:52.597047 2016] [mpm_prefork:error] [pid 26641] (12)Cannot allocate memory: AH00159: fork: Unable to fork new process
14586 /usr/sbin/sendmail: error while loading shared libraries: /lib64/librt.so.1: cannot allocate version reference table: Cannot allocate memory
We are not using sendmail in any of our application. How can I stop this attack in future?
Thank you in advance!
Sorry I have no comment facilities; it looks like one of your website pages is vulnarable for code injection, finding out where and what page may be a huge job. Focus on input (forms) variables. Always sanitize input variables before using them! P.s. php uses "sendmail", even if you use Postfix, it will use a sendmail binary to send mail and the sendmail binary will redirect it to Postfix. If your forms work well and the 12k error log lines come out of the blue, then I would think someone is trying to inject code through your website (happens all the time by the way).

error when accessing a uart device from a cgi python script

I'm trying to access a UART device from my /dev folder to control a robot. I'm trying to do this from the Internet using a cgi python script. The code works fine when I execute it on the command line but when it executes through the server I get a 500 error. I'm pretty sure this is some sort of permissions problem but I don't know how to solve it. If anyone knows what going on here or how I could fix it, the help would be much appreciated.
I can post my python code if anyone would liked to see it but I don't think the problem is in the code, but rather in the execution of the code.
Thanks in advance,
Michael,
Maybe solotion for you can be checking group of device file:
adam#sabayon ~ $ ls -lash /dev/ttyS*
0 crw-rw---- 1 root uucp 4, 64 03-10 13:20 /dev/ttyS0
0 crw-rw---- 1 root uucp 4, 65 03-10 13:20 /dev/ttyS1
0 crw-rw---- 1 root uucp 4, 66 03-10 13:20 /dev/ttyS2
0 crw-rw---- 1 root uucp 4, 67 03-10 13:20 /dev/ttyS3
For me it is uucp. And add user which start your cgi script to this group (for my system uucp). But you have to remember that all other cgi scripts started by this user will be also allowed to access UART.
EDIT:
For apache webserver it looks like suEXEC can be solution for you.
The suEXEC feature provides Apache users the ability to run CGI and
SSI programs under user IDs different from the user ID of the calling
web server. Normally, when a CGI or SSI program executes, it runs as
the same user who is running the web server.
So it looks like you can create new user for your cgi script configure it correctly and than use it with your script by apache.
Here is documentation for suEXEC:
http://httpd.apache.org/docs/2.0/suexec.html
I never used it, but I hope it will help.

How to write a wrapper - avoiding a subshell - script for apache2 rewrite maps or shell scripts in general?

I am running a rewrite map with an external rewrite program (prg) in apache2 that may produce an error and die.
When the rewrite map is not running any more the system obviously doesn't function properly.
So I wanted to start a simple wrapper shell script that itself executes map program (which is written in php) and restarts it if it dies:
#!/bin/bash
until /usr/bin/php /somepath/mymap.php; do
echo "map died but i will restart it right away!"
done
If I try that in the shell by hand, it works fine, however it does not work when started by the webserver.
...and then communicates with the rewriting engine via its stdin and
stdout file-handles. For each map-function lookup it will receive the
key to lookup as a newline-terminated string on stdin. It then has to
give back the looked-up value as a newline-terminated string on stdout
or the four-character string ``NULL'' if it fails...
The reason seems pretty clear to me. The first script takes stdin but doesn't redirect it to the sub script.
I guess I somehow need to define a descriptor using exec and redirect stdin/stdout of the scripts properly. But how do I do that?
It's a common problem that some script works executed "by hand" and do not work when executed indirectly (via cron or from apache).
Usually the root cause is one of:
your script needs some extra environment varaible (PATH, LD_LIBRARY_PATH, etc.)
your script requires terminal
First thing to do is to grab some debug info, so add to your script:
env > /tmp/$0.env # get environment
and get stderr:
... /usr/bin/php /somepath/mymap.php 2>/tmp/$0.stderr ...
This may lead you to the solution.
If your script requires terminal and you cannot fix it you can run your script via gnu screen.
Good luck.
Michał Šrajer has given one very common cause of trouble (environment). You should certainly be sure that the environment is sufficiently well set up, because Apache sets its own environment rigorously and does not pass on any inherited junk values; it only passes what it is configured to pass (SetEnv and PassEnv directives, IIRC).
Another problem is that you think your mapping process will fail; that's worrying. Further, it is symptomatic of yet another problem, which I think is the main one.
The first time the map process is run, it will read the request from the web server, but if the mapping fails, you rerun it - but the web server is still waiting for the output from the original request, and the map process is waiting for the input, so there's an impasse.
Note that a child process automatically inherits the standard input and standard output of its parent unless you do something to change it.
If you think things might fail, you'll need to capture the standard input so that when you rerun the program, you can resupply the input (though why it would work on the second time when it failed on the first is a separate mystery).
Maybe:
if tee /tmp/xx.$$ | /usr/bin/php /somepath/mymap.php
then : OK
else
until /usr/bin/php /somepath/mymap.php < /tmp/xx.$$
do echo "map died but I will restart it right away!"
done
fi
rm -f /tmp/xx.$$
Unresolved issues include:
You should add traps to ensure that the temporary file is removed;
You should probably not use /tmp as the directory;
The messages probably do not get sent to the web server and from thence to the client browser until the overall script terminates, so the echoed messages simply mess up the start of the response;
There is no limit on the number of failures;
There is no logging of the failures;
There is no attempt to fix the problem that caused the failure;
And there are probably others I've not thought of yet.
until is not a valid keyword, you probably have it aliased and aliases do not work on scripts. my mistake, it seems it is.
regardless, this is what you want to do:
while true; do
/usr/bin/php /somepath/mymap.php
done
if this also fails then yes, either your program expects a terminal or you have something missing in your env.