I would like to enable CORS for Google Places API in order to call it from an Ionic 2 app with a WkWebView.
I am doing this in my nginx default config:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
server_name _;
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Nginx doesn't support nested If statements, so we
# concatenate compound conditions on the $cors variable
# and process later
# If request comes from allowed subdomain
# (*.googleapis.com) then we enable CORS
if ($http_origin ~* (https?://.*\.googleapis\.com(:[0-9]+)?$)) {
set $cors "1";
}
# OPTIONS indicates a CORS pre-flight request
if ($request_method = 'OPTIONS') {
set $cors "${cors}o";
}
# Append CORS headers to any request from
# allowed CORS domain, except OPTIONS
if ($cors = "1") {
more_set_headers 'Access-Control-Allow-Origin: $http_origin' always;
more_set_headers 'Access-Control-Allow-Credentials: true' always;
proxy_pass http://111.111.111.111:80;
}
# OPTIONS (pre-flight) request from allowed
# CORS domain. return response directly
if ($cors = "1o") {
more_set_headers 'Access-Control-Allow-Origin: $http_origin';
more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE';
more_set_headers 'Access-Control-Allow-Credentials: true';
more_set_headers 'Access-Control-Allow-Headers: Origin,Content-Type,Accept';
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}
# Requests from non-allowed CORS domains
proxy_pass http://111.111.111.111:80;
}
}
But I am geeting a 502 Bad Gateway everytime I call:
http://111.111.111.111/maps/api/place/textsearch/json?key=APIKEY&query=starbucks
Any help, please?
Ok, I've found my mystake, proxy_pass should redirect to google not to my server:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
server_name _;
#location / {
# # First attempt to serve request as file, then
# # as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
#}
location / {
proxy_pass https://maps.googleapis.com;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'POST,GET,OPTIONS' always;
#preflight request
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';
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'POST,GET,OPTIONS' always;
return 204;
}
}
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /var/www/example.com;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}
Related
I currently have a deployed application. https://dostoevsky.rest/
It works well with Nginx and Docker.
However, I want to get a JSON response when I hit the endpoint https://dostoevsky.rest/api/rand with a subdomain.
So, I want the subdomain api.dostoevsky.rest to give the response https://dostoevsky.rest/api/rand would give.
I thought I could configure Nginx with proxy_pass, so I did the following:
server {
server_name api.dostoevsky.rest www.api.dostoevsky.rest;
location / {
default_type application/json;
proxy_pass http://<IP>:80/api/rand/;
}
}
However, when I do curl api.dostoevsky.rest I get this timeout message:
<html>
<head><title>504 Gateway Time-out</title></head>
<body>
<center><h1>504 Gateway Time-out</h1></center>
<hr><center>nginx/1.21.3</center>
</body>
</html>
Nginx Logs:
*1 upstream timed out (110: Operation timed out) while connecting to upstream, client:
I'm assuming the resource isn't found?
If I do curl https://dostoevsky.rest/api/rand it works fine. So, I think I'm making a mistake with the proxy or how the server is configured. Any help would be appreciated. Sorry if this is a low-quality question; I'm new to using Nginx.
Deployed on a DigitalOcean droplet.
I've also configured the DNS for the IP to point to api.dostoevsky.rest, by the way.
Following is my complete nginx.conf file:
server {
listen 80;
listen [::]:80;
server_name dostoevsky.rest www.dostoevsky.rest;
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 dostoevsky.rest www.dostoevsky.rest;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/dostoevsky.rest/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dostoevsky.rest/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 / {
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;
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
}
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
}
server {
server_name api.dostoevsky.rest www.api.dostoevsky.rest;
location / {
default_type application/json;
proxy_pass http://<IP>:80/api/rand/;
}
}
I want to configure two reverse proxies with ssl that proxy pass to different applications
https://api.example.com --> http://app:8080
https://pg.example.com --> http://pgadmin:80
Given the following nginx configuration, both sub-domains redirect to the first 443-server config (app). The problem occurs when hitting the 443 port. The redirect from 80 to 433 works fine for both. But when I browse https://pg.example.com it passes to app instead of pgadmin.
server {
listen 80;
listen [::]:80;
server_name api.example.com pg.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name api.example.com;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://app: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;
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name pg.example.com;
server_tokens off;
# note that api.example.com certificate has pg.example.com as alias
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_set_header X-Scheme $scheme;
proxy_set_header Host $host;
proxy_pass http://pgadmin:80;
proxy_redirect off;
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;
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
}
}
Feels like the SNI is not working or so..?! But it is enabled in nginx:
nginx -V
nginx version: nginx/1.17.10
built by gcc 9.2.0 (Alpine 9.2.0)
built with OpenSSL 1.1.1d 10 Sep 2019 (running with OpenSSL 1.1.1g 21 Apr 2020)
TLS SNI support enabled
What am I missing to make both reverse proxies work?
Edit:
When I remove the server block for server_name api.example.com; (on 443) then the other (pg.example.com:443) does work as expected. The api.example.com:443 then shows the same pgadmin upstream).
I think the easiest way is to split up the first server block into two server-blocks.
For example:
server {
listen 80;
listen [::]:80;
server_name api.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
and
server {
listen 80;
listen [::]:80;
server_name pg.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
I hope this helps, but I can't guarantee, that this config is working properly with certbot.
Turns out the reason is a misspelled domain for the sever_name of the
pg.example.com:433. Hence, not sever_name would match and nginx would then use the best match - which is the api.example.com:433.
I found out by adding a default (by making them the first in the conf file and both using sever_name _) server config for both 80 and 443 so I could ensure that the specific server configs are only used if the server_name matches. The result was that api.example.com:433 showed the same behavior as before (indicating that it works) while the pg.example.com:433 would show the newly configured default server - so it must be something that prevents the proper match on the server_name in the config. I triple checked the sever_name and finally saw the typo.
I have a side made with React running on Digital Ocean and I'm trying to use client side routing but can't get it to work. This is my Nginx default file
upstream site {
server 123.456.78.90:8080;
keepalive 64;
}
server {
server_name site.xyz www.site.xyz;
try_files $uri /index.html;
location / {
index index.html;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
try_files $uri index.html;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
proxy_max_temp_file_size 0;
proxy_pass http://site/;
proxy_redirect off;
proxy_read_timeout 240s;
}
error_page 404 /index.html;
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/site.xyz/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/site.xyz/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.site.xyz) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = site.xyz) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name site.xyz www.site.xyz;
return 404; # managed by Certbot
}
I added the try_files line and the error_page 404 /index.html so that it would default to index.html where the route could be loaded from my code there but it doesn't work at all. I need the ssl certificate and I need the cors code for another function. I'm not sure why it doesn't direct how I want.
Here's what worked for me:
...
location / {
...
proxy_intercept_errors on;
error_page 404 = /index.html;
...
}
I know this asks too much but I really don't get it.
I am using a subdomain for my server like sub.domain.com. I can reach it with ssh with typing ssh root#sub.domain.com.
I am trying use nextcloud on this server like cloud.domain.com. I can reach nextcloud when I type sub.domain.com/nextcloud. My conf file is:
upstream php-handler {
server 127.0.0.1:9000;
#server unix:/var/run/php5-fpm.sock;
}
server {
listen 80;
server_name sub.domain.com;
# enforce https
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name sub.domain.com;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
# 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;";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options "SAMEORIGIN";
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 /usr/share/nextcloud/;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
I am trying to change sub.domain.com to cloud.domain.com but it doesn't working.
Where is my mistake? Can you guys help me?
Thanks.
So I want my domain scanner-api.local to accept file sent from mobile device/web apps .
I was getting
following error
MLHttpRequest cannot load http://scanner-api.local/upload. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access.
I tried to add following in my Nginx server but its not working , Nginx is crashing
code
server {
listen 80;
listen [::]:80;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/stock_scan_api/public/;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
server_name scanner-api.local;
#location / {
# # First attempt to serve request as file, then
# # as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
#}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.php?$query_string;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
include snippets/fastcgi-php.conf;
# With php7.0-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# # With php7.0-fpm:
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;
#}
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}
}
What could be the error in this ?
Try removing the single quotes surrounding the header and value like:
add_header Access-Control-Allow-Origin *;