I want to deny access to few directories, as well as all sub-directories and files, including JS/CSS files.
I have this configuration, and it works for the most part, but it doesn't deny access to .js file I have.
server {
listen 80;
server_name DOMAIN www.DOMAIN;
root /home/me/www/app;
index index.php index.html index.htm;
autoindex on;
client_max_body_size 20m;
fastcgi_read_timeout 600;
#Forbid access to these directories
location ~ /(data|dev|py)/ {
deny all;
return 403;
}
#Force download on PDF files
location ~* /(.*\.pdf) {
types { application/octet-stream .pdf; }
default_type application/octet-stream;
}
location / {
index index.php index.html index.htm;
try_files $uri $uri/ /index.php?$args;
}
#API
location /api/v1/ {
index index.php;
try_files $uri $uri/ /api/v1/index.php?$args;
}
#php support
location ~ [^/]\.php(/|$) {
include /etc/nginx/conf.d/php_generic;
fastcgi_param DOCUMENT_ROOT /home/me/www/site1;
fastcgi_pass unix:/var/run/php/php-fpm-me.sock;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
error_log /home/me/logs/error.log;
access_log /home/me/logs/access.log;
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/DOMAIN/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/DOMAIN/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
Any ideas?
EDIT / RESOLVED
Well, the website is behind CloudFlare, so after 30 minutes of pulling my hair off, link is no longer accessible, which tells me that CloudFlare had it cached and served it, even tho nginx config was changed.
Related
This is a config "template" I am using right now:
server {
server_name {:primaryDomain};
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/{:primaryDomain}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{:primaryDomain}/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
root {:siteRoot};
index index.php index.html;
recursive_error_pages off;
error_page 403 = /HTTP_ERRORS/403.html;
error_page 404 = /HTTP_ERRORS/404.html;
error_page 500 = /HTTP_ERRORS/500.html;
location ^~ /HTTP_ERRORS/ {
alias {:sharedHtmlRoot}/;
internal;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location /manage {
root {:siteRoot}/manage;
try_files $uri $uri/ /manage/index.php?$query_string;
}
location ~* \.php$ {
fastcgi_pass unix:/run/php/php{:phpVer}-fpm-{:user}.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
location /assets/ {
alias /public/assets/;
}
}
server {
server_name {:primaryDomain} www.{:primaryDomain};
listen 80;
return 301 https://{:primaryDomain}$request_uri;
}
server {
server_name www.{:primaryDomain};
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/{:primaryDomain}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{:primaryDomain}/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
return 301 https://{:primaryDomain}$request_uri;
}
Notice the {:keywords}. These are strings that I replace with a script that is generating the nginx final config.
It works fine, but I have around 300 websites and the script will generate 300 of these configs using this template, so the final nginx .conf file is quite large.
Could I use a single nginx config for all sites somehow?
Here is a all in one configuration i have verified with nginx/1.18.0, but still need to generate a domain list file /etc/nginx/mydomains
/etc/nginx/sites-enabled/default
map $http_host $vhost_config {
hostnames;
default "";
include /etc/nginx/mydomains;
}
map $vhost_config $vhost_root {
default "";
~^([^:]+):([^:]+):([^:]+)$ $1;
}
map $vhost_config $php_version {
default "";
~^([^:]+):([^:]+):([^:]+)$ $2;
}
map $vhost_config $php_user {
default "";
~^([^:]+):([^:]+):([^:]+)$ $3;
}
map $ssl_server_name $my_cert_name {
default "";
~^(www\.)?(.+)$ $2;
}
server {
listen 80 default_server;
listen 443 ssl default_server;
ssl_certificate /etc/letsencrypt/live/$my_cert_name/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$my_cert_name/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name ~^(?<www>(www\.)?)(?<domain>.+)$;
recursive_error_pages off;
error_page 403 = /HTTP_ERRORS/403.html;
error_page 404 = /HTTP_ERRORS/404.html;
error_page 500 = /HTTP_ERRORS/500.html;
location ^~ /HTTP_ERRORS/ {
alias {:sharedHtmlRoot}/;
internal;
}
# redirect www.abc.com to abc.com
if ($www != '') {
return 301 https://$domain$request_uri;
}
# redirect http to https
if ($scheme = 'http') {
return 301 https://$domain$request_uri;
}
# if domain not exist in mydomains, return 404
if ($vhost_root = '') {
return 404;
}
root $vhost_root;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location /manage {
root $vhost_root/manage;
try_files $uri $uri/ /manage/index.php?$query_string;
}
location ~* \.php$ {
fastcgi_pass unix:/run/php/php$php_version-fpm-$php_user.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
location /assets/ {
alias /public/assets/;
}
}
content of /etc/nginx/mydomains
# domain.name "<site root>:<php version>:<php user>";
abc.com "/var/www/html/abc:7.4:user1";
efg.com "/var/www/html/efg:7.0:user2";
notes
Nginx support using variable in ssl_certificate directive since 1.15.9, and $ssl_server_name was introdued in nginx/1.70. Because http variable $http_host will not be initialized until the https connection is established, $ssl_server_name is not replace able in this configuration.
You could replace {:sharedHtmlRoot} in server block with your real path.
The all in one server block is delared as a default block, if there's already a default server block in your nginx configuration, you need to overwrite the old one.
Recently we have migrated from Apache2 to Nginx server. Consider we have domain www.test.com and following is the www.test.com.conf and I had disabled default Nginx default file.
server {
server_name www.test.com;
# Character Set
charset utf-8;
# Logs
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Directory Indexes
index index.html index.htm index.php;
# Document Root
root /var/www/html/project1/public;
# Location
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
# Error Pages
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
# PHP-FPM Support
location ~ \.php$ {
fastcgi_read_timeout 240;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; #/var/run/php5-fpm.sock;
#include fastcgi.conf;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Block access to .htaccess
location ~ \.htaccess {
deny all;
}
client_body_timeout 10s;
client_header_timeout 10s;
client_max_body_size 100M;
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.test.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.test.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.test.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen *:80;
server_name www.test.com;
return 404; # managed by Certbot
}
With the above configuration, I can access https://www.test.com without issues. In this case root /var/www/html/project1/public. Now to access multiple applications from the same domain I had changed the root directive to /var/www/html/ and tried to access https://www.test.com/project1/public but I'm getting the following error
FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream
May I know the reason for this issue? my application is Lumen which is a mirco service framework by Laravel.
By changing the following blocks it is working for me
from root /var/www/html/project1/public; to root /var/www/html;
And we need to add multiple location blocks based on the requirement. Consider I want to access two Lumen/ Laravel applications from single domain, then I need to add two location blocks as
location /project1/public {
try_files $uri $uri/ /project1/public/index.php$is_args$args;
}
location /project2/public {
try_files $uri $uri/ /project2/public/index.php$is_args$args;
}
Credits go to Richard Smith
I have an issue as given below.
Say I have a site example.com and I have made modifications to the rewrite logic to remove .php extensions. The code given below works fine in all the cases except for index.php
https://example.com --> Not accessible. This is not correct. It should display contents from index.php page.
https://example.com/index.php --> Displays 404 page. This is correct.
https://example.com/index --> Displays index page. This is not correct.
server {
root /usr/share/nginx/html;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm;
server_name example.com www.example.com;
error_page 404 /error/custom_404;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
index index.php index.html index.htm;
try_files $uri $uri/ #missing;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg)$ {
expires 365d;
}
location ~* (\.php$|myadmin) {
return 404;
}
location #missing {
if (!-f $document_root$uri.php) { return 404; }
fastcgi_param SCRIPT_FILENAME "$document_root$uri.php";
fastcgi_param PATH_TRANSLATED "$document_root$uri.php";
fastcgi_param QUERY_STRING $args;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~* \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}server {
if ($host = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 404; # managed by Certbot
}
Can someone point to where I am doing wrong?
Thanks
So I'm trying to setup 5 websites, all on the same domain just with diffrent subdomain, etc www. and cdn.
but www. works fine as it should
tho cdn. does not, It got the same files I just copyed them over, all permissions are the same for the folders.
I have each sub domain in their own files etc wwwmydomaincom and cdnmydomaincom and the config is the same, only diffrence is server_name. the file that works got www.mydomain.com the rest got somesubdomain.mydomain.com and they throw 404.
I use Nginx on ubuntu server 16.04.1.
Added
location / {
try_files $uri.html;
}
and the sub domains displays the html pages fine (now their config isent like the one that works)
But.. every asset, css, js, images or other things get 404 so it's a pure html page.
The config under is the exact same config as www.mydomain.com but changed to fit cdn.mydomain.com
server {
listen 80;
server_name cdn.domain.com;
location /.well-known/acme-challenge {
default_type "text/plain";
root /storage/webserver/certbot;
}
#Forces all other requests to HTTPS
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name cdn.domain.com;
ssl_certificate /etc/letsencrypt/live/cdn.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cdn.domain.com/privkey.pem;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA512:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:ECDH+AESGCM:ECDH+AES256:DH+AESGCM:DH+AES256:RSA+AESGCM:!aNULL:!eNULL:!LOW:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS;
ssl_session_cache shared:TLS:2m;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
# Set HSTS to 365 days
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains';
root /storage/webserver/cdn.domain.com;
index index.html index.php;
location #rewrite {
rewrite ^ $uri.php last;
try_files $uri =404;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+?\.php)(/.+)$;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
include fastcgi.conf;
try_files $uri =404;
}
rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent;
#rewrite ^/(.*)/$ /$1 permanent;
error_page 404 /404.php;
error_page 500 503 502 504 /error/40x.php;
location =/error/40x.html {
internal;
}
}
Ahem, this is why I want to learn this kind of stuff.
You obviosly need to make it look for the files.
so if anyone enters this litte situation, Don't forget to make it look in the root folder.
location / {
try_files $uri $uri/ $uri.html #rewrite;
}
i'm new to nginx and i have a problem with virtual host. The virtual host didn't work when i try to access the vhost it'll be redirect to localhost "Welcome to nginx". Here are the contents of my config:
/etc/hosts config:
127.0.0.1 localhost localhost.localdomain
::1 localhost localhost.localdomain
****Generated by Admin****
18.200.10.50 mail.testingweb.com
18.200.10.50 testingweb.com
SSL config on /etc/nginx/conf.d/ssl.conf:
server {
listen 443 default_server ssl;
server_name testingweb.com;
ssl_certificate /etc/nginx/sslcert/xxxx.crt;
ssl_certificate_key /etc/nginx/sslcert/xxxxx.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
keepalive_timeout 70;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNU$
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location / {
root /usr/share/nginx/html;
index index.php index.html index.htm;
}
location ~ \.php$ {
try_files $uri =404;
# With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
/etc/nginx/sites-available/default config:
server {
listen 80 default_server;
# listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/xhtml;
index index.php index.html index.htm;
# Make site accessible from http://localhost/
server_name testingweb.com;
return 301 https://$host$request_uri;
location / {
try_files $uri $uri/ =404;
}
error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
try_files $uri =404;
# # With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}
server {
listen 80;
listen 443;
return 403;
}
I want to access another sites from new root directory, /usr/share/nginx/html/www on www directory there is a wordpress.
/etc/nginx/sites-available/testingweb config:
server {
listen 80 default_server;
# listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html/www;
index index.php index.html index.htm;
# Make site accessible from http://localhost/
server_name testingweb.com;
# rewrite ^ https://$http_host$request_uri? permanent;
return 301 https://$host$request_uri;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.php?q=$uri&$args;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules;
}
error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
try_files $uri =404;
# # With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# location = /favicon.ico {
# alias /usr/share/nginx/html/favicon.ico;
# }
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}
According the configs, what's wrong with my config ? i cannot access the wordpress file on /usr/share/nginx/html/www directory by domain testingweb.com ? its always redirect to default host instead of testingweb host ?
sorry for my bad english..
This is a revised version of the nginx configuration from your pastebin code:
server {
listen 80;
# listen [::]:80 default_server ipv6only=on;
# Make site accessible from http://devdev.com/
server_name devdev.com;
return 301 https://$host$request_uri;
}
# HTTPS server
#
server {
listen 443 default_server ssl;
server_name devdev.com;
root /var/www;
index index.php index.html index.htm;
# uncomment to add your access log path here
# access_log /var/log/nginx/devdev.com.access.log main;
ssl_certificate /etc/ssl/ssl-unified.crt;
ssl_certificate_key /etc/ssl/ssl-my-private-decrypted.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
keepalive_timeout 70;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS +RC4 RC4";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location #default {
rewrite ^/(.*) /index.php?uri=$request_uri last;
}
location / {
try_files $uri $uri/index.php #default;
}
location ~ \.php$ {
try_files $uri =404;
# With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
The first server block listening on port 80 just redirects to https://devdev.com/. This will redirect all http requests to https so you don't need any other processing rules.
The second server block listens on port 443 and will proxy requests with a path ending with .php to php-fpm (you want to double-check that it's running on a unix socket and your permissions are correct).
The location block matching the / prefix (location /) will try to match files in the request URI and handle the request appropriately. For example:
If the request is for /index.php and the file exists, the following block will match the .php suffix and proxy to php-fpm.
If the request is for /foo and there's no match for a file by that name, nginx will try to match /foo/index.php and then proxy to php-fpm.
If there is still no match, try_files will use the #default location block, which just sends the request to your top-level /index.php with the request URI as parameters.
If your WordPress site is located in /var/www -- the top-level entry point should be /var/www/index.php -- this configuration should work. You might need to tweak the configurations based on your WordPress settings -- though this is generic enough that it should work without a lot of changes.