1

I'm extending an existing p2p/master Pub Sub framework to support additional security measures, via over the wire encryption and topic based access control. I'd like to use the x.509 certificates that I generate for nodes to communicate over TLS to also include the node's own specific topic policies; i.e limit what topics the certificate can be used to subscribe or publish with.

The current idea is as such:

  • Bootsrap
    • keyserver & master started
    • graph wide policy loaded into keyserver
    • new nodes without certs ask keyserver
    • keyserver looks up pub sub policy that match with node's namespace
    • keyserver returns node a cert with pub sub policy embedded
  • Out in the wild
    • only master is started, no keyserver
    • started nodes uses existing cert to register with master
    • master registers publisher or subscriber for requested topics
    • (master could try enforce to graph policy here, but master only notifies subscribers of where the publishers are, message transport for topics is still p2p)
    • subscriber attempts to connect to publisher
    • publisher scrutinises subscriber's cert to check to check it has permission to read topic
    • meanwhile subscriber does the same, checking publisher has permission to write to topic
    • if ether check fails, the connection is rejected!

I'd like to use apparmor's style of globbing syntax to permit novice users to simply generalize the access control over paths, this can be parsed and searched easily enough, and then embed the set of matching policies into the cert as perhaps a (human readable from common cert viewers? multi-line indented?) string. An example might look like this:

graph policy:

nodes:
  /*:
    topics:
      /logout{,_agg}:
        allow: rw
  /listener{,1,2}/**:
    topics:
      /chatter:
        allow: r
  /talker:
    topics:
      /chatter:
        allow: w

resulting node policy for /listener :

topics:
  /logout{,_agg}:
    allow: rw
  /chatter:
    allow: r

This way if the master node is ever compromised (but not the absent keyserver), nodes out in the wild still can't be fooled to talking or listening to anyone the shouldn't. Is there an existing certificate extension I should use or a particular form I should embed them with, or is there just a better way to go about this?

0

Ok, for posterity, here's my eventual approach for anyone coming along later finding this, and wonders what what I ended up doing while trying to to not obscurification the policy payload.

I essentially used the Certificate Policies extention to list the polocies applicable to the idenety. Each element in the list the containes PolicyInformation the structues the policy identifier with the policy qualifiers. The policy qualifiers is made to be a list of text strings, with each sting defining a applicable namespace scope using regex like syntax.

I used a nesting of of OIDs to map policy identifier to such actions as allowed/denied subscribable topic namespaces, etc. ttps://github.com/ros/ros_comm/blob/e8568a493f039e6112884de733af00d289213a34/tools/rosgraph/src/rosgraph/sros_consts.py#L6-L8

When two peers connect, they use the certificate context from the TLS connection to acquire the other node's Certificate Policies extension data. Before the client sends the API request, it scrutinized the server's policy extension to check it is authorized to service the API call. If it is it will proceed, and if not terminate the connection.

When the accepting server parsis the API method requested, it scrutinized the client's policy extension to check it is authorized to request the API call. If is is it will proceed and dispatch it, and if not terminate the connection.

Some minor optimizations are done, such as sorting the qualifier themselves before embedding, and then later searching the dening related policy qualifier for matching namespaces requested in the API call before searching the allowed policy qualifier, as to terminate unwanted connections sooner.

There are some pros and cons in embedding policies into the same certificate used in the transport layer. I touch on that briefly in an additional write up here: SROS: Securing ROS over thewire, in the graph, and through the kernel.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.