Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
159 lines (130 sloc) 5.9 KB

Add Another User

Objective

This use case shows the OpenC2 commands involved in allowing another user access to WS1 API.

Initial Conditions

fw

Initial condition is the configuration in 00.websvr_basecase.md. User2 is connected to Webserver1, FW5 only allows in port 443 from the internet, and FW1 blocks all ip's and all ports other than those specifically established in the base case.

Scenario

The owner of the configuration, sFractal, decides to allow another user access to the WS1 API. Out of band, sFractal authenticates this other user (User6) and provides both User6 and FK1 a private key specifically for link establishment1 of the User6/WS1 link. User6 is at ip=6.6.6.6, but that is unknown to the assets in the cloud. WS1 is protected by some of the precepts of the Cloud Security Alliance's Software Defined Perimter2 including Single Packet Authorization (SPA)3 and pinhole firewall rules (ie all ip's on all ports are denied, other than the already established connections).

User6 sends a SPA packet on port 443 which makes it thru FW5 and is stopped by FW1 on VM1.

fk

VM1, in addition to WS1 and FW1, has FK1 running on it. FK1 is an instance of fwknop4. FK1 watches all incoming packets looking for SPA packets so it detects the User6 SPA packet from ip=6.6.6.6. Since it is a valid SPA packet, FK1 decides to open FW1 to allow User6 to establish a connection. For simplicity in this use case, FK1 will send an OpenC2 command to FW1. Other potential usecases might be:

  • FK1 to send an OpenC2 allow command to the Security Orchestrator which would in turn send an OpenC2 command to FW1
  • FK1 to send an OpenC2 alert to the Security Orchestrator which would in turn send an OpenC2 command to FW5.
  • FK1 to send a CSA SDP command5) to the Security Orchestrator which would in turn send an OpenC2 command to FW5.

The net result of all these usecases is an allow command is sent to FW5 (either from FK1 or the security orchestrator).

The OpenC2 command will need to temporarily open port 443 from ip 6.6.6.6 to WS1. Per CSA SDP the pinhole is both pinhole in both space (ip/port) and time. Therefore the allow command is temporary, just long enough to allow the establishment of the connection. Since FW5 is a stateful firewall, the established User6-WS1 connection will stay up once the allow expires.

FK1 sends the command (see next section) to FW5.

User6 then establishes an HTTPS connection to WS1.

u6

The allow expires in FW5 but the User6 - WS1 connection stays up since FW5 is a stateful firewall.

OpenC2 JSON Command

The command JSON data is:

{
  "id": "054b1eca-0a9b-404c-b0be-031302dced5c",
  "action": "allow",
  "target": {
    "ip_connection": {
      "ipv4_src": "6.6.6.6", 
      "ipv4_dst": "1.1.1.1", 
      "layer4_protocol": "TCP", 
      "dst_port": 443,
      "src_port": 44306,
      }
    },
  "options": {
    "start_time": "now",
    "duration": "30s",
    "response_requested": "Ack"
    }
}

The command does not have an actuator because in this usecase the command routing, authentication, and authorization is over a pre-established dedicated HTTPS API with mutual authentication between FK1 and FW1.

The pfsense firewall is implemented using firewall rules that are staged or 'precompiled' before executing. This is hidden from the command by the implementation of the pfsense openc2 interface. The intent of the command is to allow the ip connection and the details of how that is accomplished by creating a rule and then enabling is not needed to be specified in the command.

An alternative json to accomplish same thing, but at some future time, would be:

{
  "id": "054b1eca-0a9b-404c-b0be-031302dced5c",
  "action": "allow",
  "target": {
    "ip_connection": {
      "ipv4_src": "6.6.6.6", 
      "ipv4_dst": "1.1.1.1", 
      "layer4_protocol": "TCP", 
      "dst_port": 443,
      "src_port": 44306,
      }
    },
  "options": {
    "start_time": "2025-01-02T15:00:00Z",
    "stop_time":  "2025-01-02T15:00:30Z",
    "response_requested": "Ack"
    }
}

Response

The response comes back at two levels. Since the communications channel is over an https connection, the https response code is 200/OK. The data returned is JSON:

{
    "id": "054b1eca-0a9b-404c-b0be-031302dced5c",
    "response_code" : "Command Accepted",
}

I am not wedded to the response above. It is just a placeholder until the LSC decides responses.

The 'not ok' responses will be covered in a separate abuse case in 15.abuseJson.md.

Definition of Done:

  • User6 has established connection to WS1

OpenC2 Stories:

As {a role}, I want {feature} so that {reason}.

  • As FK1 (or as SO3), I want to send an OpenC2 command to tell FW1 to temporarily allow src_ip=6.6.6.6 port 44306 to dst_ip=1.1.1.1 port 443 so that User6 can establish a connection to WS1

Endnotes

  1. how this was setup is immaterial to this usecase; but will be convered in a different usecase (maybe 13.idam.md).
  2. More info on SDP can be found at https://en.wikipedia.org/wiki/Software_Defined_Perimeter and http://www.waverleylabs.com/demo/
  3. SPA specification can be found at https://cloudsecurityalliance.org/document/sdp-specification-v2-0/
  4. fwknop code can be found at https://github.com/mrash/fwknop
  5. SDP commands can be found at (put link here). Hopefully they'll adopt OpenC2 once we come out with it :-)
You can’t perform that action at this time.