I'm tring to access the bundles directory (which is located in : /usr/src/app/public/bundles) of my symfony project.
But, all files in public dir can't be accessed with my navigator. eg:
Request URL: http://localhost:8080/bundles/easyadmin/app.css
Request Method: GET
Status Code: 404 Not Found
The file exists...
This is my nginx config :
server {
server_name ~.*;
location / {
root /usr/src/app;
try_files $uri /index.php$is_args$args;
}
client_max_body_size 100m;
location ~ ^/index\.php(/|$) {
if ($request_method ~* "(GET|POST|PATCH|DELETE)") {
add_header "Access-Control-Allow-Origin" '*' always;
}
# Preflighted requests
if ($request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" '*' always;
add_header "Access-Control-Allow-Methods" "GET, POST, PATCH, DELETE, OPTIONS, HEAD";
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
fastcgi_pass php:9000;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_read_timeout 600;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /usr/src/app/public/index.php;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
}
I don't know what is missconfigured...
Without seeing any error log I can just guess the issue but lets check directories you are using.
First of all try to avoid root in locations.
Putting root inside of a location block will work and it’s perfectly valid. What’s wrong is when you start adding location blocks. If you add a root to every location block then a location block that isn’t matched will have no root. Therefore, it is important that a root directive occur prior to your location blocks, which can then override this directive if they need to.
The configuration should look like this:
root /usr/src/app/public/;
location / {
try_files $uri /index.php$is_args$args;
}
Your location is missing the public directory. So why do see the 404:
For this request http://localhost:8080/bundles/easyadmin/app.css with your configuration NGINX will look into /usr/src/app/ for /bundles/easyadmin/app.css. And it will not be able to find it. But /usr/src/app/public/bundles/easyadmin/app.css` will be a valid path and should result in 200 OK.
Related
I'm using Nginx as a web server.
This is my nginx.conf file:
server {
listen 80;
root /usr/share/nginx/html;
index index.html index.htm;
location ^~ /start/ {
add_header 'Cross-Origin-Embedder-Policy' 'require-corp';
add_header 'Cross-Origin-Opener-Policy' 'same-origin';
try_files $uri $uri/ /index.html;
}
location / {
try_files $uri $uri/ /index.html;
}
}
When I open this link on the browser, I don't see the header in the network tab in the response headers section:
https://example.com/start/629852d359d2a400034698a2
Actually add_header directive works properly. Most probably headers does not get added since there are no /usr/share/nginx/html/start/629852d359d2a400034698a2 file or directory on your server, so request gets rewritten to /index.html according to the last try_files directive parameter, which in turn being processed by your location / { ... } (since that new URI does not start with a /start/ prefix), and that location does not set any additional headers.
Generally, if those /start/-prefixed URIs could be either internal application routes or external assets links, this would be possible to solve using the map block to evaluate required headers values:
map $uri $add_policies {
~^/start/ 1;
# default value will be an empty string, unless specified explicitly
}
map $add_policies $embedder_policy {
1 require-corp;
}
map $add_policies $opener_policy {
1 same-origin;
}
server {
...
location / {
add_header Cross-Origin-Embedder-Policy $embedder_policy;
add_header Cross-Origin-Opener-Policy $origin_policy;
try_files $uri $uri/ /index.html;
}
}
This solution is based on the add_header behavior, which is not to add the specified header to the response at all if the provided value is an empty string.
However, if you know for sure the URIs where those headers should be added are an app routes rather than links to physically existing files, you have one more option:
server {
...
location ^~ /start/ {
set $embedder_policy require-corp;
set $origin_policy same-origin;
rewrite ^ /index.html last;
}
location / {
add_header Cross-Origin-Embedder-Policy $embedder_policy;
add_header Cross-Origin-Opener-Policy $origin_policy;
try_files $uri $uri/ /index.html;
}
}
This solution should be somewhat more performant since it does not require (some kind of expensive) PCRE library call to perform the regex matching operation.
Update
Reviewing my answers, I just figured out that the last configuration can be made even more simple using rewrite ... break instead of rewrite ... last:
server {
...
location ^~ /start/ {
add_header Cross-Origin-Embedder-Policy require-corp;
add_header Cross-Origin-Opener-Policy same-origin;
rewrite ^ /index.html break;
}
location / {
try_files $uri $uri/ /index.html;
}
}
I am a little stuck with Nginx not behaving as I expect it to?
When making a curl request to curl -I http://example.com/schedule/ajax.php I get the expected output of HTTP/1.1 200 OK
However, when I add a query string it fails curl -I http://example.com/schedule/ajax.php?m=item with no matches found: http://example.com/schedule/ajax.php?m=item
Additionally:
this project has Drupal which is fully functioning and its Nginx root is at / (as
in Drupal's index.php file is in /app/web/)
then the schedule directory is not a Drupal and if files are in /app/web/schedule/
the ajax.php is a special case as all other requests are processed by
index.php so for example http://example.com/schedule/view is
processed be /schedule/index.php (yes not /app/web/index.php)
so the short version is /schedule is not Drupal but / is
So my question is why do requests to http://example.com/schedule/ajax.php?m=item fail?
My nginx config is
server {
listen ${NGINX_LISTEN:-8080} default_server;
include /etc/nginx/helpers/*.conf;
root /app/${WEBROOT:-};
index index.php;
## rewriting /index.php to / because after https://www.drupal.org/node/2599326
## autocomplete URLs are forced to go to index.php
rewrite ^/index.php / last;
location /schedule/ajax.php {
add_header X-debug-message-ajax "a: $args q:$query_string" always;
#return 403;
try_files $uri /schedule/ajax.php?$args;
}
location /schedule/ {
## Disallow access to any dot files, but send the request to wordpress
location ~* /\. {
try_files /dev/null #php;
}
## Direct Access to .php files is not alled and is sent to wordpress instead
location ~* ^.+\.php$ {
try_files /dev/null #php;
}
## Try to find a file with given URL, if not pass to wordpress
try_files $uri /schedule/$uri/ /schedule/index.php?$args;
}
## The 'default' location.
location / {
include /etc/nginx/conf.d/drupal/location_prepend*.conf;
## Do not allow access to .txt and .md unless inside sites/*/files/
location ~* ^(?!.+sites\/.+\/files\/).+\.(txt|md)$ {
deny all;
access_log off;
log_not_found off;
}
## Replicate the Apache <FilesMatch> directive of Drupal standard
## .htaccess. Disable access to any code files. Return a 404 to curtail
## information disclosure.
location ~* \.(engine|inc|install|make|module|profile|po|sh|.*sql|.*sql\.gz|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^\/(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock))$|^\/#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$ {
deny all;
access_log off;
log_not_found off;
}
## Expiring per default for four weeks and one second, Drupal will overwrite that if necessary
expires ${NGINX_DEFAULT_EXPIRES:-2628001s};
## Disallow access to any dot files, but send the request to Drupal
location ~* /\. {
try_files /dev/null #drupal;
}
### Directives for installing drupal.
location ~* ^(/install.php|/core/install.php) {
try_files /dev/null #php;
}
## Direct Access to .php files is not allowed and is sent to Drupal instead
location ~* ^.+\.php$ {
try_files /dev/null #drupal;
}
## Try to find a file with given URL, if not pass to Drupal
try_files $uri #drupal;
}
## Main Drupal Location
location #drupal {
add_header X-debug-message-drupal "1" always;
include /etc/nginx/conf.d/drupal/location_drupal_prepend*.conf;
include /etc/nginx/fastcgi.conf;
fastcgi_param SCRIPT_NAME /index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root/index.php;
fastcgi_pass ${NGINX_FASTCGI_PASS:-php}:9000;
include /etc/nginx/conf.d/drupal/location_drupal_append*.conf;
}
## PHP Location.
## Warning: This allows to execute any PHP files, use with care!
location #php {
add_header X-debug-message-php "$realpath_root : $fastcgi_script_name : $args" always;
include /etc/nginx/conf.d/drupal/location_php_prepend*.conf;
include /etc/nginx/fastcgi.conf;
fastcgi_pass ${NGINX_FASTCGI_PASS:-php}:9000;
include /etc/nginx/conf.d/drupal/location_php_append*.conf;
}
## Trying to access private files directly returns a 404.
location /sites/default/files/private/ {
internal;
}
}
As pointed out in the comments the issue was not with Nginx it was actually an error in my curl request.
I'm trying to make a cdn for fonts. But it's giving cross-origin error for fonts. Though I am allowing cross-origin.
Here is my nginx config file
server {
listen 80;
root /var/www/cdn.example.com/public_html;
index index.html index.htm index.php;
server_name cdn.example.com www.cdn.example.com;
location / {
add_header Access-Control-Allow-Origin *;
try_files $uri $uri/ /404.html;
}
location ~* .(gif|jpg|jpeg|png|ico|wmv|3gp|avi|mpg|mpeg|mp4|flv|mp3|mid|js|css|wml|swf|ttf|ttc|otf|eot|woff|woff2)$ {
add_header Access-Control-Allow-Origin "*";
expires max;
}
}
Fonts files are in /var/www/cdn.example.com/public_html/fonts
The issue has been solved. It just needs some time to take effect the cross-origin.
I'm working on load balancing on a cluster. It works great, but I realized that I want to be able to request a certain node by specify it in the url, e.g domain.com/nodeX/request_uri/ where nodeX is the actual node I want to send the request to. The reason why I want to do this, is so I can easily know which node I'm on, if I'm doing work on one of them, and need to sync the actual file(s) on this node to the other nodes, when files changes.
Right now it's only NextCloud running on the server, in the folder /nextcloud/, with a data directory that is shared with glusterfs, so it's not these files I need to replicate, but the "core files of next-cloud" or actually any files in the www-directory that is changed.
This is (in general) the setup on the master node, `/etc/nginx/sites-available/default:
upstream cluster {
ip_hash;
server node1;
server node2;
[...]
server nodeX;
}
server {
listen 443 ssl http2 default_server;
[...]more unrelated configurations[...]
# This works as expected
location / {
proxy_pass http://cluster/;
}
# But this is where I need help:
# If location starts with /nodeX, where X is a number
location ^~ /node([0-9]+) {
# If location is master node (node0)
location /node0 {
# Include nextcloud configuration
include snippets/nextcloud.conf;
}
# Otherwise pass it on to the requested node
proxy_pass http://«node[0-9]+»/;
}
}
Every slave node (nodeX, X > 0) loads the same configuration, and this is a sum-up of it:
server {
listen 80 default_server; #Yep, no need for SSL in local network
[...]
include snippets/nextcloud.conf;
}
I have removed unrelated data (such as add_header, root etc) to keep things clear. Every node (including master) shares the same snippet-folder, which is distributed through glusterfs. This file snippet/nextcloud.conf is the one I need help with. Next cloud will automatically re-direct to domain.com/nextcloud/ if I write domain.com/node0/nextcloud/, so I need a solution to trick the server to belive it's running on /nextcloud/ whenever it's actually running in a sub-directory of nodeX.
This is what I have so far, which do redirect me:
location ~ /(node[0-9]/?)nextcloud {
# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;
# This is where I should be able to trick the
# server to think its running on /nextcloud/ even
# when its request is /nodeX/nextcloud
location ~ /(node[0-9]/?)nextcloud {
rewrite ^ /nextcloud/index.php$uri;
}
location ~ ^/(node[0-9]/?)nextcloud/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/(node[0-9]/?)nextcloud/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^/(node[0-9]/?)nextcloud/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
#Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^/(node[0-9]/?)nextcloud/(?:updater|ocs-provider)(?:$|/) {
try_files $uri/ =404;
index index.php;
}
# Adding the cache control header for js and css files
# Make sure it is BELOW the PHP block
location ~* \.(?:css|js|woff|svg|gif)$ {
try_files $uri /nextcloud/index.php$uri$is_args$args;
add_header Cache-Control "public, max-age=7200";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
# Optional: Don't log access to assets
access_log off;
}
location ~* \.(?:png|html|ttf|ico|jpg|jpeg)$ {
try_files $uri /nextcloud/index.php$uri$is_args$args;
# Optional: Don't log access to other assets
access_log off;
}
}
So my question in general is; Is it possible to remove the "/nodeX/" of the URI, or any other thing? :)
Note! It may be that the /nodeX/ part is missing, when the load balancer is supposed to deal with the actual balancing.
I have an webapp that uses FastCGI. This app is deployed as different "sites". I have a general nginx configuration for the app, and then, I include upstrams and locations files for each site. Each site needs some .js and .css files. Right now, I have set these via the root of the general configuration file. My requirment now, is that I want to be able to use different .css and .js for different sites. So the lookup of the files, should first start at the site/location level and if not found, then search in the general root.
The general nginx conf file is:
# Change this directory depending on the server
include /etc/nginx/conf.d/app/upstreams/*.conf;
server
{
server_name 24.39.17.76;
root /var/www/app/files/;
listen 443;
ssl on;
ssl_certificate /etc/nginx/conf.d/app/ssl/new/app.pem;
ssl_certificate_key /etc/nginx/conf.d/app/ssl/new/app.com.key;
location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|svg|woff|ttf)$ {
access_log off; # this is because otherwise, with jail2ban the user may be banned
# add_header Access-Control-Allow-Origin "*";
expires max;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
add_header Pragma public;
}
# Change this directory depending on the server
include /etc/nginx/conf.d/app/locations/*.conf;
}
Note the lines where I include all locations conf and upstreams files.
Then a particular site, has a upstream file like:
upstream siteX
{
server localhost:9021;
server localhost:9022;
server localhost:9023;
}
And a location file like this one:
location ~ ^/siteX/reps {
access_log /var/log/nginx/app/siteX_reps_access.log;
error_log /var/log/nginx/app/siteX_reps_error info;
if ($arg_service = "true") {
rewrite ^/(.*)$ /service/$1 last;
}
rewrite ^/siteX/(.*)$ /$1 break;
try_files $uri #fastcgiSiteX;
}
location #fastcgiSiteX {
include fastcgi_params;
fastcgi_param REQUEST_URI $uri?$args;
fastcgi_pass fastcgiSiteX;
fastcgi_next_upstream error invalid_header http_500;
}
The html of my webpage that includes the css and js is like this:
<script type="text/javascript" src="/JQDevelopmentLibrary/jQuery.js"></script>
<link rel="stylesheet" type="text/css" href="/TBSDevelopmentLibrary/css/bootstrap.css"/>
But I can easily add a prefix if that helps with any possible solution, like:
<script type="text/javascript" src="/siteX/webfiles/JQDevelopmentLibrary/jQuery.js"></script>
<link rel="stylesheet" type="text/css" href="/siteX/webfiles/TBSDevelopmentLibrary/css/bootstrap.css"/>
SO...the general files are under /var/www/app/files/. However, I would like that for siteX, the files are first searched in another path, say /var/www/siteX/files and only if not found, searched in the general one.
One solution I tried but didn't work is to define this try_files expression:
try_files /siteX/webfiles$uri $uri #fastcgiSiteX;
And then, I put all the folders and files in $document_root/siteX/webfiles, that is, /var/www/app/files/siteX/webfiles/. I thought this solution should work, but it didn't.
Any ideas?
Thanks in advance,
its kind of a hack but it can be done.
location ~ ^/siteX/reps {
access_log /var/log/nginx/app/siteX_reps_access.log;
error_log /var/log/nginx/app/siteX_reps_error info;
if ($arg_service = "true") {
rewrite ^/(.*)$ /service/$1 last;
}
rewrite ^/siteX/(.*)$ /$1 break;
try_files $uri #hack;
}
location #hack {
root /var/www/siteX/files;
try_files $uri $uri/ #fastcgiSiteX;
}
location #fastcgiSiteX {
include fastcgi_params;
fastcgi_param REQUEST_URI $uri?$args;
fastcgi_pass fastcgiSiteX;
fastcgi_next_upstream error invalid_header http_500;
}