403 forbidden on wordpress index with nginx, the rest of the pages work fine - wordpress

I'm setting up my blog on a new EC2 instance because one of the sites on the server that's currently hosting it is being DDoSed.
I'm having some trouble with nginx, because I can either see all the pages fine but 403 on the index, or see the index but 404 on the pages (depending on the config I'm using)
Here's my nginx config:
server {
listen 80;
server_name www.test.com;
server_name test.com;
root /www/blog;
include conf.d/wordpress/simple.conf;
}
And simple.conf:
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location / {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when using query string
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
#NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
include fastcgi.conf;
fastcgi_intercept_errors on;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
if I change the try_files $uri $uri/ /index.php?$args; to index index.php, the front page will work fine and the rest will be 404. If I leave it like that, the front page is 403.
Here's the error log:
2013/08/07 19:19:41 [error] 25333#0: *1 directory index of "/www/blog/" is forbidden, client: 64.129.X.X, server: test.com, request: "GET / HTTP/1.1", host: "www.test.com"
That directory is 755 on the nginx user:
drwxr-xr-x 6 nginx nginx 4096 Aug 7 18:42 blog
Is there anything obvious I'm doing wrong ?
Thanks !

Add index index.php; In the server block, if it doesn't work then you need to remove the $uri/ because you don't want to do a autoindex on
EDIT: Just noticed that you already figured out your problem, so I'll add the reasoning behind it, the reason why you needed autoindex on; is because without it nginx will follow the try_files rules,
Check if there's a file called /, and of course it fails.
Check if there's a directory called / (by adding root it would = /www/blog/), this check will succeed, so it tries to list the content of the folder.
Since you didn't specify autoindex on; so by default nginx should forbid directory listing, thus it would return a 403 forbidden error.
The rest of the site works fine because it fails the $uri/ test or doesn't reach it, because you probably don't have a folder called image.jpg or stylesheet.css etc.

Looks like I needed the inded index.php in the server {} definition and not in the location {}

It seems that you are not allowing arguments to be sent to the CMS so this will not show this uris that would bring information from the database and redirect you to the 403 page.

Related

NGINX Cache Busting CSS JS URL Rewrite

I'm new to NGINX and trying to set up a portfolio. I've gotten my site working with the exception of a few errors that I noticed through Google Chrome DevTools.
I notice that javascript files aren't loading and have the incorrect path. For example, it tries to load http://site/assets/js/site.1617886701.js but the actual file is http://site/assets/js/site.js
Likewise with a css file I have: It tries to load http://site/assets/css/templates/home..css (for some reason it adds an extra .?) when it should be loading this file: http://site/assets/css/templates/home.css
This is my NGINX config file:
server {
listen 80;
listen [::]:80;
root /var/www/html/;
index index.php index.html index.htm;
server_name site wwww.site.com;
client_max_body_size 100M;
location / {
try_files $uri $uri/ /index.php?$uri&$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
location /assets {
rewrite uikit.min.(\d+).js uikit.min.js permanent;
rewrite uikit-icons.min.(\d+).js uikit-icons.min.js permanent;
rewrite uikit.app.min.(\d+).css uikit.app.min.css permanent;
try_files $uri =404;
expires max;
access_log off;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
}
From my googling online it says something about cache busting. Some people have suggested matching the file names in the NGINX config file which I'm not sure how to do or to change the paths to match the hexadecimal versions which I also don't know where to begin.
I would really appreciate any help from the pros! Thanks so much
For example, it tries to load http://site/assets/js/site.1617886701.js but the actual file is http://site/assets/js/site.js
It is not NGINX, it's your web application, which constructs such cache-busting URLs, which expect extra configuration on the side of NGINX.
The way to deal with it, is a rewrite in NGINX:
rewrite ^(.+)\.(\d+)\.(css|js)$ $1.$3 last;
This will rewrite, e.g. any /some/<foo>.<digits>.js to /some/<foo>.js.
It tries to load http://site/assets/css/templates/home..css
Obviously, a bug in your web application's code. Shouldn't be attempted to be fixed in NGINX.

NGINX + Passenger w/ Rails + WordPress permalinks

The environment is as follows:
I have https://website.com and a blog at https://website.com/blog
The root path points to a Passenger-hosted Rails app, and the blog subdirectory points to a WordPress app via php-fpm
Everything works fine with my Nginx config, but when I try to change the permalink structure to anything other than "Plain", I get a 404 page from the Rails app as if the location blocks aren't utilized. I tried looking at the error log in debug mode, and I do see it attempting to try_files, but ultimately it fails with the Rails 404 page.
It may be worth noting that the entire site is behind Cloudflare. Not sure if it could be something with that, though I kind of doubt it.
Here is the almost-working Nginx config I'm using:
server {
listen 80 default_server;
server_name IP_ADDRESS;
passenger_enabled on;
passenger_app_env production;
passenger_ruby /home/ubuntu/.rbenv/shims/ruby;
root /web/rails/public;
client_max_body_size 20M;
location ^~ /blog {
passenger_enabled off;
alias /web/blog;
index index.php index.htm index.html;
# Tried the commented line below, but then nothing works.
# try_files $uri $uri/ /blog/index.php?$args;
# The line below works, but peramlinks don't.
try_files $uri $uri/ /blog/index.php?q=$uri&$args;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
# Tried the commented line below, but then nothing works
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# The line below works, but peramlinks don't.
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
}
I wanted to comment in short but I don't have enough reputation for that.
I used the following block and worked for me. I added an add_header directive just to debug that if my request is reaching the correct block.
location ^~ /blog {
try_files $uri $uri/ /index.php?$args;
add_header reached blog;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php;
}
}
If your server is behind CloudFlare, you can try with /etc/hosts entry on your local machine if you're using Ubuntu/Mac. Which will stop the DNS lookup and site will directly be accessed from the IP address.
Check if any redirects are happening due to any other Nginx configuration.
Also, you have mentioned in the question that site is https:// while your server block has only listen 80 meaning non HTTPS.
Check for the response headers with
curl -XGET -IL site-name.tld
which may help you more debugging the situation.
Difference between alias and root directives https://stackoverflow.com/a/10647080/12257950

Dokku redirects to another domain when requested site is down

I have Dokku installed on a server, with multiple sites/domains deployed to it. When one of my sites goes down, all HTTP requests to it get redirected (for some reason) to another site. This is confusing. I'm expecting Dokku to show some error page in this case. Is it the default behavior or I did something wrong?
PS. This is the problem: https://github.com/dokku/dokku/issues/2602
How about adding a custom error page based on the error code by editing vhost file:
server{
server_name www.foo.com;
root /srv/www/foo/public_html;
expires 1M;
access_log /srv/www/foo/logs/access.log;
error_log /srv/www/foo/logs/error.log;
error_page 404 /404.html;
location / {
index index.html;
rewrite ^/(.*)/$ /$1 permanent;
try_files "${uri}.html" $uri $uri/ =404;
}
location = /404.html {
internal;
}
}
Your server error might be caught from codes 404 or 500

nginx: fallback to try_files when proxy_pass fails requires unusual config

I am using Nginx to server a single page app. Basically we just need to serve the index.html page whenever no matching file is found. The location looks like this and has been working just fine:
location / {
try_files $uri $uri/ /index.html
}
Now I would like to query an upstream server, and only if that fails, use the try_files directive as above
If the try_files is just moved to a fallback location like
location #fallback {
try_files $uri $uri/ /index.html;
}
location / {
proxy_pass http://127.0.0.1:8080;
proxy_intercept_errors on;
error_page 400 403 502 503 504 #fallback;
}
then - when the upstream server is unavailable - the client sees the Nginx 502 error page instead of the files served from the file system.
I finally found a solution that works by using a double slash in front of the /index.html fallback. This is the whole config file which can be used with the official nginx docker image for testing
events {
}
http {
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
server {
listen 80;
root /usr/share/nginx/html/;
location / {
proxy_pass http://127.0.0.1:9990;
proxy_intercept_errors on;
error_page 400 403 502 503 504 = #fallback;
}
location #fallback {
try_files $uri?$args /index.html //index.html;
}
}
}
which can be run with a command like
docker run -v /path/to/www/folder:/usr/share/nginx/html:ro -v /path/to/config/nginx.conf:/etc/nginx/nginx.conf -d -p 8080:80 nginx
In case no double slash is present before the last index.html fallback like
location #fallback {
try_files $uri?$args /index.html;
}
Then nginx constructs a path on the filesystem like <root>index.html, which has a missing delimiter instead of the correct <root>/index.html, whenever a url which is not the root url is requested.
Final question: why does this setup require a double slash within the try_files directive? Why can't one just use the try_files section from a regular config and move it to a fallback location used when intercepting errors?
I was presented with a similar situation, and I solved this going the other way around, using the suggestion from this page of common pitfalls. That is, first serve the static files, and then fallback to the proxy:
location / {
try_files $uri $uri/ #proxy;
}
location #proxy {
proxy_pass http://127.0.0.1:9990;
}
In this case, this would first look for the presence of the files as static files in the root, then proxy the request to http://127.0.0.1:9000. This is functionnally equivalent unless you want the files from the proxy to shadow the static files.

Caching Symfony 2 on Nginx

I moved from the setup of Apache 2 + Varnish to Nginx alone, and I'm kinda stuck with how I should setup/use ESI as well as fastcgi_cache in this setup.
First of all, the idea of ESI was that we setup a reverse proxy layer in front of the server to cache the cache-able parts of a page, then using esi to retrieve the dynamic parts. In my previous setup Varnish was acting as the reverse proxy and Apache only handles the esi requests when necessary.
My question is that now with Nginx acting as the sole server here, how do I make it to work? Do I need to setup another Nginx instance running as a reverse proxy server or something? I couldn't find any document on this.
The second question is regarding fastcgi_cache. I have set it up as described below but the cache does't seem to work for me, no cache file populated and I always get "MISS". I wonder if it's because I need to set max-age/shared-max-age in each controller for each to work?
fastcgi_cache_path /run levels=1:2 keys_zone=www_mysite_com:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
server {
#listen 80; ## listen for ipv4; this line is default and implied
#listen [::]:80 default ipv6only=on; ## listen for ipv6
root /var/www/mysite.com/w/w/w/www/web;
index index.php index.html index.htm;
# Make site accessible from http://www.mysite.com
server_name www.mysite.com;
# Specify a character set
charset utf-8;
# strip app.php/ prefix if it is present
rewrite ^/app\.php/?(.*)$ /$1 permanent;
# h5bp nginx configs
# include conf/h5bp.conf;
location / {
index app.php;
try_files $uri #rewriteapp;
}
location #rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
# Deny access to .htaccess
location ~ /\.ht {
deny all;
}
# Don't log robots.txt or favicon.ico files
location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt { access_log off; log_not_found off; }
# 404 errors handled by our application, for instance Symfony
error_page 404 /app.php;
# pass the PHP scripts to FastCGI server from upstream phpfcgi
location ~ ^/(app|app_dev|backend/app|backend/app_dev|config)\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
# With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME web/$fastcgi_script_name;
fastcgi_param HTTPS off;
fastcgi_cache www_mysite_com;
fastcgi_cache_valid 200 60m;
}
# Only for nginx-naxsi : process denied requests
#location /RequestDenied {
# For example, return an error code
#return 418;
#}
# redirect server error pages to the static page /50x.html
#
#error_page 500 502 503 504 /50x.html;
}
By default, responses from the Symfony 2 application have a cache control header that disables caching:
Cache-Control: no-cache
If you would like nginx to cache pages you will have to change those headers.
You can find general information about caching in the documentation
The simplest solution is to use the SymfonyFrameworkExtraBundle (you already have it if you use the SF2 standard edition) and use annotations on your controllers and/or actions to specify the cache headers. You can find more info about this approach it the docs for the #Cache annotation.

Resources