how to connect nginx, 3scale and opendaylight controller? - nginx

I am using an Ubuntu machine with an Ubuntu guest OS. On the guest OS, I ran my OpenDaylight controller, making the topologies with Mininet and viewing them in the OpenDaylight GUI at localhost:8080. Next, I used Postman REST API Client extension on my Chrome Browser to make a GET request to my ODL Controller:
localhost:8080/restconf/operational/opendaylight-inventory:nodes/
I got the proper response to it in XML format. Now, I have to pass my request through NGINX proxy to 3Scale and get authentication using the app_id and app_key parameters. The request is then to be forwarded to the ODL controller so that I gan get the proper response.
I have already downloaded the proxy config files from NGINX. What modifications must be made in these files? What should be the request I enter in the Postman Client to get the same response as before?

You should only need to change the location of the nginx_.lua file in nginx_.conf
If you want to change the port that Nginx listens on, you will also need to change the listen directive in the server block, to your desired port e.g
server {
lua_code_cache off;
listen 81;
Also, you will need to ensure that there is an upstream block for your backend, e.g
upstream backend_localhost {
server localhost:8080 max_fails=5 fail_timeout=30;
}
but if you have entered this in the proxy configuration wizard that should already be there.
That should be all that you need to change/check.
The request in Postman should target Nginx instead of the ODL Controller, and pass in the application credentials e.g if Nginx is running on port 81
localhost:81/restconf/operational/opendaylight-inventory:nodes/?app_id=<YOUR_APP_ID>&app_key=<YOUR_APP_KEY>
Hopefully that should clear up any doubts. However, you can always email us at support#3scale.net if you have any further questions or add any comments here.

Related

asp.net header forwarding not working for external Identity provider

I use asp.net Identity with AzureAD as an external Identity provider in my Balzor server side app. In development environment (localhost) logging in works fine. When I deploy the app to an on premise server in a docker image behind Nginx, it does not. Microsoft sends the error message AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application. I have added the proper reply URL to Azure portal. As far as I can tell, the request uses http, while https should be used, which causes the error.
Since Nginx handles secure transport, the headers need to be forwarded, so I configured Nginx and enabled Header forwarding in Startup.ConfigureServices:
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
options.ForwardLimit = 1;
options.KnownProxies.Add(IPAddress.Parse("123.xxx.xxx.xxx"));
});
and at the very beginning of Startup.Configure:
app.UseForwardedHeaders();
app.UseHsts();
// should not be necessary but I tried with and without
//app.UseHttpsRedirection();
When I enable logging, I think I see that the correct header is forwarded from Nginx:
...
Header: X-Forwarded-For: 123.xxx.xxx.xxx
Header: X-Forwarded-Proto: https
...
To me it looks like ChallengeResult() in ExternalLogin.Post is not using the forwarded headers and sends http://my.domain.ch/signin-oidc instead of https:// as reply URL, which causes the error.
I ran out of ideas what else I could try, any suggestions please?
After some digging I found the mistake: I did add the wrong proxy IP. Since my asp.net app is hosted on docker, I had to add the IP address of the docker image as proxy, not the IP of the server which hosts nginx and docker. In fact, I added the default network used by docker
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("172.17.0.0"), 16));

Allow access to kafka via nginx

Good day,
I want to connect to my kafka server from the internet. Kafka installed on the virtual server and all servers hidden behind a nginx.
I updated kafka settings (server.properties).
Added: listeners=PLAINTEXT://:9092
I can connect to kafka server from local network via ip address 10.0.0.1:9092, but unable connect from internet by domain name.
Response from kafka: java.util.concurrent.ExecutionException: org.apache.kafka.common.errors.TimeoutException: Topic test-topic not present in metadata after 60000 ms.
Nginx: [26/Nov/2019:12:38:25 +0100] "\x00\x00\x00\x14\x00\x12\x00\x02\x00\x00\x00\x00\x00" 400 166 "-" "-" "request_time=1.535" "upstream_response_time=-" "upstream_connect_time=-" "upstream_header_time=-"
nginx conf:
server {
listen 9092;
server_name site.name;
# Max Request size
client_max_body_size 20m;
location / {
proxy_pass http://10.0.0.1:9092;
}
}
Does anyone know what the problem is?
Kafka doesn't use http protocol for communication, so it can't be fronted by an HTTP reverse proxy.
You'll have to use nginx stream definition blocks for TCP proxying
(I've not tried this personally)
https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-udp-load-balancer/
unable connect from internet by domain name.
Sounds like an issue with your advertised.listeners configuration. Note that there is no clear way to "hide" Kafka behind a proxy since your clients are required to communicate directly with each broker individually (therefore defeating the purpose of having
Ngnix unless you want to use one Nginx server or open a new port, per broker), and would therefore also require Kafka to know that it would need to "advertise" the proxy rather than its own address.
If you really want to expose Kafka to the public web, you should really be using SSL/SASL listeners, not PLAINTEXT
If you want to use HTTP, then you can install Kafka REST Proxy, then put Nginx in front of that. Then your clients would use http rather than standard kafka libraries

NGINX Forwarding a request

I have an NGINX Server set up, I'd like to take a request and forward it to another application on a TCP port.
Let's say I have the following JSON payload
{
"someKey1": 1234,
"someKey2": "a string"
}
This is sent inside query parameters like the following
https://mywebsite.com?payload=%7B%0A%20%22someKey1%22%3A%201234%2C%0A%20%22someKey2%22%3A%20%22a%20string%22%0A%7D
Is there a way to forward that JSON payload to TCP port 1234 natively with NGINX?
Additionally, can I do any pre-processing of the above payload prior to it being forwarded to TCP port 1234. For example, I'd like to covert the above JSON to
someKey1=1234,someKey2="a string"
And then forward this data to TCP port 1234
I understang I'd have to create some sort of REST endpoint using something like springboot to do this, but I'd really like to try and accomplish the above natively with NGINX if possible.
Nginx's primary purpose is HTTP server/proxy.
It can be scripted via ngx_http_lua_module, but for your task it is much simpler to make an app/microservice that will listen HTTP and forward your custom protocol, or modify your app that listens mentioned port to understand HTTP.
When your endpoint talks HTTP - nginx can then be used for routing:
location /some_path/ {
proxy_pass http://localhost:1234/;
}
location /some_other_path/ {
proxy_pass http://localhost:1235/;
}
NGINX is simple web-server, which accepts HTTP requests and forwards them to configured location (may be application server, or any other web-server), and responds back on HTTP to the requester. Data can't be processed inside NGINX.
You can configure forwarding rules in default file under sites-available directory in NGINX installation directory.
Here is the nice tutorial of NGINX configuration which might help you.

Nginx as TCP forward proxy

I know I could use some like this:
stream {
upstream ssh {
server X.X.X.X:22;
}
server {
listen 2222;
proxy_pass ssh;
}
}
to proxy pass incoming traffic to port 2222 to another IP's port 22.
Straightforward. But, is there a way to create a dynamic proxy that accepts final destination's hostname and port as parameters?
Something that could be used like this:
proxy_hostname:8080?destination_hostname=example.com&destination_port=1111
ngx_stream_core_module does not accept url parameters. Could nginx be used as a dymanic proxy or only for static tunneling?
I'm asking this because I need a way to hide the IP of a machine firing php mysql requests.
mysqli_connect($hostname, ...)
right now I cannot specify a proxy for the php script alone, only for the entire machine.
Maybe with a small script and fcgiwrap:
https://www.nginx.com/resources/wiki/start/topics/examples/fcgiwrap/
fcgiwrap calls a bash script where you can convert the URI to the program you want to call (mysql) and return the output to nginx as web content.
You could also alter the config of nginx and reload the service. This way you could "dynamicly" open/forward ports. Quite insecure if you make it publicly available.

Https communication on localhost in IIS using self-signed certificate

I have 2 sites running on the same machine, a client and an API.
Let's say the computer's IP is 10.10.10.10.
The API has a default page when you browse to it, the rest of the API is under 10.10.10.10/api.
The API has HTTP binding to port 80, and HTTPS binding to port 443.
The client has HTTP binding to port 8080, and HTTPS binding to port 64300.
Both HTTPS bindings use a self signed certificate I created via IIS manager.
Both sites have a HTTP to HTTPS redirect using "URL Rewrite".
When I try to browse either one of the apps, it works fine (gives the warning in the browser that you can skip).
When I do some action in the client which involves a HTTP request to the api using one of the following calls I get an error:
http://localhost/api/someMethod
http://localhost:80/api/someMethod
https://localhost/api/someMethod
https://localhost:443/api/someMethod
https://10.10.10.10/api/someMethod
The exception includes this error:
"The remote certificate is invalid according to the validation procedure"
I tried using the method described in this link (add the self-signed certificate to the Trusted Root Certificate Authorities folder) but it won't work.
Help please :D
found the answer.. posting if anyone else will get stuck on it.
It's pretty weird but the only thing that worked was to make the localhost http(s) request using the HOST NAME.
example:
https://the_name_of_the_computer:443/api/someMethod

Resources