Symfony on virtual host (document root problem) - php

I'm developing an application in Symfony and on localhost (XAMPP) I want to simulate the same conditions as on the webserver.
The web server is configured as follows:
/www => mydomain.com
/foo => foo.mydomain.com
/bar => bar.mydomain.com
...
I'm going to put my Symfony application into /www direcotry so there'll be:
/www
/www/apps
/www/apps/frontend
/www/apps/frontend/...
/www/apps/backend
/www/apps/backend/...
/www/cache
/www/config
... and so on...
/www/web
The thing is that the document root is still set to the /www directory but Symfony expects it in the /www/web.
Of course it will work if I call http://mydomain.com/web but I guess you understand this is quiet stupid solution.
So my question is: Is there any way how can I change/bypass the default document root setting using .htaccess or whatever?
EDIT: I solved it.

I don't know much about Symfony but /web is supposed to be the document root. All the other directories should be outside the document root for security reasons for one, and to avoid the /web part in the URL for another. But it looks like you already know that.
If you can edit the web server's configuration, try to reflect that and set DocumentRoot to the web directory.
If you can't do that: It's not possible to change the DocumentRoot in a .htaccess file but it is possible to rewrite all requests so they go to /web internally using mod_rewrite. It's kludgy, but probably the best solution if you can't influence DocumentRoot.
I'm not a mod_rewrite guru so I can't provide an example (I would have to test it first and I can't do that right now) but I'm sure somebody will. Maybe add the mod_rewrite tag to your question.
Update: Untested but should work. Put into a .htaccess file in /www:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} !^/web/
RewriteRule .* /web/%1 [QSA]
you would then need to change your configuration files to use http://www.domain.com/ instead of http://www.domain.com/web/ of course.
I can't say whether that interferes with any other .htaccess rules on the Symfony end - you'd have to try out.

I you got hand on apache config, the better is to move document root from /www to /www/web in you virtualHost config and allow php (if restricted by open_basedir configuration directive) to access the whole /www directory.

Change the way symfony expects your directory to be named :
// config/ProjectConfiguration.class.php
class ProjectConfiguration extends sfProjectConfiguration
{
public function setup()
{
$this->setWebDir($this->getRootDir().'/www/or/whatever/directory');
}
}

Related

.htaccess, use mod_rewrite to rewrite to a file OUTSIDE the web root

Here is a representation of my directory structure:
/var/www
/html/site
.htaccess
/secret
file.php
I'd like to use the .htaccess file to rewrite url requests made to http://example.com/files/1234 to the code file.php sitting outside of the webroot. This is for security reasons, the other developers I'm working with are insistent that this code sit outside of web accessible directories. So far, my .htaccess file looks like this:
RewriteEngine On
RewriteRule ^files/(.*)$ ../../secret/file.php?file_name=$1 [NC,L]
But I'm getting a 400 Bad Request when I try to do this. Is it even possible?
Short answer: no. The webserver can't directly access files outside of the document root. If you think about it, there would be quite a security problem if it could. What you can do is rewrite to a file within the document root that includes or reads from the file that is located outside of the root. (Moved from comments...)
You can't access files located outside document-root using .htaccess.
But you can do that by adding an alias to your apache config file, like that:
Alias /secret/ /home/site_name/web/yoursite.com/secret/

How can the document root be changed in web server behavior?

I'd like to know if there is a way of changing the relative document root for extra security. I'll try to explain myself through the following example:
/root
/app
/public
Say an www.example.com request to the web server would point to the root folder.
I was wondering if there was a configuration, for instance through an .htaccess file located in said root folder, that would make the server point to the public folder instead, therefore having any remote paths always be relative to said public folder.
In this instance, www.example.com/app would request an app folder inside of public, instead of an app folder inside of root, leaving the latter to be inaccessible from a remote url request.
In the same manner, www.example.com/public would request a public folder inside of our root public folder and so forth.
I've read various topics like this one that mention using a custom .htaccess configuration to achieve something similar, but it requires the manual configuration of the request url in said file, while my intention is for it to work without further configuration no matter where you host the application.
Another possible solution I've seen is doing a hard redirect through the .htaccess file, which does not solve anything actually.
Feel free to edit this post as I might have had a hard time trying to get my point across.
You can use this simple .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ /public/$1 [L]
</IfModule>
Any request on your server will point to the public folder.
Inside the public folder you can add an extra .htaccess file handling your site rules.
Also you can Host multiple sites on One webserver. You can combine making VirtualHosts and Alias using mod_alias mentioned before
In this example is suposed to have your own server (either dedicated or VPS)
By using Virtualhosts you can tell to the webserver when you recieve a request to www.example.com to serve content from a specific folder.
An example Virtualhost of it is:
<Virtualhost *:80>
ServerName ^domain_or_ip^
DocumentRoot ^path of the public folder^
DirectoryIndex index.php home.php index.html index.htm
ErrorLog ^path for a file containing php errors^
CustomLog ^path for logging whitch browser and ip visited your site^ combined
</Virtualhost>
I suggest that you point your server to the public folder anyhow, as it is much more secure, you could see that all frameworks behave the same way, they all have a "public" folder where the server points to.
In the public folder you have one point of entry to your scripts, like
index.php
and from this entry you will communicate with your application.
Of course you can still work the way you requested, and it will work great, but who knows maybe you will miss something and someone could access and view your "inner" files.
You're on Apache web server? If I understand correctly, you're looking for Virtual Directories. Usually, we have to put our web application inside the document root of Apache in order to make the application accessible from the network. However, there is a trick to make the web application still accessible even though we put it outside of Apache's document root. Please read up on that here: http://w3shaman.com/article/creating-virtual-directory-apache
Credits to W3Shaman.com, obviously.

Why should we keep index.php in the public folder instead of in the root?

I still don't quite understand why we must keep index.php in a public directory instead of in the root directory.
root/of/project
public/
index.php
.htacess
(html, image, css, etc)
Then, write the following in our virtual host file:
DocumentRoot /path/to/myapp/app/public
<Directory "/path/to/myapp/app/public">
# other setting here
</Directory>
The .htaccess file then redirects all non-existing URLs to index.php:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
I notice that most frameworks do so, such as Symfony and Zend, just as this tutorial. What is the actual benefits really by having the trouble of modifying the virtual host file?
Why shouldn't we do have this below instead without modifying the virtual host file? Is it a security risk or something?
root/of/project
index.php
.htacess
public/
(html, image, css, etc)
If keeping index.php and modifying the virtual host file is better, how can we modify the virtual host file in the live server then? Let's say I have this domain name, http://my-website.com/ and I access it on my browser, what I see first is not the web page but the directories below untill I click the public directory then I see the home page,
root/of/project
public/
index.php
.htacess
(html, image, css, etc)
I assume that this is the same for Zend or Symfony project as well without being able to modify the virtual host file in the live server. I am no good at these frameworks, I will see this below if I upload my Zend project to the live server,
So, how do you deploy your Zend or Symfony project to your live server to see your web page right away?
It is a very good idea to keep index.php outside of your project root directory because of one simple reason:
You don't want your user to access any files other that one in public folder (index.php, css, js etc). When you will put index.php in root folder you will be also able to access composer.json file for example which is a security risk - a potential hacker will know what packages are you using, in which versions so it's easier for him to perform attack.
When it comes to your hosting - you should have some public_html folder on your root directory which is meant to be public folder (web) of your Symfony app and you should also be able to keep files outside of public folder. If you don't - you really need to think about changing hosting partner
EDIT:
Answering your comment. Let's assume you have public_html folder on your hosting and you want to deploy Symfony app which should be accessible directly on http://your-domain.com. Then you should put whole Symfony project anywhere (but outside of public_html folder) and make a public_html folder a symbolic link to web folder of your Symfony project. This action is equivalent of editing virtual host and changing DocumentRoot which, I assume, you are not able to do.
You can also check my answer on another question to get more clarification

Route All Requests to Subfolder htaccess

I'm building an application for broad distribution and I want to change the way it's routed so that all the files can exist in the document root but still be secure as if they were above the doc root.
The ideal set up would be to house the application folder above the docroot like so:
/home
/---/username
/---/--->application
/---/---/--->all application files
/---/--->public_html
/---/---/--->all public files
But I know this isn't ideal for all potential users of my app, so I'd prefer to move this to a structure like so:
/home
/---/username
/---/--->public_html
/---/---/--->application
/---/---/---/--->all application files
/---/---/--->public
/---/---/---/-->all public files
Basically just putting everything within the doc root, forbidding access to the application directory, and routing all requests to the public folder, so that we can get the same security of having files above the doc root, but making it simpler for those that may not want this type of set up for their shared hosts.
I was thinking of using an include inside public_html/index.php that would include public_html/public/index.php but I can't seem to get that to work.
Any help would be appreciated.
As I understand it you want to have home/username/public_html as the real Apache Document Root, deny access from the /application directory and, ideally, route all web requests into the /public sub-directory instead (presumably for users not on dedicated servers who can't install outside of the docroot) ... If I've misunderstood the question let me know and I'll update/remove the answer ;)
You should be able to achieve this with an .htaccess file in /home/username/public_html like:
RewriteEngine on
# deny access to the application directory
RewriteRule ^application/? - [F]
# route all requests to the public directory that aren't already there
RewriteRule ^(?!public/)(.*)$ /public/$1 [L,QSA]
Any attempts to access the /application directory will result in a 403 error and all requests to http://www.myserver.tld/file.ext will be routed to http://www.myserver.tld/public/file.ext.
Caveat: To prevent recursive loops of the redirect, the rewrite rule will not redirect any URL path that already begins with /public ... this means that any file under /public will be accessible on both the http://www.mysite.tld/filename.ext and http://www.mysite.tld/public/filename.ext - which may upset search engines.
To be extra safe you could also add an .htaccess file to the /application directory like:
Deny from all
Use this.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ public_html/ [L]
RewriteRule (.*) public_html/$1 [L]
</IfModule>
Are you using any framework in your app?
Have you a sample of code we could access to understand your problem?
Basically, you just need an htaccess in your public_html folder that redirect the request to the public folder and disable the access to any other directory than public.

Set some folder on Apache server as a defaul folder

I'm developing some web based application based on PHP.
I have some folder structure that will be located inside the public html file.
I'd like to make it work so that when a user types for ex. http://mysite.com/ he/she gets into http://mysite.com/public but I don't want the user to know that he/she is inside public, the user should think that his directly inside public_html folder.
Any hints?
P.S. I'm doing it on hosted server, so I have access with only Cpanel, I'm not the admin of the server.
You either need to use mod_alias or mod_rewrite for this. How much of cPanel is available to you? How much does you host let you do?
I'll just have to have a look through my WHM server to work out how to do Aliases, but you can do rewrites with a .htaccess file. I would recommend Aliases over rewrites thought, as they are less complicated and less resource-hungry.
EDIT
Just been into my root login for our WHM/cPanel based server, and I can't find any way to use mod_alias - I think this is probably because it would require an Apache restart. You will have to use mod_rewrite.
Put this in a .htaccess file in public_html:
RewriteEngine on
RewriteRule (.*) public/$1 [L]
You can set up an addon domain and point it to /public_html/public directory.
Edit:
Parked domain should work too.

Categories