GSSAPI Proxy initiative
Subsystems (2)
Hello everyone,
you are all CCed because you either expressed interested, are already involved with or may be affected/interested in this initiative.
At the recent MIT Kerberos Conference there has been some renewed interested in a concept that has surfaced in GSSAPI related circles a few times. That of building a GSSAPI Proxy to allow separation of privileges between applications and key handling.
There are various stakeholders that would like to have a solution in this areas for various reasons:
== Privilege separation ==
One of the needs that GSSAPI Proxy is able to address is separation of privileges. Initiating/accepting is delegated to the GSSAPI Proxy so that applications do not have direct access to the key material. This helps to avoid exposing keys when network facing applications are compromised. On some OSs Mandatory Access Control will help keep those keys secure if they are not directly accessible to the applications.
== Kernel Network File Systems ==
There are a number of file systems implemented in kernel and especially NFS that uses gss-krb5 to negotiate security over the network.
Most implementations use a gssd daemon in user space to handle accepting/initiating. In particular in the Linux kernel a few people feel that the current implementation is sub-optimal and would like to improve it. The functionality needed by the kernel is pretty similar to that needed to proxy gssapi for other apps, so it seem like a good idea to unify these implementations, or at least use a common protocol so that the same implementation can be used if OS vendors/Integrators want to do so.
== PAC/PAD verification ==
When using Kerberos applications can receive tickets that contain a MS-PAC or (in future) a PAD*.
In some scenarios we want to use the PAC to synthesize a user on the target system so that it can create and access files and other resources. A PAC/PAD is very useful for file servers for example because it can standardize how identities are retrieved w/o forcing file server developers to mess with protocols like LDAP and other amenities.
These structures are signed with service keys, the same keys apps have currently access to. If key material is left accessible to apps it means a compromised application could create a PAC/PAD to attempt privilege escalation by injecting this data in the system.
Although these structures are also signed with a KDC key, it would be very expensive to require a roundtrip to the KDC to ask for verification. It would also make the server reliant on KDC availability which is normally not required for kerberos based auth after the ticket is acquired.
== SSH credential forwarding ? ==
Currently, when using GSSAPI in conjunction with SSH, credentials are made available to the remote end by simply copying them over and thus giving the remote host direct access to the user creds. Quite a few people would prefer to use a ssh-agent like approach instead where credentials stay always on the local machine and context establishment is proxied over the ssh channel. Although this initiative will *not* address this feature, we'd like to build the protocol in such a way that it will become easy to implement this mechanism in the future.
==== Current status ====
I am trying to push this initiative and I am organizing and contacting people to enter the planning phase. I have received initial availability from some stakeholders in helping to shape this initiative from protocol design to transport/interface (esp. against the kernel) design, implementation, testing, etc..
Because there are many parties involved I would like to try to keep this discussion focused as much as possible to the proxy functionality.
I see this effort involving mainly 3 areas at this stage.
1) design of the protocol
I this area I had some preliminary discussion with some of the people that are interested in the effort. Due to availability in both kernel and user space implementation is seem like an ONC/RPC - XDR based protocol is the best common denominator and easily implementable by all parties.
Nothing is set in stone yet, any idea is welcome.
2) kernel and user space interfaces to the GSSAPI Proxy Daemon
For user-space to user-space communication is seem clear that a unix socket is probably the more natural transport to use.
From the Linux kernel side deciding on the right upcall mechanism seem not as straight forward. One option seem to be the netlink or rather the connector interface that is layered on top of it. More discussion is definitely needed on this front.
3) Changes to libgssapi to implement transparent proxying for user space applications
Some high level ideas have been floating around on where to hook this proxy layer in libgssapi but it is all in the air for now. Ideas here are very welcome.
Additional areas involve the design of the daemon in terms of scalability, access control and various security considerations, portability (?), etc...
Any feedback is welcome esp. if you have valuable ideas on the design issues.
We will probably keep cross-posting a bit so that we can involve all possible stakeholders, going forward we'll find a way to refocus discussions around a few forums depending on what part of the problem people is working on.
If you know other people/lists that should be involved, please feel free to forward and include them in the discussion.
Regards,
Simo.
Signature · 1 line
Simo Sorce * Red Hat, Inc * New York
Forgot a footnote. See at the end.
Quoted 128 lines · Simo Sorce
Hello everyone,
you are all CCed because you either expressed interested, are already involved with or may be affected/interested in this initiative.At the recent MIT Kerberos Conference there has been some renewed interested in a concept that has surfaced in GSSAPI related circles a few times. That of building a GSSAPI Proxy to allow separation of privileges between applications and key handling.
There are various stakeholders that would like to have a solution in this areas for various reasons:
== Privilege separation ==
One of the needs that GSSAPI Proxy is able to address is separation of privileges. Initiating/accepting is delegated to the GSSAPI Proxy so that applications do not have direct access to the key material. This helps to avoid exposing keys when network facing applications are compromised. On some OSs Mandatory Access Control will help keep those keys secure if they are not directly accessible to the applications.
== Kernel Network File Systems ==
There are a number of file systems implemented in kernel and especially NFS that uses gss-krb5 to negotiate security over the network.
Most implementations use a gssd daemon in user space to handle accepting/initiating. In particular in the Linux kernel a few people feel that the current implementation is sub-optimal and would like to improve it. The functionality needed by the kernel is pretty similar to that needed to proxy gssapi for other apps, so it seem like a good idea to unify these implementations, or at least use a common protocol so that the same implementation can be used if OS vendors/Integrators want to do so.
== PAC/PAD verification ==
When using Kerberos applications can receive tickets that contain a MS-PAC or (in future) a PAD*.
In some scenarios we want to use the PAC to synthesize a user on the target system so that it can create and access files and other resources. A PAC/PAD is very useful for file servers for example because it can standardize how identities are retrieved w/o forcing file server developers to mess with protocols like LDAP and other amenities.These structures are signed with service keys, the same keys apps have currently access to. If key material is left accessible to apps it means a compromised application could create a PAC/PAD to attempt privilege escalation by injecting this data in the system.
Although these structures are also signed with a KDC key, it would be very expensive to require a roundtrip to the KDC to ask for verification. It would also make the server reliant on KDC availability which is normally not required for kerberos based auth after the ticket is acquired.
== SSH credential forwarding ? ==
Currently, when using GSSAPI in conjunction with SSH, credentials are made available to the remote end by simply copying them over and thus giving the remote host direct access to the user creds. Quite a few people would prefer to use a ssh-agent like approach instead where credentials stay always on the local machine and context establishment is proxied over the ssh channel. Although this initiative will *not* address this feature, we'd like to build the protocol in such a way that it will become easy to implement this mechanism in the future.
==== Current status ====
I am trying to push this initiative and I am organizing and contacting people to enter the planning phase. I have received initial availability from some stakeholders in helping to shape this initiative from protocol design to transport/interface (esp. against the kernel) design, implementation, testing, etc..
Because there are many parties involved I would like to try to keep this discussion focused as much as possible to the proxy functionality.
I see this effort involving mainly 3 areas at this stage.
1) design of the protocol
I this area I had some preliminary discussion with some of the people that are interested in the effort. Due to availability in both kernel and user space implementation is seem like an ONC/RPC - XDR based protocol is the best common denominator and easily implementable by all parties.
Nothing is set in stone yet, any idea is welcome.2) kernel and user space interfaces to the GSSAPI Proxy Daemon
For user-space to user-space communication is seem clear that a unix socket is probably the more natural transport to use.
From the Linux kernel side deciding on the right upcall mechanism seem not as straight forward. One option seem to be the netlink or rather the connector interface that is layered on top of it. More discussion is definitely needed on this front.
3) Changes to libgssapi to implement transparent proxying for user space applications
Some high level ideas have been floating around on where to hook this proxy layer in libgssapi but it is all in the air for now. Ideas here are very welcome.
Additional areas involve the design of the daemon in terms of scalability, access control and various security considerations, portability (?), etc...
Any feedback is welcome esp. if you have valuable ideas on the design issues.
We will probably keep cross-posting a bit so that we can involve all possible stakeholders, going forward we'll find a way to refocus discussions around a few forums depending on what part of the problem people is working on.
If you know other people/lists that should be involved, please feel free to forward and include them in the discussion.
Quoted 2 lines
Regards,
Simo.
*PAD: Stands for Principal Authorization Data,
see: http://tools.ietf.org/html/draft-ietf-krb-wg-general-pac-01.html
Signature · 1 line
Simo Sorce * Red Hat, Inc * New York
Hi Simo,
As you know, I completely agree that we need this. We have several implementations, of course (in Linux, in Solaris, probably elsewhere, such as the BSDs, as well as proprietary ones), but all are -to my knowledge- focused on providing services to kernel-mode distributed filesystems (AFS, NFS, Lustre -- all come to mind). But we need to generalize this into a service for user-land consumers too, not just kernel mode consumers.
A few thoughts:
- XDR is quite fine for this.
- We want stateless GSS daemons, or mostly stateless at least, for
several reasons:
a) to protect them against DoS, intentional and not;
b) to make GSS daemon restart a non-event (OK, this is a much
lesser concern).
This basically requires credential handle export and
partially-established security context export support. It also requires composite name export (to capture name attributes, which won't be captured by normal exported names).
Statelessness is not strictly necessary, just highly desirable, so
if this proves difficult (or in some cases credential export turns out to not possibly be stateless for some mechanisms/credentials), oh well. But the *protocol* should be designed to facilitate statelessness, and certainly not preclude it.
Note: I really don't want to have an extended sub-thread about
exporting partially-established sec contexts. We've had that enough at KITTEN WG, so unless you (whoever wants to bring this up) are familiar with those threads, please don't bring up the subject, and if you must, then please use a separate subject.
- I would like mechglues to support mechanisms being provided by
multiple providers. This is tricky, and for some mechanisms it will not be possible to make this perfect, but it's worthwhile The reason is this: it should be possible to use a proxy for some credentials and not a proxy for others (particularly on the initiator side, where a user may not have direct access to some of their credentials but maybe can always kinit ones that they do have access to).
This too is a nice to have rather than a critical feature, but if
we don't have this then we need to make it possible for all GSS apps to run with just the proxy provider as the one provider (or: the proxy provider *is* the mechglue as far as the application is concerned). Otherwise we can get into situations where a library should use the proxy while another should not, both in the same process, and that could be obnoxious.
- Finding credentials, and authorization, will be a bit of a problem. How to deal with things like kernel keyrings and KRB5CCNAME-type
environment variables?
One possibility is that the proxy client passes everything the
proxy server needs to the proxy server. But that still requires that the proxy server be able to implement authorization correctly.
For authorization it will be best to run a proxy for each user or
{user, session} if there's session isolation, or {user, label} for labeled systems. This approach helps with finding credentials too.
- But the more GSS proxy server daemon processes we have, the more we
need to worry about ensuring timely termination.
- Thus the protocol should look very much like an XDR type for each
GSS function's input arguments and another for each functions output arguments and return value, plus, for functions dealing in exportable objects, exported objects on input and output, plus, perhaps, environmental / credential location information for certain functions.
The environmental / credential location information may not be needed
in some operating systems (because the proxy server will be able to use APIs like door_ucred(3DOOR), on Solaris, to find out what it needs about the caller), and in any case will need to be either a typed hole a an opaque type defined by each OS.
- Preferably we should have a set pattern for mapping {argument
direction, C type} to/from XDR types that can be applied in an automated fashion to the GSS C bindings header file(s), thus making it possible to avoid having to specify the abstract syntax for the protocol. I believe this is entirely feasible.
Of course, for extensibility purposes we need to be careful to use
wide integer XDR types for any C integer types in the API, and in particular we may want to use octet strings for flags arguments, just in case we widen any of these in a possible future major version of the C bindings (yes, the function names would have to change) and so that we don't unnecessarily constrain other language bindings. (Yes, I know that for req_flags, for example, widening the argument has knock on effects on the wire for actual mechanisms. I'm only asking that we be as forward-looking as possible in the GSS proxy protocol; I'm not proposal actual changes to the API.)
- To make it possible to some day consider the "PGSS" or variant
proposals, we should make the representation of the minor_status argument extensible and both, an input and output.
- The protocol probably need not be straight up ONC RPC however,
though where ONC RPC supports suitable IPC interfaces as transports, it'd certainly be worth considering.
- New functions should be possible to add at any time. For ONC RPC
this would mean we'd need to have at least a registry of procedure numbers. For a non-ONC RPC protocol we could use function name strings to name the functions "on the wire", which would then obviate the need for a new registry, simplifying the addition of extensions.
I'll probably have more to add later.
Thanks,
Nico
--
Quoted 10 lines · Nico Williams
Hi Simo,
As you know, I completely agree that we need this. We have several implementations, of course (in Linux, in Solaris, probably elsewhere, such as the BSDs, as well as proprietary ones), but all are -to my knowledge- focused on providing services to kernel-mode distributed filesystems (AFS, NFS, Lustre -- all come to mind). But we need to generalize this into a service for user-land consumers too, not just kernel mode consumers.
Quoted 8 lines
A few thoughts:
- XDR is quite fine for this.
- We want stateless GSS daemons, or mostly stateless at least, for
several reasons:a) to protect them against DoS, intentional and not;
I get this.
Quoted 2 lines
b) to make GSS daemon restart a non-event (OK, this is a much
lesser concern).
I am not sure I get this one, can you expand.
Also how do you plan to keep conversations going and still be stateless ? I am not sure transferring state back and forth is necessarily a good thing.
Quoted 4 lines
This basically requires credential handle export and
partially-established security context export support. It also requires composite name export (to capture name attributes, which won't be captured by normal exported names).
Given one of the aims is to perform privilege separation I wonder if exporting partially-established security contexts is going to expose us to some risk of disclosing to the application stuff we should not. Should we sign/seal each partially established context to avoid tampering ?
Isn't this going to be quite expensive ?
Quoted 5 lines
Statelessness is not strictly necessary, just highly desirable, so
if this proves difficult (or in some cases credential export turns out to not possibly be stateless for some mechanisms/credentials), oh well. But the *protocol* should be designed to facilitate statelessness, and certainly not preclude it.
I do not want to preclude anything if possible, but I also would like to avoid over-complicating it. Being stateless often makes it slower as state has to be reconstructed instead of simply being directly available. But I guess we will see how it goes during the implementation phase. I hear you on the DoS side, but there are other methods to prevent DoSs, like rate limiting, etc.
Quoted 6 lines
Note: I really don't want to have an extended sub-thread about
exporting partially-established sec contexts. We've had that enough at KITTEN WG, so unless you (whoever wants to bring this up) are familiar with those threads, please don't bring up the subject, and if you must, then please use a separate subject.
Quoted 7 lines
- I would like mechglues to support mechanisms being provided by
multiple providers. This is tricky, and for some mechanisms it will not be possible to make this perfect, but it's worthwhile The reason is this: it should be possible to use a proxy for some credentials and not a proxy for others (particularly on the initiator side, where a user may not have direct access to some of their credentials but maybe can always kinit ones that they do have access to).
The initiator side seem more complex indeed, but in general we need to discuss how proxy vs non-proxy is going to be selected. The method may differ between initiatior and acceptor as they are objectively different cases. And it may differ also based on what app is using libgssapi. How I am not sure, one of the objectives is to keep this almost completely transparent to current user space applications, but I guess adding new API to add some sort of awareness is a possibility. But we should avoid adding anything unless it really is absolutely needed.
Quoted 7 lines
This too is a nice to have rather than a critical feature, but if
we don't have this then we need to make it possible for all GSS apps to run with just the proxy provider as the one provider (or: the proxy provider *is* the mechglue as far as the application is concerned). Otherwise we can get into situations where a library should use the proxy while another should not, both in the same process, and that could be obnoxious.
Do you have an example in mind, I think it would benefit everyone to wrap their minds around these needs/issues if we provide some concrete examples here and there.
Quoted 7 lines
- Finding credentials, and authorization, will be a bit of a problem. How to deal with things like kernel keyrings and KRB5CCNAME-type
environment variables?One possibility is that the proxy client passes everything the
proxy server needs to the proxy server. But that still requires that the proxy server be able to implement authorization correctly.
I think we need to pass everything, and yet the proxy MUST be allowed to decide what to trust and what not of course. Also we should not preclude future developments where the proxy becomes capable of applying policy in order to deny some operations. This means we need to make it very clear to the other side when an error means it should try to proceed w/o the proxy and when an error means the proxy decided to deny the operation and so the library should drop everything and return an error.
Quoted 3 lines
For authorization it will be best to run a proxy for each user or
{user, session} if there's session isolation, or {user, label} for labeled systems. This approach helps with finding credentials too.
I do not think we should dictate how the proxy is run. On embedded systems there will be a request to keep it small. I am also not sure that forking a process for each user is desirable. It means having a process sitting there doing nothing most of the time. The GSSAPI Proxy should be considered a very trusted service. I was thinking of a multi-threaded design in order to scale when many requests come in at once (I am thinking of servers being hit in the morning when all users log in roughly at the same time), but that can scale back when load spikes are gone.
Quoted 2 lines
- But the more GSS proxy server daemon processes we have, the more we
need to worry about ensuring timely termination.
This is one reason why I do not favor multiple processes per user.
Quoted 5 lines
- Thus the protocol should look very much like an XDR type for each
GSS function's input arguments and another for each functions output arguments and return value, plus, for functions dealing in exportable objects, exported objects on input and output, plus, perhaps, environmental / credential location information for certain functions.
Agreed.
Quoted 5 lines
The environmental / credential location information may not be needed
in some operating systems (because the proxy server will be able to use APIs likedoor_ucred(3DOOR), on Solaris, to find out what it needs about the caller), and in any case will need to be either a typed hole a an opaque type defined by each OS.
I am not sure I really want to care about OSs that cannot ask the kernel who's on the other side of a pipe. I would rather let whoever cares about those to send patches later, they can be as simple as requiring the creation of multiple sockets with appropriate permissions. After all if the kernel does not help we cannot make choice of how much trust what the user is sending us stuff anyway, either we always trust all or nothing in those cases.
Quoted 5 lines
- Preferably we should have a set pattern for mapping {argument
direction, C type} to/from XDR types that can be applied in an automated fashion to the GSS C bindings header file(s), thus making it possible to avoid having to specify the abstract syntax for the protocol. I believe this is entirely feasible.
Looks like worth putting some effort into this, would keep stuff simpler and leaner.
Quoted 11 lines
Of course, for extensibility purposes we need to be careful to use
wide integer XDR types for any C integer types in the API, and in particular we may want to use octet strings for flags arguments, just in case we widen any of these in a possible future major version of the C bindings (yes, the function names would have to change) and so that we don't unnecessarily constrain other language bindings. (Yes, I know that forreq_flags, for example, widening the argument has knock on effects on the wire for actual mechanisms. I'm only asking that we be as forward-looking as possible in the GSS proxy protocol; I'm not proposal actual changes to the API.)
Quoted 3 lines
- To make it possible to some day consider the "PGSS" or variant
proposals, we should make the representation of theminor_statusargument extensible and both, an input and output.
I am not familiar with 'PGSS' care to elaborate if it is really something we need to care about ?
Quoted 3 lines
- The protocol probably need not be straight up ONC RPC however,
though where ONC RPC supports suitable IPC interfaces as transports, it'd certainly be worth considering.
We definitely MUST NOT require ONC RPC for the protocol, if someone wants to use it for something specific and build it on our work I am quite fine and I do not want to prevent it. But I thikn we do not want to force all that overhead on Kernels and other implementations by default as we do not really need it for a local daemon.
Quoted 5 lines
- New functions should be possible to add at any time. For ONC RPC
this would mean we'd need to have at least a registry of procedure numbers. For a non-ONC RPC protocol we could use function name strings to name the functions "on the wire", which would then obviate the need for a new registry, simplifying the addition of extensions.
If we do not keep a registry we should probably enforce custom extensions to use a custom name space otherwise we still risk issues with competing implementation and name collisions.
Quoted 1 line
I'll probably have more to add later.
Please do, I'd like to get some rough consensus and then quickly proceed to start the implementation phase.
No I do not want to have roll calls like in IETF here, just a feeling that people is comfortable and there aren't major obstacles for any of the stakeholders when we set the direction.
So if you something that you think will cause you pain down the road, please speak early so we do not have to do painful adjustment later.
I am fully aware that we may still have to do painful adjustments down the road if we find unforseen obstacles. If we do we will make changes, the planning phase will not set things in stone like an approved RFC.
I would also like to ask for some volunteers to cover some of the areas during implementation. We will certainly need at least one kernel engineer familiar with NFS and gssd to step up and help coding the changes that may be needed on the kernel side (mostly in the area of upcall mechanism and upcall protocol handling).
But any help is welcome, I'd like to have a clear idea of what resources and domain expertise we can count on in order to prioritize the work that will need to be done and work with people and their schedule to help make this effort proceed as smoothly as possible.
If you want feel free to call/write to me in private to discuss your needs and schedule availability.
Simo.
Signature · 1 line
Simo Sorce * Red Hat, Inc * New York
Quoted 4 lines · Simo Sorce
Quoted 3 lines · Nico Williams
- We want stateless GSS daemons, or mostly stateless at least, for several reasons:
Quoted 8 lines
Quoted 1 line
a) to protect them against DoS, intentional and not;
I get this.
Quoted 2 lines
b) to make GSS daemon restart a non-event (OK, this is a much lesser concern).
I am not sure I get this one, can you expand.
If the proxy daemon process dies, how should the proxy client recover?
If the client merely knows about credential handles for credentials
stored in the proxy, then those are invalidated. If the client has [encrypted] exported credential handle tokens then the new daemon process will be able to decrypt and import the client's credential handles. Statelessness is helpful.
Quoted 3 lines
Also how do you plan to keep conversations going and still be stateless ? I am not sure transferring state back and forth is necessarily a good thing.
What I'd like to see is the state cookies passed to the client be structured something like this (note that this would be an implementation detail, not part of the protocol spec): {object reference, verifier cookie, exported object token, [key ID for key that encrypted the exported token object, if any]}. This allows for speed (no need to re-import state all the time) and statelessness (the server can restart, the server can push state out of a fixed-sized cache).
Quoted 10 lines
Quoted 4 lines
This basically requires credential handle export and partially-established security context export support. It also requires composite name export (to capture name attributes, which won't be captured by normal exported names).
Given one of the aims is to perform privilege separation I wonder if exporting partially-established security contexts is going to expose us to some risk of disclosing to the application stuff we should not. Should we sign/seal each partially established context to avoid tampering ?
See above.
Quoted 1 line
Isn't this going to be quite expensive ?
See above.
Quoted 8 lines
Quoted 5 lines
Statelessness is not strictly necessary, just highly desirable, so if this proves difficult (or in some cases credential export turns out to not possibly be stateless for some mechanisms/credentials), oh well. But the *protocol* should be designed to facilitate statelessness, and certainly not preclude it.
I do not want to preclude anything if possible, but I also would like to avoid over-complicating it. Being stateless often makes it slower as
There's no complication. The protocol needs to allow for arbitrary-sized object handles -- that's all.
Quoted 4 lines
state has to be reconstructed instead of simply being directly available. But I guess we will see how it goes during the implementation phase. I hear you on the DoS side, but there are other methods to prevent DoSs, like rate limiting, etc.
No, rate limiting is a hack.
Quoted 9 lines
Quoted 7 lines
- I would like mechglues to support mechanisms being provided by multiple providers. This is tricky, and for some mechanisms it will not be possible to make this perfect, but it's worthwhile The reason is this: it should be possible to use a proxy for some credentials and not a proxy for others (particularly on the initiator side, where a user may not have direct access to some of their credentials but maybe can always kinit ones that they do have access to).
The initiator side seem more complex indeed, but in general we need to
Let's agree to be careful with client/server vs. initiator/acceptor. The latter should refer exactly to the GSS meanings of "initiator" and "acceptor". The former should refer to the proxy client and server.
Quoted 3 lines
discuss how proxy vs non-proxy is going to be selected. The method may differ between initiatior and acceptor as they are objectively different cases. And it may differ also based on what app is using libgssapi.
The GSS-API lacks a concept of caller context handl -- an equivalent to krb5_context. This is a problem. We can't speak of who the application is, not in a world where many libraries use the GSS-API, because there can be multiple applications in one process and we can't easily distinguish which application the caller is.
I refer you to past discussions of how to address this. I really want to avoid that subject for now though.
Quoted 5 lines
How I am not sure, one of the objectives is to keep this almost completely transparent to current user space applications, but I guess adding new API to add some sort of awareness is a possibility. But we should avoid adding anything unless it really is absolutely needed.
I don't entirely agree with this. Sometimes it's not clear that one needs X until X is available. Knowing that X will be necessary is what we call "vision" :)
Quoted 11 lines
Quoted 7 lines
This too is a nice to have rather than a critical feature, but if we don't have this then we need to make it possible for all GSS apps to run with just the proxy provider as the one provider (or: the proxy provider *is* the mechglue as far as the application is concerned). Otherwise we can get into situations where a library should use the proxy while another should not, both in the same process, and that could be obnoxious.
Do you have an example in mind, I think it would benefit everyone to wrap their minds around these needs/issues if we provide some concrete examples here and there.
Layered software. Particularly pluggable layers like PAM.
Quoted 9 lines
Quoted 7 lines
- Finding credentials, and authorization, will be a bit of a problem. How to deal with things like kernel keyrings and KRB5CCNAME-type environment variables?
One possibility is that the proxy client passes everything the proxy server needs to the proxy server. But that still requires that the proxy server be able to implement authorization correctly.
I think we need to pass everything, and yet the proxy MUST be allowed to
I'd much rather not have to pass anything, but we need to support OSes where that's just how it's done. I'd rather that IPC end-points can find out what what they need about their peers. Think door_ucred(3DOOR).
Quoted 1 line
decide what to trust and what not of course. Also we should not preclude
Trust nothing. Authorization is separate.
Quoted 5 lines
future developments where the proxy becomes capable of applying policy in order to deny some operations. This means we need to make it very clear to the other side when an error means it should try to proceed w/o the proxy and when an error means the proxy decided to deny the operation and so the library should drop everything and return an error.
The protocol itself needs to be generic and allow for passing everything.
Quoted 5 lines
Quoted 3 lines
For authorization it will be best to run a proxy for each user or {user, session} if there's session isolation, or {user, label} for labeled systems. This approach helps with finding credentials too.
I do not think we should dictate how the proxy is run. On embedded
Indeed, I'm not interested in dictating implementation details. It's going to be very difficult to avoid discussing possible implementation details, so I don't bother trying not to :) But the protocol itself needs to be agnostic regarding these things.
Quoted 8 lines
systems there will be a request to keep it small. I am also not sure that forking a process for each user is desirable. It means having a process sitting there doing nothing most of the time. The GSSAPI Proxy should be considered a very trusted service. I was thinking of a multi-threaded design in order to scale when many requests come in at once (I am thinking of servers being hit in the morning when all users log in roughly at the same time), but that can scale back when load spikes are gone.
Multi-threaded is fine. On Solaris it'd have to be multi-processed because it's not possible to have different process credentials for different threads of the same process in Solaris -- ias with this in mind that I mentioned the possible [implementation-specific detail of a] design where there's a daemon process per {user session}, {user, label}, ...
I suppose I need to be more careful in separating what I intend to be part of a standard and what I intend to be an implementation detail when I describe these sorts of things. To me it's clear, but perhaps not so much to others.
Quoted 4 lines
Quoted 2 lines
- But the more GSS proxy server daemon processes we have, the more we need to worry about ensuring timely termination.
This is one reason why I do not favor multiple processes per user.
See above.
Quoted 14 lines
Quoted 5 lines
- Thus the protocol should look very much like an XDR type for each GSS function's input arguments and another for each functions output arguments and return value, plus, for functions dealing in exportable objects, exported objects on input and output, plus, perhaps, environmental / credential location information for certain functions.
Agreed.
Quoted 5 lines
The environmental / credential location information may not be needed in some operating systems (because the proxy server will be able to use APIs like
door_ucred(3DOOR), on Solaris, to find out what it needs about the caller), and in any case will need to be either a typed hole a an opaque type defined by each OS.
Quoted 7 lines
I am not sure I really want to care about OSs that cannot ask the kernel who's on the other side of a pipe. I would rather let whoever cares about those to send patches later, they can be as simple as requiring the creation of multiple sockets with appropriate permissions. After all if the kernel does not help we cannot make choice of how much trust what the user is sending us stuff anyway, either we always trust all or nothing in those cases.
I assume all OSes will have something for this, but possibly not enough, thus the need to pass some environmental context in some cases. I want to not preclude that.
Quoted 8 lines
Quoted 5 lines
- Preferably we should have a set pattern for mapping {argument direction, C type} to/from XDR types that can be applied in an automated fashion to the GSS C bindings header file(s), thus making it possible to avoid having to specify the abstract syntax for the protocol. I believe this is entirely feasible.
Looks like worth putting some effort into this, would keep stuff simpler and leaner.
Yes.
Quoted 6 lines
Quoted 3 lines
- To make it possible to some day consider the "PGSS" or variant proposals, we should make the representation of the
minor_statusargument extensible and both, an input and output.I am not familiar with 'PGSS' care to elaborate if it is really something we need to care about ?
Yes, but not right now. Maybe tonight.
Quoted 9 lines
Quoted 3 lines
- The protocol probably need not be straight up ONC RPC however, though where ONC RPC supports suitable IPC interfaces as transports, it'd certainly be worth considering.
We definitely MUST NOT require ONC RPC for the protocol, if someone wants to use it for something specific and build it on our work I am quite fine and I do not want to prevent it. But I thikn we do not want to force all that overhead on Kernels and other implementations by default as we do not really need it for a local daemon.
ONC RPC has next to no overhead when the transport is something like doors, for example.
I'm out of time. More later.
Nico
--
Quoted 7 lines · Nico Williams
Quoted 6 lines · Simo Sorce
Quoted 4 lines · Nico Williams
- We want stateless GSS daemons, or mostly stateless at least, for
several reasons:a) to protect them against DoS, intentional and not;
Quoted 8 lines
Quoted 6 lines
I get this.
Quoted 2 lines
b) to make GSS daemon restart a non-event (OK, this is a much
lesser concern).I am not sure I get this one, can you expand.
If the proxy daemon process dies, how should the proxy client recover?
Either wait for the proxy to restart or treat it as an unrecoverable error, just like if the network goes away ?
Quoted 5 lines
If the client merely knows about credential handles for credentials
stored in the proxy, then those are invalidated. If the client has [encrypted] exported credential handle tokens then the new daemon process will be able to decrypt and import the client's credential handles. Statelessness is helpful.
Well this case is true only if the proxy keeps state only in memory and not in persistent storage. But this is something we want to keep in mind, definitely, if the overhead is not too much it may make things more robust.
Quoted 4 lines
Quoted 3 lines
Also how do you plan to keep conversations going and still be stateless ? I am not sure transferring state back and forth is necessarily a good thing.
Quoted 8 lines
What I'd like to see is the state cookies passed to the client be structured something like this (note that this would be an implementation detail, not part of the protocol spec): {object reference, verifier cookie, exported object token, [key ID for key that encrypted the exported token object, if any]}. This allows for speed (no need to re-import state all the time) and statelessness (the server can restart, the server can push state out of a fixed-sized cache).
Ok, I can see how this may help.
Quoted 11 lines
Quoted 8 lines
Quoted 5 lines
Statelessness is not strictly necessary, just highly desirable, so
if this proves difficult (or in some cases credential export turns out to not possibly be stateless for some mechanisms/credentials), oh well. But the *protocol* should be designed to facilitate statelessness, and certainly not preclude it.I do not want to preclude anything if possible, but I also would like to avoid over-complicating it. Being stateless often makes it slower as
There's no complication. The protocol needs to allow for arbitrary-sized object handles -- that's all.
Ok, I was complaining about making the server more complicated, but that's probably not really true, we will just trade one set of issues with another as the state is kept 'somewhere' anyway, so I retire my concern.
Quoted 18 lines
Quoted 9 lines
Quoted 7 lines
- I would like mechglues to support mechanisms being provided by
multiple providers. This is tricky, and for some mechanisms it will not be possible to make this perfect, but it's worthwhile The reason is this: it should be possible to use a proxy for some credentials and not a proxy for others (particularly on the initiator side, where a user may not have direct access to some of their credentials but maybe can always kinit ones that they do have access to).The initiator side seem more complex indeed, but in general we need to
Let's agree to be careful with client/server vs. initiator/acceptor. The latter should refer exactly to the GSS meanings of "initiator" and "acceptor". The former should refer to the proxy client and server.
Quoted 3 lines
discuss how proxy vs non-proxy is going to be selected. The method may differ between initiatior and acceptor as they are objectively different cases. And it may differ also based on what app is using libgssapi.
Quoted 8 lines
The GSS-API lacks a concept of caller context handl -- an equivalent to
krb5_context. This is a problem. We can't speak of who the application is, not in a world where many libraries use the GSS-API, because there can be multiple applications in one process and we can't easily distinguish which application the caller is.I refer you to past discussions of how to address this. I really want to avoid that subject for now though.
Ok, let's defer for now.
Quoted 14 lines
Quoted 3 lines
Do you have an example in mind, I think it would benefit everyone to wrap their minds around these needs/issues if we provide some concrete examples here and there.
Layered software. Particularly pluggable layers like PAM.
Quoted 8 lines
Quoted 7 lines
- Finding credentials, and authorization, will be a bit of a problem. How to deal with things like kernel keyrings and KRB5CCNAME-type
environment variables?One possibility is that the proxy client passes everything the
proxy server needs to the proxy server. But that still requires that the proxy server be able to implement authorization correctly.
Quoted 6 lines
Quoted 1 line
I think we need to pass everything, and yet the proxy MUST be allowed to
I'd much rather not have to pass anything, but we need to support OSes where that's just how it's done. I'd rather that IPC end-points can find out what what they need about their peers. Think
door_ucred(3DOOR).
I don't think I want to use the PID and then try to pull out environment variables through /proc or similar interface, that would be bad. For the krb5 mech we only care about a handful of environment variables. Perhaps the protocol should be allowed to pass a list of variable libgssapi should check for and return back, so that we can easily make the list extensible and not have libgssapi always have to shove back the full env var set of the process just in case.
Quoted 3 lines
Quoted 1 line
decide what to trust and what not of course. Also we should not preclude
Trust nothing. Authorization is separate.
That depends on the client.
When the client is the kernel we can decide to trust whatever it says.
Quoted 4 lines
Indeed, I'm not interested in dictating implementation details. It's going to be very difficult to avoid discussing possible implementation details, so I don't bother trying not to :) But the protocol itself needs to be agnostic regarding these things.
ACK
Quoted 6 lines
Multi-threaded is fine. On Solaris it'd have to be multi-processed because it's not possible to have different process credentials for different threads of the same process in Solaris -- ias with this in mind that I mentioned the possible [implementation-specific detail of a] design where there's a daemon process per {user session}, {user, label}, ...
I am not sure you need that separation, but as it is an implementation detail I think we should set discussion around this aside for now.
Quoted 4 lines
I suppose I need to be more careful in separating what I intend to be part of a standard and what I intend to be an implementation detail when I describe these sorts of things. To me it's clear, but perhaps not so much to others.
It is ok to agree that any time we mention implementation details of the proxy itself these are not binding, but just a tool to explain why something may be needed.
Quoted 4 lines
Quoted 4 lines
Quoted 3 lines
- The protocol probably need not be straight up ONC RPC however,
though where ONC RPC supports suitable IPC interfaces as transports, it'd certainly be worth considering.
Quoted 8 lines
Quoted 5 lines
We definitely MUST NOT require ONC RPC for the protocol, if someone wants to use it for something specific and build it on our work I am quite fine and I do not want to prevent it. But I thikn we do not want to force all that overhead on Kernels and other implementations by default as we do not really need it for a local daemon.
ONC RPC has next to no overhead when the transport is something like doors, for example.
I mean conceptual and development over head, not talking about performance.
Simo.
Signature · 1 line
Simo Sorce * Red Hat, Inc * New York
Quoted 5 lines · Simo Sorce
Quoted 1 line · Nico Williams
If the proxy daemon process dies, how should the proxy client recover?
Either wait for the proxy to restart or treat it as an unrecoverable error, just like if the network goes away ?
If state is lost the client has to recover. Sure, it's going to somehow (perhaps by returning an error to the user, who then retries).
Point is: a stateless (or stateless + caching, for perf) design would
avoid this.
For the protocol that just means that handles need to be opaque octet strings, NOT just small integers. Whether a given implementation is stateless is another story. This is what I was driving at.
Quoted 1 line
Ok, I can see how this may help.
:)
Quoted 7 lines
Quoted 2 lines
There's no complication. The protocol needs to allow for arbitrary-sized object handles -- that's all.
Ok, I was complaining about making the server more complicated, but that's probably not really true, we will just trade one set of issues with another as the state is kept 'somewhere' anyway, so I retire my concern.
Right.
Quoted 7 lines
Quoted 4 lines
I'd much rather not have to pass anything, but we need to support OSes where that's just how it's done. I'd rather that IPC end-points can find out what what they need about their peers. Think
door_ucred(3DOOR).I don't think I want to use the PID and then try to pull out environment variables through /proc or similar interface, that would be bad.
I would never have suggested that.
What I had in mind was something like PAGs or keyrings. Or, to be much more specific, search for my name and the string "credentials process groups" -- a PAG on steroids.
The idea is that the IPC peer can observe the other's PAG/keyring/CPG/whatever and use that to find the correct credentials (authorization is still required though).
Quoted 1 line
For the krb5 mech we only care about a handful of environment variables.
And for others? Anyways, environment variables -> ewwww.
Quoted 4 lines
Quoted 1 line
Trust nothing. Authorization is separate.
That depends on the client.
When the client is the kernel we can decide to trust whatever it says.
Of course. But if at all possible the mechanism for identifying the correct credentials stores should be the same for kernel and non-kernel consumers (see above).
Quoted 6 lines
Quoted 4 lines
Indeed, I'm not interested in dictating implementation details. It's going to be very difficult to avoid discussing possible implementation details, so I don't bother trying not to :) But the protocol itself needs to be agnostic regarding these things.
ACK
:)
I use possible implementation choices to inform/motivate/justify protocol design choices.
Quoted 9 lines
Quoted 6 lines
Multi-threaded is fine. On Solaris it'd have to be multi-processed because it's not possible to have different process credentials for different threads of the same process in Solaris -- ias with this in mind that I mentioned the possible [implementation-specific detail of a] design where there's a daemon process per {user session}, {user, label}, ...
I am not sure you need that separation, but as it is an implementation detail I think we should set discussion around this aside for now.
Sure. But without separation, and using the true GSS API, there's no way to pass the authorization context to the GSS-API, so that leaves... impersonating the user, which is either not thread safe (in POSIX) or not standard (or Windows). This is context that I left out when I posted (it was late :/).
Quoted 3 lines
It is ok to agree that any time we mention implementation details of the proxy itself these are not binding, but just a tool to explain why something may be needed.
Good.
Quoted 10 lines
Quoted 10 lines
Quoted 9 lines
Quoted 3 lines
- The protocol probably need not be straight up ONC RPC however, though where ONC RPC supports suitable IPC interfaces as transports, it'd certainly be worth considering.
We definitely MUST NOT require ONC RPC for the protocol, if someone wants to use it for something specific and build it on our work I am quite fine and I do not want to prevent it. But I thikn we do not want to force all that overhead on Kernels and other implementations by default as we do not really need it for a local daemon.
Quoted 5 lines
Quoted 2 lines
ONC RPC has next to no overhead when the transport is something like doors, for example.
I mean conceptual and development over head, not talking about performance.
If you don't need rpcbind/portmapper (and you don't for local non-IP IPC) then the conceptual overhead is zero. The Solaris kernel kidmap module uses RPC over doors without any RPC runtime code on the client-side -- it's just XDR -- it can be done.
Nico
--
Quoted 40 lines · Nico Williams
Quoted 5 lines · Simo Sorce
Quoted 1 line · Nico Williams
If the proxy daemon process dies, how should the proxy client recover?
Either wait for the proxy to restart or treat it as an unrecoverable error, just like if the network goes away ?
If state is lost the client has to recover. Sure, it's going to somehow (perhaps by returning an error to the user, who then retries).
Point is: a stateless (or stateless + caching, for perf) design would
avoid this.For the protocol that just means that handles need to be opaque octet strings, NOT just small integers. Whether a given implementation is stateless is another story. This is what I was driving at.
Quoted 1 line
Ok, I can see how this may help.
:)
Quoted 7 lines
Quoted 2 lines
There's no complication. The protocol needs to allow for arbitrary-sized object handles -- that's all.
Ok, I was complaining about making the server more complicated, but that's probably not really true, we will just trade one set of issues with another as the state is kept 'somewhere' anyway, so I retire my concern.
Right.
Quoted 7 lines
Quoted 4 lines
I'd much rather not have to pass anything, but we need to support OSes where that's just how it's done. I'd rather that IPC end-points can find out what what they need about their peers. Think
door_ucred(3DOOR).I don't think I want to use the PID and then try to pull out environment variables through /proc or similar interface, that would be bad.
I would never have suggested that.
Quoted 7 lines
What I had in mind was something like PAGs or keyrings. Or, to be much more specific, search for my name and the string "credentials process groups" -- a PAG on steroids.
The idea is that the IPC peer can observe the other's PAG/keyring/CPG/whatever and use that to find the correct credentials (authorization is still required though).
Linux already has per-user, per-process and per-thread keyrings which offer a high security storage solution for keys. The problem with those is that they are difficult to use in an asynchronous context when the original user's process/thread context is no longer available to us.
Ideally, though, that's what we'd like to see used.
Trond
Signature · 6 lines
Trond Myklebust Linux NFS client maintainer NetApp [email protected] www.netapp.com
Quoted 4 lines · Trond Myklebust
Quoted 4 lines
What I had in mind was something like PAGs or keyrings. Or, to be much more specific, search for my name and the string "credentials process groups" -- a PAG on steroids.
Quoted 8 lines
Quoted 3 lines
The idea is that the IPC peer can observe the other's PAG/keyring/CPG/whatever and use that to find the correct credentials (authorization is still required though).
Linux already has per-user, per-process and per-thread keyrings which offer a high security storage solution for keys. The problem with those is that they are difficult to use in an asynchronous context when the original user's process/thread context is no longer available to us.
For async IPC methods you'd want something like SCM_CREDENTIALS to give you the keyring/PAG/whatever information you need abou thte peer.
The ancillary data should be complete enough that you can past the
client process/thread being dead, although it's nice to not have to process a request from a dead entity...
For sync IPC you need something like door_ucred(). And for sync IPC you can make sure to get SIGCANCEL or equivalent when the client gets canceled (this is the default in doors).
Quoted 1 line
Ideally, though, that's what we'd like to see used.
Agreed!
Nico
--
Quoted 21 lines · Nico Williams
Quoted 4 lines · Trond Myklebust
Quoted 4 lines
What I had in mind was something like PAGs or keyrings. Or, to be much more specific, search for my name and the string "credentials process groups" -- a PAG on steroids.
Quoted 8 lines
Quoted 3 lines
The idea is that the IPC peer can observe the other's PAG/keyring/CPG/whatever and use that to find the correct credentials (authorization is still required though).
Linux already has per-user, per-process and per-thread keyrings which offer a high security storage solution for keys. The problem with those is that they are difficult to use in an asynchronous context when the original user's process/thread context is no longer available to us.
For async IPC methods you'd want something like
SCM_CREDENTIALSto give you the keyring/PAG/whatever information you need abou thte peer.
The ancillary data should be complete enough that you can past the
client process/thread being dead, although it's nice to not have to process a request from a dead entity...
Quoted 7 lines
For sync IPC you need something like
door_ucred(). And for sync IPC you can make sure to get SIGCANCEL or equivalent when the client gets canceled (this is the default in doors).Quoted 1 line
Ideally, though, that's what we'd like to see used.
Agreed!
I have discussed use of the keyring in a private discussion before starting the thread, and it turns out the keyring has a number of limitations that makes it probably unsuitable for this project.
As an upcall mechanism it has some limitations on the size of the payloads, IIRC limited to a page, and that means that you cannot pass blobs carrying big kerberos tickets.
As a storage mechanism for credential caches it also has size limits. Currently the limit is 20k per user which is not even enough to hold a single ticket in some cases. This limit can be increased of course, but then you end keeping around a huge amount of unswappable ram depending on the number of users.
So for long term storage of credentials we will probably not rely on kernel keyrings, nor as an upcall mechanism.
Simo.
Signature · 1 line
Simo Sorce * Red Hat, Inc * New York
Quoted 38 lines · Simo Sorce
Quoted 21 lines · Nico Williams
Quoted 4 lines · Trond Myklebust
Quoted 4 lines
What I had in mind was something like PAGs or keyrings. Or, to be much more specific, search for my name and the string "credentials process groups" -- a PAG on steroids.
Quoted 8 lines
Quoted 3 lines
The idea is that the IPC peer can observe the other's PAG/keyring/CPG/whatever and use that to find the correct credentials (authorization is still required though).
Linux already has per-user, per-process and per-thread keyrings which offer a high security storage solution for keys. The problem with those is that they are difficult to use in an asynchronous context when the original user's process/thread context is no longer available to us.
For async IPC methods you'd want something like
SCM_CREDENTIALSto give you the keyring/PAG/whatever information you need abou thte peer.
The ancillary data should be complete enough that you can past the
client process/thread being dead, although it's nice to not have to process a request from a dead entity...Quoted 7 lines
For sync IPC you need something like
door_ucred(). And for sync IPC you can make sure to get SIGCANCEL or equivalent when the client gets canceled (this is the default in doors).Quoted 1 line
Ideally, though, that's what we'd like to see used.
Agreed!
I have discussed use of the keyring in a private discussion before starting the thread, and it turns out the keyring has a number of limitations that makes it probably unsuitable for this project.
As an upcall mechanism it has some limitations on the size of the payloads, IIRC limited to a page, and that means that you cannot pass blobs carrying big kerberos tickets.
Quoted 5 lines
As a storage mechanism for credential caches it also has size limits. Currently the limit is 20k per user which is not even enough to hold a single ticket in some cases. This limit can be increased of course, but then you end keeping around a huge amount of unswappable ram depending on the number of users.
Allowing keys to be swapped out is a really really really really really really bad idea when your kernel depends upon them being available as part of the memory reclaim process, as would be the case when you are talking about NFS, CIFS or AFS dirty page writebacks.
Quoted 2 lines
So for long term storage of credentials we will probably not rely on kernel keyrings, nor as an upcall mechanism.
So this would be an argument for scrapping keyrings from the kernel? If they're not good for kerberos tickets, why would we want to keep them at all?
What would you replace them with, given the above requirements concerning swapping?
Signature · 6 lines
Trond Myklebust Linux NFS client maintainer NetApp [email protected] www.netapp.com
Quoted 45 lines · Trond Myklebust
Quoted 38 lines · Simo Sorce
Quoted 21 lines · Nico Williams
Quoted 4 lines · Trond Myklebust
Quoted 4 lines
What I had in mind was something like PAGs or keyrings. Or, to be much more specific, search for my name and the string "credentials process groups" -- a PAG on steroids.
Quoted 8 lines
Quoted 3 lines
The idea is that the IPC peer can observe the other's PAG/keyring/CPG/whatever and use that to find the correct credentials (authorization is still required though).
Linux already has per-user, per-process and per-thread keyrings which offer a high security storage solution for keys. The problem with those is that they are difficult to use in an asynchronous context when the original user's process/thread context is no longer available to us.
For async IPC methods you'd want something like
SCM_CREDENTIALSto give you the keyring/PAG/whatever information you need abou thte peer.
The ancillary data should be complete enough that you can past the
client process/thread being dead, although it's nice to not have to process a request from a dead entity...Quoted 7 lines
For sync IPC you need something like
door_ucred(). And for sync IPC you can make sure to get SIGCANCEL or equivalent when the client gets canceled (this is the default in doors).Quoted 1 line
Ideally, though, that's what we'd like to see used.
Agreed!
I have discussed use of the keyring in a private discussion before starting the thread, and it turns out the keyring has a number of limitations that makes it probably unsuitable for this project.
As an upcall mechanism it has some limitations on the size of the payloads, IIRC limited to a page, and that means that you cannot pass blobs carrying big kerberos tickets.
Quoted 5 lines
As a storage mechanism for credential caches it also has size limits. Currently the limit is 20k per user which is not even enough to hold a single ticket in some cases. This limit can be increased of course, but then you end keeping around a huge amount of unswappable ram depending on the number of users.
Quoted 4 lines
Allowing keys to be swapped out is a really really really really really really bad idea when your kernel depends upon them being available as part of the memory reclaim process, as would be the case when you are talking about NFS, CIFS or AFS dirty page writebacks.
You do not need long term keys on existing mounts which is the only case where you have anything to release, gss context session keys will be kept in the kernel but need not be shared with anything.
It is ok to use keyring if that's deemed the right place for session keys, but I think you already have structures where you currently store them so I don't thik you necessarily need to change that part of the kernel implementation.
Quoted 6 lines
Quoted 2 lines
So for long term storage of credentials we will probably not rely on kernel keyrings, nor as an upcall mechanism.
So this would be an argument for scrapping keyrings from the kernel? If they're not good for kerberos tickets, why would we want to keep them at all?
See above.
We could also break the tickets so that only the valuable part is kept in the keyring, and the rest (encrypted with the session key) in a file. I don;t think this influences the GSSAPI Proxy protocol and mechanism. It is an implementation detail we can discuss within the linux specific implementation.
Quoted 2 lines
What would you replace them with, given the above requirements concerning swapping?
Currently credential caches are stored in files, is there a problem with that model ? Do you need access to credential caches from the kernel when under memory pressure ?
Simo.
Signature · 1 line
Simo Sorce * Red Hat, Inc * New York
PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBTaW1vIFNvcmNlIFttYWlsdG86 c2ltb0ByZWRoYXQuY29tXQ0KPiBTZW50OiBUaHVyc2RheSwgTm92ZW1iZXIgMDMsIDIwMTEgNjow MCBQTQ0KPiBUbzogTXlrbGVidXN0LCBUcm9uZA0KPiBDYzogTmljbyBXaWxsaWFtczsgZGhvd2Vs bHM7IGxpbnV4LW5mc0B2Z2VyLmtlcm5lbC5vcmc7IGtyYmRldg0KPiBTdWJqZWN0OiBSZTogR1NT QVBJIFByb3h5IGluaXRpYXRpdmUNCj4gDQo+IE9uIFRodSwgMjAxMS0xMS0wMyBhdCAxNzo0NiAt MDQwMCwgVHJvbmQgTXlrbGVidXN0IHdyb3RlOg0KPiA+IE9uIFRodSwgMjAxMS0xMS0wMyBhdCAx NzozMCAtMDQwMCwgU2ltbyBTb3JjZSB3cm90ZToNCj4gPiA+IE9uIFRodSwgMjAxMS0xMS0wMyBh dCAxNTo1MyAtMDUwMCwgTmljbyBXaWxsaWFtcyB3cm90ZToNCj4gPiA+ID4gT24gVGh1LCBOb3Yg MywgMjAxMSBhdCAzOjM5IFBNLCBUcm9uZCBNeWtsZWJ1c3QNCj4gPiA+ID4gPFRyb25kLk15a2xl YnVzdEBuZXRhcHAuY29tPiB3cm90ZToNCj4gPiA+ID4gPj4gV2hhdCBJIGhhZCBpbiBtaW5kIHdh cyBzb21ldGhpbmcgbGlrZSBQQUdzIG9yIGtleXJpbmdzLiAgT3IsIHRvDQo+ID4gPiA+ID4+IGJl IG11Y2ggbW9yZSBzcGVjaWZpYywgc2VhcmNoIGZvciBteSBuYW1lIGFuZCB0aGUgc3RyaW5nDQo+ ID4gPiA+ID4+ICJjcmVkZW50aWFscyBwcm9jZXNzIGdyb3VwcyIgLS0gYSBQQUcgb24gc3Rlcm9p ZHMuDQo+ID4gPiA+ID4+DQo+ID4gPiA+ID4+IFRoZSBpZGVhIGlzIHRoYXQgdGhlIElQQyBwZWVy IGNhbiBvYnNlcnZlIHRoZSBvdGhlcidzDQo+ID4gPiA+ID4+IFBBRy9rZXlyaW5nL0NQRy93aGF0 ZXZlciBhbmQgdXNlIHRoYXQgdG8gZmluZCB0aGUgY29ycmVjdA0KPiA+ID4gPiA+PiBjcmVkZW50 aWFscyAoYXV0aG9yaXphdGlvbiBpcyBzdGlsbCByZXF1aXJlZCB0aG91Z2gpLg0KPiA+ID4gPiA+ DQo+ID4gPiA+ID4gTGludXggYWxyZWFkeSBoYXMgcGVyLXVzZXIsIHBlci1wcm9jZXNzIGFuZCBw ZXItdGhyZWFkIGtleXJpbmdzDQo+ID4gPiA+ID4gd2hpY2ggb2ZmZXIgYSBoaWdoIHNlY3VyaXR5 IHN0b3JhZ2Ugc29sdXRpb24gZm9yIGtleXMuIFRoZQ0KPiA+ID4gPiA+IHByb2JsZW0gd2l0aCB0 aG9zZSBpcyB0aGF0IHRoZXkgYXJlIGRpZmZpY3VsdCB0byB1c2UgaW4gYW4NCj4gPiA+ID4gPiBh c3luY2hyb25vdXMgY29udGV4dCB3aGVuIHRoZSBvcmlnaW5hbCB1c2VyJ3MgcHJvY2Vzcy90aHJl YWQNCj4gY29udGV4dCBpcyBubyBsb25nZXIgYXZhaWxhYmxlIHRvIHVzLg0KPiA+ID4gPg0KPiA+ ID4gPiBGb3IgYXN5bmMgSVBDIG1ldGhvZHMgeW91J2Qgd2FudCBzb21ldGhpbmcgbGlrZSBTQ01f Q1JFREVOVElBTFMNCj4gdG8NCj4gPiA+ID4gZ2l2ZSB5b3UgdGhlIGtleXJpbmcvUEFHL3doYXRl dmVyIGluZm9ybWF0aW9uIHlvdSBuZWVkIGFib3UgdGh0ZQ0KPiBwZWVyLg0KPiA+ID4gPiAgVGhl IGFuY2lsbGFyeSBkYXRhIHNob3VsZCBiZSBjb21wbGV0ZSBlbm91Z2ggdGhhdCB5b3UgY2FuIHBh c3QNCj4gPiA+ID4gdGhlIGNsaWVudCBwcm9jZXNzL3RocmVhZCBiZWluZyBkZWFkLCBhbHRob3Vn aCBpdCdzIG5pY2UgdG8gbm90DQo+ID4gPiA+IGhhdmUgdG8gcHJvY2VzcyBhIHJlcXVlc3QgZnJv bSBhIGRlYWQgZW50aXR5Li4uDQo+ID4gPiA+DQo+ID4gPiA+IEZvciBzeW5jIElQQyB5b3UgbmVl ZCBzb21ldGhpbmcgbGlrZSBkb29yX3VjcmVkKCkuICBBbmQgZm9yIHN5bmMNCj4gPiA+ID4gSVBD IHlvdSBjYW4gbWFrZSBzdXJlIHRvIGdldCBTSUdDQU5DRUwgb3IgZXF1aXZhbGVudCB3aGVuIHRo ZQ0KPiA+ID4gPiBjbGllbnQgZ2V0cyBjYW5jZWxlZCAodGhpcyBpcyB0aGUgZGVmYXVsdCBpbiBk b29ycykuDQo+ID4gPiA+DQo+ID4gPiA+ID4gSWRlYWxseSwgdGhvdWdoLCB0aGF0J3Mgd2hhdCB3 ZSdkIGxpa2UgdG8gc2VlIHVzZWQuDQo+ID4gPiA+DQo+ID4gPiA+IEFncmVlZCENCj4gPiA+DQo+ ID4gPiBJIGhhdmUgZGlzY3Vzc2VkIHVzZSBvZiB0aGUga2V5cmluZyBpbiBhIHByaXZhdGUgZGlz Y3Vzc2lvbiBiZWZvcmUNCj4gPiA+IHN0YXJ0aW5nIHRoZSB0aHJlYWQsIGFuZCBpdCB0dXJucyBv dXQgdGhlIGtleXJpbmcgaGFzIGEgbnVtYmVyIG9mDQo+ID4gPiBsaW1pdGF0aW9ucyB0aGF0IG1h a2VzIGl0IHByb2JhYmx5IHVuc3VpdGFibGUgZm9yIHRoaXMgcHJvamVjdC4NCj4gPiA+DQo+ID4g PiBBcyBhbiB1cGNhbGwgbWVjaGFuaXNtIGl0IGhhcyBzb21lIGxpbWl0YXRpb25zIG9uIHRoZSBz aXplIG9mIHRoZQ0KPiA+ID4gcGF5bG9hZHMsIElJUkMgbGltaXRlZCB0byBhIHBhZ2UsIGFuZCB0 aGF0IG1lYW5zIHRoYXQgeW91IGNhbm5vdA0KPiA+ID4gcGFzcyBibG9icyBjYXJyeWluZyBiaWcg a2VyYmVyb3MgdGlja2V0cy4NCj4gPiA+DQo+ID4gPiBBcyBhIHN0b3JhZ2UgbWVjaGFuaXNtIGZv ciBjcmVkZW50aWFsIGNhY2hlcyBpdCBhbHNvIGhhcyBzaXplIGxpbWl0cy4NCj4gPiA+IEN1cnJl bnRseSB0aGUgbGltaXQgaXMgMjBrIHBlciB1c2VyIHdoaWNoIGlzIG5vdCBldmVuIGVub3VnaCB0 byBob2xkDQo+ID4gPiBhIHNpbmdsZSB0aWNrZXQgaW4gc29tZSBjYXNlcy4gVGhpcyBsaW1pdCBj YW4gYmUgaW5jcmVhc2VkIG9mDQo+ID4gPiBjb3Vyc2UsIGJ1dCB0aGVuIHlvdSBlbmQga2VlcGlu ZyBhcm91bmQgYSBodWdlIGFtb3VudCBvZg0KPiB1bnN3YXBwYWJsZQ0KPiA+ID4gcmFtIGRlcGVu ZGluZyBvbiB0aGUgbnVtYmVyIG9mIHVzZXJzLg0KPiA+DQo+ID4gQWxsb3dpbmcga2V5cyB0byBi ZSBzd2FwcGVkIG91dCBpcyBhIHJlYWxseSByZWFsbHkgcmVhbGx5IHJlYWxseQ0KPiA+IHJlYWxs eSByZWFsbHkgYmFkIGlkZWEgd2hlbiB5b3VyIGtlcm5lbCBkZXBlbmRzIHVwb24gdGhlbSBiZWlu Zw0KPiA+IGF2YWlsYWJsZSBhcyBwYXJ0IG9mIHRoZSBtZW1vcnkgcmVjbGFpbSBwcm9jZXNzLCBh cyB3b3VsZCBiZSB0aGUgY2FzZQ0KPiA+IHdoZW4geW91IGFyZSB0YWxraW5nIGFib3V0IE5GUywg Q0lGUyBvciBBRlMgZGlydHkgcGFnZSB3cml0ZWJhY2tzLg0KPiANCj4gWW91IGRvIG5vdCBuZWVk IGxvbmcgdGVybSBrZXlzIG9uIGV4aXN0aW5nIG1vdW50cyB3aGljaCBpcyB0aGUgb25seSBjYXNl DQo+IHdoZXJlIHlvdSBoYXZlIGFueXRoaW5nIHRvIHJlbGVhc2UsIGdzcyBjb250ZXh0IHNlc3Np b24ga2V5cyB3aWxsIGJlIGtlcHQgaW4NCj4gdGhlIGtlcm5lbCBidXQgbmVlZCBub3QgYmUgc2hh cmVkIHdpdGggYW55dGhpbmcuDQoNClRoYXQncyBub3Qgc3VmZmljaWVudC4gU2VlIGJlbG93Lg0K DQo+IEl0IGlzIG9rIHRvIHVzZSBrZXlyaW5nIGlmIHRoYXQncyBkZWVtZWQgdGhlIHJpZ2h0IHBs YWNlIGZvciBzZXNzaW9uIGtleXMsIGJ1dCBJDQo+IHRoaW5rIHlvdSBhbHJlYWR5IGhhdmUgc3Ry dWN0dXJlcyB3aGVyZSB5b3UgY3VycmVudGx5IHN0b3JlIHRoZW0gc28gSSBkb24ndA0KPiB0aGlr IHlvdSBuZWNlc3NhcmlseSBuZWVkIHRvIGNoYW5nZSB0aGF0IHBhcnQgb2YgdGhlIGtlcm5lbCBp bXBsZW1lbnRhdGlvbi4NCg0KTm8sIGJ1dCB3ZSBzdGlsbCBuZWVkIHRvIGJlIGFibGUgdG8gZG8g cmVjb3Zlcnkgb2YgcnBjc2VjX2dzcyBjb250ZXh0cyBvbmNlIHRoZXkgYXJlIGJyb2tlbiwgYW5k IHJpZ2h0IG5vdyB3ZSBoYXZlIGEgbWFqb3IgZmxhdyBkdWUgdG8gdGhlIGZhY3QgdGhhdCByZWNv dmVyeSBkZXBlbmRzIG9uIGEgbG90IG9mIHNtYWxsIHByb2Nlc3NlcyBhbmQgZGF0YSB0aGF0IGlz IGFsbG93ZWQgdG8gYmUgc3dhcHBlZCBvdXQgYXQgdGhlIG1vbWVudCB3aGVuIHdlIG5lZWQgdGhl bSB0aGUgbW9zdCAoaS5lLiBpbiBhIG1lbW9yeSByZWNsYWltIHNpdHVhdGlvbikuDQoNCklmIHRo ZSBzZXJ2ZXIgcmVib290cyB3aGlsZSBvdXIgY2xpZW50IGlzIGluIHRoZSBtaWRkbGUgb2Ygd3Jp dGluZyBiYWNrIGEgZmlsZSAob3Igc2V2ZXJhbCBmaWxlcyksIHRoZW4gdGhlIGNsaWVudCBuZWVk cyB0byByZWNvdmVyIHRob3NlIHJwY3NlY19nc3MgY29udGV4dHMgdGhhdCBhdXRoZW50aWNhdGUg dGhlIHByb2Nlc3NlcyB3aGljaCBvd24gYW55IGRpcnR5IHBhZ2VzIHRoYXQgcmVtYWluIHRvIGJl IHdyaXR0ZW4gb3V0Lg0KS2V5IHNlY3VyaXR5IGlzIGFuIGlycmVsZXZhbnQgY29uY2VybiBvbmNl IHlvdXIga2VybmVsIGRlYWRsb2NrcyBpbiBhbiBPT00gc3RhdGUuDQoNCj4gPiA+IFNvIGZvciBs b25nIHRlcm0gc3RvcmFnZSBvZiBjcmVkZW50aWFscyB3ZSB3aWxsIHByb2JhYmx5IG5vdCByZWx5 IG9uDQo+ID4gPiBrZXJuZWwga2V5cmluZ3MsIG5vciBhcyBhbiB1cGNhbGwgbWVjaGFuaXNtLg0K PiA+DQo+ID4gU28gdGhpcyB3b3VsZCBiZSBhbiBhcmd1bWVudCBmb3Igc2NyYXBwaW5nIGtleXJp bmdzIGZyb20gdGhlIGtlcm5lbD8NCj4gPiBJZiB0aGV5J3JlIG5vdCBnb29kIGZvciBrZXJiZXJv cyB0aWNrZXRzLCB3aHkgd291bGQgd2Ugd2FudCB0byBrZWVwDQo+ID4gdGhlbSBhdCBhbGw/DQo+ IA0KPiBTZWUgYWJvdmUuDQo+IA0KPiBXZSBjb3VsZCBhbHNvIGJyZWFrIHRoZSB0aWNrZXRzIHNv IHRoYXQgb25seSB0aGUgdmFsdWFibGUgcGFydCBpcyBrZXB0IGluIHRoZQ0KPiBrZXlyaW5nLCBh bmQgdGhlIHJlc3QgKGVuY3J5cHRlZCB3aXRoIHRoZSBzZXNzaW9uIGtleSkgaW4gYSBmaWxlLg0K PiBJIGRvbjt0IHRoaW5rIHRoaXMgaW5mbHVlbmNlcyB0aGUgR1NTQVBJIFByb3h5IHByb3RvY29s IGFuZCBtZWNoYW5pc20uDQo+IEl0IGlzIGFuIGltcGxlbWVudGF0aW9uIGRldGFpbCB3ZSBjYW4g ZGlzY3VzcyB3aXRoaW4gdGhlIGxpbnV4IHNwZWNpZmljDQo+IGltcGxlbWVudGF0aW9uLg0KPiAN Cj4gPiBXaGF0IHdvdWxkIHlvdSByZXBsYWNlIHRoZW0gd2l0aCwgZ2l2ZW4gdGhlIGFib3ZlIHJl cXVpcmVtZW50cw0KPiA+IGNvbmNlcm5pbmcgc3dhcHBpbmc/DQo+IA0KPiBDdXJyZW50bHkgY3Jl ZGVudGlhbCBjYWNoZXMgYXJlIHN0b3JlZCBpbiBmaWxlcywgaXMgdGhlcmUgYSBwcm9ibGVtIHdp dGggdGhhdA0KPiBtb2RlbCA/IERvIHlvdSBuZWVkIGFjY2VzcyB0byBjcmVkZW50aWFsIGNhY2hl cyBmcm9tIHRoZSBrZXJuZWwgd2hlbg0KPiB1bmRlciBtZW1vcnkgcHJlc3N1cmUgPw0KDQoNClll cywgdGhlcmUgaXMgYSBtYWpvciBwcm9ibGVtIHdpdGggdGhhdCBtb2RlbCwgYW5kIHllcyB3ZSBk byBwb3RlbnRpYWxseSBuZWVkIGFjY2VzcyB0byBjcmVkZW50aWFsIGNhY2hlcyB3aGVuIGluIGEg cmVjb3Zlcnkgc2l0dWF0aW9uICh3aGljaCBpcyBhIHNpdHVhdGlvbiB3aGVuIHdlIGFyZSB1c3Vh bGx5IHVuZGVyIG1lbW9yeSBwcmVzc3VyZSkuDQoNClRyb25kDQo=
On Thu, 2011-11-03 at 15:16 -0700, Myklebust, Trond wrote:
[..]
Quoted 12 lines
No, but we still need to be able to do recovery of
rpcsec_gsscontexts once they are broken, and right now we have a major flaw due to the fact that recovery depends on a lot of small processes and data that is allowed to be swapped out at the moment when we need them the most (i.e. in a memory reclaim situation).If the server reboots while our client is in the middle of writing back a file (or several files), then the client needs to recover those
rpcsec_gsscontexts that authenticate the processes which own any dirty pages that remain to be written out.
Key security is an irrelevant concern once your kernel deadlocks in an OOM state.
[..]
Quoted 8 lines
Quoted 3 lines
Currently credential caches are stored in files, is there a problem with that model ? Do you need access to credential caches from the kernel when under memory pressure ?
Yes, there is a major problem with that model, and yes we do potentially need access to credential caches when in a recovery situation (which is a situation when we are usually under memory pressure).
This sounds like a catch 22 situation.
Even if the keys are pinned in kernel memory you still need the GSSAPI Proxy daemon in order to re-establish the security context, and that process could have been swapped off too.
I am not sure I see a way out here.
Simo.
Signature · 1 line
Simo Sorce * Red Hat, Inc * New York
Quoted 28 lines · Simo Sorce
On Thu, 2011-11-03 at 15:16 -0700, Myklebust, Trond wrote:
[..]
Quoted 12 lines
No, but we still need to be able to do recovery of
rpcsec_gsscontexts once they are broken, and right now we have a major flaw due to the fact that recovery depends on a lot of small processes and data that is allowed to be swapped out at the moment when we need them the most (i.e. in a memory reclaim situation).If the server reboots while our client is in the middle of writing back a file (or several files), then the client needs to recover those
rpcsec_gsscontexts that authenticate the processes which own any dirty pages that remain to be written out.
Key security is an irrelevant concern once your kernel deadlocks in an OOM state.[..]
Quoted 8 lines
Quoted 3 lines
Currently credential caches are stored in files, is there a problem with that model ? Do you need access to credential caches from the kernel when under memory pressure ?
Yes, there is a major problem with that model, and yes we do potentially need access to credential caches when in a recovery situation (which is a situation when we are usually under memory pressure).
Quoted 4 lines
This sounds like a catch 22 situation.
Even if the keys are pinned in kernel memory you still need the GSSAPI Proxy daemon in order to re-establish the security context, and that process could have been swapped off too.
Yes, this has been hashed over before.
You can try to pin it in memory. And then you'd also need some way the process could tell the kernel (e.g. when doing a system call that required allocation) that it was working on behalf of a filesystem. But at that point moving context negotiation into the kernel might be more practical.
Seems like a hard problem, but it would nice to at least have some long-term plan.
--b.
Quoted 8 lines · Trond
Quoted 3 lines
It is ok to use keyring if that's deemed the right place for session keys, but I think you already have structures where you currently store them so I don't thik you necessarily need to change that part of the kernel implementation.
No, but we still need to be able to do recovery of
rpcsec_gsscontexts once they are broken, and right now we have a major flaw due to the fact that recovery depends on a lot of small processes and data that is allowed to be swapped out at the moment when we need them the most (i.e. in a memory reclaim situation).If the server reboots while our client is in the middle of writing back a file (or several files), then the client needs to recover those
rpcsec_gsscontexts that authenticate the processes which own any dirty pages that remain to be written out. Key security is an irrelevant concern once your kernel deadlocks in an OOM state.
Ah, this problem. Hopefully the client has enough resources to thrash a lot in the process but still manage to recover. A better solution (see below) is possible, but will require more protocol/mechanism work.
Quoted 5 lines
Quoted 3 lines
Currently credential caches are stored in files, is there a problem with that model ? Do you need access to credential caches from the kernel when under memory pressure ?
Yes, there is a major problem with that model, and yes we do potentially need access to credential caches when in a recovery situation (which is a situation when we are usually under memory pressure).
Ideally we could store in each RPCSEC_GSS context (not GSS context) enough state on the client side to recover quickly when the server reboots. How would we do this? Suppose the server gives the client a "ticket", and a key much like the Kerberos ticket session key is agreed upon or sent by the server -- that could be stored in the RPCSEC_GSS context and could be used to recover it quickly for recovery from server reboot. I'm eliding a lot of details here, but I believe this is fundamentally workable.
A similar solution would be to store some GSS "sub-credential" in the RPCSEC_GSS context, but this would work for Kerberos and maybe not so well for other mechanisms -- and even with Kerberos, the service ticket might be expired when it comes time to recover. So I prefer the RPCSEC_GSS-level solution I mentioned above.
If you agree with me on this then this sub-thread will be best moved to the NFSv4 WG, particularly if we agree on a protocol-level solution.
Nico
--
Also, the recovery issue can come up with the server's cache of RPCSEC_GSS contexts is under pressure.
I really think we want an RPCSEC_GSS-level solution for this. I don't think we can address this problem entirely in the GSS stack. Since RPCSEC_GSSv3 isn't done yet, maybe now is the time to work on a solution there.
I'd build the solution by borrowing tech from Kerberos. The server would mint a ticket for itself using some local secret key for the ticket's encrypted part and with authorization data storing all of the relevant server-side authorization context for the client principal, then the server sends a KRB-CRED with that ticket and session key with the KRB-CRED wrapped in a GSS wrap token OR with an encryption key for the KRB-CRED based on GSS_Pseudo_random() OR it sends the ticket and the client uses GSS_Pseudo_random() to compute the same session key that the server did.
Nico
--
Quoted 20 lines · Nico Williams
Quoted 8 lines · Trond
Quoted 3 lines
It is ok to use keyring if that's deemed the right place for session keys, but I think you already have structures where you currently store them so I don't thik you necessarily need to change that part of the kernel implementation.
No, but we still need to be able to do recovery of
rpcsec_gsscontexts once they are broken, and right now we have a major flaw due to the fact that recovery depends on a lot of small processes and data that is allowed to be swapped out at the moment when we need them the most (i.e. in a memory reclaim situation).If the server reboots while our client is in the middle of writing back a file (or several files), then the client needs to recover those
rpcsec_gsscontexts that authenticate the processes which own any dirty pages that remain to be written out. Key security is an irrelevant concern once your kernel deadlocks in an OOM state.Ah, this problem. Hopefully the client has enough resources to thrash a lot in the process but still manage to recover. A better solution (see below) is possible, but will require more protocol/mechanism work.
Quoted 4 lines
Quoted 3 lines
Currently credential caches are stored in files, is there a problem with that model ? Do you need access to credential caches from the kernel when under memory pressure ?
Quoted 5 lines
Quoted 1 line
Yes, there is a major problem with that model, and yes we do potentially need access to credential caches when in a recovery situation (which is a situation when we are usually under memory pressure).
Ideally we could store in each
RPCSEC_GSScontext (not GSS context) enough state on the client side to recover quickly when the server reboots.
You mean not to use the user Kerberos credential to re-establish the GSS context with the server?
Quoted 6 lines
How would we do this? Suppose the server gives the client a "ticket", and a key much like the Kerberos ticket session key is agreed upon or sent by the server -- that could be stored in the
RPCSEC_GSScontext and could be used to recover it quickly for recovery from server reboot. I'm eliding a lot of details here, but I believe this is fundamentally workable.
So re-establish the RPCSEC_GSS session lost at the server on server reboot by storing enough additional info on the client?
-->Andy
Quoted 17 lines
A similar solution would be to store some GSS "sub-credential" in the
RPCSEC_GSScontext, but this would work for Kerberos and maybe not so well for other mechanisms -- and even with Kerberos, the service ticket might be expired when it comes time to recover. So I prefer the RPCSEC_GSS-level solution I mentioned above.If you agree with me on this then this sub-thread will be best moved to the NFSv4 WG, particularly if we agree on a protocol-level solution.
Nico
--
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 6 lines · Andy
Quoted 3 lines · Nico Williams
Ideally we could store in each
RPCSEC_GSScontext (not GSS context) enough state on the client side to recover quickly when the server reboots.You mean not to use the user Kerberos credential to re-establish the GSS context with the server?
Kerberos has tickets. Other GSS mechanisms don't. The GSS-API completely abstracts this, so there's no way to extract a service ticket and store it alongside the context (RPCSEC_GSS, in this case) where you might need it in the future. Storing all of a GSS-API credential (think of a whole ccache) in kernel memory is not an option either (ccaches have unbounded size).
Moreover, if we do this in a light-weight enough fashion we might be able to handle all of the recovery path in kernel-mode, with no dependence on upcalls. But if we didn't by somehow extracting the service ticket and storing it in the RPCSEC_GSS context we'd probably still need to upcall to make use of it.
Quoted 8 lines
Quoted 6 lines
How would we do this? Suppose the server gives the client a "ticket", and a key much like the Kerberos ticket session key is agreed upon or sent by the server -- that could be stored in the
RPCSEC_GSScontext and could be used to recover it quickly for recovery from server reboot. I'm eliding a lot of details here, but I believe this is fundamentally workable.So re-establish the
RPCSEC_GSSsession lost at the server on server reboot by storing enough additional info on the client?
Yes. And not just server reboot. The server is free to lose RPCSEC_GSS contexts any time it wants to.
Basically, we need a fast re-authentication facility that is easy to code entirely in kernel-mode. Thinking of it this way I would not reuse any Kerberos tech for this. The server would return a ticket in RPCSEC_GSS context establishment, but the ticket would consist of {secret key index, encrypted octet string} and the server and client would both compute a "session key" (for proving ticket possession) with GSS_Pseudo_random() (this way we can make this work even when the GSS mech only does MICs and not wrap tokens). To re-authenticate the client would send the ticket and an authenticator just like in Kerberos, but simpler.
Nico
--
Quoted 34 lines · Nico Williams
Quoted 6 lines · Andy
Quoted 3 lines · Nico Williams
Ideally we could store in each
RPCSEC_GSScontext (not GSS context) enough state on the client side to recover quickly when the server reboots.You mean not to use the user Kerberos credential to re-establish the GSS context with the server?
Kerberos has tickets. Other GSS mechanisms don't. The GSS-API completely abstracts this, so there's no way to extract a service ticket and store it alongside the context (
RPCSEC_GSS, in this case) where you might need it in the future. Storing all of a GSS-API credential (think of a whole ccache) in kernel memory is not an option either (ccaches have unbounded size).Moreover, if we do this in a light-weight enough fashion we might be able to handle all of the recovery path in kernel-mode, with no dependence on upcalls. But if we didn't by somehow extracting the service ticket and storing it in the
RPCSEC_GSScontext we'd probably still need to upcall to make use of it.Quoted 8 lines
Quoted 6 lines
How would we do this? Suppose the server gives the client a "ticket", and a key much like the Kerberos ticket session key is agreed upon or sent by the server -- that could be stored in the
RPCSEC_GSScontext and could be used to recover it quickly for recovery from server reboot. I'm eliding a lot of details here, but I believe this is fundamentally workable.So re-establish the
RPCSEC_GSSsession lost at the server on server reboot by storing enough additional info on the client?Yes. And not just server reboot. The server is free to lose
RPCSEC_GSScontexts any time it wants to.
Quoted 10 lines
Basically, we need a fast re-authentication facility that is easy to code entirely in kernel-mode. Thinking of it this way I would not reuse any Kerberos tech for this. The server would return a ticket in
RPCSEC_GSScontext establishment, but the ticket would consist of {secret key index, encrypted octet string} and the server and client would both compute a "session key" (for proving ticket possession) withGSS_Pseudo_random()(this way we can make this work even when the GSS mech only does MICs and not wrap tokens). To re-authenticate the client would send the ticket and an authenticator just like in Kerberos, but simpler.
I agree this would be a very nice feature for fast reconnects in NFSv4, but it looks more and more out of topic.
Time to move this sub-thread to the NFSv4 WG ?
Simo.
Signature · 1 line
Simo Sorce * Red Hat, Inc * New York
Quoted 3 lines · Simo Sorce
I agree this would be a very nice feature for fast reconnects in NFSv4, but it looks more and more out of topic.
Time to move this sub-thread to the NFSv4 WG ?
I agree, but I think first we need to hear agreement from the NFS folks in this thread that we should follow this, else we should pursue a different solution, at least for a while.
Quoted 7 lines · Nico Williams
Quoted 5 lines · Andy
Quoted 3 lines · Nico Williams
Ideally we could store in each
RPCSEC_GSScontext (not GSS context) enough state on the client side to recover quickly when the server reboots.
Quoted 8 lines
Quoted 1 line
You mean not to use the user Kerberos credential to re-establish the GSS context with the server?
Kerberos has tickets. Other GSS mechanisms don't. The GSS-API completely abstracts this, so there's no way to extract a service ticket and store it alongside the context (
RPCSEC_GSS, in this case) where you might need it in the future. Storing all of a GSS-API credential (think of a whole ccache) in kernel memory is not an option either (ccaches have unbounded size).
Well, don't all GSS mechanisms have credentials? We use the UID to map between the RPCSEC_GSS context and the credential, so we don't need to store the credential along side of the context.
That said, I agree that a light-weight method of re-establishing a context is very appealing.
-->Andy
Quoted 36 lines
Moreover, if we do this in a light-weight enough fashion we might be able to handle all of the recovery path in kernel-mode, with no dependence on upcalls. But if we didn't by somehow extracting the service ticket and storing it in the
RPCSEC_GSScontext we'd probably still need to upcall to make use of it.Quoted 8 lines
Quoted 6 lines
How would we do this? Suppose the server gives the client a "ticket", and a key much like the Kerberos ticket session key is agreed upon or sent by the server -- that could be stored in the
RPCSEC_GSScontext and could be used to recover it quickly for recovery from server reboot. I'm eliding a lot of details here, but I believe this is fundamentally workable.So re-establish the
RPCSEC_GSSsession lost at the server on server reboot by storing enough additional info on the client?Yes. And not just server reboot. The server is free to lose
RPCSEC_GSScontexts any time it wants to.Basically, we need a fast re-authentication facility that is easy to code entirely in kernel-mode. Thinking of it this way I would not reuse any Kerberos tech for this. The server would return a ticket in
RPCSEC_GSScontext establishment, but the ticket would consist of {secret key index, encrypted octet string} and the server and client would both compute a "session key" (for proving ticket possession) withGSS_Pseudo_random()(this way we can make this work even when the GSS mech only does MICs and not wrap tokens). To re-authenticate the client would send the ticket and an authenticator just like in Kerberos, but simpler.Nico
--
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 1 line · Andy
Well, don't all GSS mechanisms have credentials? We use the UID to map between the
RPCSEC_GSScontext and the credential, so we don't need to store the credential along side of the context.
The problem is that for some mechs credentials can get huge over time (e.g., Kerberos ccaches). Ensuring that all those credentials are available when we need them in order to reestablish RPCSEC_GSS contexts with the server so we can WRITE out cached dirty blocks in a memory pressure situation is... difficult or impossible -- anything we do to make that possible will be generally brittle.
If the GSS-API gave us a way to extract a "sub-credential" we might make do, BUT, that's ugly, IMO, and we still have to deal with the fact that that sub-credential's expiration time might not be convenient, thus needing extra code to refresh it proactively, and so on. I.e., a GSS-based solution to this problem could be a nightmare. An RPCSEC_GSS-based solution seems trivial by comparison.
Quoted 1 line
That said, I agree that a light-weight method of re-establishing a context is very appealing.
Not least because any re--auth credential refresh operations will involve only that client and server.
Nico
--
Quoted 8 lines · Trond Myklebust
Quoted 7 lines · Simo Sorce
I have discussed use of the keyring in a private discussion before starting the thread, and it turns out the keyring has a number of limitations that makes it probably unsuitable for this project.
As an upcall mechanism it has some limitations on the size of the payloads, IIRC limited to a page, and that means that you cannot pass blobs carrying big kerberos tickets.
I never meant storing the ccache, or even the TGTs in the keyring.
Quoted 10 lines
Quoted 5 lines
As a storage mechanism for credential caches it also has size limits. Currently the limit is 20k per user which is not even enough to hold a single ticket in some cases. This limit can be increased of course, but then you end keeping around a huge amount of unswappable ram depending on the number of users.
Allowing keys to be swapped out is a really really really really really really bad idea when your kernel depends upon them being available as part of the memory reclaim process, as would be the case when you are talking about NFS, CIFS or AFS dirty page writebacks.
If you have local swap you'll be fine. Of course, the text for the gssd had better be in-core. Diskless over NFS doesn't work all that well, IMO.
Obviously you'll need to be able to block the triggering process/syscall, and you'll need to make sure there's no deadlock, but the first is a given (since we're talking about NFS) and the second should be possible if gssd does not stray into any NFS mounts (see my comment about disklessness over NFS).
But even if you want diskless over NFS with RPCSEC_GSS (you'll want RPCSEC_GSSv3) you can make this work by ensuring that all of the text of gssd and its libraries and plugins and... are pinned in-core, and by not swapping over NFS. The way Linux boot works this is quite feasible. You'll want ccaches stored in tmpfs, of course.
Quoted 8 lines
Quoted 2 lines
So for long term storage of credentials we will probably not rely on kernel keyrings, nor as an upcall mechanism.
So this would be an argument for scrapping keyrings from the kernel? If they're not good for kerberos tickets, why would we want to keep them at all?
What would you replace them with, given the above requirements concerning swapping?
No, I don't think it's an argument for scrapping keyrings, just for not storing actual credentials in them (store references to them instead).
I like to think that my CPG proposal for Solaris from a few years ago is much cleaner than keyrings. But keyrings could be made to do.
Nico
--
Quoted 6 lines · Trond Myklebust
Linux already has per-user, per-process and per-thread keyrings which offer a high security storage solution for keys. The problem with those is that they are difficult to use in an asynchronous context when the original user's process/thread context is no longer available to us.
Ideally, though, that's what we'd like to see used.
Perhaps I misunderstand what you're proposing to use the keyring for, but I would like to clarify a few things.
Opaque key storage is probably not the right abstraction level to represent the kind of privilege separation we want here. It's clearly already possible to use the Linux keyring, TPM, smart cards, etc. to achieve opaque key storage.
One of the original goals is privilege separation. The GSS proxy can allow an unprivileged process to perform specific restricted operations with key material such as a host key, instead of the mostly unrestricted encryption, decryption, etc. access that you would get with an opaque or unextractable key model. The proxy could limit the client's use of the key to gss_accept_sec_context(), without allowing the sort of generalized cryptographic operations that would allow the client to, say, forge a PAC signature.
FYI, I also think Love needs to be on the cc list, if not heimdal-discuss.
Nico
--
Quoted 1 line · Nico Williams
FYI, I also think Love needs to be on the cc list, if not heimdal-discuss.
I knew I'd miss someone as said in the first email feel free to keep adding people or lists for now.
Incidentally I have been informed that some lists are holding message due to too many CCs, so I trimmed out people I *think* are subscribed to at least one of the mailing lists above. Apologies if I cut someone not on one of the lists.
Simo.
Signature · 1 line
Simo Sorce * Red Hat, Inc * New York