Is it possible to send webhook through NGINX proxy - docker

I have a setup where i can access to my docker containers through nginx proxy. All containers are in internal network and does not have access to the internet.
Now I need to send webhook to slack from my docker container. In container i edited file "/etc/hosts", just added a record to my proxy, which is similiar to hooks.slack.com. I did this, because container sending request to proxy, after that proxy get it and redirects to the internet original hooks.slack.com.
server {
listen 80;
server_name hooks.slack.com;
return 301 https://hooks.slack.com$reques_uri;
}
When i am testing this by CURL from my docker container i get answer 301 and nothing happened, no message delivered to slack.
SOLVED:
Needed to add this intead of my actual setup.
server {
listen 80;
server_name hooks.slack.com
location / {
proxy_pass https://hooks.slack.com;
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
}
}

Use proxy_pass instead of 301 redirect
server {
listen 80;
server_name hooks.slack.com;
location / {
proxy_pass https://hooks.slack.com;
}
}

Related

How to access local backend services to a deployed Web app using nginx?

I'm deploying some services using Docker, with docker-compose and a nginx container to proxy to my domain.
I have already deployed the frontend app, and it is accessible from the web. Supposedly, I only need to expose the frontend/nginx port to the web, without me needing to expose the rest of the services. But I'm not able to do that for now.
For example, Client -> Login Request -> frontend <-> (local) Backend get request.
Right now, I'm getting connection refused, and the get is pointing to http://localhost, and not the name of the service defined in docker-compose. (all containers are deployed on the same network, one that I have created)
What do I need to do to configure this?
Here is my nginx config so far:
server {
listen 80 default_server;
listen 443 ssl;
server_name mydomain;
ssl_certificate /etc/letsencrypt/live/mydomain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mydomain/privkey.pem;
location / {
proxy_pass http://frontend:3000/;
}
location /auth {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://auth:3003;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
# Same for the other services
(...)
EDIT:
Should I create a location for every get and post that I have for my services?
As:
location getUser/ {
proxy_pass http://auth:3003;
}

NGINX reverse proxy not forwarding the request hostname to docker container

Problem:
We've setup a docker container running on port 3002 and then configured port 3002 to /path/ on my domain www.example.com. There's an express rest api is running on 3002 port container which outputs the req.hostname and when I make a request from let's say www.abc.com, the consoled value of req.hostname is shown to be www.example.com instead of www.abc.com.
Nginx Conf
server {
listen 443 ssl;
ssl_certificate /etc/ssl/__abc.crt;
ssl_certificate_key /etc/ssl/abc.key;
listen 80 default_server;
listen [::]:80 default_server;
location / {
proxy_pass http://localhost:3001/;
proxy_set_header Host $host;
}
location /path/ {
proxy_pass http://localhost:3002/;
proxy_set_header Host $http_host;
}
}
What changes do I have to make so I can get the www.abc.com in consoled value?
Nginx's location blocks should be ordered such that more specific expressions come first.
In your example, you should have:
location /path/ {
proxy_pass http://localhost:3002/;
proxy_set_header Host $http_host;
}
location / {
proxy_pass http://localhost:3001/;
proxy_set_header Host $host;
}
Make sure your changes take effect by either running nginx -s reload or restarting the container

Nginx redirect https->http(reverse proxy)->port(docker container)

Context
Simple setup
A docker container exposing 8090 as a website (node, express)
A nginx conf exposing 80 and mapping it to localhost 8090
Issue
I don't have paid SSL certificate, I want end users that try to reach https to be redirected to http.
I have tried redirects, rewrite, and here below a simple listen.. without success. Browser would return 'ERR_SSL_PROTOCOL_ERROR'.
server {
listen 80;
listen 443;
ssl off;
server_name xxxx.com;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass "http://0.0.0.0:8090";
}
}
Question
Could you please advise on the cleanest way to redirect https->http(reverse proxy) ? Regards
Edit 1
The following config results in a browser "ERR_SSL_PROTOCOL_ERROR".
server {
listen 80;
server_name xxxx.com;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass "http://0.0.0.0:8090";
}
}
server {
listen 443;
server_name xxxx.com;
rewrite ^(.*) http://$host$1 permanent;
}
Using letsencrypt to get a free certificate and then either use https or redirect to http was the solution for me.
Credits to #RichardSmith
You can try to use TCP restreaming by ngx_stream_core_module
http://nginx.org/en/docs/stream/ngx_stream_core_module.html
stream {
server {
listen 443;
proxy_pass 127.0.0.1:80;
}
}

Why is my Nginx reverse proxy doing a 301 redirect instead of proxying?

I have an Nginx reverse proxy inside a docker container, which listens to port 3000 and is exposed to 3002: docker run -p "3002:3000" ....
The idea is that this reverse proxy will proxy /my-app to the instance running in my laptop on port 8080; and /my-app/api to the cloud instance, in https://my-domain.
Here's the configuration:
upstream my-laptop {
server host.docker.internal:8080; # this is a magic hostname for the laptop's IP address.
keepalive 64;
}
upstream cloud {
server my-domain.com:443;
keepalive 64;
}
server {
listen 3000;
include ssl/ssl-certs.conf;
include ssl/ssl-params.conf;
location /my-app {
proxy_pass http://my-laptop;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /my-app/api {
proxy_pass https://cloud;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
...
}
The issues are:
when I hit https://localhost:3002/my-app I get a 301 response to /my-app/ (trailing slash). I don't know why is that. The local app instance is shown in the browser, so I guess I can let it slide for the moment?
when I hit https://localhost:3002/my-app/api/students, I get a 301 response to https://cloud/my-app/api/students. This causes CORS issues, of course, and the endpoint doesn't return data.
Now, I have configured reverse proxies a couple of times, so I am completely shocked that I'm not seeing what's wrong, this is not my first time.
I have tried tweaking with the upstreams, the proxy_set_headers, compared with another reverse proxy that I have for a different app; I'm out of ideas.
What am I doing wrong?
Although the questioner's config doesn't have this particular issue, a redirect instead of proxying can also be caused by trailing slash issues, as described in the docs:
If a location is defined by a prefix string that ends with the slash character, and requests are processed by one of proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, or grpc_pass, then the special processing is performed. In response to a request with URI equal to this string, but without the trailing slash, a permanent redirect with the code 301 will be returned to the requested URI with the slash appended. If this is not desired, an exact match of the URI and location could be defined like this:
location /user/ {
proxy_pass http://user.example.com;
}
location = /user {
proxy_pass http://login.example.com;
}
The problem was my Host header in the cloud upstream, I had
proxy_set_header Host $http_host;
But it needed to be
proxy_set_header Host my-domain.com;
here is an example config for nginx as a reverse proxy which works for me,
I simplified it and removed unnecessary parts.
I hope it helps.
upstream OAUTH {
server remote_oauth;
}
server {
listen 80;
server_name example.com;
client_header_timeout 300;
location = /servies/oauth {
return 301 /services/oauth/;
}
location /services/oauth/ {
proxy_pass_request_headers on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://OAUTH/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-ROOT-URI /services/oauth;
proxy_set_header Accept-Encoding "gzip";
proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_intercept_errors on;
proxy_redirect default;
client_max_body_size 4M;
}
}
I think you missed this part :
proxy_pass_request_headers on

Nginx Config for IP Address URL

I wish to setup my URL like this https://IP_ADDRESS/. I have already setup rails and puma and I'm struggling with the Nginx config. My server is on Ubuntu 16.04.
/etc/nginx/sites-available/default :
upstream app-name-production-backend {
server unix:///home/rails/apps/app-name/production/shared/sockets/puma.sock;
}
server {
listen 80;
listen [::]:80 ipv6only=on;
root /home/rails/apps/app-name/production/current/public/;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://app-name-production-backend;
break;
}
}
}
Is my Nginx config correct?
So, the issue I was having is that I had the force_ssl statement in the application_controller.rb, this was forcing everything through https (port 443) and not serving anything through http (port 80) and because port 443 was not configured and I didn't have any SSL certificates in place it was displaying the This site can’t be reached (on chrome) message.

Resources