Skip to content

[DX] Improving Vagrant support #11395

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
javiereguiluz opened this issue Jul 16, 2014 · 18 comments
Closed

[DX] Improving Vagrant support #11395

javiereguiluz opened this issue Jul 16, 2014 · 18 comments
Labels
DX DX = Developer eXperience (anything that improves the experience of using Symfony)

Comments

@javiereguiluz
Copy link
Member

The problem

When using Vagrant and Symfony, you'll end up with some problems when trying to
access app_dev.php controller because of the following check:

// web/app.php
if (isset($_SERVER['HTTP_CLIENT_IP'])
    || isset($_SERVER['HTTP_X_FORWARDED_FOR'])
    || !(in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1')) || php_sapi_name() === 'cli-server')
) {
    header('HTTP/1.0 403 Forbidden');
    exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}

Your Vagrant host IP will always be different from 127.0.0.1 and therefore,
Symfony will prevent you to access app_dev.php controller.

The solution

The obvious solution is to manually add the host IP (e.g. 192.168.56.1) to the
previous condition, but this doesn't look like a professional way to fix this problem.

After talking with @frastel he proposed me the following alternative. We could introduce a new server variable (e.g. SYMFONY__TRUSTED_HOSTS) and then, modify the dev controller (the resulting code may be a bit ugly):

if (isset($_SERVER['HTTP_CLIENT_IP'])
    || isset($_SERVER['HTTP_X_FORWARDED_FOR'])
    || (
        //BC
        !in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1', '192.168.0.1'))
        &&
        // the new way
        (
            isset($_SERVER['SYMFONY__TRUSTED_HOSTS'])
            && !in_array(@$_SERVER['REMOTE_ADDR'], explode(',', $_SERVER['SYMFONY__TRUSTED_HOSTS']))
        )
    )
) {
    header('HTTP/1.0 403 Forbidden');
    exit('You are not allowed to access this file. Check ' . basename(__FILE__) . ' for more information.');
}

The last step would be to set up this variable with the web server. For instance, if you use nginx:

location ~ ^/(app|app_dev|config)\.php(/|$) {
   ...
   fastcgi_param SYMFONY__TRUSTED_HOSTS 192.168.0.1,192.168.56.1;
   ...
}
@fabpot
Copy link
Member

fabpot commented Jul 16, 2014

There are some other problems with a Vagrant setup like performance: http://www.whitewashing.de/2013/08/19/speedup_symfony2_on_vagrant_boxes.html

See also: http://www.sitepoint.com/guide-install-orocrm-vagrant-box/ for more frustrations.

@frastel
Copy link

frastel commented Jul 16, 2014

@fabpot the problem mentioned by @javiereguiluz is actually not really dependent to Vagrant. It's a common problem when you are running your system within a VM (and that is really really often the case).
Within a VM the host is different to the default localhost of the client and thus the dev front controller and especially the IP whitelist needs always some modification.
For trainings and customers I don't want to drop this security check and it would be nice to have a more generic possibility there to allow some "trusted host" (naming could be changed of course).
We would provision the trusted host so the web server is able to pass this value to the PHP process.

@jderusse
Copy link
Member

@fabpot It's really easy with ansible|puppet|chef to automaticly mount a tmpfs partition on the guest and synchronize your source code (on your host) with a rsync watch daemon (like lsyncd). Your VM became quicker than your host.

BTW it's not the purpose of this issue.

@sudent
Copy link

sudent commented Jul 19, 2014

Since this is titled 'improving vagrant support', I want to chime in and shared that I've come into issue with sessions in a vagrant setup detailed in my comment here #7885 (comment) which is not an issue with my vagrant setup before, but now it is after I update my virtualbox/vagrant which I thought those who develops with vagrant should be aware of.

@javiereguiluz
Copy link
Member Author

I know that there are a lot of Vagrant fans in the Symfony community. Anyone can please take a look at this issue and see if we can/should do anything to improve Vagrant support? Thanks!

@kimausloos
Copy link

@javiereguiluz I found this issue while looking for a solution for this kind of problem. This works for me: https://github.com/kimausloos/symfony-standard/commit/1feac8dfa5ffd02adf55c01e4613b51c7ebd5bd0

Any feedback or do I create a pull request?

@timglabisch
Copy link

👍 for this solution, but most time i use fig / vagrant + port forwarding. so i don't need such a workaround.

@jderusse
Copy link
Member

jderusse commented Jan 7, 2015

@javiereguiluz What's about providing an app_env.php which use the the SYMFONY_ENV environment variable (see https://gist.github.com/gerryvdm/f633eda0b8dd194143e2).
Vagrants users can easily add a SetEnv SYMFONY_ENV dev in the apache configuration (or fastcgi_param SYMFONY_ENV dev; in Nginx)

@kimausloos
Copy link

@jeremy-derusse as an extra file and not a replacement for app_dev.php you mean? Because replacing app_dev.php would mean developers wo are not using environment variables are unable to use the dev environment.

Anyway, I will have a look at the feedback @xelaris gave and create a pull request later tonight.

@javiereguiluz
Copy link
Member Author

@kimausloos I don't really know what to say because I personally don't use Vagrant.

@jeremy-derusse the Symfony console actually uses that trick to set the environment and the debug options (see https://github.com/symfony/symfony-standard/blob/2.7/app/console#L18-19). I don't know the reasons why the front controllers don't use that trick.

@xelaris
Copy link
Contributor

xelaris commented Jan 7, 2015

@jeremy-derusse @javiereguiluz I think the main reason for the separated front controllers is to enable simple switching between the environments in the browser. It also enables to keep the individual front controllers clean and simple while allowing different setups (e.g. AppCache/ApcClassLoader in prod, umask(0000) in dev). Finally all app_* files can be simply removed on prod deploy.
While an app_env.php could be added in addition, I don't see the benefits of such a front controller.

@jderusse
Copy link
Member

jderusse commented Jan 7, 2015

@javiereguiluz exactly, I use the same environment variable on purpose...
This is (probably) not done in SE front controllers for simplicity:

  • editing an virtualhost could be hard for beginners (that why we also have a .htaccess).
  • letting the developper to tests his application in prod environment without reloading his the server

@xelaris the main avantage of an app_env controller, his to get rid of IP checking.
I'm tired (as every symfony's developer who simply comment those security lines), each times I start or I join an existing project: to search my IP, to edit the app_dev.php or to edit the vhost and reload the web server.
BTW, merging app.php and app_dev.php produce a 25 lines of code script (included umask and ApcClassLoader)

@xelaris
Copy link
Contributor

xelaris commented Jan 7, 2015

@jeremy-derusse Choosing the app environment (e.g. via an environment parameter) and limiting access to this environment (e.g. via IP checking) are two separate things IMO. If you configure your server to run your app in dev environment, you might nevertheless like to limit access to this environment.
If not, what is most likely true in case of a vagrant environment with host-only network, one could also set a simple SYMFONY__ENABLE_NON_PROD_FRONT_CONTROLLER server environment parameter and add a check for the existents in the non-prod front controllers. This would in a way correspond to php_sapi_name() === 'cli-server' and would also keep the possibility to switch between environments via URL.

@timglabisch
Copy link

👎 for app_env

@jderusse
Copy link
Member

jderusse commented Jan 7, 2015

@xelaris indeed, I mixed environment and checking.
IMO, The SYMFONY__ENABLE_NON_PROD_FRONT_CONTROLLER could be good alternative to the check by IP.

if (isset($_SERVER['HTTP_CLIENT_IP'])
    || isset($_SERVER['HTTP_X_FORWARDED_FOR'])
    || !(
        in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1')) 
        || php_sapi_name() === 'cli-server'
        || false !== getenv('SYMFONY__ENABLE_NON_PROD_FRONT_CONTROLLER')
    )
) {
    header('HTTP/1.0 403 Forbidden');
    exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}

We have to find an alternative to the IP check

@fabpot
Copy link
Member

fabpot commented Feb 10, 2015

Closing this issue as it's outside of the scope of Symfony core anyway. The snippet discussed is in the SE anyway.

@fabpot fabpot closed this as completed Feb 10, 2015
@kimausloos
Copy link

@fabpot should I close pullrequest symfony/symfony-standard#768 too?

@fabpot
Copy link
Member

fabpot commented Feb 11, 2015

The one on SE should not be closed as it is something different.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DX DX = Developer eXperience (anything that improves the experience of using Symfony)
Projects
None yet
Development

No branches or pull requests

9 participants