Fluster
Fluster

Reputation: 133

Permission denied with apache filter

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

Answers (1)

Wolfgang Fahl
Wolfgang Fahl

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

  1. call the command directly
  2. switch to awk

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

Related Questions