I am using Apache and the Apache agent. I can't use the Location
directive to do this because "Location" can only protect a path (e.g.
"example.com/public" vs. "example.com/private") (unless it's a proxied
request I guess). I also don't want to setup multiple virtual hosts.
So I have Apache listening for all requests and passing them to
shibboleth through this:
<Location / >
AuthType shibboleth
ShibRequireSession On
require shibboleth
</Location>
And I feel like I have shibboleth.xml configured to only redirect the
people going to private.example.com to the IdP, but it's still
redirecting people going to public.example.com. In shibboleth.xml I
have:
<RequestMapper type="Native">
<RequestMap applicationId="default">
<Host name="private.example.com">
<Path name="user/login" authType="shibboleth"
requireSession="true"/>
</Host>
</RequestMap>
</RequestMapper>
Shouldn't all the other subdomains now go through without requiring a
Session since I only have a host defined for "private.example.com"?
I thought maybe because I had the "ShibRequireSession On" part in
apache's conf, but taking it out leaves private and public.example.com
unprotected; no request gets redirected anymore to the IdP.
Any help would greatly be appreciated.
In fact if I can get through this I probably will go with shibboleth
as our SSO solution at inklingmarkets.com and I really could use a
part time contractor to help us with a Shibboleth install/config. So
please feel free let me know also if you have free time to help
contract with us soon.
Thank you!
Nate
inklingmarkets.com
This is, I believe, the root of your confusion. You started out specifically
saying that you wanted virtual hosts. Responding to both private.example.com
and public.example.com but doing so differently implies 2 virtual hosts.
So, in short, sorry, you MUST setup virtual hosts.
> And I feel like I have shibboleth.xml configured to only redirect the
> people going to private.example.com to the IdP, but it's still
> redirecting people going to public.example.com. In shibboleth.xml I
> have:
> <Host name="private.example.com">
The "host" of your web server is not determined by Shibboleth, it's what
Apache decides it is. If you turn off canonical names, then it's whatever
the client happens to enter. If canonical names are on, it's whatever
ServerName says it is. If you're going to use the RequestMap, then by
definition ServerName better be set and UseCanonicalName better be On.
But with one vhost, you get one ServerName.
> Shouldn't all the other subdomains now go through without requiring a
> Session since I only have a host defined for "private.example.com"?
There's no such thing as a "subdomain". That isn't an Apache concept, at
least not one I'm aware of.
> I thought maybe because I had the "ShibRequireSession On" part in
> apache's conf, but taking it out leaves private and public.example.com
> unprotected; no request gets redirected anymore to the IdP.
That says right there your Apache doesn't know its name or what you want to
do with it. The RequestMap never runs, probably because ServerName is set to
something else entirely. Or possibly set to public.example.com, which of
course isn't being protected.
As a rule of thumb, it seems to be the case that most of the Apache
deployments out there are basically broken. People install it, don't
configure it, things accidentally "sort of" work, and then they can't get
the SP to work because in fact Apache had no idea what it was supposed to be
doing.
The first step of using the SP is to fully configure the hosting
environment. That's a precondition for the SP to work, because it relies on
the hosting environment for most of its contextual information.
-- Scott
Why do you not want to set up multiple virtual hosts? It's something
that Apache does well. Trying to multiplex various host names
you want to behave differently though a single virtual host
seems like a way to make your life complicated. It may be
possible, but it seems needlessly tricky.
Can you explain what's behind this better?
(I'd be willing to talk off-line about issues that are purely Apache
configuration: I'm running a production web server with two dozen
virtual hosts on Apache 2.0.x, so I've got some idea what they
can do.)
--
Albert Lunde albert...@northwestern.edu
atl...@panix.com (new address for personal mail)
albert...@nwu.edu (old address)
> On Fri, Oct 24, 2008 at 09:48:01AM -0500, Nathan Kontny wrote:
>> I've been trying to protect one subdomain but not another. I have
>> one
>> virtual host setup for all *.example.com. I'd like to use
>> shibboleth to
>> protect private.example.com but not public.example.com, but I'm
>> having
>> some trouble.
>>
>> I am using Apache and the Apache agent. I can't use the Location
>> directive to do this because "Location" can only protect a path (e.g.
>> "example.com/public" vs. "example.com/private") (unless it's a
>> proxied
>> request I guess). I also don't want to setup multiple virtual hosts.
>> So I have Apache listening for all requests and passing them to
>> shibboleth through this:
>
> Why do you not want to set up multiple virtual hosts? It's something
> that Apache does well. Trying to multiplex various host names
> you want to behave differently though a single virtual host
> seems like a way to make your life complicated. It may be
> possible, but it seems needlessly tricky.
>
> Can you explain what's behind this better?
Thanks Albert for the quick reply and help.
Using 2 virtual hosts (one for port 80 and one for port 443) is a
popular practice in much of the Ruby on Rails community as well as
those folks building web apps to support multiple customers off of a
single domain (*.example.com). This allows each new customer of ours
to be provisioned programatically without altering an apache config
and also doesn't require a webserver restart. It also reduces the
need to keep yet another configuration file up to date with each
client provisioned/deleted, especially when you start clustering
apache servers over multiple machines.
Another reason is for the SSL virtual host. I do believe you can't
use multiple name based virtual hosts and use SSL, correct? Isn't
there something about the SSL handshake that sits on top of the HTTP
request, and when the handshake occurs it needs to read the virtual
host config, but since it's over SSL, the request can't read the host
name from the request header until the handshake is actually
complete. So you are stuck to doing SSL virtual hosts over IP
addresses. So if I were to need separate virtual hosts for each
customer needing SSO and needing SSL I would need a separate IP
address for each of those customers. Multiple ip addresses aren't a
fun resource to manage or provision either.
Whatever the reasons, if you choose to do that, then you'd better not rely
on the software configuration to control anything, and do whatever it is you
need to do inside the application code.
In effect, what you're saying is you don't want to use Apache as intended.
In that case, you can't use the SP as intended either, because its
configuration is composed with Apache's, it's not a replacement for it.
At one level, you can do the <Location /> trick, and get away with it. That
will get mod_shib running for every request, and you can do whatever you
want to do to manage session setup and so forth in your application.
But that won't actually be reliable in a lot of cases, because if you leave
canonical naming off, the redirection back from the IdP will be left to the
whims of the client's choice of hostname, and an assertion consumer service
location passed by value will potentially be invalid and not match the SP's
metadata, which can't include every hostname a client might use.
In short, it isn't a reliable approach.
> Another reason is for the SSL virtual host. I do believe you can't
> use multiple name based virtual hosts and use SSL, correct?
No.
> So you are stuck to doing SSL virtual hosts over IP
> addresses. So if I were to need separate virtual hosts for each
> customer needing SSO and needing SSL I would need a separate IP
> address for each of those customers. Multiple ip addresses aren't a
> fun resource to manage or provision either.
Pretty much the cost of doing this safely. SAML assumes SSL and does not
pretend to be as secure without it. Nor are your application sessions safe.
-- Scott
>> Why do you not want to set up multiple virtual hosts?
[...]
>> Can you explain what's behind this better?
>
> Thanks Albert for the quick reply and help.
> Using 2 virtual hosts (one for port 80 and one for port 443) is a
> popular practice in much of the Ruby on Rails community as well as those
> folks building web apps to support multiple customers off of a single
> domain (*.example.com). This allows each new customer of ours to be
> provisioned programatically without altering an apache config and also
> doesn't require a webserver restart. It also reduces the need to keep
> yet another configuration file up to date with each client
> provisioned/deleted, especially when you start clustering apache servers
> over multiple machines.
>
> Another reason is for the SSL virtual host. I do believe you can't use
> multiple name based virtual hosts and use SSL, correct? Isn't there
> something about the SSL handshake that sits on top of the HTTP request,
> and when the handshake occurs it needs to read the virtual host config,
> but since it's over SSL, the request can't read the host name from the
> request header until the handshake is actually complete. So you are
> stuck to doing SSL virtual hosts over IP addresses. So if I were to need
> separate virtual hosts for each customer needing SSO and needing SSL I
> would need a separate IP address for each of those customers. Multiple
> ip addresses aren't a fun resource to manage or provision either.
None of what follows is about Shibboleth, as such.
As scott said previously, if you are talking about foo.example.com
and bar.example.com, you've got two host names.
You (1) can attach them to two different virtual hosts and configure
them independently, or you can (2) make them ServerName and/or ServerAlias
names on one virtual host. If you choose (2) don't expect them
to be configured independently: they are _supposed_ to be nearly
equivalent.
(There are tricks you can do in mod_rewrite conditional on hostname,
but these tend to be too clever for one's own good.)
For the purposes of isolating applications, virtual hosts provide
a better boundry. Cookies for all sorts of SSO schemes and applications
are one issue here. (Others can say more about shibboleth as such.)
I think you've got the basic facts right with regard to SSL, one wants
to put each distinct hostname on an IP based virtual host. You can only
serve up a single SSL certficate/hostname on a given host:port combination.
ServerAlias names don't help here.
(The one exception might involve putting alternate names in the SSL
certificates: but that requires more cooperation across sites than
I suspect you can arrange.)
One thing you can do is redirect traffic from HTTP to HTTPS,
so it is possible to set up "vanity name" redirect sites that
are port 80 only, on one IP, and redirect to corresponding locations
on a HTTPS host with a different name on a different IP.
With regard to setting up new virtual hosts on the fly, you might
look at mod_vhost_alias. It requires that all hosts fit a common
layout. I haven't used it, I've got too many legacy hand-crafted hosts.
Well really what is the risk in the whim of the client choice in
hostname? I'm not all that worried people are going to be doing a lot
of www.public.example.com. Is that what you were talking about?
So I have turned off UseCanonincalName and now the ServerName is set
to what the client request provides as the host, so now as pointed
out, shib is now able to match this ServerName with one of the host
names I've specified in the RequestMapper. A related question I have
is can the RequestMap protect a root level path here?
Most of the examples in the shib docs are like the following:
<RequestMapper type="Native">
<RequestMap applicationId="default">
<Host name="public.example.com">
<Path name="secure" authType="shibboleth"
requireSession="true"/>
</Host>
</RequestMap>
</RequestMapper>
So home.example.com/secure will be protected, but home.example.com/
won't be. Is there a trick to getting the root level protected. I've
tried a regex to match everything:
<Host name="public.example.com">
<PathRegex regex=".*" authType="shibboleth"
requireSession="true"/>
</Host>
And it seems to protect every path except the root still. So
public.example.com/secure, and public.example.com/asd is protected,
but public.example.com/ still not. Any ideas here?
Experience teaches me that whatever you might think, users will do things
you wouldn't believe. And what I'm saying is that if they do, the IdPs will
halt with an invalid ACS error. Try it and see.
Aside from that point, if you do turn off canonical naming, you MUST NOT
rely on the RequestMap for anything because it cannot be trusted. If you
don't take away anything else, understand that much.
> So I have turned off UseCanonincalName and now the ServerName is set
> to what the client request provides as the host, so now as pointed
> out, shib is now able to match this ServerName with one of the host
> names I've specified in the RequestMapper. A related question I have
> is can the RequestMap protect a root level path here?
That's what the Host element does, but again, you MUST NOT do this. You
cannot turn off that setting and use the RequestMap.
> So home.example.com/secure will be protected, but home.example.com/
> won't be. Is there a trick to getting the root level protected. I've
> tried a regex to match everything:
Ignore the RequestMap. You MUST rely on Apache commands to control the SP if
you're turning off canonical naming. Nothing else will work because the
settings you want to use will simply be bypassed if the client supplies a
different hostname.
-- Scott
I understand if public.example.com and private.example.com was
protecting the same data, but it's not. It's programatically two
entirely different things.
Am I missing what your saying? If a user supplies public.example.com
as a hostname gets through the request map, they are going to get
exactly public.example.com.
They can also enter "private", an IP address, or any hostname they choose to
make up and put in a local hosts file. If there's material you're trying to
limit access to, then that's a legitimate concern.
> But that's fine. public.exaple.com isn't meant to be
> protected, and all the data returned is keyed from that domain name.
> So if the client supplies a different domain name, they get the data
> associated with that domain name.
If you rely on the client's hostname, and are using one virtual host for
everything, you have no way to discriminate anything. The client can use an
infinite number of names. How are you intending to decide what to return?
> I understand if public.example.com and private.example.com was
> protecting the same data, but it's not. It's programatically two
> entirely different things.
I don't see how that's possible without virtual hosting. Unless you're doing
something like using scripts that all start with "if hostname=="public" then
return X else return Y"...
> Am I missing what your saying? If a user supplies public.example.com
> as a hostname gets through the request map, they are going to get
> exactly public.example.com.
Which is exactly the same set of resources as private.example.com if you're
using a single virtual host, because there's one document root.
What am I missing?
(Also, none of that fixes the invalid ACS problem, which will end up causing
immense trouble for IdPs, since the error will appear on that end and appear
to be their fault instead of yours. I run into that constantly because of
this kind of thing.)
-- Scott
It's a very common pattern in web apps these days, especially out of
the Rails community. One virtual host (2 actually, one for port 80
and one for 443), and the Rails app is doing all the differentiation
and control over what a user should have access to based on their
hostname. If you have a chance take a look at what 37signals.com is
doing with apps like highrise (highrisehq.com). They have 10,000s of
customers all with a unique "something.highrisehq.com". If they had
to manage 10,000s of virtual hosts and 10,000s of IP addresses across
dozens of web servers clustered for load balancing, it'd be an insane
effort. So using application logic to decipher each requests context
and scoping data returned for that context is the way to go here.
These and ours included are database driven apps, where everything
viewed is dynamically generated. Everything static is primarily
common stuff that can safely not exist behind any security: css,
javascript, images, logos, etc.
So if I may ask again, because I think I'm still safe using the
RequestMap with canonical naming turned off in our app: how can I
configure the Host to protect the top level of the path.
<RequestMapper type="Native">
<RequestMap applicationId="default">
<Host name="public.example.com">
<Path name="secure" authType="shibboleth"
requireSession="true"/>
</Host>
</RequestMap>
</RequestMapper>
is going to protect public.example.com/secure
but I want to protect public.example.com/
I've tried changing the path to:
<Path name="/" authType="shibboleth" requireSession="true"/>
or the name to blank or not including the Path at all, but it doesn't
protect at that root level. I've tried matching everything with a
regex as I mentioned before and still can't protect that top level.
Is this not possible in shib's XML config? Am I stuck with only being
able to protect a directory under the root level using solely this
shib xml config?
I still don't see how you can make SSL work, but what about using, say,
four virtual hosts. You can make virtual hosts with the same
document root and Alias/Redirect/ScriptAlias directives
(consider using includes to pull in another file of directives
if it's a long list), but different lists of host names
and different access control directives.
Are you talking about how we make SSL work for say https://client1.example.com
and https://client2.example.com when people visit our application
over the web? All of us folks running *.example.com over a single
virtual host are using wildcard certificates. So one certificate is
valid for public.example.com, private.example.com, etc. We don't need
a new virtual host every time someone wants to use SSL for a new domain.
Or are you talking about SSL communication between the IdP and SP that
you see I'm going to need multiple virtual hosts for?
> but what about using, say,
> four virtual hosts. You can make virtual hosts with the same
> document root and Alias/Redirect/ScriptAlias directives
> (consider using includes to pull in another file of directives
> if it's a long list), but different lists of host names
> and different access control directives.
So you don't think you can use the shib XML config alone can protect
the root level of a URL?
Though Liberty Interoperable interworking agreements (what about InCommon federation rules?) REQUIRE that server certs are used in https URLS (implicitly disallowing any non-PKI ciphersuites, essentially), it says nothing about how namespaces matching is to be handled, when enforcing SAML2's own requirements concerning release of signed responses to only known/secured destinations. (SAML2 seems to relax these rules, if one takes the option to leave a POSTED SAML Response unsigned)
Formally (and none of this formality is published), https is a variant of the original HTTP URL scheme, where for the SSLv3 PKI-based ciphersuites the CA has been delegated power under that (hierarchical form) scheme to manage the authority component of the URI, and it shall register (wildcarded) domain names in its registration authority - to be reflected in the CN= component of the subject Name of the certificate. (A cert is formally a copy of the record, either signed as issued or optionally as resigned when re-issued during certain types of access to the records repository). If one was being ultra rigorous and formal with SAML2 (which may be a useful thing to be, for academic research purpose), one might require the relationship between the SAML2 destination checking rule for signed response release and https URL semantics to be specified/profiled in far more detail.
I could see wildcard certs being prohibited for now, simply pending better understanding. Without the original Netscape 2 policy concerning root authorities and that policies role in delegating control over certain namespaces to certain CAs, wildcard certs are a really quite an incendiary mechanism - now they are in the hands of the freebie-cert crowd ...and "liberated from" the original delegation rules.
Of course, this is only of any relevance to the formal world of security engineering. Go free, use a wildcard, and lots of SSL fragments will be encrypted. If this is all you want, stick with it!
I didn't say that. I don't know all of what shibboleth configuration
can do.
But if you want some host names protected and others public, for the
same relative URL, it makes sense to consider parallel virtual hosts,
with the same content but different Location blocks.
All I can tell you is that I think you will have problems with invalid ACS
error conditions.
> So if I may ask again, because I think I'm still safe using the
> RequestMap with canonical naming turned off in our app: how can I
> configure the Host to protect the top level of the path.
I told you earlier, that's what <Host> does.
> <Host name="private.example.com" authType="shibboleth"
> requireSession="true"/>
-- Scott
Front-channel SSL has nothing to do with SAML SSO. It's used and assumed to
obtain confidentiality to improve the security of the protocol, but that's
it. It has no relevance to the profile otherwise.
> It's not obvious from the core and bindings specs of SAML2 how the
> SAML responder can enforce the "destination rule" for signed responses,
> if the ACS is https and the server cert the SAML2 Responder uses
> (presumably the server cert delivered over and used by the https bearer)
> has a wildcard name registration.
It's quite obvious to me. A server knows its own identity. The responder is
told by the server what its location is, and can compare that as needed.
-- Scott