How to set up strapi through Nginx with SSL - nginx

I'm working on digitalOcean droplets.
https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/deployment/optional-software/nginx-proxy.html#strapi-server
I've been trying to follow this guide for hours now, but I just can't get it to work.
When I try to connect, I get 502 bad gateway, don't know what that means. When I had just the 8011 port enabled through firewall and connected to the port directly through the DNS, it worked fine.
doing nginx -t says that syntax is fine, I tried restarting the service many times, the keys work.
/etc/nginx/conf.d/upstream.conf:
# Strapi server
upstream strapi {
server 127.0.0.1:8011;
}
etc/nginx/sites-available/default:
server {
# Listen HTTP
listen 80;
server_name losslessly-api.djkato.net;
# Redirect HTTP to HTTPS
return 301 https://$host$request_uri;
}
server {
# SSL configuration
#
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/nginx/certificate/losslessly-api.djkato.net.crt;
ssl_certificate_key /etc/nginx/certificate/losslessly-api.djkato.net.key;
server_name losslessly-api.djkato.net;
# Proxy Config
location / {
proxy_pass http://strapi;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $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;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass_request_headers on;
}
}
./config/server.js:
module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 8011),
url: 'https://losslessly-api.djkato.net',
});
sudo ufw status:
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
8011/tcp DENY Anywhere
Nginx HTTP ALLOW Anywhere
Nginx HTTPS ALLOW Anywhere
8011 DENY Anywhere
Nginx Full ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
8011/tcp (v6) DENY Anywhere (v6)
Nginx HTTP (v6) ALLOW Anywhere (v6)
Nginx HTTPS (v6) ALLOW Anywhere (v6)
8011 (v6) DENY Anywhere (v6)
Nginx Full (v6) ALLOW Anywhere (v6)

I did a netstat -tulpn | grep LISTEN and found out that my app wasn't listening on localhost, but the public IP.
Looking at my strapis .env file I realised that I setHOST:{public ip}, not APP_URL:{public ip}, meaning my upstream connection was on the wrong IP. Fixing my env file solved it.

Related

How to make a secure request?

Since this morning I try to simulate a POST request on my remote database with the https protocol because I installed an ssl certificate. (my site is secure).
https://example.com/api/v1/data_tag
But when I try to send a Postman request to my database in secure mode I get this error :
SSL Error: Unable to verify the first certificate
When I remove the "s" from https in my url the request is done correctly.
http://biotagsensor.com:3000/api/v1/data_tag
I have configured the firewalls of my server in this way :
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
80/tcp (Nginx HTTP) ALLOW IN Anywhere
3000 ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
80/tcp (v6) ALLOW IN Anywhere (v6)
443/tcp (v6) ALLOW IN Anywhere (v6)
80/tcp (Nginx HTTP (v6)) ALLOW IN Anywhere (v6)
3000 (v6) ALLOW IN Anywhere (v6)
and here is the default file of nginx :
upstream backend {
server localhost:3000;
}
server {
listen 80;
rewrite ^ https://$host$request_uri? permanent;
}
server {
# listen 80 default_server;
# listen [::]:80 default_server;
listen 443 ssl;
ssl_certificate /home/debian/site.com.chain.pem;
ssl_certificate_key /home/debian/myserver.key;
root /home/debian/site.com/dist;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location ^~ /api {
proxy_redirect off;
proxy_http_version 1.1;
proxy_pass http://backend;
proxy_set_header Host $host ;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}
Do you know where this can come from ?
It looks like you have a misconfigured intermediate certificate.
Verify if site.com.chain.pem has correct content and the path to it is correct.
http://ipadress:3000/api/v1/data_tag
This is your internal server, which is not HTTPS enabled. You even access this server explicitly with plain HTTP from your nginx:
proxy_pass http://backend;
If you want to use the HTTPS configured in nginx, you need to use the port configured for HTTPS in nginx, i.e.
https://example.com:443/api/v1/data_tag
Or simpler, since 443 is the default port for HTTPS:
https://example.com/api/v1/data_tag
example.com in this case is the placeholder for your domain which is configured for your server and inside the certificate.

Force nginx reverse proxy to resolve AAAA record only (and ignore A record) of a domain?

I am trying to use nginx on my VPS (mydoamin.com with A and AAAA record) with public static IP address (both IPv4 and IPv6) to create an IPv4-to-IPv6 proxy to make a IPv6-only home server reachable from normal IPv4 networks. The A record of the domain points to the nginx server and AAAA record to the IPv6-only home server directly.
My current nginx server block looks like this:
server {
listen 443 ssl http2;
server_name mydomain.com;
ssl_certificate /etc/letsencrypt/live/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/key.pem;
ssl_trusted_certificate /etc/letsencrypt/live/ca.pem;
location / {
proxy_pass https://[IPv6 address of the home server];
proxy_set_header Host $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;
}
}
So far the proxy works quite good and all traffic via mydomain.com from IPv4 will be proxied by nginx but I am wondering is there a way to use the domain instead of the IPv6 address in the proxy_pass while nginx will only resolve its AAAA record? Many thanks in advance!

How to proxy pass from url path to different subdomain on different dns server?

Let's say I have my main domain on one server and one of the subdomains to another server.
both of these addresses are using Cloudflare DNS to different ip addresses, so:
example.com => ip1
new.example.com => ip2
Now I want to proxy_pass a certain path on example.com to new.example.com without changing the url, so:
example.com/something should show content of new.example.com/somethingElse
These are my nginx config files, the problem is if I point example.com/something to google.com or even an ngrok server that I hosted for test, everything works just fine, but when I point it to new.example.com/something it gives me 502 error, so my guess is there's something wrong with my new.example.com config.
example.com Config:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl on;
ssl_certificate /etc/letsencrypt/live/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/key.pem;
server_name example.com www.example.com;
resolver 8.8.8.8;
location = /something {
proxy_set_header X-Forwarded-Host new.example.com;
proxy_set_header Host new.example.com;
proxy_pass https://new.example.com/somethingElse;
}
}
new.example.com Config:
server {
listen 443;
server_name www.new.example.com new.example.com;
ssl_certificate /etc/ssl/private/cert.pem;
ssl_certificate_key /etc/ssl/private/key.pem;
location / {
proxy_pass http://container-name:80;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Please test the connectivity between the servers. Login into example.com server and send CURL request to the new.example.com service.
Looks like example.com server is not able to reach new.example.com server.
Please check nginx service logs.
Another option to achieve your requirements is cloudflare worker service.

Nginx proxying 1935 to a subdirectory path?

I have Ant Media Server running. It typically runs on the standard RTMP port 1935. I've changed Ant to 11935 (works currently), and I want nginx to recieve 1935 and re-route it to 11935 (with a subdir).
So instead of streaming to rtmp://server.com/LiveApp/[key] you can stream to rtmp://server.com/[key]
nginx.conf
stream {
server {
listen 1935;
proxy_pass 127.0.0.1:11935;
proxy_buffer_size 32k;
}
}
sudo ufw status
1935/tcp ALLOW Anywhere
1935/tcp (v6) ALLOW Anywhere (v6)
This works currently. I can stream to rtmp://server.com/LiveApp/[key] and it's fine. But now I want to proxy rtmp://server.com/[key] -> rtmp://server.com:11935/LiveApp/[key]
My (failed) attempt at adding it as an http proxy:
server {
listen 1935;
server_name _;
location ~/(.*)$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass localhost:11935/LiveApp/$1;
}
}

Nginx upstream and listen of the same port

I have configured nginx on an EC2 instance.
I am running rabbitmq-management which is running on port 15672 and is accessible using the IP address of the instance.
http://ip-address:15672
I do not want to allow access using the IP address and want to use my domain but using the same port as
http://utils.example.com:15672
For that, I tried to configure the nginx server with configuration
upstream rabbitmq_server {
server localhost:15672;
}
server {
listen 15672 ssl;
server_name utils.example.com;
location / {
proxy_pass http://rabbitmq_server/;
proxy_redirect off;
proxy_set_header Host $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-Protocol $scheme;
}
}
But, this is giving error on starting the nginx server as
[emerg] 7476#7476: bind() to 0.0.0.0:15672 failed (98: Address already in use)
When I change the port to listen 15673, it works and is accessible using the domain also but is accessible using the IP address also.
How can I use the same internal IP on which application is running to be accessible from http://utils.example.com?
How can I disable direct access from the IP address and restrict access to domain/sub-domain only?
You could use an IF and check the $host variable inside the location, you can find the IF guide for nginx here
https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/
Result would be similar to this one
upstream rabbitmq_server {
server localhost:15672;
}
server {
listen 15672 ssl;
server_name utils.example.com;
location / {
if ($host = utils.example.com) {
proxy_pass http://rabbitmq_server/;
proxy_redirect off;
proxy_set_header Host $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-Protocol $scheme;
}
}
}
1)How can I use the same internal IP on which application is running to be accessible from http://utils.example.com?
You can't have those 2 applicacions (nginx and rabbit) listening to the same port.
sending a petition to ip: http://utils.example.com:15672 and http://ip:15672 is the same (not exactly, but for the example it will work).
My recomendation:
Change rabbitmq port to another one, lets say 15673. and set the nginx config like this:
upstream rabbitmq_server {
server localhost:15673;
}
server {
listen 15672 ssl;
server_name utils.example.com your_ip_numbers;
location / {
proxy_pass http://rabbitmq_server/;
proxy_redirect off;
proxy_set_header Host $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-Protocol $scheme;
}
}
Like this, both your_ip:15672 and utils.example.com:15672 will go through nginx to be proxied to rabbitmq.
2) How can I disable direct access from the IP address and restrict access to domain/sub-domain only?
Take out "your_ip_numbers" from the server_name directive if you are going to use the recomendation and block any access to port 15673 in the firewall. Localhost proxies are not considered as a normal connection by most firewalls.
And if you only have proxy to rabbitmq to the server bracket of server_name utils.example.com; that's already a way to filter only this subdomain connections to rabbitmq.
If I have not expressed myself correctly, ask me in the comments what I'm refering to, I'd be glad to answer
Edit:
For the ip not to be proxy_passed, creating another default_server bracket in the same port (it's nginx so they don't collide) will send the ip there.
server {
listen 15672 ssl default_server;
server_name _;
return 418; #(or really any code you like)
}
Hope I helped.

Resources