Hacker News new | ask | show | jobs
by vince14 426 days ago
Because projects like these were missing back then, I got creative with nginx and do not need any config changes to serve new projects:

  server {
    listen 80;
    server_name ~^(?<sub>\w+)(\.|-)(?<port>\d+).*; # projectx-20201-127-0-0-1.nip.io
    root sites/$sub/public_html;
    try_files $uri @backend;
    location @backend {
      proxy_pass http://127.0.0.1:$port;
      access_log logs/$sub.access;
    }
  }
Configuration is done via the domain name like projectx-20205-127-0-0-1.nip.io which specifies the directory and port.

All you need to do is create a junction (mklink /J domain folder_path). This maps the domain to a folder.

3 comments

Am I reading this wrong or does this almost open up any server bound to localhost to the outside?

I think proxy_pass will forward traffic even when the root and try_files directives fail because the junction/symlink don't exist? And "listen 80" binds on all interfaces doesn't it, not just on localhost?

Is this clever? Sure. But this is also the thing you forget about in 6 months and then when you install any app that has a localhost web management interface (like syncthing) you've accidentally exposed your entire computer including your ssh keys to the internet.

Nothing is preventing you to add an IP whitelist and/or basic auth to same configuration. That is what I do to all my nginx configurations to be extra careful, so nothing slips by accident.
Will just any request even pass the host matching?
I got something similar running with nginx myself with purpose of getting access to my internal services from outside. The main idea here is that internal services are not on same machine this nginx is running on, so it will pass around to needed server in internal network. It goes like this:

  server_name ~^(?<service>(?:lubelogger|wiki|kibana|zabbix|mail|grafana|git|books|zm))\.domain\.example$;
  location / {
        resolver 127.0.0.1;
        include proxy.conf;
        proxy_set_header Authorization "";
        proxy_set_header Host $service.internal;
        proxy_set_header Origin http://$service.internal;
        proxy_redirect http://$proxy_host/ /;
        proxy_pass http://$service.internal;
  }
Basically any regex matched subdomain is extracted and resolved as $service.internal and proxy passed to it. For this to work, of course any new service has to be registered in internal DNS. Adding whitelisted IPs and basic auth is also a good idea ( which I have, just removed from example ).
That's why I switched to Caddy for most of my needs. I create one Caddy server template, and then instantiate it as a new host with one line per server.