How to modify path used in signature

Hello,

I work at a big company with several different ops teams. For the most
part, each ops team maintains its own open-source Chef server.

I’m looking into the feasibility of mimicking the Hosted Chef style of
paths, e.g. /organizations/opsteam1. So, for a node list from knife, the
request would look like ‘GET /organizations/opsteam1/nodes’.

If I put this behind a proxy and rewrite the path to just ‘/nodes’, I get a
401. After looking at the auth page at http://docs.opscode.com/auth.html,
that makes sense, since the hashed path is part of the signed request.

In order for this to work, the client needs to sign the request with
’/nodes’ as the path, even if the target path differs.

I know I’ll likely need to override


in both knife and chef-client to achieve what I’m looking for. I don’t
mind requiring that folks install a knife plugin or a gem for this to work.

Could you give me direction on how to best achieve this?

I know I could probably just setup some nginx rewrites on the Chef server,
but I’d like for the server to be as vanilla as can be.

Thanks!
-Ameir

P.S. This is just a high-level example of what I’m trying to achieve. I’m
mainly looking to find out how to proxy a request that updates values used
in the signature, without the proxy having to be the signer. Sending the
correctly-signed payload from the client is ideal.

On Jul 19, 2014, at 4:32 PM, Ameir Abdeldayem ameirh@gmail.com wrote:

Hello,

I work at a big company with several different ops teams. For the most part, each ops team maintains its own open-source Chef server.

I'm looking into the feasibility of mimicking the Hosted Chef style of paths, e.g. /organizations/opsteam1. So, for a node list from knife, the request would look like 'GET /organizations/opsteam1/nodes'.

If I put this behind a proxy and rewrite the path to just '/nodes', I get a 401. After looking at the auth page at Chef Infra Client Security, that makes sense, since the hashed path is part of the signed request.

In order for this to work, the client needs to sign the request with '/nodes' as the path, even if the target path differs.

I know I'll likely need to override https://github.com/opscode/mixlib-authentication/blob/a32e96a6a8cd53e2ff2a775ef0f757550289f89b/lib/mixlib/authentication/signedheaderauth.rb#L119 in both knife and chef-client to achieve what I'm looking for. I don't mind requiring that folks install a knife plugin or a gem for this to work.

Could you give me direction on how to best achieve this?

Best? Purchase an Enterprise Chef license. While you might be able to hack this together, its going to be both highly insecure (no audit records, etc) and very breakable.

--Noah

We wanted to implement some custom Chef behavior and it wasn't too
difficult to write a Chef proxy that decrypts signed requests from
clients/nodes, processes them with whatever logic necessary, and
re-encrypts it using appropriate keys and sends it on their way to
appropriate Chef server or rejects them. Chef's mixlib-authentication
library can be used for verifying signed headers and signing new requests.
I think it's easiest to use Rails for the proxy as mixlib-authentication
seems to work best with its Request object.

So, it definitely can be done, and then you'll have the flexibility of
adding any custom behavior to it, including notifications, auditing, better
access control, etc.

On Sat, Jul 19, 2014 at 4:38 PM, Noah Kantrowitz noah@coderanger.net
wrote:

On Jul 19, 2014, at 4:32 PM, Ameir Abdeldayem ameirh@gmail.com wrote:

Hello,

I work at a big company with several different ops teams. For the most
part, each ops team maintains its own open-source Chef server.

I'm looking into the feasibility of mimicking the Hosted Chef style of
paths, e.g. /organizations/opsteam1. So, for a node list from knife, the
request would look like 'GET /organizations/opsteam1/nodes'.

If I put this behind a proxy and rewrite the path to just '/nodes', I
get a 401. After looking at the auth page at
Chef Infra Client Security, that makes sense, since the hashed
path is part of the signed request.

In order for this to work, the client needs to sign the request with
'/nodes' as the path, even if the target path differs.

I know I'll likely need to override
https://github.com/opscode/mixlib-authentication/blob/a32e96a6a8cd53e2ff2a775ef0f757550289f89b/lib/mixlib/authentication/signedheaderauth.rb#L119
in both knife and chef-client to achieve what I'm looking for. I don't
mind requiring that folks install a knife plugin or a gem for this to work.

Could you give me direction on how to best achieve this?

Best? Purchase an Enterprise Chef license. While you might be able to hack
this together, its going to be both highly insecure (no audit records, etc)
and very breakable.

--Noah

--
Best regards, Dmitriy V.

You could achieve this pretty easily by setting custom http headers in the
chef client (an already supported feature) that were something along the
lines of 'x-custom-organization'. The proxy could route based on this
header and everything else about the signature could remain the same,
removing the need to alter the signature at the proxy and reduce security.

Another alternative would be to adopt a naming scheme for nodes that the
proxy could route by, and the switching would occur based on the
'x-chef-user' header.

Cheers!
Stephen

On Sunday, July 20, 2014, DV vindimy@gmail.com wrote:

We wanted to implement some custom Chef behavior and it wasn't too
difficult to write a Chef proxy that decrypts signed requests from
clients/nodes, processes them with whatever logic necessary, and
re-encrypts it using appropriate keys and sends it on their way to
appropriate Chef server or rejects them. Chef's mixlib-authentication
library can be used for verifying signed headers and signing new requests.
I think it's easiest to use Rails for the proxy as mixlib-authentication
seems to work best with its Request object.

So, it definitely can be done, and then you'll have the flexibility of
adding any custom behavior to it, including notifications, auditing, better
access control, etc.

On Sat, Jul 19, 2014 at 4:38 PM, Noah Kantrowitz <noah@coderanger.net
<javascript:_e(%7B%7D,'cvml','noah@coderanger.net');>> wrote:

On Jul 19, 2014, at 4:32 PM, Ameir Abdeldayem <ameirh@gmail.com
<javascript:_e(%7B%7D,'cvml','ameirh@gmail.com');>> wrote:

Hello,

I work at a big company with several different ops teams. For the most
part, each ops team maintains its own open-source Chef server.

I'm looking into the feasibility of mimicking the Hosted Chef style of
paths, e.g. /organizations/opsteam1. So, for a node list from knife, the
request would look like 'GET /organizations/opsteam1/nodes'.

If I put this behind a proxy and rewrite the path to just '/nodes', I
get a 401. After looking at the auth page at
Chef Infra Client Security, that makes sense, since the hashed
path is part of the signed request.

In order for this to work, the client needs to sign the request with
'/nodes' as the path, even if the target path differs.

I know I'll likely need to override
https://github.com/opscode/mixlib-authentication/blob/a32e96a6a8cd53e2ff2a775ef0f757550289f89b/lib/mixlib/authentication/signedheaderauth.rb#L119
in both knife and chef-client to achieve what I'm looking for. I don't
mind requiring that folks install a knife plugin or a gem for this to work.

Could you give me direction on how to best achieve this?

Best? Purchase an Enterprise Chef license. While you might be able to
hack this together, its going to be both highly insecure (no audit records,
etc) and very breakable.

--Noah

--
Best regards, Dmitriy V.

--
Stephen Delano
Software Development Engineer
Opscode, Inc.
1008 Western Avenue
Suite 601
Seattle, WA 98104