Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Subscribe to our newsletter

Advertise on LowEndTalk.com

Latest LowEndBox Offers

    Nginx: proxy forwarding other ports than 80 (e.g. 22)
    New on LowEndTalk? Please read our 'Community Rules' by clicking on it in the right menu!

    Nginx: proxy forwarding other ports than 80 (e.g. 22)

    jvnadrjvnadr Member
    edited September 2015 in Help

    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

    • If a program actually fits in memory and has enough disk space, it is guaranteed to crash.
    • If such a program has not crashed yet, it is waiting for a critical moment before it crashes.

    Comments

    • One port, one listening socket.

    • jvnadrjvnadr Member
      edited September 2015

      @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)

      • If a program actually fits in memory and has enough disk space, it is guaranteed to crash.
      • If such a program has not crashed yet, it is waiting for a critical moment before it crashes.

    • 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?

      • If a program actually fits in memory and has enough disk space, it is guaranteed to crash.
      • If such a program has not crashed yet, it is waiting for a critical moment before it crashes.

    • 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?

      • If a program actually fits in memory and has enough disk space, it is guaranteed to crash.
      • If such a program has not crashed yet, it is waiting for a critical moment before it crashes.

    • mikhomikho Member, Provider

      Haproxy?

      Thanked by 1deadbeef
      Get a LES NAT VPS! (or 10) in United States (3), Germany, Bulgaria, France, Norway, Australia (2), Singapore. | -> 500gb NAT Storage
    • perennateperennate Member, Provider
      edited September 2015

      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.

      Thanked by 1ucxo
    • @mikho said:
      Haproxy?

      +1

    • mikho said: Haproxy?

      I am not familiar at all with haproxy, but I should definitely start searching it a bit!

      • If a program actually fits in memory and has enough disk space, it is guaranteed to crash.
      • If such a program has not crashed yet, it is waiting for a critical moment before it crashes.

    • perennateperennate Member, Provider

      The section relevant to SSH is just this:

      backend foo_bk_ssh
              mode tcp
              option tcplog
      
              # add a nice, long timeout
              # (so that the ssh client doesn't get disconnected every few minutes)
              timeout server 2h
              server foo_srv_ssh 127.0.0.1:22

      So it's just passing SSH connections to a single SSH server.

    • mikhomikho Member, Provider

      Dispatching connections to different backends depending on the hostname which the client connected to is impossible to do on the TCP layer.

      Sorry, was thinking of a regular HTTP connection.

      Get a LES NAT VPS! (or 10) in United States (3), Germany, Bulgaria, France, Norway, Australia (2), Singapore. | -> 500gb NAT Storage
    • ClouviderClouvider Member, Provider

      Or iptables forwarding perhaps.

      Thanked by 1doghouch

      Clouvider Leading UK Cloud Hosting solution provider || UK Dedicated Servers Sale || Tasty KVM Slices || Latest LET Offer

      Web hosting in Cloud | SSD & SAS True Cloud VPS on OnApp | Private Cloud | Dedicated Servers | Colocation | Managed Services

    • jvnadrjvnadr Member
      edited September 2015

      Clouvider said: 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).

      • If a program actually fits in memory and has enough disk space, it is guaranteed to crash.
      • If such a program has not crashed yet, it is waiting for a critical moment before it crashes.

    • perennate said: Not possible

      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?

      • If a program actually fits in memory and has enough disk space, it is guaranteed to crash.
      • If such a program has not crashed yet, it is waiting for a critical moment before it crashes.

    • perennateperennate Member, Provider
      edited September 2015

      jvnadr said: 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.

      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.

    • perennate said: What do you mean?

      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! :)

      • If a program actually fits in memory and has enough disk space, it is guaranteed to crash.
      • If such a program has not crashed yet, it is waiting for a critical moment before it crashes.

    • perennateperennate Member, Provider
      edited September 2015

      jvnadr said: 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.

      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].

      Thanked by 1jvnadr
    • ServercowServercow Member, Provider

      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...

      Thanked by 2deadbeef jvnadr

      mailcow - your self hosted mail server solution

      Servercow - looking for a great vps for mailcow? - servercow.de

    • 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.

    • BochiBochi Member
      edited September 2015

      This pretty much reminds of this: http://www.lowendtalk.com/discussion/comment/1165606/ :D
      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.

      Thanked by 1jvnadr
      How many stars in your bowl? How many sorrows in your soul?
    • @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!

      Thanked by 2jvnadr mikho

      Have an Allwinner H3 device? Android? Check out H3Droid! | Lichee Pi Zero - The 6$ SBC | #SYSarm - Get It! | Atomic Pi - $35 x86 SBC
      20+ Years IT Experience in Linux/Windows Hosting, Administration and Development

    • doghouchdoghouch Member
      edited September 2015

      @Clouvider said:
      Or iptables forwarding perhaps.

      Let me help with that:

      iptables -t nat -A PREROUTING -d (other IP):22 dport 22 -j DNAT --to-destination 192.168.1.50
      
      iptables -t nat -A POSTROUTING -o venet0 -j MASQUERADE
      
      service iptables save
      

      You get the idea (if you're not using OpenVZ, change the ethernet adapter accordingly) :)

    • jvnadrjvnadr Member
      edited September 2015

      doghouch said: Let me help with that:

      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.

      • If a program actually fits in memory and has enough disk space, it is guaranteed to crash.
      • If such a program has not crashed yet, it is waiting for a critical moment before it crashes.

    • ServercowServercow Member, Provider

      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.

      Thanked by 1jvnadr

      mailcow - your self hosted mail server solution

      Servercow - looking for a great vps for mailcow? - servercow.de

    • doghouchdoghouch Member
      edited September 2015

      @jvnadr said:
      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.

      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."

      Thanked by 1jvnadr
    • 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 :p

    Sign In or Register to comment.