2

Just wondering if SNI is useful in segregating public content from private content. I managed to configure our server to serve /foo for every client but serve /bar only for clients from the intranet, by specifying the host name that is resolved only from intranet.

So the config goes like: (stripped to very essential part)

NameVirtualHost *:443
# JkWorkersFile must be global so including it here
JkWorkersFile workers.properties

<VirtualHost *:443>
  ServerName public.foo.com
  JkMountFile uriworkermap-pub.properties
</VirtualHost>

<VirtualHost *:443>
  ServerName private-foo
  JkMountFile uriworkermap-priv.properties
</VirtualHost>

<VirtualHost *:443>
  ServerName 10.1.2.3
  JkMountFile uriworkermap-priv.properties
</VirtualHost>

The catch is, if you add that name into your hosts file to resolve to the public IP then SNI will actually resolve handle it the same way as if it were a valid request from the intranet.

I played around the thoughts of using only numeric IP instead of names (e.g. 10.1.2.3) but I presume the same can be tricked if the client has the same IP in their own subnet (e.g. a Linux host that forwards ports to the public IP of my web server.

The node sits behind a firewall on which I don't have influence. It has only one IP (the internal one) but if needed I can probably make it two.

Practical question is: how do you prevent such a leak? By means of htaccess for example? By specifying different IP addresses? Or is there no other way than creating a separate server instance and forgetting SNI?

2 Answers2

9

What you're trying is called "security through obscurity" - you haven't actually secured the resource, you are just hoping that nobody will know to look for it unless they're from the inside of your company.

Also, SNI has nothing to do with this issue. You would be having the exact same issue if the content was served over HTTP with no certificate at all, and you tried blocking the content by hiding it using separate hostnames.

This is not actually secure.

If you want to preent access to a resource, you need to do so in some other fashion. One way would be to set up a separate server instance, on a separate IP and use firewalls to protect that instance. Another would be to use an IP-based block on the virtual server containing the restricted content, or the directory. Or you could combine it with requiring the client to use a certificate issued by your internal CA, if you have one. Or pretty much any other way of combining authentication with authorization.

But hoping that nobody outside of your company will attempt to use the "secret" hostname is not a valid security measure, whether you use SSL/SNI or not.

Jenny D
  • 28,400
  • 21
  • 80
  • 117
5

If you need to restrict content based on the origin of the site visitors you use that information as the primary access control (and not just the name of the resource you are trying to protect).

With Apache 2.2 that would be the Allow Directive.

<VirtualHost *:443>
  ServerName private-foo
  <Location />
    Order Deny,Allow
    Deny from all
    # Allow from the internal subnet 10.1.2.0/24
    Allow from 10.1.2
  </Location>
  ...

Often in your scenario a server would have an internal and a public ip-address though and since internal users would come in using that internal IP-address only you would bind the virtual host to only that internal IP e.g. <VirtualHost 10.1.2.3:443> rather than listening to all IP's

Additionally your remark regarding .htaccess triggered my pet peeve, quoted from from the manual on .htaccess files:

You should avoid using .htaccess files completely if you have access to httpd main server config file. Using .htaccess files slows down your Apache http server. Any directive that you can include in a .htaccess file is better set in a Directory block in the main Apache configuration file(s), as it will have the same effect with better performance.

HBruijn
  • 84,206
  • 24
  • 145
  • 224