example/

directory
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 19, 2023 License: Apache-2.0

README

RCE Agent Example

This example demonstrates how to write a client and server (agent). Read the source code, client/main.go and server/main.go, to learn how it's done.

Running Client and Server (Agent)

To run the example, first go build in each directory, client/ and server/.

Second, cp server/slow-count.sh /tmp/. This script slowly counts to 10 to demonstrate streaming output (shown later).

Third, run the server (agent) without TLS certificates:

$ cd server/

$ ./server
2020/01/19 21:26:39.344626 server.go:77: insecure server listening on 127.0.0.1:5501
CTRL-C to shut down

Note for container users: although not covered by the present guide, the server (agent) may run inside containers. In this case, it should be started with ./server --addr 0.0.0.0:5501 to allow port mapping and hence external access.

By default, the server listens on 127.0.0.1:5501. The file server/commands.yaml contains the whitelist commands that the client can run:

commands:
  - name: exit-zero
    exec: ["/bin/bash", "-c", "exit 0"]
  - name: exit-one
    exec: ["/bin/bash", "-c", "exit 1"]
  - name: echo
    exec: ["/bin/echo"]
  - name: ls-tmp
    exec: ["/bin/ls", "/tmp/"]
  - name: slow-count
    exec: ["/tmp/slow-count.sh"]

The client can run show-count, for example (shown later).

Fourth, in another terminal, run the client:

$ cd client

$ ./client ls-tmp
2020/01/19 16:32:58 Connecting to 127.0.0.1:5501...
       ID: 6537d416d2744284b7cd6f613e4717ae
     Name: ls-tmp
    State: COMPLETE
      PID: 68820
StartTime: 1579469585591061000
 StopTime: 1579469585597939000
 ExitCode: 0
    Error:
   Stdout:
         : com.apple.launchd.O797Q43x0q
         : com.apple.launchd.zJM2uY1rsy
         : mysql.sock
         : mysql.sock.lock
         : powerlog
         : slow-count.sh
   Stderr:

This command makes the agent run ls /tmp. The full STDOUT and STDERR of the remote command is always returned. The Stdout output should match what is actually in /tmp on your computer.

Streaming Output

The ls-tmp command is almost instantaneous, so let's run the slow-count command which makes the agent run /tmp/slow-count.sh, the script you copied in step 2. Before the final output above, the client will stream the remote command's STDOUT every 2s:

$ ./client slow-count
2020/01/19 16:39:05 Connecting to 127.0.0.1:5501...
1
2
3
4
5
6
7
8
9
10
       ID: 119f8927d7ba417299e73079886f4af3
     Name: slow-count
    State: COMPLETE
      PID: 68863
StartTime: 1579469945914887000
 StopTime: 1579469955999737000
 ExitCode: 0
    Error:
   Stdout:
         : 1
         : 2
         : 3
         : 4
         : 5
         : 6
         : 7
         : 8
         : 9
         : 10
   Stderr:

The output at top (1 through 10) should print every 2 seconds before the command finishes and the final output is printed at bottom. This demonstrates how clients can stream the STDOUT and STDERR of long-running remote commands.

Using TLS Certificates

Normally, both client and server (agent) use TLS certificates (certs) issued by your private certificate authority (CA). This is how client and server (agent) mutually authenticate: the client verifies the agent's cert, and the agent verifies the client's cert. This requires a properly built Go tls.Config; see TLSConfig() in rce.go in the project root directory.

Re-run the agent and client with -tls-* options using the test certs:

$ cd server/

$ ./server -tls-ca ../../test/tls/test_root_ca.crt -tls-key ../../test/tls/test_server.key -tls-cert ../../test/tls/test_server.crt
TLS loaded
2020/01/19 21:48:21.513650 server.go:75: secure server listening on 127.0.0.1:5501
CTRL-C to shut down

Be sure the output says "secure server listening".

Then run the client again:

$ cd client/

$ ./client -tls-ca ../../test/tls/test_root_ca.crt -tls-key ../../test/tls/test_client.key -tls-cert ../../test/tls/test_client.crt ls-tmp
TLS loaded
2020/01/19 16:49:20 Connecting to 127.0.0.1:5501...
       ID: 6de0867081c2432f945de8500b85da3f
     Name: ls-tmp
    State: COMPLETE
      PID: 69067
<output truncated>

If there are any problems with the certs, the client won't connect.

Increasing gRPC Verbosity

Run the client and server with environment variables GRPC_GO_LOG_VERBOSITY_LEVEL=99 GRPC_GO_LOG_SEVERITY_LEVEL=info, like:

$ GRPC_GO_LOG_VERBOSITY_LEVEL=99 GRPC_GO_LOG_SEVERITY_LEVEL=info ./client ls-tmp
2020/01/19 16:53:16 Connecting to 127.0.0.1:5501...
INFO: 2020/01/19 16:53:16 parsed scheme: ""
INFO: 2020/01/19 16:53:16 scheme "" not registered, fallback to default scheme
INFO: 2020/01/19 16:53:16 ccResolverWrapper: sending new addresses to cc: [{127.0.0.1:5501 0  <nil>}]
INFO: 2020/01/19 16:53:16 ClientConn switching balancer to "pick_first"
INFO: 2020/01/19 16:53:16 pickfirstBalancer: HandleSubConnStateChange: 0xc00009d440, CONNECTING
INFO: 2020/01/19 16:53:16 pickfirstBalancer: HandleSubConnStateChange: 0xc00009d440, READY
INFO: 2020/01/19 16:53:16 transport: loopyWriter.run returning. connection error: desc = "transport is closing"
INFO: 2020/01/19 16:53:16 pickfirstBalancer: HandleSubConnStateChange: 0xc00009d440, TRANSIENT_FAILURE
2020/01/19 16:53:16 client.Start: %srpc error: code = Unavailable desc = transport is closing

The client failed ("transport is closing") because the agent is using TLS but the client is not.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL