Apache HTTPS recognized as HTTP in PHP - php

I have a Symfony API REST, enabled in my apache production server, which uses HTTPS and certified A+ security by Querys SSL test.
Via a POST route https://hooks-api.com/hooks, the API returns a url property, generated with $request->generateUrl method of Symfony Request.
The problem is that the API always generates a http:// URL since Symfony does not recognize that the server is using HTTPS (tested with $request->getScheme & $request->getPort).
After some researches, it seems that the phpinfo prints a Appache HTTP Configuration with REQUIRE_SCHEME http, and all the stuff for SSL is missing like HTTPS on & SSL_TLS_SNI.
I have created a new production environnement on my own local, with the same virtual host config: it works !
But I still don't understand why the production server does not work... Here is my config :
<VirtualHost *:80>
ServerName api.hooks
Redirect 308 / https://prod.api.hooks/
</VirtualHost>
<VirtualHost *:443>
ServerName prod.api.hooks
SSLEngine on
SSLCertificateKeyFile "${SRVROOT}/conf/key/private.key"
SSLCertificateFile "${SRVROOT}/conf/key/certificate.crt"
Header set Access-Control-Allow-Origin "*"
Header always set Content-Security-Policy "default-src 'none'!"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains;"
Header always set X-Content-Type-Options "nosniff"
DocumentRoot C:/wamp64/www/production/hooks/public
<Directory "C:/wamp64/www/production/hooks/public">
AllowOverride None
Require all granted
FallbackResource /index.php
</Directory>
<Directory "C:/wamp64/www/production/hooks/public/bundles">
FallbackResource disabled
</Directory>
</VirtualHost>

Related

How can I prevent ProxyPreserveHost from redirecting indefinitely?

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?
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.
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.
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.

wordpress+docker+apache mod proxy redirects to http://localhost

My environment is, a docker container running wordpress on apache can be accessed via ip:port . The host environment has an apache instance which redirects traffic that comes to http://myurl to localhost:port using mod proxy (I have the same set up with other docker containers in the same host which is working fine). But accessing http://myurl (after changing the wordpress config) will just redirect you to localhost (in the wordpress container's apache log i can see it giving a 301 to redirect you) .
The problem is only there when you access the base url. (http://myurl/wp-login.php works)
Host Apache config:
<VirtualHost *:80>
ServerName my.url.com
<IfModule mod_proxy.c>
ProxyRequests Off
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</IfModule>
</VirtualHost>
This works (in wp-config.php):
define('WP_HOME','http://8.8.8.8:8080');
define('WP_SITEURL','http://8.8.8.8:8080');
This doesn't
define('WP_HOME','http://my.url.com');
define('WP_SITEURL','http://my.url.com');
These are the wordpress plugins i have enabled. But note that i changed their configs accordingly as well.
wp-support-plus
admin custom login
UPDATE:
This seems to have fixed the problem somewhat.
define('WP_HOME','http://8.8.8.8:8080');
define('WP_SITEURL','http://my.url.com');
Some of the components (home buttons etc) still go for the ip:port but the system works.
Turns out the problem is the headers being stripped when the redirection happens. I fixed this by adding ProxyPreserveHost On to the host apache configuration. The changed file looks like this now.
Host Apache config:
<VirtualHost *:80>
ServerName my.url.com
<IfModule mod_proxy.c>
ProxyRequests Off
ProxyPreserveHost On # needed if you need to pass the original host header
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</IfModule>
</VirtualHost>

Apache setHandler only only works on index

I am using docker for local development on a PHP powered craft website. My shared host requires a SetHandler php70-cgi directive, but the version of apache in the official PHP container does not have php-cgi and does not interpret PHP scripts. Because the container is development only, and not an attempt to 1:1 replicate production, I'm attempting to work around this with a custom apache config that sets an InDocker request variable:
<VirtualHost *:80>
ServerAdmin me#mydomain.com
DocumentRoot /var/www/craft/public
SetEnv InDocker true
<!-- ... more config -->
</VirtualHost>
And an .htaccess in my public folder that conditionally checks for the request env and only runs the:
Header set InDocker "%{InDocker}e"
<FilesMatch \.php$>
<If "!reqenv('InDocker') =~ /true/">
Header set IfMatch "We are not in docker"
SetHandler php70-cgi
</If>
Header set FilesMatch "yo"
</FilesMatch>
When I make a request to the root of my application, things render correctly and I see the following headers:
http -h :4020/
InDocker: true
FilesMatch: yo
However, if I make a request to another path, things do not render correctly and I can see the following headers are set:
http -h :4020/
InDocker: true
FilesMatch: yo
IfMatch: We are not in a container
Is there a way I can get this to work using my If or a better way to accomplish conditionally using SetHandler?
I could not get this to work using SetEnv and if reqenv so I had to fall back to using Define and IfDefine.
I added Define InDocker to my container's apache config:
<VirtualHost *:80>
ServerAdmin me#mydomain.com
DocumentRoot /var/www/public
Define InDocker
<Directory /var/www/public>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order deny,allow
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
And then used IfDefine in my .htaccess file:
<IfDefine !InDocker>
<FilesMatch \.php$>
SetHandler php70-cgi
</FilesMatch>
</IfDefine>
This allows me to keep things as-is on my shared host and use the same .htacess for development.

zf3 virtual host redirects to the wrong page

I configured zend framework 3 through composer on remote debian server. I added virtual host to etc/apache2/sites-available/mysite.conf like below but it shows just "It works!" page instead of zf3 public. Do anyone knows hos to solve it?
<VirtualHost *:80>
ServerName zfapp.localhost
DocumentRoot /var/www/mysite/skeleton-application/public
<Directory /var/www/mysite/skeleton-application/public>
DirectoryIndex index.php
AllowOverride All
Order allow,deny
Allow from all
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
</Directory>
Check the following:
Have you enabled the site on the remote Debian server. To enable the site you should use a2ensite mysite
The ServerName directive should correspond the the HTTP hostname in the HTTP request. When you are dereferencing a URL on the remote server, the hostname part in the browser should correspond with the ServerName. It is unlikely you are using zfapp.localhost since most OS's have reserved host entries of 127.0.0.1 for any localhost derivative.

Getting SSL to work in Xampp - Access forbidden error

I am trying to get Xampp to work in https, but I am having a few issues.
What I have done so far:
mod_ssl.so is loaded
php_openssl.dll is loaded
DocumentRoot in httpd-ssl.conf was changed from C:/xampp/htdocs to C:/xampp/ as this is where all of the directories of my sites are.
Do I need to change the server name in httpd-ssl.conf?
Edit: do I need to add virtual host in httpd-vhosts.conf on port 443 as well as 80? Also, do Xampp come with a built in SSL cert etc.?
I think the best way is creating a VirtualHost for each project you're developing.
Otherwise, you would need change the DocumentRoot for the project you're developing at the time.
So, you can change "httpd-vhosts.conf" file and create a VH for port 80 redirecting all the requests to a VH for port 443 (if you want to disable HTTP only), like this:
• HTTP
<VirtualHost *:80>
ServerName yoursite.your.domain
Redirect / https://yoursite.your.domain/
</VirtualHost>
• HTTPS
<VirtualHost *:443>
ServerName yoursite.your.domain:443
#in your case you're not using htdocs, so DocumentRoot be like
DocumentRoot "C:\xampp\yourproject"
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, PUT, GET, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "Content-Type"
</IfModule>
#the same here
<Directory "C:\xampp\yourproject">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require all granted
</Directory>
#check your absolute path bellow
SSLEngine on
SSLCertificateFile "C:\xampp\apache\conf\ssl.crt\server.crt"
SSLCertificateKeyFile "C:\xampp\apache\conf\ssl.key\server.key"
</VirtualHost>
About the certificate, I think XAMPP actually come with a built in SSL certificate, but, even it didn't came, you can generate it using his tools. You can see a lot of tutorials in the internet about this.

Categories