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?

Surranó
  • 33
  • 4

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
  • 27,358
  • 21
  • 74
  • 110
  • You confirmed my fears all right. The only reason I won't accept this as the best answer is because I can't select more than one, can I? :) – Surranó Mar 31 '15 at 12:07
  • 1
    Well, the answer you accepted does contain more specific information about how to setup the blocking, so don't feel bad about choosing it! The main thing is that you got the answers you need to make a good decision about your security issues - who gets the 15 extra internet points isn't something I worry about :-) – Jenny D Mar 31 '15 at 19:01
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
  • 72,524
  • 21
  • 127
  • 192
  • 1
    Apache needs a "you just edited the conf file! htaccess file access speed now 10%" feature to drill that peev-point home. – AD7six Mar 31 '15 at 08:50
  • That's just about where I ended up myself. I don't like it because it replies 403 instead of 404 (i.e. "some" info is leaked after all) but miles better than SNI alone. For the record, it's not "/" I want to restrict. Can I say, like, deny / from all except LAN then allow /ext from all? – Surranó Mar 31 '15 at 12:10
  • See the section in the manual on [merging](http://httpd.apache.org/docs/2.2/sections.html#mergin), so start with the ACL's for `/etc` and follow those with the ones for `/`. – HBruijn Mar 31 '15 at 17:18
  • If you want to return a 404, you could probably do that with `mod_rewrite`, by having a `RewriteCond` match against client IP addresses that aren't from your network. This may have some impact on performance, though, so you should probably run some performance testing on it if you're close to your limits. There's a fair amount of `mod_rewrite` tips at http://serverfault.com/questions/214512/everything-you-ever-wanted-to-know-about-mod-rewrite-rules-but-were-afraid-to-ask – Jenny D Mar 31 '15 at 19:06