Cole Diffin Cole Diffin - 1 month ago 15
Apache Configuration Question

How can i use parts of the Referrer Header in an Apache Rewrite Rule

I'm writing a generic proxy of sorts - so I can access a single host in the form of

http://<proxy-host>/<host-to-proxy-to>/<port>/<path>/
which currently uses rewrites to Proxy requests to
https://<host-to-proxy-to>:<port>/<path>


I've got that part working and it seems to do what I want it to. However in some scenarios I'm using it with a stubborn sites that are forcing root relative urls. The application in question is not particularly easy (and in some cases impossible) to change.

My problem is how to identify the root relative URLs that are hitting apache, and proxy them to the correct host. I have identified that the correct host details are still in the path of the referrer header, so I'm trying to break apart and use the referrer path in a rewrite rule.

Updated Code Below:

<VirtualHost *:80>
ServerName wtf.devbox-cole.orion.internal
ServerAlias wtf.devbox-cole

RewriteEngine On

<LocationMatch "^/$">
Header always set X-CRAP-BASE "Its working kinda"
Redirect 410 /
</LocationMatch>

<Location /web/>
Header always set X-CRAP-BASE "Hardly Working"
RewriteCond %{HTTP_REFERER} "http://%{HTTP_HOST}/([a-zA-Z0-9_\.]*)/([0-9]*)/.*"
RewriteRule (.*) https://%1:%2/$1 [P]
</Location>

<LocationMatch "^/(?<host>[a-zA-Z0-9_\.]*)/(?<port>[0-9]*)/(?<path>.*)">
RewriteRule ".*" https://%{env:MATCH_HOST}:%{env:MATCH_PORT}/%{env:MATCH_PATH} [P]
ProxyPassReverse "https://%{env:MATCH_HOST}:%{env:MATCH_PORT}/%{env:MATCH_PATH}"
</LocationMatch>

# Enable proxying to https://
SSLProxyEngine On
# Allow Proxying to https without valid cert
SSLProxyVerify none
# Disable Domain Nmae checking on the Certs
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
# disbaled cert expiryt Check
SSLProxyCheckPeerExpire off

LogLevel debug rewrite:trace8
CustomLog "/var/log/apache2/wtf_log" "%h"
ErrorLog "/var/log/apache2/wtf_error
</VirtualHost>


The above code still isn't quite working. Still trying to track down why..

Answer

So after many attempts and reading as much documentation as I can find - I managed to solve my initial question. The following VHost block will Proxy http://domain.com/// to https://:/ AND it will map any requests to /web/* originating from that domain, back to the proper place.

<VirtualHost *:80>
  ServerName domain.com

  RewriteEngine On

  <LocationMatch "^/$">
    Header always set X-CRAP-BASE "Its working kinda"
    Redirect 410 /
  </LocationMatch>

  <Location /web/>
    Header always set X-CRAP-BASE "Hardly Working"
  </Location>

  RewriteCond %{REQUEST_URI} "^/web/.*"
  RewriteCond %{HTTP_REFERER} "http://.*/([a-zA-Z0-9_\.\-]*)/([0-9]*)/.*"
  RewriteRule (.*) https://%1:%2/$1 [P]

  RewriteCond %{REQUEST_URI} "^/([a-zA-Z0-9_\.\-]*)/([0-9]*)/(.*)"
  RewriteRule ".*" https://%1:%2/%3 [P]

  <LocationMatch "^/(?<host>[a-zA-Z0-9_\.\-]*)/(?<port>[0-9]*)/(?<path>.*)">
    ProxyPassReverse "https://%{env:MATCH_HOST}:%{env:MATCH_PORT}/%{env:MATCH_PATH}"
  </LocationMatch>

  # Enable proxying to https://
  SSLProxyEngine On
  # Allow Proxying to https without valid cert
  SSLProxyVerify none
  # Disable CN Checking on the Certs
  SSLProxyCheckPeerCN off
  SSLProxyCheckPeerName off
  # Disable Cert Expiry Check
  SSLProxyCheckPeerExpire off

  # Extra Logging
  #LogLevel debug rewrite:trace8
  CustomLog "/var/log/apache2/domain.com_log" "%h"
  ErrorLog "/var/log/apache2/domain.com_error
</VirtualHost>

And then i remembered how silly Referrer headers are, in that if a CSS file requests another CSS file, or an image for example, then the Referrer isnt set as expected :facepalm: