The best way is probably to use nginx on your router as a reverse proxy.
But it will only work for http, I don't think it's possible for ftp or even https.
When for example a ftp clients connects it connects to an IP-address and a port, there is no way to know what hostname the client used to get the IP-address. With http the client (normally today) includes the hostname in the request, with https the connection is encryted so I'm not sure it works as you want to. It will have to be nginx that provides the SSL encryption if it is going to be able to intercept the hostname from the request.