I'm trying to exclude the API route "https://example.com/api/" from the Nginx HTTP Basic Authentication.
Here is my Nginx Conf:
server {
listen 80;
listen [::]:80;
server_name example.com;
return 302 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/nginx/ssl/cert.crt;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_client_certificate /etc/nginx/ssl/cloudflare.crt;
ssl_verify_client on;
server_name example.com;
root /var/www/mysite;
index app.php index.php;
location / {
try_files $uri $uri/ /app.php$is_args$args;
# Restricting Access
auth_basic 'Administrator Area';
auth_basic_user_file /etc/apache2/.htpasswd;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
# Restriction off for api
location ^~ /api/ {
auth_basic off;
allow all;
}
}
But when I try to hit "https://example.com/api/" on the browser, it's still asking for basic authentication. Usually, without basic authentication, it should provide a JSON response on the browser.
Does anyone know how to solve this issue? Any kind of help would be greatly appreciated. Thanks.
Related
I would like to serve some of my website static assets like .txt, .csv, images and other document types as non https. But my current configuration always redirects to https.
server {
listen 80;
listen [::]:80;
root /var/www/public;
index index.php index.html index.htm;
server_name example.com www.example.com;
location / {
return 301 https://$host$request_uri;
}
location /static/ {
root /var/www/public/static;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
root /var/www/public;
index index.php index.html index.htm;
server_name example.com www.example.com;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
}
}
I have been reading similar questions here in SO:
Nginx: Redirect all to https except one laravel url = too many redirects
nginx: redirect everything from http to https, except one url-pattern
But nothing works for me and worst returns too many redirect.
Firstly, I'm sorry about my poor english and also I warn you that i'm a newbie still learning those technologies that I'm going to talk about.
So, I work on a companie and they needed some simple pages apps. I choose to use the React.js technologie with an Node.js API running with Express. (Sorry if I am wrong about the terms but I'm not english and still student).
I've done my 2 react apps and my api that are actually working correctly. I must deploy them on a CentOs. SO I've "daemonized" my 2 react apps and my API. The first react app with the port :8080, the other one with the port :3000 and the api, with the port :8081.
Then I installed Nginx, with a simple conf. It worked well. After that I've been trying to use https. So I did. But I'm now facing a problem.
When I try to reach one of my apps, I got a blank page with those messages :
GET https://domain_name/src/index.js net::ERR_ABORTED 404 (index):19
GET https://domain_name/static/js/2.3d1c602b.chunk.js net::ERR_ABORTED 404 (index):20
GET https://domain_name/static/js/main.95db8d0e.chunk.js net::ERR_ABORTED 404 manifest.json:1
GET https://domain_name/manifest.json 404 manifest.json:1
Manifest: Line: 1, column: 1, Syntax error.
And if I try to reach one of my api routes I get this :
Cannot GET /api/oneThing
and :
GET https://patt_www_ppd/api/ 404 patt_www_ppd/:1
I couldn't figure out with the problem in the net. I've found some possible solutions but I didn't understood them or it didn't worked. Can somebody help me?
Here is my nginx.conf :
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 65535;
events {
multi_accept on;
worker_connections 65535;
}
http {
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
log_not_found off;
types_hash_max_size 2048;
client_max_body_size 16M;
# MIME
include mime.types;
default_type application/octet-stream;
# logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
# SSL
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites
ssl_dhparam /etc/nginx/dhparam.pem;
# Mozilla Intermediate configuration
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
resolver_timeout 2s;
# load configs
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
And here is my domain_name.conf under the /sites-available/ directory :
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name domain_name;
# SSL
ssl_certificate /etc/certifs/domain_name.pem;
ssl_certificate_key /etc/certifs/domain_name.key;
# security
include nginxconfig.io/security.conf;
# logging
access_log /var/log/nginx/domain_name.access.log;
error_log /var/log/nginx/domain_name.error.log warn;
# reverse proxy
location /inventaire/ {
proxy_pass http://127.0.0.1:8080;
include nginxconfig.io/proxy.conf;
}
location /api/ {
proxy_pass http://127.0.0.1:8081;
include nginxconfig.io/proxy.conf;
}
location /ticket/ {
proxy_pass http://127.0.0.1:3000;
include nginxconfig.io/proxy.conf;
}
# additional config
include nginxconfig.io/general.conf;
}
# subdomains redirect
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name *.domain_name;
# SSL
ssl_certificate /etc/certifs/domain_name.pem;
ssl_certificate_key /etc/certifs/domain_name.key;
return 301 https://domain_name$request_uri;
}
# HTTP redirect
server {
listen 80;
listen [::]:80;
server_name .domain_name;
return 301 https://domain_name$request_uri;
}
I really thank anyone that can bring me some answers... And again, sorry for my english and my poor abilities in this domain, but I'm still learning.
I'm running Docker Containers with a Vue.js front and a Node.js+Express.js backend and managing the routes using Nginx.
When I access the route https://equilibrista.app/ and click the link inside the page to go to https://equilibrista.app/exams it works fine, but I got an error when I directly goes to this page (and a Express error shows up Cannot GET /exams).
Why is this happening? It looks like an Nginx redirect error, but I couldn't find anything wrong on nginx.conf
server {
listen 80;
listen [::]:80;
server_name equilibrista.app www.equilibrista.app;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name equilibrista.app www.equilibrista.app;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/equilibrista.app/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/equilibrista.app/privkey.pem;
ssl_buffer_size 8k;
ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
location /api/ {
proxy_pass http://api:3000/;
proxy_redirect off;
}
location / {
proxy_pass http://front:8888;
}
}
The way we got it to work with a Vue app was following.
1) First you have a location that capture all the physical files and paths that exists.
2) Secondly you redirect any other request to the main application file, for Vue it is index.html.
So your location configuration should look like this:
location /api/ {
proxy_pass http://api:3000/;
}
location ~* \/(index\.html|favicon\.ico|styles\.css|styles\.min\.css|css\/.*|js\/.*|images\/.*) {
proxy_pass http://front:8888;
}
location / {
rewrite / /index.html;
proxy_pass http://front:8888;
}
(updated to match question)
we have the static files on the nginx server, but it should work the same way with proxy_pass.
I am getting 403 Forbidden on Server virtual host configure using Nginx for NodeJS application.
Configuration file code:
server {
listen 443 default_server;
listen [::]:443 default_server;
ssl on;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /mnt/var/www/example.com/app/public/;
index index.html index.htm index.php;
server_name example.com www.example.com;
access_log /var/log/nginx/dygnostica_access.log;
error_log /var/log/nginx/dygnostica_error.log;
location / {
include /etc/nginx/proxy_params
try_files $uri $uri/ =404;
}
}
server {
listen 0.0.0.0:80;
server_name example.com www.example.com;
rewrite ^ https://$host$request_uri? permanent;
}
I have setup all configuration based on this article.
Need help to resolve 403. Thanks in advance.
EDIT:
Error log says:
directory index of "/mnt/var/www/example.com/app/public/" is forbidden.
I think you have wrong configuration for virtual host. Here is my nginx config file. I have standard PHP application (https) on main domain and node app on subdomain (running on port 3000):
#// virtual host for node app:
server {
server_name node.domain.cz;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
#// host (for PHP app)
server {
listen 80;
server_name domain.cz www.domain.cz;
root /var/www/domain.cz/www;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php7.1-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
listen 443 ssl; # managed by Certbot
# ssl_certificate ...
if ($scheme != "https") {
return 301 https://$host$request_uri;
} # managed by Certbot
}
Nginx isn't working to redirect non-www to www if I'm on https:
https://domain.com to https://www.domain.com
My curent setup in .conf is:
server {
listen 80;
server_name www.domain.com domain.com;
return 301 https://www.domain.com$request_uri;
}
server {
listen 443;
server_name domain.com;
return 301 https://www.domain.com$request_uri;
}
server {
listen IP_ADDRESS:443 ssl;
server_name www.domain.com;
...
}
http://domain.com to https://www.domain.com and http://www.domain to https://www.domain.com works, but non-www to www on https isn't working.
If I added the IP_ADDRESS on the second server block, I get an error in Chrome (SSL error) and both (www and non-www) stop working.
UPDATE:
Thanks to Steffen (below answer), I updated the self-signed certificate to be *.domain.com and not domain.com.
The .conf file was updated under this format:
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
server {
listen 80;
server_name www.domain.com domain.com;
return 301 https://www.domain.com$request_uri;
}
server {
listen 443 ssl;
server_name domain.com;
return 301 https://www.domain.com$request_uri;
}
server {
listen 443 ssl;
server_name www.domain.com;
...
}
I had similar kind of scenario and this is how I solved the redirection problem
https://example.com -----> https://www.example.com
server {
listen 443;
server_name example.com;
if ($host = example.com) {
rewrite ^(.*) https://www.example.com:443$request_uri? permanent;
}
}
Hope this helps!
Using if condition in nginx
Directive if has problems when used in location context, in some cases it doesn't do what you expect but something completely different instead. In some cases it even segfaults. It's generally a good idea to avoid it if possible. The only 100% safe things which may be done inside if in location context are:
return ...; rewrite ... last;
In 2nd server block (one starting with "listen 443;") you must add all SSL-related directives that are in the SSL server group (last group). This is my example.conf:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://www.$server_name$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
return 301 https://www.$server_name$request_uri;
# SSL
ssl on;
ssl_certificate /var/www/example.com/cert/bundle.cer;
ssl_certificate_key /var/www/example.com/cert/example.com.key;
# Enables all versions of TLS, but not SSLv2 or 3 which are weak and now deprecated.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# Intermediate cypersuite as recommended by Mozilla
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
# Add HSTS (HTTPStrictTransportSecurity)
add_header Strict-Transport-Security "max-age=31536000";
}
server {
listen 443 ssl;
server_name www.example.com;
root /var/www/example.com/public;
index index.html index.htm index.php;
client_max_body_size 32m;
access_log /var/www/example.com/access.log;
error_log /var/www/example.com/error.log;
# SSL
ssl on;
ssl_certificate /var/www/example.com/cert/bundle.cer;
ssl_certificate_key /var/www/example.com/cert/example.com.key;
# Enables all versions of TLS, but not SSLv2 or 3 which are weak and now deprecated.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# Intermediate cypersuite as recommended by Mozilla
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
# Add HSTS (HTTPStrictTransportSecurity)
add_header Strict-Transport-Security "max-age=31536000";
# Directives to send expires headers and turn off 404 error logging.
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
#expires max;
log_not_found off;
access_log off;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
## Disable viewing .htaccess & .htpassword
location ~ /\.ht {
deny all;
}
location ^~ /admin/ {
auth_basic "Restricted";
auth_basic_user_file /var/www/example.com/.htpasswd;
try_files $uri $uri/ /index.php$is_args$args;
location ~ \.php$ {
include /etc/nginx/php-inside.conf;
}
}
include /etc/nginx/php.conf;
}
This is probably because you don't have a certificate for domain.com, but only for www.domain.com or *.domain.com. See Nginx redirect http://www and naked http/https to https://www or https://serverfault.com/questions/579916/nginx-redirect-https-www-to-https-non-www-without-untrusted-connection-warn/579917#579917 for details.
This is a more graceful solution that I use. Requires one server block for the actual website, and one server block for the redirect from non-www/non-https to https://www.*.
server {
listen IP_ADDRESS:443 ssl;
server_name www.domain.com;
}
server {
listen IP_ADDRESS:80 ssl default_server;
listen IP_ADDRESS:443 ssl default_server;
return 301 https://www.domain.com$request_uri;
}
The default_server option is important, otherwise the first definition becomes the default which can work against your intentions of redirecting all requests other than www.domain.com. By using default_server, your redirect server block acts as a catch-all.
In my opinion though, you should NOT be using "www". You should be redirecting from www to non-www. www is a legacy thing that isn't relevant these days. You're perpetuating this irrelevant legacy by redirecting from non-www to www.
I have used rewrite on both server directive and it worked for me:
General Rewrite Directive non www to https wwww
server {
listen 80;
server_name example.com www.example.com;
return 301 https://www.$server_name$request_uri;}
SSL Rule directive for non www to https wwww
server {
listen 443 ssl;
server_name example.com;
return 301 https://www.$server_name$request_uri;}