nginx non http port redirection - nginx

Theres a server in a customer that runs a nginx, a salt master daemon from saltstack and a secret web app that does secret things.
Considerations:
In this scenario, theres only one ip, only one server and multiple DNS records available;
I have nginx running in port 80;
And salt master running in 6453;
A domain.example.com binding to that IP, exposing my nginx 80 port, that points to the secret webapp;
otherdomain.example.com binding to the same IP, exposing my nginx 80 port, that I want to use to proxy salt port.
That customer has a machine in other place, that does need to connect to the salt and the internet connection is provided by a secret organization and they only allow connections to port 80, no negotiation possible.
My question:
Is possible to use nginx to redirect the otherdomain.example.com 80 port to the 6453 port? I tried the following:
server {
listen 80;
server_name otherdomain.example.com;
proxy_pass 127.0.0.1:6453;
}
But that doesn't work as expected. It is possible? There's some way to do this using nginx?
The error I got from log was:
"proxy_pass" directive is not allowed here

proxy_pass needs to be specified within a location context, and is fundamentally a Web Thing. It only comes into play after the web headers are sent and interpreted.
Things like what you're trying to accomplish are commonly done using HAProxy in tcp mode, although there is a tcp proxy module that also does similar things.
However, I don't think you're going to be very successful, as ZMQ does not participate in the protocol (HTTP Host: headers) that easily allows you to tell the web requests apart from the non-web requests (that come in on the same port).
My recommendation is to either find some way to use another port for this, a second IP address, or write a tricky TCP proxier that'll identify incoming HTTP and/or ZMQ connections and transparently forward them to the correct local port.

Related

Running Minecraft server through NGINX - Only ports 80 and 443 available

I've been looking at possible ways to run a Minecraft server behind a reverse proxy on NGINX with a IP/location/to/server (e.g. 127.0.0.1/minecraft-server) connection, but the only information that I've found is to either use a SRV DNS record, or to use a stream proxy (but no further information is included about this possibility, or it does not provide a NGINX location config).
I need to use a NGINX reverse proxy as ports 80 and 443 will be the only ports that will be open externally via our provider (HTTP/S servers only allowed, they can't be used for anything else and the connection will be managed by administrators), and I don't have a domain. I can get one and a SSL certificate if that's all that's needed in order to be able to do this.
I know Minecraft runs on a TCP or UDP connection, and that's part of the reason why this is not an easy task, but since this is the only way I can possibly have future external access to my Minecraft Server (self hosted), I need a way to run the connection through an HTTP reverse proxy.
Is there any way to do this through NGINX or NGINX+other software?
Thank you in advance.

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

Reverse proxy Elasticsearch transport port

In my environment, elasticsearch sits on a server that only has standard ports (80, 443, etc.) open. All the other ports are firewalled off. I currently have a reverse proxy on port 80 that reroutes all the elasticsearch HTTP requests to elasticsearch's http port.
I would also like to reroute TCP requests to elasticsearch's transport port, so that my local client can directly query elasticsearch as a client node. Nginx 1.9.0 recently allowed TCP load balancing, which is what I would like to utilize for this, but I'm having some trouble getting my system to work. Here is my nginx.conf file (removed the HTTP context to isolate the issue):
worker_processes 1;
events {
worker_connections 1024;
}
stream {
server {
listen 80;
proxy_pass 127.0.0.1:9300;
}
}
My client node is set up to talk to mydomain.com:80, so it should ideally be routing all traffic to the internal transport port. However, I am getting a the following exceptions: org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available
Is there something else I need to configure on my client node or the tcp proxy?
EDIT 1:
Some additional information. I changed Elasticsearch's transport port from 9300 to 8030, which is a port that is open. When I correspondingly changed my nginx.conf to proxypass to 127.0.0.1:8030 my local client node started working, and got appropriate responses to my queries.
So the issue seems to be that if I'm proxy pass to an already open port, it works, but if the port is closed (9300), the proxy pass fails. Does anyone know why this would be and how to fix it? I'd prefer to stick to using port 9300 if possible.

Nginx proxy_pass to Minecraft server

I'm trying to run two Minecraft servers on the same machine on two different ports. I want to reference them based on subdomains:
one.example.com -> <minecraft>:25500
two.example.com -> <minecraft>:25501
I have used nginx for things like this before, but it's not working with Minecraft. It's responding with http status 400. Here is a sample from my log:
192.168.0.1 - - [21/Apr/2013:17:25:40 -0700] "\x02<\x00\x0E\x00t\x00h\x00e\x00s\x00a\x00n\x00d\x00y\x00m\x00a\x00n\x001\x002\x003\x00\x1C\x00t\x00e\x00s\x00t\x00.\x00r\x00y\x00a\x00n\x00s\x00a\x00n\x00d\x00y\x00.\x00i\x00s\x00-\x00a\x00-\x00g\x00e\x00e\x00k\x00.\x00c\x00o\x00m\x00\x00c\xDD" 400 173 "-" "-"
Here is my nginx config:
upstream mine1 {
server 127.0.0.1:25500;
}
upstream mine2 {
server 127.0.0.1:25501;
}
server {
listen 25565;
server_name one.example.com;
access_log /var/log/nginx/one.access;
error_log /var/log/nginx/one.error;
location / {
proxy_pass http://mine1;
}
}
server {
listen 25565;
server_name two.example.com;
access_log /var/log/nginx/two.access;
error_log /var/log/nginx/two.error;
location / {
proxy_pass http://mine2;
}
}
If I'm reading this correctly, nginx is responding with 400. My guess is the Minecraft client is not sending valid HTTP headers and Nginx is tossing out the request. But I'm totally at a loss. Any help would be appreciated.
try this in your DNS records
A RECORD
Name one.example.com
Value <server_ip>
TTL 86400
Name two.example.com
Value <server_ip>
TTL 86400
SRV RECORD
Name _minecraft._tcp.one.example.com
Port 25500
Value one.example.com
Name _minecraft._tcp.two.example.com
Port 25501
Value two.example.com
As Dag Nabbit stated, a Minecraft server does not talk http. You would typically do this via NAT. A proxy server needs to know the protocol, because as the name suggests, it acts on behalf of the the client. Nginx knows various protocols, not just http, but Minecraft is not one of them. You can however write a proxy module for this protocol and use the existing nginx infrastructure. Since I'm not familiar with the protocol, I can't comment on the fact that this would have any advantages over NAT.
One thing to note for future readers, while yes nginx does pass connections off as a "proxy" to any server:port listing that is defined though the upstream definition in a socks proxy style of connection. This does not work when nginx itself is listening for HTTP communications. This is simply because nginx is is designed by default as a dead simple static http server.
Any sort of reverse proxing of TCP/UDP connections is more scalable at a lower OSI level (ie layer 3 or layer 2 instead of layer 6/7 as nginx is operating at). This is where Source and Destination NATs come into play which is better handled by a firewall or routing policy directive of your edge device.
DNS-RR is not the best solution as this, while yes lower level OSI layering, is only viable if the end applications (layer 7 OSI) understand the method. Minecraft (or just about any game server) at last check did not have this built into the game's networking code.
Now I did look into this and there is a few solutions for minecraft itself that one should look further into:
Transporter plugin
BungeeCord
Be sure to read all the documentation as these are very complex to configure and install. Hench the recommendation to just use NAT-ed network topology instead.
I tried to setup my multiple minecraft instances with SRV but that also doesn't work
nslookup of my srv records show:
C:\Users\Administrator>nslookup -type=SRV _minecraft._tcp.xxx.net
Server: mijnmodem.kpn
Address: 192.168.1.1
Non-authoritative answer:
_minecraft._tcp.xxx.net SRV service location:
priority = 5
weight = 5
port = 25565
svr hostname = camelot.xxx.net
_minecraft._tcp.xxx.net SRV service location:
priority = 5
weight = 5
port = 25566
svr hostname = cityworld.xxx.net
On my router(ZTE H369) port 25565 and 25566 are straight forwarded (TCP and UDP) to the IP wher the instances run. Accessing the urls (in Minecraft) gives io.netty.channel.Abstart$AnnotatedConnectException
Any suggestions how to investigate further?

How to use nginx or apache to process tcp inbound traffic and redirect to specific php processor?

This is the main idea, I want to use NGINX or Apache webservers as a tcp processor, so they manage all threads and connections and client sockets, all packets received from a port, lets say, port 9000 will be redirected to a program made on php or python, and that program will process each request, storing the data in a database. The big problem is also that this program needs to send data to the client or socket that is currently connecting to the NGINX or Apache server, I've been told that I should do something like this instead of creating my own TCP server, which is too difficult and is very hard to maintain since the socket communication with huge loads could lead in memory faults or even could crash down the server. I have done it before, and in fact the server crashed.
Any ideas how to achieve this ??
thanks.
apache/ nginx is web server and could be used to provide static content service to your cusomter and forwarding the application service requests to other application servers.
i only knows about django and here is sample configuration of nginx from Configuration for Django, Apache and Nginx
location / {
# proxy / requests to apache running django on port 8081
proxy_pass http://127.0.0.1:8081/;
proxy_redirect off;
}
location /media/ {
# serve static media directly from nginx
root /srv/anuva_project/www/;
expires 30d;
break;
}
Based on this configuration, the nginx access local static data for url under /media/*
and forward requests to django server located at localhost port 8018.
I have the feeling HAProxy is certainly a tool better suited for your needs, which have to do with TCP and not HTTP apparently. You should at least give it a try.

Resources