New on LowEndTalk? Please Register and read our Community Rules.
All new Registrations are manually reviewed and approved, so a short delay after registration may occur before your account becomes active.
All new Registrations are manually reviewed and approved, so a short delay after registration may occur before your account becomes active.
Nginx: proxy forwarding other ports than 80 (e.g. 22)
Need some help:
Is it possible to use nginx as proxy forwarding for NAT vps, to other ports than 80? For example, is it possible to configure in sites-enabled, a route that listens to port 22 for specific domain (e.g. example.com) and forwards it to an internal ip (e.g. 192.168.1.50)?
How can this be done without conflicting with ssh listening server on the main node? (getting error nginx: [emerg] bind() to 0.0.0.0:22 failed (98: Address already in use)
)
Or mail ports to be used as a normal mail server to a NAT vps.
Thank you
Comments
One port, one listening socket.
@deadbeef Yes, but how to use ports that are already used by the host node? Port 22 is being used for ssh the main node and port 25, for example, for the main mail service of the node. What if I want nginx listen to those ports only to forward any request to a specific domain (that is what I want to do)
Unless you stop the ssh server from listening to 22, nginx can not listen to it at the same time. Perhaps I am misunderstanding what you are saying.
@deadbeef No, that's what I'm asking. If there is a way nginx listens for a port only for specific domain requests. So, only way is to do that is changing ssh port to the main node (something that in any case should be done), so, port 22 is free to be forwarded by nginx to the virtual machines. Is that right?
Ah, no. Nginx listens to a port and then based on rules (one of which the server name) does or doesn't do something with a given connection. It can't forward that connection to ssh/mail as far as I know.
@deadbeef So, is there a way to forward ports for ssh/mail to a virtual machine by domain request to the main note? I mean, as example.com is redirecting to the internal ip 192.168.1.50 from port 80 to port 80, the same way a ssh request to example com redirecting this request to the internal ip and port 22?
Haproxy?
Not possible.
http://serverfault.com/questions/34552/is-there-a-name-based-virtual-host-ssh-reverse-proxy
It says hostname used by client to connect is not sent in the SSH protocol.
As suggested in the link above, what you could do is give them a username/password (or keypair) to login to a locked down shell (ideally not full OpenSSH server) in a gateway server from which they can login to their VPS on the internal interface. If you do it well, you can even make it make the connection to internal VPS automatically.
+1
I'm not sure, look at this guy: https://coolaj86.com/articles/adventures-in-haproxy-tcp-tls-https-ssh-openvpn/
I am not familiar at all with haproxy, but I should definitely start searching it a bit!
The section relevant to SSH is just this:
So it's just passing SSH connections to a single SSH server.
Sorry, was thinking of a regular HTTP connection.
Or iptables forwarding perhaps.
I would like this be done via domain name, not ip tables (I already forward ports to the internal virtual machine).
So, nginx cannot forward ssh packets only, or it can only forward http/https requests? I mean, can nginx forward mail ports (like 25 etc.) ot it cannot, just like cannot forward ssh port?
What do you mean? It can certainly forward SSH packets using its TCP mode, however SSH protocol does not include transfer of the hostname so it can't sniff the packets to determine which host the connection should go to. The alternative would be to set up the gateway server as mentioned in the Server Fault discussion I linked.
I got that. I'm asking if this can be done with nginx proxy for ports that are be used for mail. Having a virtual machine with the domain name example.com and use nginx proxy to configure a mail server that is working with the domain name, because it's ip is internal (e.g. 192.168.1.50). So incoming and outcoming mails using domain and packets are forwarded correctly to the virtual machine by nginx.
I don't know If I am clear, but I tried!
SMTP with haproxy isn't possible either, the host sends data before the client. Of course SMTP is designed to allow relays, all you need to do is set up Postfix/exim/other mail server on the external IP and configure it to relay based on the recipient domain to various IPs.
In Postfix, you can do this by setting relay_domains to the list of domains, and include transport map that has each domain name mapping to relay:[intenal ip].
Postfix and SMTP is possible - and they are even a perfect team using the PROXY protocol.
I wrote about it in my personal blog: https://goo.gl/AqyLgm (This is a Google tanslated version, the original article is written in German, sorry).
Moreover Nginx can act as a TCP proxy with a plugin: https://goo.gl/OtC8Ze - works great (had no problems with load-balancing multiple IMAP instances).
Whatever... what you want is simple DNAT'ing. But: You cannot use a TCP proxy with SNI (server name indication). Both act on different layers. When you get to know the server name, you passed the TCP relevant layers already. You can use Guacamole or something like that to "proxy" a SSH server. I do not recommend it anyway...
what you want: two servers listening on the same port on the same IP and forwarding based on hostname is possible only for HTTP and HTTPS as far as I know. So, no, you can't do this. Simple solution is to assign more IPs on your host.
This pretty much reminds of this: http://www.lowendtalk.com/discussion/comment/1165606/
And I think this is quite related to this use case...
If you're looking to forward/proxy a general TCP port (i.e, SSH, SMTP, etc) to another server, there's a nginx_tcp_proxy module that can do it. https://github.com/yaoweibin/nginx_tcp_proxy_module
If you are looking for bind http and other services on the same ip:port, the answer is no, at least not with nginx.
@jvnadr What I think you are really looking for here, if I understand what your needing, is sslh. Sslh accepts connections on specified ports, and forwards them further based on tests performed on the first data packet sent by the remote client. Sslh acts as a protocol demultiplexer, or a switchboard. Its name comes from its original function to serve SSH and HTTPS on the same port.
Though I am not sure if this would allow you to have the same ssh port for all vms, but it would allow you to run more than one service on a single port, as in https and openvpn or smtp or ssh, etc.
Hope this helps.
Cheers!
Let me help with that:
You get the idea (if you're not using OpenVZ, change the ethernet adapter accordingly)
Thanks but that's not what I am asking. I (of course) already have port forwarding for accessing the NAT boxes and a nginx reverse proxy to point external domain names directly to the internal vm's ip for http. I want to do forwarding based on the domain thru nginx proxy or other method, for other ports/services (mainly ssh and mail server). So, a request for mail should point to the internal virtual machine's postfix/exim passing thru the proxy to the normal ports (e.g. 25) and not using different ports on the main node.
SNI is not available on that layer. I guess you want simple TCP forwarding (like DNAT above) routed by a name. Like
if server_name ssh.xy.z; then tcp_forward 22;
or something like that.My new post to address your problem: http://pastebin.com/C1tn3NWP
CrapFlare wouldn't let me submit the other one on account of "Possible SQL injection detected, request blocked."
nginx shouldn't work for that. I would try haproxy or iptables forwarding.
Don't use haproxy, it was unreliable in forwarding for me @martinandrino