Closed colorando-de closed 5 months ago
Hi there!
That's an interesting point, thanks -
It seems like the main change is this part, correct?
location ~ \.php$ {
return 403;
}
Depending on what we're aiming for, there's various (kind of gross) changes to the Nginx configuration we can go for.
I think as a default, blocking all but the index.php file makes sense. If people want access to other PHP files, they may need to handle that as a special case (Not a hill I'll die on, but I think it makes sense to document something more secure).
Assuming I've understood your point correctly, I'm agreeing that the addition of this might make sense:
location ~ \.php$ {
return 403;
}
An alternative configuration that's uglier/harder to document would be to serve any *.php file as normal, which looks a bit like this (not yet tested):
# Example file: /etc/nginx/octane.conf
set $suffix "";
if ($uri = /index.php) {
set $suffix ?$query_string;
}
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Scheme $scheme;
proxy_set_header SERVER_PORT $server_port;
proxy_set_header REMOTE_ADDR $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://127.0.0.1:8000$suffix;
##########################################################
# Example File /etc/nginx/sites-enabled/laravel.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name domain.com;
server_tokens off;
root /home/forge/domain.com/public;
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ @octane;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/domain.com-error.log error;
error_page 404 /index.php;
# Capture direct requests to .php files
location ~ \.php$ {
include octane.conf;
}
location @octane {
include octane.conf;
}
}
Wondering if frankenphp-worker.php
needs to be accessible... @dunglas do you might know that?
@driesvints Our Laravel application with up to 400 users simulateously works great with octane, having access blocked to the frankenphp-worker.php. But this is only my experience. I don't know the reason why frankenphp-workper.php
lives in the public directory.
@driesvints Technically, it may be possible to store the worker outside of the public directory using some trickery, but internally FrankenPHP works like that: if the requested URL (after rewriting, etc) matches a running worker, FrankenPHP uses this worker to handle the request ; if no worker match, then it executes the PHP script as usual.
The feature has been designed like this to be able to support easily FrankenPHP (in worker mode) and more traditional setups like FPM in the same app (as does for instance Symfony by always calling index.php
).
I see two ways to not expose frankenphp-worker.php
publicly:
index.php
(as Symfony does): this would be the cleaner way, but I'm not sure if it is acceptable for you because we'll have to at least detect if Octane is used in index.php
(which is part of the standard Laravel install, not of Octane) to include
the worker script (that can stay in the vendors).wdyt?
@dunglas I think frankenphp-worker.php in the public dir is fine, no worries there. Just want to make sure that if we adapt the example Nginx file in the docs everything still works as expected.
@driesvints sure, the docs update is ok and shouldn't hurt.
@colorando-de could you send in the docs update proposed by @fideloper? Thanks all for helping out here 👍
Since I was tagged here; IMO the problem is one that simply wouldn't exist if you just didn't use Nginx. If you're using FrankenPHP, you don't need Nginx at all, because you have the full power of Caddy at your disposal. You could just delete certbot and Nginx, then let Caddy do its thing, doing TLS automation, serving PHP, etc.
I think the Octane docs should recommend this approach instead of using Apache/Nginx as a proxy, when using FrankenPHP.
But anyway, there are some creative ways FrankenPHP could handle working without the frankenphp-worker.php
file existing in the actual filesystem; Caddy since v2.8.0 has an fs
directive which allows configuring a virtual filesystem to use, FrankenPHP could bundle a virtual FS module which intercepts lookups for frankenphp-worker.php
and loads it from memory instead of from file, and otherwise any other file lookup would be deferred to the OS filesystem as normal. But that's like... but why? That's a solution looking for a problem.
Octane Version
2.3.11
Laravel Version
10.48.10
PHP Version
8.3
What server type are you using?
FrankenPHP
Server Version
1.1.5
Database Driver & Version
MariaDB 10.6
Description
When I try to access any php file in the public folder, like the frankenphp-worker.php, it downloads the PHP files sourcecode instead of parsing it. So https://app.domain.com/frankenphp-worker.php doesn't parse the php file but downloads the plain file.
It's unusual to have critical source code in the public folder. But if so, this would be a big security issue.
For the while I changed it to the following configuration to stop delivering PHP files at all, except of index.php:
But in regular PHP setups, all PHP files are parsed by the PHP interpreter. Imho this should be the desired solution here, too.
Steps To Reproduce
I have a