Rewrite virtual servers directory into a top level domain - regex

I would like to rewrite directories of my RootDocument into thei'r own addresses.
For exaimple, I would like to be able to visit: http://localhost/FOO and be redirected to http://FOO.dev. Please note that the URL domain is static ass all subdirectory domains will have the same tol-level domain. I need to create a redirect within chunk of code:
<VirtualHost *:80>
ServerName 127.0.0.1
ServerAlias localhost
DocumentRoot /usr/local/var/www
<Location />
Options All
AllowOverride All
Require all granted
</Location>
<LocationMatch ^/[^.].+/$>
RewriteEngine on
/*
I NEED A REWRITE HERE WHEN I REACH THE DIRECTORY LOCATION
AS LOCATION IS ALREADY MATCHED, I'M NOT SURE HOW TO EXTRACT IT
*/
</LocationMatch>
<LocationMatch ^/[.].+/$>
Options none
AllowOverride none
Require all denied
</LocationMatch>
</VirtualHost>
Since I have already figured out how to get into directories I need to be at, how would I use my logic to extract and redirect me into correct place?

You need a two-step-approach for this, since you have to handle two separate requests in the scenario you want to set up:
This is the rule to redirect clients to the new host name:
RewriteEngine on
RewriteRule ^/?(\w+)(/?.*)$ http://$1.dev$2 [R=301]
This is the rule inside that host to remap the request onto the internal folder in the file system again:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(\w+)\.dev$
RewriteCond /%1 -d
RewriteRule ^/?(.*)$ /%1/$1 [END]
Obviously the rewriting needs to be loaded and enabled for this.
In case you receive back a http status 500 ("internal server error") for the first request (the one to be redirected) chances are that you are using a very old version of the apache http server. In that case try replacing the [END] flag with the [L] flag...
Above rules will work likewise in the http servers host configuration or in dynamic configuration files. However you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only supported as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

Related

Apache2 not redirecting to https

I have an ec2 instance with my website files properly installed using apache2 as the web server. The ec2 is configured to receive http traffic on port 80 only from the elb (pretty sure about this but not 100%). The elb has an https listener (port 443) and an http listener (port 80). The elb sends traffic to the ec2 instance after decrypting the data according to the aws docs. My issue is that I cannot figure out how to redirect all traffic to the load balancer that is http to https.
I tried using this rewrite rule in both the virtual host for the site and the apache2.conf, but it isn't having any kind of effect (no errors either).
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}
The entire virtual host looks like this (located in /etc/apache2/sites-available/SewaneeEats.conf):
ServerName classicloadbalancer-1929710381.us-east-1.elb.amazonaws.com
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html/SewaneeEats/public
<Directory /var/www/html/SewaneeEats>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}
AllowOverride All
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
I can confirm also that module rewrite is enabled.
So when I type in the url sewaneeeats.com (these links are live if you need to check them out), it will still be sewaneeeats.com (with no ssl whatsoever) rather than redirecting. I know the ssl is working on https://www.sewaneeeats.com. On https://sewaneeeats.com I get a broken ssl red symbol in the url bar on chrome. I think the reason it is broken on the https://sewaneeeats.com url is because the cert is registered for www subdomain, but I am not sure. The domain is configured using aws's route 53 console, so I can give info on that if it would be helpful.
Any help would be really appreciated because I have been trying to figure this out for about a 12 hours or so. Would have posted this on serverfault.com, but I couldn't because I can only have 2 links for a question when I am under 10 rep.
I usually use the following rule to redirect all traffic to https:
RewriteCond %{HTTPS} =off
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R,L]
Also, no need to place the rewrite rules between directives if you want to apply the rules globally for the vhost.

Django Invalid HTTP_HOST header on Apache - fix using Require?

A couple weeks ago, I had a wonderful time setting up an Apache and Django configuration to work while forcing SSL and operating behind an AWS load balancer.
Now that it is all working nicely, I'm still constantly receiving the common "Invalid HTTP_HOST header" error, and trying to figure out the right way to go about fixing it.
Searching has brought me to the following answer regarding the Apache configuration:
How to disable Django's invalid HTTP_HOST error?
Which recommends placing the following settings inside the <Directory></Directory> block in the VirtualHost file:
SetEnvIfNoCase Host .+ VALID_HOST
Order Deny,Allow
Deny from All
Allow from env=VALID_HOST}
This works, but according to Apache (https://httpd.apache.org/docs/2.4/howto/access.html) this method is deprecated.
I've read through the Apache docs but when I tried using the following code it just shut down access to the site and gave me a "Not Authorized" error.
<RequireAll>
Require host example.org
</RequireAll>
Not entirely sure what I'm missing. I know I can solve the problem using the first answer, just trying to figure out the "right" way using code that isn't deprecated. Site is using WSGIDaemonProcess to run the Django App and has the following set to force the SSL through AWS
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTP:X-Forwarded-For} !=""
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}
No need to use mod_setenvif as HTTP_HOST is already a variable and you can evaluate it directly.
<Directory /var/www/html/>
Require expr %{HTTP_HOST} == "example.com"
Options
</Directory>
So, after messing with this for a long time I figured out that the problem I was dealing with may have something to do with the hostname reverse DNS lookup failing, since the IP address was pointing to an AWS EC2 instance instead of my domain.
After finally giving up on getting it right I returned to the post on how to disable the log error, and tried using the env variable, which seems to be working.
Apparently the correct format for Require is:
<Directory /var/www/html/>
SetEnvIfNoCase Host example\.com VALID_HOST
Require env VALID_HOST
Options
</Directory>
These guys had it right, just need to update it for the current "Require" directive.
How to disable Django's invalid HTTP_HOST error?

Insert a directory at the start of a URL in Apache Config

Apologies if this question has already been asked before. I couldn't find an example that handled my exact situation.
I have an Apache Server and have access to the httpd.conf file.
I have a domain (say www.example.com) and I want to insert a directory (say test) after the domain.
So for example I want www.example.com to be mapped to www.example.com/test and www.example.com/folder to be mapped to www.example.com/test/folder and so on.
I have achieved this using the a RedirectMatch directive like this:-
<VirtualHost *:80>
ServerName www.example.com
RedirectMatch ^/$ test/
</VirtualHost>
However this changes the URL in the browser to include the test folder and I would like to keep this hidden from the end user.
I have tried using a rewrite rule but my lack of regex knowledge has let me down here! This is what I have tried (within the virtual host element):-
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/test/
RewriteRule ^(.*)$ /test/$1
I have tried various combinations with this but nothing seems to work!
Any help would be much appreciated.
Ok, I found the problem here. This was working ok but my browser cache (Firefox) was remembering the old values.
I turned of caching in the browser (by going to about:config and setting browser.cache.disk.enable = FALSE
Then everything started working correctly.
Hopefully this will help others who have the same issue!

Invalid OpenID Namespace u'http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0'

I'm using django-socialregistration on Apache. I started getting this error message.
Invalid OpenID Namespace u'http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0'
It starts with a rewrite rule in my Apache configuration file.
<VirtualHost *:80>
ServerName foobar.org
ServerAlias foobar.net
RewriteEngine On
RewriteRule ^(.*)$ https://foobar.org$1 [R=301,L]
</VirtualHost>
So any request that comes in to foobar.net or doesn't come over https gets redirected to https://foobar.org. When Apache does this redirect, by default, it escapes the url. See http://httpd.apache.org/docs/current/rewrite/flags.html#flag_ne
So one solution is to just do this:
RewriteRule ^(.*)$ https://foobar.org$1 [R=301,L,NE]
But why is the redirect happening in the first place? In my case, it's because django-socialregistration checks a setting to determine whether or not to use ssl in the OpenID workflow. I watched my runserver and saw something like
GET /openid/redirect/?openid_provider=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fid&next=%2Faccounts%2Fnext%2F%3Fnext%3Dundefined
I curl -v <that_url>, and saw that the Location header (that is, the redirect url) contained something like this:
...openid.return_to=http%3A%2F%2Ffoobar.org%2Fopeni...
Notice that it isn't using https. I dug through django-socialregistration and saw that I need this in settings.py:
SOCIALREGISTRATION_USE_HTTPS = True

What is the best way to serve media on a shared hosting from a Django app?

I'm using FastCGI to serve my Django app, so basically it works like this: http://docs.djangoproject.com/en/dev/howto/deployment/fastcgi/#running-django-on-a-shared-hosting-provider-with-apache
What is the best way I can serve static media (images, css, etc) from this? Thanks!
If using Apache to front the site we normally go with WSGI for connecting to django and then let Apache handle '/media/...anything...' as statically served content. It's a couple lines of config and Bob's your Uncle!
Update: I should add that most of our Django sites are on dedicated servers, but you also can do this easily at webfaction.com.
E.g.
<Location "/media">
SetHandler None
</Location>
Add any appropriate Alias directives to your web server configuration, from deepest to shallowest.
I use this in my apache conf:
Alias /static/ /path/to/static/files/
<Directory /path/to/static/files/>
Order deny,allow
Allow from all
</Directory>
If you don't have write access to your apache conf, you can do this in your .htaccess
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/path/to/media/files/
RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]
Or something similar. This ensures that any urls beginning with the path to your media files do not redirect to fast cgi. If you already have some conditions you can add multiple RewriteConds using [OR].