CORS rules coversion from Apache .htaccess to nginx - apache

Presently I have these .htaccess rules working perfectly on my Apache server:
<IfModule mod_headers.c>
SetEnvIf Origin "https://(www\.)?(domain.com|beta.domain.com|domain.loc)$" AccessControlAllowOrigin=$0
Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, X-CSRF-Token, X-XSRF-TOKEN"
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header set Access-Control-Allow-Credentials true
</IfModule>
<IfModule mod_rewrite.c>
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
Recent decision to switch to nginx requires us to implement the same. I'm still getting a hang of its internals and really need help converting this into its nginx config counterpart.
EDIT: What I tried so far:
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
server_name api.mydomain.loc;
root /var/www/mydomain/api/public;
index index.html index.htm index.php;
location / {
if ($http_origin ~* https://(www\.)?(mydomain.loc)) {
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, X-CSRF-Token, X-XSRF-TOKEN";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Credentials true;
}
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
Help would be greatly appreciated.

The simplest nginx equivalent of the Apache config in the question would be, just use add_header and wrap it all in anif block that does a regex match against $http_origin:
location / {
if ($http_origin ~* https://(www\.)?(domain.com|beta.domain.com|domain.loc)) {
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, X-CSRF-Token, X-XSRF-TOKEN";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
add_header Access-Control-Allow-Credentials true
}
# use $http_authorization to get the value of the Authorization request header
}
The extra RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] stuff that you need to do with Apache isn’t necessary with nginx; instead just use $http_authorization.
Note that variables in nginx that have names prefixed with $http_ are special variables:
$http_name
arbitrary request header field; the last part of a variable name is the field name
converted to lower case with dashes replaced by underscores
Thus $http_origin gives you the value of the Origin request header, $http_authorization gives you the value of the Authorization request header, etc.

Related

Nginx Proxy cookies too large

I have deployed my VueJs APP on docker container, but when I added nginx reverse proxy in my config file my cookie header become too large
my nginx conf
location / {
add_header "Access-Control-Allow-Origin" "*";
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'X-Requested-With,Accept,Content-Type, Origin';
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://[back-end-api]/public/index.php/api ;
}

Nginx is not proxying to the node backend

I have react application running on Nginx and backend application on Nodejs(running on another port 8080) with routes of patterns "/org-metadata/**, /proxy-api/**, /node-api/**".
I am trying to proxy the nginx to nodejs running on 8080, but it does not reach the backend. and the nginx gives the 503 Service Unavailable response and some times response 200 with You need to enable JavaScript to run this app.
Can some one pls point where am I missing anything?
Below is my nginx.conf file :
worker_processes auto;
events {
worker_connections 8000;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
# listen on port 80
listen 80;
# where the root here
root /var/www;
# what file to server as index
index index.html index.htm;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to redirecting to index.html
try_files $uri $uri/ /index.html;
}
# Javascript and CSS files
location ~* \.(?:css|js)$ {
try_files $uri =404;
expires 1y;
access_log off;
add_header Cache-Control "public";
}
location ~ (proxy-api|org-metadata|node-api) {
try_files $uri #nodejs;
}
location #nodejs {
proxy_pass http://nodejs:8080;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
}
}
}

Nginx redirects to first Subdomain when accessing second

So here's my situation: I have a Nextcloud and OpenHAB set up on my server and want to access both from outside my local network. I use Nginx as my reverse proxy to access my nextcloud on cloud.foo.bar and my openHAB on home.foo.bar. This works for my cloud, however if I access home.foo.bar, I either get redirected to cloud.foo.bar (on my Windows 10 machine) or just access my nextcloud under the home.foo.bar domain. Here's my nginx config (sites-available/default).
server {
listen 80;
server_name home.foo.bar;
location / {
proxy_pass http://localhost:8080/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
upstream php-handler {
#server 127.0.0.1:9000;
server unix:/var/run/php/php7.2-fpm.sock;
}
server {
if ($host = cloud.foo.bar) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name cloud.foo.bar;
# enforce https
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name cloud.foo.bar;
ssl_certificate /etc/letsencrypt/live/cloud.foo.bar/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/cloud.foo.bar/privkey.pem; # managed by Certbot
# Add headers to serve security related headers
# Before enabling Strict-Transport-Security headers please read into this
# topic first.
# add_header Strict-Transport-Security "max-age=15768000;
# includeSubDomains; preload;";
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
add_header X-Content-Type-Options nosniff;
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;
# Path to the root of your installation
root /var/www/nextcloud/;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# The following 2 rules are only needed for the user_webfinger app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json
# last;
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# Uncomment if your server is build with the ngx_pagespeed module
# This module is currently not supported.
#pagespeed off;
location / {
rewrite ^ /index.php$request_uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\.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;
fastcgi_param HTTPS on;
#Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^/(?: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 /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463";
# Add headers to serve security related headers (It is intended to
# have those duplicated to the ones above)
# Before enabling Strict-Transport-Security headers please read into
# this topic first.
# add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
add_header X-Content-Type-Options nosniff;
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 /index.php$request_uri;
# Optional: Don't log access to other assets
access_log off;
}
}
I only have an A record for the ipv4 of the server for #foo.bar, I tried using two records for cloud.foo.bar and home.foo.bar pointing towards the same ipv4, which didn't change anything.
I seem to answer a lot of my question just after posting them myself... I had to add a redirect for https requests, as my configurations forwareded all requests on port 80 to port 443 which only has a listener for cloud.foo.bar.

SSL Redirect Only for Sub-directory

I have redirected all www to non www as well as enabled https/ssl for my website.
My goal is to enable https/ssl for the domain/site on this root level(non subdomain) but enable ssl and well as redirect any http://domain.com/shop traffic to the https://domain.com/shop sub-directory /shop
Essentially all traffic to the site should 301 to http://domain.com and any traffic to the /shop sub-directory should be https://domain.com/shop
Root site is WordPress
/shop is Magento
Here is what I have for my domain.conf in /etc/nginx/sites-available
server {
server_name www.domain.com www.domain2.com;
return 301 $scheme://domain.com$request_uri;
}
server {
server_name domain.com domain2.com;
listen 80 default_server ipv6only=on;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
include /etc/nginx/ssl.conf;
root /home/domain/public_html;
set $no_cache 0;
location /admin {
set $no_cache 1;
}
location = /favicon.ico {
try_files $uri =204;
}
location ~* \.(jpe?g|gif|css|png|js|ico|pdf|zip|tar|t?gz|mp3|wav|swf)$ {
expires max;
}
location / {
index index.html index.php;
try_files $uri $uri/ #handler;
#rewrite ^/my-url.html /my-url/ permanent;
#rewrite ^/my-url.html http://domain.co.uk/ permanent;
expires 7d;
}
location /shop {
try_files $uri /shop/index.php;
}
location /shop/downloader {
# rewrite ^/shop/downloader /shop/downloader/index.php; NO
try_files $uri /shop/downloader/index.php;
}
location ~ ^/(app|includes|media/downloadable|pkginfo|report/config.xml|var)/ { deny all; }
location ~ ^/(info.php|var/export/)/ {
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/htpasswd;
}
location #handler {
rewrite / /index.php;
}
location ~ .php/ {
rewrite ^(.*.php)/ $1 last;
}
location ~ .php$ {
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param MAGE_RUN_TYPE website;
fastcgi_param MAGE_RUN_CODE base;
fastcgi_cache phpcache; # The name of the cache key-zone to use
fastcgi_cache_valid 200 30m; # What to cache: 'code 200' responses, for half an hour
fastcgi_cache_methods GET HEAD; # What to cache: only GET and HEAD requests (ot POST)
add_header X-Fastcgi-Cache $upstream_cache_status; # Allow us to see if the cache was HIT, MISS, or BYPASSED inside a browser's Inspector panel
fastcgi_cache_bypass $no_cache; # Dont pull from the cache if true
fastcgi_no_cache $no_cache; # Dont save to the cache if true
include fastcgi_params;
}
location ~ ([^/]*)sitemap(.*)\.x(m|s)l$ {
## this redirects sitemap.xml to /sitemap_index.xml
rewrite ^/sitemap\.xml$ /sitemap_index.xml permanent;
## this makes the XML sitemaps work
rewrite ^/([a-z]+)?-?sitemap\.xsl$ /index.php?xsl=$1 last;
rewrite ^/sitemap_index\.xml$ /index.php?sitemap=1 last;
rewrite ^/([^/]+?)-sitemap([0-9]+)?\.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;
## The following lines are optional for the premium extensions
## News SEO
rewrite ^/news-sitemap\.xml$ /index.php?sitemap=wpseo_news last;
## Local SEO
rewrite ^/locations\.kml$ /index.php?sitemap=wpseo_local_kml last;
rewrite ^/geo-sitemap\.xml$ /index.php?sitemap=wpseo_local last;
## Video SEO
rewrite ^/video-sitemap\.xsl$ /index.php?xsl=video last;
}
include /etc/nginx/minify.conf;
include /etc/nginx/scripts.conf;
location ~ /wp-content/cache/minify.*\.js$ {
types {}
default_type application/x-javascript;
expires modified 31536000s;
add_header Vary "Accept-Encoding";
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
}
location ~ /wp-content/cache/minify.*\.css$ {
types {}
default_type text/css;
expires modified 31536000s;
add_header Vary "Accept-Encoding";
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
}
location ~ /wp-content/cache/minify.*js\.gzip$ {
gzip off;
types {}
default_type application/x-javascript;
expires modified 31536000s;
add_header Vary "Accept-Encoding";
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
add_header Content-Encoding gzip;
}
location ~ /wp-content/cache/minify.*css\.gzip$ {
gzip off;
types {}
default_type text/css;
expires modified 31536000s;
add_header Vary "Accept-Encoding";
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
add_header Content-Encoding gzip;
}
location ~ \.(css|htc|less|js|js2|js3|js4)$ {
expires 31536000s;
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
}
location ~ \.(htm|rtf|rtx|svg|svgz|xsd|xsl|xml)$ {
expires 3600s;
add_header Pragma "public";
add_header Cache-Control "max-age=3600, public";
}
location ~ \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|woff|xla|xls|xlsx|xlt|xlw|zip)$ {
expires 31536000s;
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
}
rewrite ^/wp-content/cache/minify.*/w3tc_rewrite_test$ /wp-content/plugins/w3-total-cache/pub/minify.php?w3tc_rewrite_test=1 last;
set $w3tc_enc "";
if ($http_accept_encoding ~ gzip) {
set $w3tc_enc .gzip;
}
if (-f $request_filename$w3tc_enc) {
rewrite (.*) $1$w3tc_enc break;
}
rewrite ^/wp-content/cache/minify/(.+/[X]+\.css)$ /wp-content/plugins/w3-total-cache/pub/minify.php?test_file=$1 last;
rewrite ^/wp-content/cache/minify/(.+\.(css|js))$ /wp-content/plugins/w3-total-cache/pub/minify.php?file=$1 last;
}
In your .htaccess of wordpress add the following lines:
RewriteEngine on
RewriteCond %{HTTPS} !=on [NC]
RewriteCond %{REQUEST_URI} /shop/
RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301, L]

Nginx alias configuration for API with Silex

I've a problem with my NGinx configuration, I know there is a lot of topics already, but I didn't manage to my working properly...
So I've mydomain.com and mydomain.com/api/, my folders are like:
/var/www/mydomain.com/website/dist and /var/www/mydomain.com/api/public
And at the moment, I've something almost working. But the index.php still get the /api part in my routes.
server {
listen 80;
server_name mydomain.com www.mydomain.com;
index index.php index.html;
location / {
root /var/www/mydomain.com/website/dist;
}
location ~ ^/api(/|$) {
root /var/www/mydomain.com/api/public;
try_files $uri /api/index.php;
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_pass unix:/tmp/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param APPLICATION_ENV production;
}
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Headers' 'X-Requested-With,Content-Type,Authorization';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
}
access_log /var/logs/nginx/logs/mydomain.com-access.log;
error_log /var/logs/nginx/logs/mydomain.com-error.log;
}
I guess I'm not understanding something with the location or with php-fpm. What did I miss ? What should I do to get this working properly ?
I read too that a try_file is enought for that, than a rewrite rule... I don't know :/
Thank you for your help !