Port forwarding security issue?

I am using pi-hole/unbound with Lighttpd and in order to use LetsEncrypt I have forwarded ports 80 and 43 to my Pi and have ddns access using
myddns.mydomain.com.
All sites are in /var/www/html/ in folders ‘myddns’ ‘localsite’ ’ etc. and access using domain/host name passed address are correct ands secure.

However if you use the direct ip address for myddns.mydomain.com, as the router has port forwarding enabled it accesses the base web /var/www
Consequently if you use the public ip such as xx.xx.xx.xx/html/local/ the local websites can be accessed.
Clearly a security issue.

I must missing something but there must be a way to block this, I just can’t work out how.
Note It is good to see that Pihole is blocked WAN access so it is immune from this back door route.

I know its not strictly a Dietpi issue but thought it would be a good place to start.

In Dietpi the web server root is /var/www and not /var/www/html.
However you can configure lighttpd (the default web server) to serve specific sites/ subfolders of the web root when reached from specific domains and even deni access when reached by the public ip instead of a domain.
Sure you can do the same with nginx and apache.

I will post a config example for lighttpd later, I’m just on mobile right now.

Thanks Jappe. It not always clear when reading on the phone.
I realise the root is /var/www, its just that the specific sites are configured in the html sub flolder, which also happens to be the default for dietpi dashboard and pihole.

I can disable the direct ip access if I were using apache or nginx, but can’t seem to work out to do it in lighttpd which is being used here.

Example config in /etc/lighttpd/lighttpd.conf:

$HTTP["remoteip"] != "192.168.0.0/24" {
   $HTTP["url"] =~ "^/myddns/" {
    url.access-deny = ( "" )
 }
   $HTTP["url"] =~ "^/localsite/" {
    url.access-deny = ( "" )
 }
    $HTTP["url"] =~ "^/specificFile.php" {
    url.access-deny = ( "" )
 }

 }

First of all you have to use the module mod_access to use this. I’m not sure if it is enabled by default.

Explanation: IPs which do not (!=) match the range I defined can’t access anything (empty string in url.access-deny means anything) in the sites (subfolders of /var/www) I listed underneath.

Of course you can also use domains instead of IP ranges, and use url.access-allow to allow specific things or allow specific domains / remote IPs (= instead of !=)
More info here: https://redmine.lighttpd.net/projects/1/wiki/Docs_ModAccess

Jappe Thanks again for your help, my understanding of the syntax of the config files is very limited. Never really have to use it - although I.m slowely picking it up.

Based on your suggestions rather than a global solutiion I have set the relevant virtual site folders to only be accessible from the local IP range which gave me the greatest flexibility

You can also block every connection comming in via http://publicIP/something and just allow connections from http://DDNS.domain.com/something.
But your “local” sites are then still accessible via DDNS.domain.com/html/local

So if you want to block public access from the internet for a specific subfolder, use the config mentioned above and change the local IP and the paths to your desire.

If you have a lot of “local” sites and just a few public sites, you can do it the other way around and block every connection from the outside and “whitelist” just the few you want.

It sounds a bit complicated, but if you can specify what you want I can help you with a sample config.

Jappe Thanks again.
As mentioned earlier, I have blocked each local sites each specifically from public access, and that works with the IP address/path access issue.

Add these lines at the end of /etc/lighttpd/lighttpd.conf:

server.modules += ( "mod_access" )

$HTTP["host"] !~ "DDNS.domain.net|192.168.1.1" {
    url.access-deny = ( "" )
  }
 
 $HTTP["remoteip"] != "192.168.1.0/24" {
   $HTTP["url"] =~ "^/html/local/" {
    url.access-deny = ( "" )
 }
}

where you replace DDNS.domain.net with your domain and 192.168.1.1 with the LAN IP of your Raspberry Pi and 192.168.1.0/24 with your LAN IP range. (It’s the same IP as of your Raspberry Pi, but the last digit is .0/24 !)

Now your webserver is only reachable via your domain and from inside your LAN via it’s local IP and /html/local/ is only reachable from inside your LAN.

That is good solution and does exactly what I asked about , thanks
I did not mention, I use Pi-hole and local names rather than IP addresses , unfortunately your solution seems to block access those.
I’m slowly beginning to understand the syntax for the conf files however, looking at the Pihole lighttpd config which blocks any remote access I modified that specificaly for each relevant html/folder.

 
  $HTTP["url"] =~ "^(/html)?/local(/|$)" {
        $HTTP["remoteip"] !~ "^(1(27|92\.168|0|72\.(1[6-9]|2[0-9]|3[0-1]))\.|::1|fe[89ab].:|f[cd]..:)" {
                url.access-deny = ("")
        }
 }

Note FYI it seems the Mod_access module is enabled by default. if you add web server via the dietpi installer .

Interesting, I also use PiHole but I can’t find any config for pihole inside the conf-enabled folder.
Bc of this I can reach it via hostname.
BTW I have enabled “Permit all origins” in PiHole, maybe this is the reason I don’t have this config file :thinking:

But to make hostnames reachable for you, you could just add them:

$HTTP["host"] !~ "DDNS.domain.net|192.168.1.1|host.local|host2.local" {
    url.access-deny = ( "" )
  }

Or even use some RegEx like [a-zA-Z]+[0-9]+.local
Note: In this example I already use the operator !~ instead of != to have RegEx working. (see https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_Configuration)

And I use this handy too to generate regular expressions: https://regex-generator.olafneumann.org.

Edit: OK my guess with the “permit all orgigins” makes no sense, bc this is about from where the DNS request come, and not from where the admin panel is accessed :smiley:

I can’t find any config for pihole inside the > conf-enabled > folder.

Have a look into conf-available :wink:

In your case the config might not be activated but it should be available

ls -la /etc/lighttpd/conf-available/*pihole*

It’s also not there but it can’t be there, because it forgot that I migrated Pihole and unbound and other “network critical” services to another device :rofl:
And sure, when I look into the right device, the config is there and activated :slight_smile: