separate nginx server blocks for same ports - nginx

nginx server blocks are defined as
server {
listen 80;
We have a context where a series of server_name domains have their certificates issued on the server and wish to redirect them with
return 301 https://$server_name$request_uri;
however, a few other domains are not going to have a certificate issued. So the requirement is to listen to port 80 and redirect for a sub-set of domains while serving the others in plain http.
Should that be done with two nginx files, under Ubuntu 14.04, in /etc/nginx/sites-enabled/ or can this be syntactically done in a single file?

Related

Redirection to newsite in nginx

We have an nginx 1.20.1 webserver on Ubuntu 16.04 hosting many sites. One site is oldsite.example.com and while we're building a newsite.example.com we wish for users to start using the new URL (newsite.example.com). We already made a DNS change but wanted clarity on the nginx part. New URL has to work with both HTTP/HTTPS and we have separate SSL cert it as well.
Thank you for reading.
oldsite nginx conf:
server {
server_name oldsite.example.com
;
listen 80;
if ($host = oldsite.example.com) {
return 301 https://$host$request_uri;
}
return 404;
}
server {
listen 443 ssl;
add_header Content-Security-Policy upgrade-insecure-requests;
For your question about redirection, a simple 302 will do the trick. It is similar to the 301 redirection you are already using:
return 301 https://$host$request_uri;
And you can return sth. like this, but in your ssl server section:
server {
listen 443 ssl;
server_name newsite.example.com;
return 302 https://oldsite.example.com$request_uri;
...
But I would recommend a proxy_pass, or just copy & paste your old configs into the new one. It will save you a redirection.
And for all of your misunderstandings about the protocol,
There is a server name indicator, or SNI, in plain text, in a TLS request (at least for now). If you know about the Host: header, that is it. You can have multiple HTTPS sites on the same host distinguished by server_name, which is exactly what you do for HTTP sites.
Even for HTTP sites, the Host: header is required (for HTTP/1.1 or higher, but no higher), and the server will look at it. You cannot simply CNAME (or sth. similar) a domain into another without modifying server configuration.
wouldn't the user's browser, when they type newsite.example.com and end up at oldsite.example.com
As I said, there is a server name indicator and the server will look at it, as it will look at Host: header. You can distinguish different sites on the same host by different server names.

Basic proxy_pass from nginx from one local ip to another local ip

I am a new user of nginx and I am following a video guide from Linode on youtube (How to Set Up an NGINX Reverse Proxy).
I have a working nginx and apache server both on port 80. I know that because when I type the ip address of both in firefox, it directs me to nginx/apache welcome page.
The youtube video configuration template is as follow (where the server_name is the linode ip) :
server {
listen 80;
listen [..]:80;
server_name 172.105.104.226;
location / {
proxy_pass http://localhost:3000/;
}
On my Proxmox machine, the nginx server is on a VM at 192.168.1.241 and the apache server on another VM at 192.168.1.243.
Looking at nginx documentation we find that this :
location /some/path/ {
proxy_pass http://www.example.com/link/;
}
should proxy all the traffic received on the nginx listening port and redirect it to the address specified by proxy pass.
With all these information, my configuration file is like this :
server {
listen 80;
listen [::]:80;
server_name 192.168.1.241;
location / {
proxy_pass http://192.168.1.243;
}
}
My understanding is that this configuration file should listen at the address 192.168.1.241 on port 80 (nginx server) and redirect it to the specified address 192.168.1.243 (apache server)/
If i understand correctly, Location / should take the request as is received on the nginx server and redirect it to the apache server.
However, when I enter 192.168.1.241 in my browser, it doesn't show the apache welcome message but shows the nginx welcome message. That means that the proxy isn't working.
My nginx understanding is extremely limited as I am just starting to learn, but to me it seems like this should work but doesn't.
Thank you for your help
It turns out that the configuration is correct.
The problem was that the webpage was cached. By forcing a full refresh, 192.168.1.241 redirected to 192.168.1.243 successfully.

Nginx redirecting too many times with reverse proxy

I have a debian server with MySQL and Meilisearch, I want to use Nginx as a reverse proxy for future load balancing and also having TLS security.
I'm following Meilisearch's Documentation to set up Nginx with Meilisearch and Lets Encrypt with success, but they force Nginx to proxy everything to port 7700, I want to proxy to 3306 for MySQL, 7700 for Meilisearch, and 80 for an error page or a fallback web server. But after modifying /etc/nginx/nginx.conf, the website reloads too many times.
This is the configuration I'm trying at /etc/nginx/nginx.conf:
user www-data;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
stream {
upstream mysql {
server 127.0.0.1:3306;
}
upstream meilisearch {
server 127.0.0.1:7700;
}
server {
listen 6666;
proxy_pass mysql;
}
server {
listen 9999;
proxy_pass meilisearch;
}
}
http {
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com;
return 301 https://\$server_name$request_uri;
}
server {
server_name example.com;
location / {
proxy_pass http://127.0.0.1:80;
}
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
# ssl_certificate managed by Certbot
# ssl_certificate_key managed by Certbot
}
}
The only difference is example.com is replaced by my domain, which has been already set to redirect to the server ip.
As ippi pointed out, it isn't necessary to reverse proxy MySQL in this particular case.
I used proxy_pass http://127.0.0.1:7700 as Meilisearch docs suggest.
For future DB load balancing, I'd use MySQL Clusters, and point out to them on another Nginx implementation that proxies everything (ie. HTTPS to web server, DB access to list of clusters, etc.).
Also, in this particular case, I don't actually require encrypted connections to the DB, but if I needed them, I'd use a self signed certificate in MySQL, and a CA certificate for the website, since my front ends communicate with a "central" Nginx proxy that could encrypt communication between backend servers and the proxy.
If I actually wanted to use the Let's Encrypt certificates for MySQL, I've found a good
recipe, but instead of copy pasting the certificate (which is painful) I'd mount the Let's Encrypt certificates' directory into MySQL's and change the permissions to 600 with chown. But then again, this is probably bad practice and would be better to use self signed certificates for MySQL as it's own docs suggest.

Nginx redirect not applied

I am configuring an nginx server at the moment and I have two domain types:
www.example.com
example.com
On the server I added a new server block with the following code to redirect every incoming requests to the domain without www.
server {
server_name www.example.com;
return 301 $scheme://example.com$request_uri;
}
The problem is that I only got HTTP 200 instead of 301.
The changed file is: /etc/nginx/sites-enabled/default
What am I missing? I did exactly how the documentation says in Digital Ocean.

Nginx Subdomain accessible on subdomain its not configured for

I have my staging config setup like so:
server {
listen 80;
server_name staging.domain.com;
root /var/www/staging/public;
and my production config setup like this:
server {
listen 80;
server_name www.domain.com;
root /var/www/production/public;
With no other redirects or anything.
The issue is that even if I disable the production config I can still access the staging server at www.domain.com.
Why is it not being restricted to its configured subdomain?
I've answered a similar question like this before
Let me start with a small explanation on how nginx matches the hosts, quoting from how nginx processes a request
In this configuration nginx tests only the request’s header field
“Host” to determine which server the request should be routed to. 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.
When you disable the main server you only have 1 left, so nginx passes the request to it, if you want to avoid that you need to add a main server to block all unconfigured domains
server {
listen 80 default_server;
return 403;
}
Then run
sudo service nginx reload
Then you're set

Resources