1

I'm trying to have two subdomains, my.domain.com and foo.my.domain.com, both redirect to the same directory of my Apache2 server (127.0.0.1/my/).

However, I want the scripts there to be able to tell from which domain the request came from. The way I see it, there would be two ways to do that:

  • Using a RewriteRule to add ?foo=bar at the end of every request that contains .php, but that sounds quite dirty
  • Use ProxyPreserveHost to indicate to the PHP script what the original domain is, which sounds more normal and sane.

However, the second I enable ProxyPreserveHost I'm getting a neverending 301 redirection loop. This is the virtual host configuration:

My.Domain.com:

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName my.domain.com

    ProxyPass / http://127.0.0.1/my/
    ProxyPassReverse / http://127.0.0.1/my/
    ProxyRequests Off

    SSLCertificateFile /etc/letsencrypt/live/my.domain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/my.domain.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

Foo.My.Domain.Com:

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName foo.my.domain.com

    ProxyPass / http://127.0.0.1/my/
    ProxyPassReverse / http://127.0.0.1/my/
    ProxyRequests Off
    ProxyPreserveHost On      # creates 301 loop!

    SSLCertificateFile /etc/letsencrypt/live/my.domain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/my.domain.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

Note: I've also tried to put ProxyPassReverse / https://foo.my.domain.com/ in the second domain foo.domain.com, but it didn't change anything.

How can I preserve the host without causing a redirect loop?

Rackover
  • 91
  • 1
  • 15

3 Answers3

1

As the documentation states, setting ProxyPreserveHost causes apache to ignore the ProxyPass directive and use the host name provided, so you are trying to forward the request to foo.my.domain.com resulting in your infinite redirect loop. I don't think I would have set up my server to proxy forward to localhost, but given that you have, the simplest change I could suggest is to get rid of the ProxyPreserveHost statement and change the ProxyPass to something like http://127.0.0.1/myfoo, and add a bit of code to preserve the foo address.

wordragon
  • 1,297
  • 9
  • 16
  • How and where would I add that bit of code? I don't see anything in the PHP side that would allow me to know the address once i've been redirected : – Rackover Dec 05 '20 at 19:32
  • I'm not sure how you have apache mapped, but you will have a web head directory which will probably have a subdirectory "my", and there might be an index.php there - or perhaps your configuration maps it to a different script. In either case, you want to end up with myfoo going to a different script which sets some global variable or other indicator that you came in though myfoo, and then invokes the other script. There are lots of other ways to lay this out - this is just one example. If I were starting over, I would lose the internal proxy entirely and set it up as a standard web site. – wordragon Dec 06 '20 at 00:16
  • So you confirm there is no way under Apache to have two addresses redirect to the same website, while still letting that website know from which address came the request? And that I will have to duplicate the whole site or play with linked directories to make any of that work? – Rackover Dec 06 '20 at 17:41
1

Found it:

$_SERVER["HTTP_X_FORWARDED_HOST"] contains the hostname, so foo.my.domain.com in my case. I did not need UseCanonicalName nor ProxyPreserveHost in the end.

Rackover
  • 91
  • 1
  • 15
0

if you want to get the domain in php script, there are better solution to do this:

in php :

echo $_SERVER['SERVER_NAME'];
echo $_SERVER['HTTP_HOST'];

and in appache virtual hosts:

UseCanonicalName off

as here suggested:

https://stackoverflow.com/a/50301646/9287628

UPDATE

add this to your appache virtual hosts:

RequestHeader set mydomain "my.domain.com"

and for another one:

RequestHeader set mydomain "foo.my.domain.com"

then retrieve it in php like this:

echo $_REQUEST["mydomain"];

if it dosent recognized RequestHeader:

a2enmod headers
systemctl restart apache2.service // or whatever your appache service name is httpd 

As RockOver has Found The Solution

$_SERVER["HTTP_X_FORWARDED_HOST"];

will reflect the the actual domain name and will be preserve during redirecting.

Abilogos
  • 4,777
  • 2
  • 19
  • 39