gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/seccheck/sinks/remote/README.md (about)

     1  # Introduction
     2  
     3  The remote sink implements a protocol that allows remote processes to monitor
     4  actions being taken inside the sandbox. This document provides information
     5  required to implement a monitoring process that consumes trace points. The
     6  remote sink uses a Unix-domain socket (UDS) for communication. It opens a new
     7  connection and sends a stream of trace points being triggered inside the sandbox
     8  to the monitoring process. The monitoring process is expected to have already
     9  created the UDS and be listening for new connections. This allows for a single
    10  process to monitor all sandboxes in the machine, for better resource usage, and
    11  simplifies lifecycle management. When a new sandbox starts, it creates a new
    12  connection. And when a sandbox exits, the connection is terminated.
    13  
    14  # Security Considerations
    15  
    16  It’s important to note that in gVisor’s Threat Model, the Sentry is not trusted.
    17  In order to ensure a secure posture, we assume the worst and consider that the
    18  Sentry has been exploited. With that in mind, the monitoring process must
    19  validate and never trust input received from the Sentry because it can be
    20  controlled by a malicious user. All fields must have hard coded size limits.
    21  Each sandbox uses a dedicated socket to prevent a malicious container from
    22  corrupting or DoS’ing other sandboxes communication.
    23  
    24  Simplicity in the protocol is paramount to keep the code easy to audit and
    25  secure. For this reason we chose to use UDS type `SOCK_SEQPACKET` to delimitate
    26  message boundaries. Also, each message contains a header and the payload uses
    27  [Protocol Buffers](https://developers.google.com/protocol-buffers) which is safe
    28  to deserialize using standard libraries.
    29  
    30  # Protocol
    31  
    32  Upon a new connection, there is a handshake message to ensure that both sides
    33  can communicate with each other. The handshake contract is detailed
    34  [here](https://cs.opensource.google/gvisor/gvisor/+/master:pkg/sentry/seccheck/points/common.proto;drc=e06df74a657e01008194f905f2795d43dd5a825e;bpv=1;bpt=1;l=63?gsn=Handshake&gs=kythe%3A%2F%2Fgithub.com%2Fgoogle%2Fgvisor%3Flang%3Dprotobuf%3Fpath%3Dpkg%2Fsentry%2Fseccheck%2Fpoints%2Fcommon.proto%234.0).
    35  
    36  This is the only time that the monitoring process writes to the socket. From
    37  this point on, it only reads a stream of trace points generated from the Sentry.
    38  Each message contain a header that describes the message being sent and a few
    39  more control fields, e.g. number of messages dropped. There is a full
    40  description of the header
    41  [here](https://cs.opensource.google/gvisor/gvisor/+/master:pkg/sentry/seccheck/sinks/remote/wire/wire.go).
    42  
    43  The payload can be deserialized based on the message type indicated in the
    44  header, Each message type corresponds to a protobuf type defined in one of
    45  [these files](https://cs.opensource.google/gvisor/gvisor/+/master:pkg/sentry/seccheck/points/).
    46  
    47  # Compatibility
    48  
    49  It’s important that updates to gVisor do not break compatibility with trace
    50  consumers. They may not understand new events, or new event fields, but should
    51  continue to work with the old event schema.
    52  
    53  *   **New message/trace point:** new messages and trace points can be added
    54      freely. The monitoring process will fail when it tries to deserialize an
    55      unknown proto type. They should ignore this error.
    56  *   **New field to event:** as long as proto updating rules are followed, the
    57      monitoring process will be able to deserialize the event, ignoring new
    58      fields.
    59  *   **Changes to existing fields:** these are rare given that syscall arguments
    60      don’t change. But if this is necessary, it should be handled as a deletion
    61      of the old field and addition of the new one. It may break event consumers
    62      that are relying on the old field being set, but at least the event can be
    63      deserialized and other fields will be correct. If possible, populate both
    64      fields until consumers have migrated over.
    65  *   **Message header change:** similar to proto, header changes can only be
    66      additional. Existing fields cannot change offsets. Header size can be used
    67      to determine what portions of the header are available.
    68  *   **Change in wire format:** it requires changing protocol version. This will
    69      be detected and handled during the handshake. If one of the side decide that
    70      it cannot talk to the other side, the communication will terminate.
    71  
    72  # Examples
    73  
    74  If you're looking to create a new monitoring process, you can use any of the
    75  examples provided as a starting point. As a picture is worth a thousand words,
    76  the same applies for code examples:
    77  
    78  1.  **Go:**
    79      [pkg/sentry/seccheck/sinks/remote/server/server.go](https://cs.opensource.google/gvisor/gvisor/+/master:pkg/sentry/seccheck/sinks/remote/server/server.go)
    80  1.  **C++:**
    81      [examples/seccheck/README.md](../../../../../examples/seccheck/README.md)
    82  
    83  # Testing
    84  
    85  Apart from using `runsc` directly to test that your code works, you can use a
    86  tool that we created to save and replay trace sessions in full without the need
    87  for complex setup. Just run `runsc` once to capture the trace files you need for
    88  the test, then just replay from the file as often as needed. See
    89  [tracereplay](../../../../../tools/tracereplay/README.md) for more details.