I'm trying to set up a web application using Nginx, but when trying to access it I am getting a 403 error. I've followed various different approaches to solving this including making sure that my permissions are set but to no avail.
here iss the config for the web application:
server {
listen 80;
server_name localhost
index index.php index.html index.htm;
root /usr/share/nginx/html/my-app/webapp;
port_in_redirect off;
# Use cached or actual file if they exists, otherwise pass request to WordPress
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
# Deny access to hidden files
location ~* /\.ht {
deny all;
access_log off;
log_not_found off;
}
# Pass PHP scripts on to PHP-FPM
location ~* \.php$ {
try_files $uri /index.php;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
I ran chmod -R 777 my-app to give it all permissions.
yet I still get the 403 error.
You are missing a ; on your server_name directive, which would normally be a syntax error, but in your case it translates to:
server_name localhost index index.php index.html index.htm;
Which may be a weird list of server names, but more importantly, it means you do not have an index directive. This means that you will get an HTTP 403 response code whenever you attempt to list a directory such as /.
Related
I have two projects both using identical nginx configurationg, only difference is host name and path to web directory:
server {
listen 80;
server_name {project_host};
root /var/www/{project_path}/web;
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_log /var/log/nginx/{project_name}_error.log;
access_log /var/log/nginx/{project_name}_access.log;
error_page 404 /index.php;
sendfile off;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
}
location ~ /\.ht {
deny all;
}
}
both in the web dir has folder docs which has all swagger-ui files with index.html.
All is working fine for project one, I can get access to swagger ui using url prject1/docs/index.html, but in case of project 2 when I going to project2/docs/index.html I'm getting my not found page which should be shown by php when a route is not found. Why in case of app 1 nginx understand that /docs/index.html is not route but in case of app 2 it's considering it as a route instead of path to the file if configurations the same
My web dir structure is (identical for both projects) :
web/
index.php
docs/
index.html
other_swagger_ui_files
Maybe it'll also be useful, both projects are kind of microservices, and locally I have a docker-compose configuration to start and up them, so they both under the same network and using the same Nginx-proxy container and sharing same PHP container, but each of them has own Nginx container (but as I already told they identical and have identical configuration)
I have installed the Homestead VM and setup the Moodle installation folder on my Mac (OSX Yosemite). I also created the 'moodledata' folder and gave it the permissions 0777 as well as the folder 'moodledata/sessions' via my system command line (I tried doing this via SSH inside the VM but it didn't appear to change the permissions). However checking the permissions after doing it via my system showed the folder was writable from inside the VM.
I then moved on to the installation which ran through and created the DB tables and did the check which showed 2 check warnings:
Intl and xmlrpc to check
I don't believe these are essential for initial installation so carried on. It is when I get to the admin user creation where I am getting a problem. The page (/user/editadvanced.php?id=2) stops loading any images and when I post the form I get an error: 'Incorrect sesskey submitted, form not accepted!'
I thought this could be down to the session not being writable in the moodledata folder but as I have checked that now I am out of ideas!
I have attached a couple of screenshots.
Many thanks, Mike.
Ok after a good few days of head scratching I fixed my own issue by editing the NGINX config file. Below is what it was by default:
server {
listen 80;
server_name example.com;
root /home/forge/example.com;
# FORGE SSL (DO NOT REMOVE!)
# ssl_certificate;
# ssl_certificate_key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
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/example.com-error.log error;
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
And this is what I changed it to and it now works:
server {
listen 80;
server_name example.com; #REPLACE SERVER NAME
root /var/www/example.com/www/; #REPLACE MOODLE INSTALL PATH
error_log /var/www/example.com/log/example.com_errors.log; #REPLACE MOODLE ERROR LOG PATH
access_log /var/www/example.com/log/example.com_access.log; #REPLACE MOODLE ACCESS LOG PATH
rewrite ^/(.*\.php)(/)(.*)$ /$1?file=/$3 last;
location / {
index index.php index.html index.htm;
try_files $uri $uri/ /index.php;
}
fastcgi_intercept_errors on;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
I haven't had time to see which part/parts of the above config fixed the issue, maybe someone who knows can see straight away? I suspect it could be the rewrite rule? Either way I hope this helps someone else in the future and I am really happy to get this working!
I can confirm is just the rewrite part for that specific config file, although in the Moodle Nginx page it's not documented that way.
My guess is that the location ~ [^/]\.php(/|$) { part is doing the same thing as the rewrite rule rewrite ^/(.*\.php)(/)(.*)$ /$1?file=/$3 last; and the location ~ \.php$ { directive. Will need to make some test changing the location directive to see if that works as well.
I have 12 sites that I plan to run on a single server that has NGinx and php5-fpm on it. I set them all up using one server block per conf file, all included by the main nginx.conf file. It's a mix of Wordpress, PhpMyAdmin, and PHP sites. The wordpress and PhpMyAdmin sites are working fine, but the PHP sites are not. Meaning, when I pull up example.com, Chrome says connection refused, and there's no trace of an incoming connection on NGinx logs. test.example.com pulls up the default site(because I didn't configure test.example.com then) at the same time.
I copied the nginx configs from the working sites to set up the sites that are not working, but no luck. The only difference in nginx config between the working and non-working sites are the server_name directive.
After checking and rechecking for over 2 hours, I found out that the sites that have the server_name as pqr.example.com work, but the ones with example.com don't. All of the working sites are configured to use subdomain URLs, and that's probably why they're working.
My questions are -
1. What am I missing in the config to make the abc.com work ?
2. I have two sites, example.com and example.net that I'm trying to run on the same server. Is that going to be a problem for NGinx ?
3. Does Nginx have a problem with differentiating between example.com, test.example.com, and example.net ?
4. I also noticed that if www.example.net works, www.example.com doesn't and vice versa, which means I have to assign each site that has the name abc in it different subdomains like www.example.net and test.example.com. Is this a standard/expected behavior of Nginx, or am I missing something ?
5. All of my base URLs auto redirect from http://example.com to http://www.example.com; How do I find out where that redirect is happening ?
Below are the Nginx config files that I'm having problems with, truncated to include the important parts; Please let me know if more info is needed.
Main nginx.conf file -
user www-data www-data;
pid /var/run/nginx.pid;
worker_processes 4;
worker_rlimit_nofile 100000;
events {
worker_connections 4096;
include /etc/nginx.custom.events.d/*.conf;
}
http {
default_type application/octet-stream;
access_log off;
error_log /var/log/nginx/error.log crit;
.......
server_tokens off;
include proxy.conf;
include fcgi.conf;
include conf.d/*.conf;
include /etc/nginx.custom.d/*.conf;
}
include /etc/nginx.custom.global.d/*.conf;
Here is the full working .conf file for a blog that works. All other sites have this full config, since they are just basic PHP sites.
server {
listen *:80;
server_name blog.example.com;
access_log /var/log/nginx/blog-example.access.log;
error_log /var/log/nginx/blog-example.error.log;
root /var/www/example/blog;
index index.html index.htm index.php;
# This order might seem weird - this is attempted to match last if rules below fail.
location / {
try_files $uri $uri/ /index.php?$args;
}
# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
# Directives to send expires headers and turn off 404 error logging.
location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
access_log off; log_not_found off; expires max;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~ /\. {
deny all;
}
# Deny access to any files with a .php extension in the uploads directory
# Works in sub-directory installs and also in multisite network
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}
location ~ [^/]\.php(/|$) {
# Zero-day exploit defense.
# http://forum.nginx.org/read.php?2,88845,page=3
# Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
# Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine. And then cross your fingers that you won't get hacked.
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include fcgi.conf;
fastcgi_pass unix:/var/run/php-fcgi-blog-example-php-fcgi-0.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Here's the truncated .conf file for example.com
server {
listen *:80;
server_name example.com www.example.com test.example.com;
access_log /var/log/nginx/examplecom.access.log;
error_log /var/log/nginx/examplecom.error.log;
root /var/www/example/com;
index index.html index.htm index.php;
# This order might seem weird - this is attempted to match last if rules below fail.
location / {
try_files $uri $uri/ /index.php?$args;
}
........
location ~ [^/]\.php(/|$) {
......
fastcgi_index index.php;
include fcgi.conf;
fastcgi_pass unix:/var/run/php-fcgi-examplecom-php-fcgi-0.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Here's the truncated file for example.net
server {
listen *:80;
server_name example.net www.example.net test.example.net;
access_log /var/log/nginx/examplenet.access.log;
error_log /var/log/nginx/examplenet.error.log;
root /var/www/example/net;
index index.html index.htm index.php;
# This order might seem weird - this is attempted to match last if rules below fail.
location / {
try_files $uri $uri/ /index.php?$args;
}
........
location ~ [^/]\.php(/|$) {
......
fastcgi_index index.php;
include fcgi.conf;
fastcgi_pass unix:/var/run/php-fcgi-examplenet-php-fcgi-0.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Meaning, when I pull up example.com, Chrome says connection refused, and there's no trace of an incoming connection on NGinx logs. test.example.com pulls up the default site(because I didn't configure test.example.com then) at the same time.
Well, your server is listening. Chances are you haven't configured your DNS records correctly, or there is DNS caching. Set your host file to test this theory.
I am looking for some help configuring my nginx to allow laravel routes to work correctly, I have found numerous tutorials giving slightly different ways but to no avail.
following: nginx configuration for Laravel 4 seems quite close to what I need, however I am getting the error No input file specified.
when I look into the error log I can see that instead of my route going to eg
/url/index.php/args
it is instead being routed to /url/args/index.php
This is my nginx app configuration file, and it's all you need to make it work, and, nginx doesn't make use of .htaccess:
server {
listen 80;
server_name laravel.dev;
root /var/www/laravel/public/;
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log /var/log/nginx/laravel.dev-access.log combined;
error_log /var/log/nginx/laravel.dev-error.log error;
error_page 404 /index.php;
sendfile off;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
I managed to get my site working, I think at least one of the configs I had already tried was correct however my sites-enabled copy of the config was a copy and not a symlink so my changes weren't actually updating.
I have just got forge up and running and serving my site and it works great. The frontend of my site is pure angular.
I have abstracted all of the angular aspects out of the laravel app into its own directoy on my local machine and have mapped this directory to say code/app/angular on the forge vm
the laravel app is mapped to code/app/laravel
lets say I have named the site awesome.app in the Homestead.yaml file and I have mapped that in my hosts file. what I want / need is to be able to hit awesome.app and have the angular app returned and then for any calls made by the angular app to the laravel backend to be made through awesome.app/users/1 and for the laravel app to pick that up and return the correct response. Is this possible?
so basically awesome.app should return the static files and then the laravel app should be listening for requests on awesome.app/
edit: I can create two sites on the vm one for the laravel app and one for the angular and then set up angular so its default base url is the laravel site but this is not ideal as it would mean removing that setting from angular before pushing to production
edit1: I imagine that this is going to require setting up nginx to reply with the contents of the angular folder when the root domain (awesome.app) is requested and to send the rest of the requests (awesome.app/ or awesome.app/api/)to the laravel folder. I do not know how to configure nginx at all as I was using apache until switching to homestead today.
The ultimate goal being to keep the angular and laravel codebases seperate so that I can push just the angular app to s3 and just the laravel app to ec2 / elasticbeanstalk
edit2:
Thanks fideloper I finally got a chance to try out your suggestion and I think I got most of the way there. the angular app from /home/vagrant/code/awesome/angular/build is being served correctly but the requests to the /api route are returning no input file specified. I dug around and I dont think its a permissions issue as I can access the laravel app with a vanilla homestead setup so I imagine it is something wrong with the config
the laravel app is in /home/vagrant/code/awesome/laravel with the index.php being in /public as normal. as a result I changed your suggestion slightly by moving the root to the location blocks as the roots are different for / and /api. I also tried keeping the root in the server block and adding an alias in the /api/ location block instead but this also returned no input file specified
maybe you can see where I am going wrong?
server {
listen 80;
server_name awesome.app;
index index.html index.htm;
charset utf-8;
location / {
root /home/vagrant/Code/awesome/angular/build;
try_files $uri $uri/ =404;
}
location /api/ {
root /home/vagrant/Code/awesome/laravel/public;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \/api\/index\.php$ {
root /home/vagrant/Code/awesome/laravel/public;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
#This specifically sets so the /api/ portion
#of the URL is not included
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param ENV production;
}
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/awesome.app-error.log error;
error_page 404 /index.php;
sendfile off;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
edit3: if I remove that second location ~ .php$ location block (which I am guessing I should) I get an actual nginx 404 html page not just a 404 with no input file specified
edit4: below config works
server {
listen 80;
server_name awesome.app;
root /home/vagrant/Code/awesome/laravel/public;
index index.html index.htm index.php;
charset utf-8;
location /api/ {
try_files $uri $uri/index.php?$query_string;
}
location / {
root /home/vagrant/Code/awesome/angular/build;
try_files $uri $uri/ index.html;
}
location ~ \/api\/index\.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
#This specifically sets so the /api/ portion
#of the URL is not included
#fastcgi_param SCRIPT_FILENAME $document_root/index.php;
#fastcgi_param PATH_INFO $fastcgi_path_info;
#fastcgi_param ENV production;
}
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/awesome-error.log error;
error_page 404 /index.php;
sendfile off;
location ~ \.php$ {
fastcgi_split_path_info ^(.+.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
You're right on your assumption on the Nginx configuration. I would do something like this on the nginx configuration (change names or file paths as needed for Homestead. I think it puts code in /home/vagrant/www instead of /var/www for example).
One Issue
I see you are differentiating at first with the url http://awesome.app vs http://awesome.app/ - however those are effectively the same URI. I would go with your second idea of http://awesome.app/ being static and http://awesome.app/api being your Laravel app.
You have two avenues of attack (well, 2 that I'll talk to, I'm sure there' more) for that:
Have Laravel serve the HTML for the home page (what you would otherwise have in an index.html page). Then create the /api route within Laravel. This lets you use a stock Nginx configuration. The story ends there, this is the easier way.
Configure the /api/ URL in Nginx to talk to PHP, while leaving any other URL to only serve static assets. A natural consequence of this is a bit more work in in your Nginx configuration.
Here's what that might look like:
server {
listen 80;
server_name awesome.app;
root /var/www/awesome.app/public;
# Not listing index.php file here on purpose
index index.html index.htm;
charset utf-8;
access_log /var/log/nginx/awesome.app.log;
error_log /var/log/nginx/awesome.app-error.log error;
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
location / {
try_files $uri $uri/ =404;
}
# Make index.php in /api url unnecessary
location /api {
try_files $uri /api/index.php$is_args$args;
}
# Only parse PHP for /api/index.php
location ~ \/api\/index\.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
# This specifically sets so the /api/ portion
# of the URL is not included
fastcgi_param SCRIPT_FILENAME $document_root/index.php
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param ENV production;
}
}
As a result, only the /api URL will be parsed by PHP.
Now, in this setup, your laravel application might get called with the url /api/index.php, which should just work still when using a base route Route::get('/', ...);.
Personally I'd keep this simpler and not do this funky Nginx setup, since it could cause more issues than it's worth. However it all depends on your setup.