0

We have a virtual machine with a public IPv4 address, to which our example.com and *.example.com domain points.

We have several distributed low-tech computers establishing a wireguard connection/tunnel with the publicly reachable virtual machine.

We want the virtual machine to serve a website on ports 80/443, accept ssh connections via port 22, and more.

We want the low-tech computers to be publicly reachable, via respective subdomains like low-tech-01.example.com, low-tech-02.example.com, et cetera, and proxying/routing requests to respective local/wireguard IP addresses. This should work for websites via ports 80/443, ssh connections via port 22, and more.

Edit: Idealy, the SSL certificates should be served from the low-tech computers, and the SSL connection should not be terminated on the virtual machine.

Edit: Ideally, the ssh private keys for establishing the connection to the low-tech computers should not exist on the virtual machine, but only on the client.

Edit: For ssh, we could open and route one unique port for each of the low-tech computers from public_IPv4:22xxx to local/wireguard_IP:22

Unfortunately, after spending two days with nginx configuration trial and error, we figured that this task probably cannot be solved by nginx alone.

Note: ssh does not send SNI; nginx cannot listen on the same ports for http as well as stream connections; and maybe more problems.

But also, we’re completely out of ideas and overwhelmed by which approach could indeed properly solve this task.

(www\.)?example.com –> public IPv4 –> website, ssh, etc.

low-tech-01.example.com –> public IPv4 –> ??? ~> 10.0.0.101 –> website, ssh, etc.

low-tech-02.example.com –> public IPv4 –> ??? ~> 10.0.0.102 –> website, ssh, etc.

Thank you for your advice and time.

Edit: The following nginx stream config is close to what we’re trying to achieve. The (maybe) only downside is that we’d have to manually define a port for each low-tech computer instead of having this handled dynamically like for SSL connections.

stream {
  map $ssl_preread_server_name $name {
    example.com example.com;
    www.example.com example.com;
    low-tech-01.example.com low-tech-01.example.com;
    low-tech-02.example.com low-tech-02.example.com;
  }

  upstream example.com {
    server 127.0.0.1:8443;
  }

  upstream low-tech-01.example.com {
    server 10.0.0.101:443;
  }

  upstream low-tech-02.example.com {
    server 10.0.0.102:443;
  }

  server {
    listen 443;
    proxy_pass $name;
    ssl_preread on;
  }

  server {
    listen 22101;
    proxy_pass 10.0.0.101:22;
  }

  server {
    listen 22102;
    proxy_pass 10.0.0.102:22;
  }

  …
}
fooness
  • 1
  • 1
  • Maybe you can use `s_client` command from the client machines when connecting via SSH protocol? Check [this](https://serverfault.com/a/1023845/498657) answer. – Ivan Shatsky Oct 16 '21 at 09:42
  • Have a look at this Q/A to understand the limitation: https://serverfault.com/questions/878080/how-do-i-make-protocol-foo-hostname-aware – A.B Nov 05 '21 at 00:31

1 Answers1

0

You need to get multiple IP addresses on the server, one for each of the subdomains you want to use.

Then you need to assign a public IP address to each VM. After that you can bind the subdomain to the IP address. In the VM, one can do port forwarding to whichever final destination one wants.

Tero Kilkanen
  • 34,499
  • 3
  • 38
  • 58
  • Thank you for you answer. Unfortunately this does not solve the problem. If there were public IPv4 addresses available, then we wouldn’t need the VM to proxy/route the requests. – fooness Oct 14 '21 at 07:20
  • That is the only option for SSH if you want to map domains to different instances. Another option is separate TCP ports for each domain, and then do port forwarding. – Tero Kilkanen Oct 14 '21 at 14:49
  • Separate TCP ports for each domain is what we ended up using for now, yes. We wish, though, that this could happen somehow dynamically instead of manually creating an entry for each port in e.g. our nginx `stream` block. – fooness Oct 14 '21 at 17:56
  • Whatever the mechanism is, you need to manage its configuration somehow. A configuration management system should help with it. – Tero Kilkanen Oct 14 '21 at 19:37