I'm using the builtin MongoDB "simple REST interface" to try to tie together my MongoDB collection with a simple javascript frontend without writing an API myself. I have the REST server up and running, as proven by running the following inside my production server:
$> http get "http://localhost:28017/mydb/mycoll/?limit=1"
HTTP/1.0 200 OK
Connection: close
Content-Length: 437
Content-Type: text/plain;charset=utf-8
x-action:
x-ns: mydb.mycoll
{
"offset" : 0,
"rows": [
{ <redacted data> }
],
"total_rows" : 1 ,
"query" : {} ,
"millis" : 0
}
The Mongodb REST server does not by, by default, bind to an interface which is publicly accessible, so I'm proxying localhost:28017 to the outside world using Nginx, with the following configuration:
server {
listen 80;
server_name api.myapp.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443 default_server;
server_name api.myapp.com;
ssl on;
ssl_certificate /etc/ssl/myapp.crt;
ssl_certificate_key /etc/ssl/myapp.key;
access_log /logs/nginx_access.log;
error_log /logs/nginx_error.log;
location /mongo {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://127.0.0.1:28017;
break;
}
}
}
I reload nginx and try the same query I ran inside the machine hosting Mongo from a machine outside that network instead, and get:
$> http get "https://api.myapp.com/mongo/mydb/mycoll/?limit=1"
HTTP/1.1 200 OK
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/plain;charset=utf-8
Date: Fri, 27 Feb 2015 17:06:40 GMT
Server: nginx/1.4.6 (Ubuntu)
Transfer-Encoding: chunked
Vary: Accept-Encoding
x-action:
x-ns: mongo.mydb.mycoll
{
"offset" : 0,
"rows": [
],
"total_rows" : 0 ,
"query" : {} ,
"millis" : 0
}
Essentially, it is hitting the Mongo REST server (making it through the nginx proxy), but it is not returning any results for the same query that I ran on localhost.
The only lead I have so far is that the x-ns header on the two responses is different - like the Mongo REST server is not picking up the fact that Nginx is instructing it to lie behind the https://api.myapp.com/mongo route and is instead thinking I'm trying to access the database mongo.
Thanks for your help.
Solved my own issue. The problem was as I guessed at the end of my question: the Nginx config was proxying requests to the Mongo API server with the /mongo/ path intact, resulting in queries being run on the (nonexistent) database mongo.
I fixed the problem by adding the following line to the /mongo/ location in the Nginx configuration file:
rewrite /mongo/(.+) /$1 break;
so that it reads, in full:
location /mongo/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
rewrite /mongo/(.+) /$1 break;
proxy_pass http://127.0.0.1:28017;
break;
}
}
Thanks to anyone who gave this question a look.
Related
I have this nginx config.. i want it to accept all domains that have the word competitions in it and end with .com.au.. I have tested with a domain name that should NOT be accepted but it reaches the application.. is the server_name being ignore because I'm using a proxy?
server {
listen 80 default_server;
server_name ~^(.+)competitions?(.+)\.com\.au;
access_log /var/log/nginx/$host.access.log;
error_log /var/log/nginx/error.log;
if ($host !~* ^www){
rewrite ^/(.*)$ https://www.$host/$1 permanent;
}
location / {
proxy_no_cache 1;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8888;
try_files $uri $uri/ #proxy;
}
location #proxy {
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8888;
proxy_intercept_errors on;
recursive_error_pages on;
error_page 404 = #rewrite_proxy;
}
location #rewrite_proxy {
rewrite /(.*) /index.cfm?path=$1;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8888;
}
}
You'd have to remove the default_server from there, because this is a catch-all directive.And you still could setup another one server with the default_server directive, if required.
See How nginx processes a request for a more detailed explanation:
If its value does not match any server name, or the request does not contain this header field at all, then nginx will route the request to the default server for this port.
I have a nginx conf like below
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80 default_server;
access_log off;
return 200 'Hello, World! - nginx\n';
}
server {
listen 80;
server_name ~^(dev-)?(?<app>[^.]+)\.mysite\.com$;
access_log off;
location / {
resolver 127.0.0.11;
proxy_set_header Host $host;
proxy_pass http://${app}-web;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
I expected that redirecting
dev-blog.mysite.com into service blog-web
dev-market.mysite.com into service market-web
and so on
Is there any way to implement this in k8s ingress-nginx?
No, you would make a separate Ingress object for each (or one huge one, but that's less common). Usually this is semi-automated through either Helm charts or custom controllers.
http://prntscr.com/coliya -Chrome
http://prntscr.com/coljez -Opera
NGINX
server {
listen 0.0.0.0:80;
listen 0.0.0.0:443 ssl;
root /usr/share/nginx/html;
index index.html index.htm;
ssl on;
sslcertificate /etc/ssl/certs/ssl-bundle.crt;
sslcertificatekey /etc/ssl/private/budokai-onlinecom.key;
sslciphers '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:kED$
ssldhparam /etc/ssl/private/dhparmas.pem;
sslpreferserverciphers on;
sslprotocols TLSv1 TLSv1.1 TLSv1.2;
if ($sslprotocol = "") {
rewrite ^ https://$host$requesturi? permanent;
}
largeclientheader_buffers 8 32k;
location / {
proxyhttpversion 1.1;
proxysetheader Accept-Encoding "";
proxysetheader X-Real-IP $remoteaddr;
proxysetheader Host $host;
proxysetheader X-Forwarded-For $proxyaddxforwardedfor;
proxysetheader XFORWARDEDPROTO https;
proxysetheader X-NginX-Proxy true;
proxybuffers 8 32k;
proxybuffersize 64k;
proxysetheader Upgrade $httpupgrade;
proxysetheader Connection "Upgrade";
proxyreadtimeout 86400;
proxypass http://budokai-online.com:8080 ;
}
The problem I'm having is that some computers and some browsers are being redirected when trying to get a connection to the websocket. When that 302 error shows up, the '/*' routes has been activated! This route redirects the user to the login page as you saw in the redirect response.The websocket upgrade request is turned into an ordinary http request somehow, somewhere! This seems to be where the problem is. What can be causing this?
i had the same problem but it was related to varnish settings. if you are using varnish add:
sub vcl_recv {
if (req.http.upgrade ~ "(?i)websocket") {
return (pipe);
}
}
sub vcl_pipe {
if (req.http.upgrade) {
set bereq.http.upgrade = req.http.upgrade;
set bereq.http.connection = req.http.connection;
}
}
check this link for reference:
https://varnish-cache.org/docs/4.1/users-guide/vcl-example-websockets.html
I have the folloiwng Nginx configuration:
server {
listen 80;
server_name .example.net .example.com;
return 301 https://example.com$request_uri;
}
server {
listen 80;
server_name beta.example.com;
error_page 403 /403;
error_page 404 /404;
error_page 500 /500;
client_max_body_size 5M;
# Handle all locations
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 443;
ssl on;
ssl_certificate /etc/ssl/cert_chain.crt;
ssl_certificate_key /etc/ssl/csr.pem;
server_name example.com;
error_page 403 /403;
error_page 404 /404;
error_page 500 /500;
client_max_body_size 5M;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
I'm wanting to redirect HTTP requests to HTTPS however I get a redirect loop. I've read other answers on different questions including this one and this one however none of their solutions solved mine. Any ideas? Thanks.
It seems like your backend (running on 127.0.0.1:8000) issues Location: http://example.com/ header.
Please look into the access logs, nginx's and backend's too.
Or use httpliveheaders or tcpdump to investigate the traffic.
I want to redirect conditionally based on the server name, but where I redirect to also depends on the subdomain. So for example, here is my basic config
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name company.com compa.ny;
ssl on;
ssl_client_certificate /etc/ssl/certs/godaddy_CA.crt;
ssl_certificate /etc/ssl/certs/wildcard.company.com.crt;
ssl_certificate_key /etc/ssl/private/wildcard.company.com.key;
ssl_prefer_server_ciphers on;
root /var/www/company;
access_log /var/log/nginx/nginx.access.log;
error_log /var/log/nginx/nginx.error.log;
client_max_body_size 8M;
location ^~ /application {
proxy_set_header HOST $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://127.0.0.1:8080;
}
}
I want to have something that looks for the short url host "compa.ny" and redirects to "company.com/shortUrldRedirector" and I also want to include the subdomain, so in dev or qa this will work correctly:
https://compa.ny/abc123 -> https://company.com/shortUrldRedirector/abc123
and
https://dev.compa.ny/abc123 -> https://dev.company.com/shortUrldRedirector/abc123
I see there is a $server_name config variable, but how do I accomplish the above redirects respecting the subdomain?
I would use map construction like this:
map $http_host $long_domain {
default company.com;
dev.compa.ny dev.company.com;
compa.ny company.com;
}
server {
...
return 301 https://$long_domain/shortUrldRedirector$request_uri;
}