Reputation: 133
I use apache httpd on Centos7 (SELinux) and am trying to create an output filter to modify all served html pages. I've browsed some tutorials on how to create them, but I keep stumbling on step one even before I get to the coding part.
Currently I have this in my httpd.conf
ExtFilterDefine portal_header mode=output intype=text/html cmd="/var/www/root/main/portal/portal.php"
SetOutputFilter portal_header
To pinpoint my problem I have deleted all the actual code in the file /var/www/root/main/portal/portal.php for the moment and currently it looks like this
#!/usr/bin/php
<php?
/* test */
?>
But when I know try to access any html on the server I get "500 Internal Server Error". After commenting out the SetOutputFilter line in httpd.conf the pages work so the error is generated by the filter.
In my error log it reads
[Fri Feb 10 14:36:55.458174 2017] [ext_filter:error] [pid 171495] (13)Permission denied: [client 10.2.8.109:49278] AH01458: couldn't create child process to run `/var/www/root/main/portal/portal.php'
[Fri Feb 10 14:36:55.458215 2017] [ext_filter:error] [pid 171495] (13)Permission denied: [client 10.2.8.109:49278] AH01467: can't initialise output filter portal_header: aborting
I have at least
but none of the above has any effect. The only change in matters was that when I deliberately mis-spelled the file name I got "No such file or directory" error instead.
Does anyone have an idea what I should do to make this work? For the moment I would be happy to see the script to even do nothing at all, if it just didn't break, and only afterwards add some functionalities into it.
UPDATE: I was able to pinpoint the problem to SELinux policies, since after disabling them (setenforce 0) the error vanished. So currently I'm trying to figure out how I should alter the policies.
Upvotes: 2
Views: 967
Reputation: 15604
I ran into a similar problem when trying to improve on a simple sed filter command. According to the https://httpd.apache.org/docs/2.4/mod/mod_ext_filter.html documentation it should be possible to use a command like sed as a filter and indeed it does:
The following filter works for me and replaces global links to local ones so that i can use a docker image with data from an existing site.
# Filter configuration
# mod_ext_filter directive to define a filter which
# replaces text in the response
#
ExtFilterDefine fixtext mode=output intype=text/html \
cmd="/bin/sed s#http://ceur.ws.org#http://capri:8880#g"
<Location "/">
# core directive to cause the fixtext filter to
# be run on output
SetOutputFilter fixtext
</Location>
when trying to replace the sed command with accessing a script with
"cmd=/root/bin/filter.sh"
I got the error message :
AH01458: couldn't create child process to run `/root/bin/filter.sh'
AH01467: can't initialise output filter fixtext: aborting
which is your original reason for your question.
Now i am also looking for a better solution and tried:
cmd="/bin/bash /root/bin/filter.sh"
assuming that the shebang resolving might be the culprit. Interestingly i then get:
AH01461: apr_file_write(child input), len 0
AH01468: ef_unified_filter() failed
and that's why i am already posting this answer in the hope I'll find a proper solution soon or others might be able to help because the list of related AH014## error codes is getting longer in this Q&A thread.
See https://github.com/omnigroup/Apache/blob/master/httpd/modules/filters/mod_ext_filter.c for the relevant source code.
I am assuming that the apr_proc_create is not capable of calling scripts using a shebang. So my workaround was to
Working apache filter.conf
# Filter configuration
# mod_ext_filter directive to define a filter which
# replaces text in the response
#
ExtFilterDefine fixtext mode=output intype=text/html \
cmd="/usr/bin/awk -f /var/www/filter.awk"
<Location "/">
# core directive to cause the fixtext filter to
# be run on output
SetOutputFilter fixtext
</Location>
working awk script to filter links
# WF 2020-06-03
#
# filter HTML output thru this awk script to fix global links to local ones
#
# you might want to try out this filter from the command line with
# cat /var/www/html/index.html | awk -f filter.awk
#
# setup the replacement
BEGIN {
port=8880
host="capri"
sourceServer="http://ceur-ws.org"
targetServer=sprintf("http://%s:%s",host,port)
}
# for each line
{
# get the line
line=$0
# replace any sourceServer reference with the targetServer reference
gsub(sourceServer,targetServer,line)
# output the modified line
print line
}
/root/bin/filters.sh
#!/bin/bash
# WF 2020-06-02
# filter all html output thru this script
port=8880
host=capri
# substitute all hard links in CEUR-WS with a local link
/bin/sed s#http://ceur.ws.org#http://$host:$port#g
# try out this filter with
# cat /var/www/html/index.html | /root/bin/filter.sh | grep capri
Upvotes: 1