Unable to call shell script from apache httpd - apache

I am trying to call shell script from 000-default.conf inside /etc/httpd/sites-available.
The 000-default.conf file content is :
<VirtualHost *:80>
ServerName localhost
DocumentRoot /var/www/html/
CustomLog "| sh /scratch/user/test.sh" custom_user_tracking
</VirtualHost>
My /etc/httpd/conf/httpd.conf has below content added:
ServerName localhost
LogFormat "%t [%h] [%m] [%U] [%B] [%b] [%D] [%q] [%s] [%{Referer}i] [%{User-Agent}i]" custom_user_tracking
IncludeOptional sites-enabled/*.conf
IncludeOptional sites-available/*.conf
I have kept a dummy html file inside /var/www/html/
Content of index.html:
<!DOCTYPE html>
<html>
<body>
<h1>Hello World!</h1>
</body>
</html>
When ever I hit http://localhost:80 the shell script is not called at all. The shell script is executable and it just prints "Hello World".
But when I call apache kafka binary from 000-default.conf file then it works properly.
Modified 000-default.conf file:
<VirtualHost *:80>
ServerName localhost
DocumentRoot /var/www/html/
CustomLog "| [HOME_DIR_KAFKA]/bin/kafka-console-producer.sh --topic access-log --broker- list <Remote_host_ip>:9092" custom_user_tracking
</VirtualHost>
Now when I click on http://localhost:80 then message is send in remote kafka server.
Can any one help here how can I call shell script from apache httpd?

Consider making the test.sh script executable using "shebang" ($!), instead of using sh.
000-default.conf :
CustomLog "| /scratch/user/test.sh" custom_user_tracking
/scratch/user/test.sh
#! /bin/sh
...
Alternatively run 'sh' using full path
CustomLog "| /bin/sh /scratch/user/test.sh" custom_user_tracking
Also, double check the execute permission on /scratch/user/test.sh, and the permission on the folder. https is usually running as non-privileged account.

Here is the content of send_message.sh:
#! /bin/sh
PRIVATE_KEY=$1
HOST=$2
TOPIC_NAME=$3
MESSAGE=$4
echo "OCI VM IP : $HOST"
echo "PRIVATE KEY : $PRIVATE_KEY"
echo "TOPIC-NAME: $TOPIC_NAME"
echo "MESSAGE: $MESSAGE"
## Run Cmd in vm
ssh -o "StrictHostKeyChecking no" -i $PRIVATE_KEY opc#$HOST /bin/bash << EOF
sudo su
echo $MESSAGE | [HOME_DIR]/bin/kafka-console-producer.sh --broker-list [VM_IP]:9092 --topic $TOPIC_NAME
EOF
And content of /etc/httpd/sites-available/000-dafult.conf
<VirtualHost *:80>
ServerName localhost
DocumentRoot /var/www/html/
CustomLog "| /home/opc/send_message.sh /home/opc/dev2oci.key 100.111.69.61 access-log apache-httpd" custom_user_tracking
</VirtualHost>
The message is sent in topi access_log for every 5s interval. Though the http://localhost:80 is not triggered from browser.
If I replace the CustomLog with below entry:
CustomLog "| [HOME_DIR]/bin/kafka-console-producer.sh --topic access-log --broker-list [VM_IP]:9092" custom_user_tracking
Then message is sent on triggering http://localhost:80 from browser.
Can anyone let me know what I am missing here.

Related

Send Apache errorlogs from a docker container to syslog host

I have a container with apache2 and modsecurity installed.
My question is: how to send the logs generated by apache and modsecurity (stored in /var/apache2/error.log) to the host?
I have syslog within the host that already collect locally and send the logs to a remote server; I'm able to send the logs from other containers correctly but not from the apache container.
I tried several ways but unfortunately i was not able to achieve this objective:
Piping with: ErrorLog "| :514"
ErrorLog /dev/stderr
TransferLog /dev/stdout
Within dockerfile: RUN ln -sf /proc/self/fd/1 /var/log/apache2/access.log &&
ln -sf /proc/self/fd/1 /var/log/apache2/error.log
This is my current configuration:
/etc/apache2/sites-available/000-default.conf
...
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SecRuleEngine On
...
There is a default modsecurity configuration for now.
Thank you.

how to disable auto refresh in apache httpd

I am trying to call shell script from 000-default.conf inside /etc/httpd/sites-available.
The 000-default.conf file content is :
<VirtualHost *:80>
ServerName localhost
DocumentRoot /var/www/html/
CustomLog "| /bin/sh /scratch/user/test.sh" custom_user_tracking
</VirtualHost>
My /etc/httpd/conf/httpd.conf has below content added:
ServerName localhost
LogFormat "%t [%h] [%m] [%U] [%B] [%b] [%D] [%q] [%s] [%{Referer}i] [%{User-Agent}i]" custom_user_tracking
IncludeOptional sites-enabled/*.conf
IncludeOptional sites-available/*.conf
I have kept a dummy html file inside /var/www/html/ Content of index.html:
<!DOCTYPE html>
<html>
<body>
<h1>Hello World!</h1>
</body>
</html>
When ever I hit http://localhost:80 the shell script is called. The shell script is executable and it just prints "Hello World".
But the script is auto called in 5s interval though the url http://localhost:80 is not triggered from the browser.
Can any one help here how can I disable auto refresh in apache httpd?

Apache: Serving content from two different locations and ports

I have an Apache server running on Ubuntu 14 on a server on which I have sudo.
When users request the server's IP, Apache serves content from /var/www/html.
I'd like to keep this behavior intact, and make it so that users who request IP/cats get some special content that's hosted by a Docker container on port 7777.
What's the best way to achieve this functionality in Apache?
With thanks to #arkascha I did the following to get this going:
Create a file /etc/apache2/sites-available/wow.conf with the following content:
<VirtualHost *:*>
# enable proxies
ProxyPreserveHost On
ProxyPass /cats http://0.0.0.0:7777/
ProxyPassReverse /cats http://0.0.0.0:7777/
ServerAdmin douglas.duhaime#yale.edu
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
This says when requests come in for IP/cats, serve the users the content from port 7777.
I then symlinked this file to the sites-enabled directory:
sudo ln /etc/apache2/sites-available/wow.conf /etc/apache2/sites-enabled/wow.conf
Finally, I needed to delete the default sites enabled file and restart the server:
sudo rm /etc/apache2/sites-enabled/000-default.conf
sudo service apache2 restart
P.S. Apache is amazing.

Docker www-data grant write permissions to var/www

I'm running a php:7.0-apache Docker image, but I have no permissions to write to /var/www/html. How is it possible to grant write rights to this user?
Dockerfile:
FROM php:7.0-apache
# PHP Extensions
RUN docker-php-ext-install pdo_mysql
# Composer
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php composer-setup.php
RUN php -r "unlink('composer-setup.php');"
RUN mv composer.phar /usr/local/bin/composer
ADD vhost-default.conf /etc/apache2/sites-enabled/000-default.conf
# Open Ports
EXPOSE 80
EXPOSE 443
Host Conf
<VirtualHost *:80>
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory /var/www/html >
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
To resolve this you will need to add an extra line in your Dockerfile like:
RUN chown www-data:www-data /var/www/html/
Sergiu's answer is not working, because your volume is bound after chown.
What you should do is that you should run chown after bound to your volume and before start the Apache.
To do that, I add chown command in the apache2-foreground script.
RUN sed -i 's/^exec /chown www-data:www-data \/var\/www\/html/\n\nexec /' /usr/local/bin/apache2-foreground
So when you start your container, it will change the permission to www-data.
PS: Your container's user should be in root or a user who can execute chown.

Multiple vhosts on one and the same docker container

I'm trying to run two different domains on one and the same Docker container and port.
The Docker container runs CentOS. docker-compose.yml looks like so:
web:
image: fab/centos
ports:
- "80:80"
volumes:
- ./src/httpd.conf:/etc/httpd/conf/httpd.conf
- ./src:/var/www/html
- ./src/hosts:/etc/hosts
environment:
- VIRTUAL_HOST=dummy.dev,tests.dev
I also declared both .dev domain names inside of /etc/hosts on the host computer (OS X.)
It's been a while since I configured virtual hosts. My understanding was that I just needed to declare them and that Apache would automatically serve the proper files depending on the HTTP HOST being requested.
This is what I have, added at the end of httpd.conf:
<VirtualHost *:80> # first host = default host
DocumentRoot /var/www/html/default
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/html/dummy
ServerName dummy.dev
ServerAdmin webmaster#dummy.dev
ErrorLog logs/dummy.dev-error_log
CustomLog logs/dummy.dev-access_log common
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/html/tests
ServerName tests.dev
ServerAdmin webmaster#tests.dev
ErrorLog logs/tests.dev-error_log
CustomLog logs/tests.dev-access_log common
</VirtualHost>
However, in practice, visiting either dummy.dev or tests.dev actually serves /var/www/html/default. This is as if Apache didn't realize which host is being called (though a dump of $_SERVER in PHP does show the expected HTTP_HOST value, i.e.: either 127.0.0.1, dummy.dev or tests.dev depending on which URL I visit.)
What did I miss?
It's unclear to me whether this is an Apache issue or a Docker one.
(Please note this is a different question from how to host multiple apps on the same domain with different port. In my case, I do want the virtual hosts to be all inside/on the same app/port/container.)
Turns out this was an Apache configuration issue.
I needed to explicitly enable domain-named virtualhosts, like so:
NameVirtualHost *:80
This answer helped.
Docker had nothing to do with the matter.
The fab/centos does not exist in public docker hub, so not sure why you are experiencing the issue.
My recommendation would be to take a step back and try to make it work with a simple example.
docker search apache yields eboraas/apache as most starred image, so I'll use that one for the example.
In a test directory, use your sample:
File: httpd.conf
<VirtualHost *:80> # first host = default host
DocumentRoot /var/www/html/default
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/html/dummy
ServerName dummy.dev
ServerAdmin webmaster#dummy.dev
ErrorLog logs/dummy.dev-error_log
CustomLog logs/dummy.dev-access_log common
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/html/tests
ServerName tests.dev
ServerAdmin webmaster#tests.dev
ErrorLog logs/tests.dev-error_log
CustomLog logs/tests.dev-access_log common
</VirtualHost>
Then create the vhost websites & the logs directory.
mkdir -p logs; for i in default tests dummy; do mkdir -p $i; echo "hello $i" > $i/index.html; done
Finally, run docker.
docker run -it -v $(pwd):/var/www/html -v $(pwd)/httpd.conf:/etc/apache2/sites-available/000-default.conf -v $(pwd)/logs:/etc/apache2/logs -p 9090:80 --rm --name apache_c eboraas/apache
Note that I use basically the same volumes as you did in your docker-compose.yml, except that I use site-available instead of changing the httpd.conf.
To test, make sure you have tests.dev and dummy.dev in your /etc/hosts pointing at the right Docker IP and test:
$> curl dummy.dev:9090
hello dummy
$> curl tests.dev:9090
hello tests
From this point, build up on top of this by first trying the docker apache image that you are using, then try with your custom /etc/hosts file, then put it back in a docker-compose file
Turn on NameVirtualHost in your httpd config:
File : /etc/httpd/conf/httpd.conf
NameVirtualHost *:80
NameVirtualHost *:443