From cb880db0b5921acf6ed213df50acc8e45b00f169 Mon Sep 17 00:00:00 2001 From: Solomon Himelbloom <7608183+TechSolomon@users.noreply.github.com> Date: Tue, 5 Mar 2024 13:38:51 -0900 Subject: [PATCH] Security policy updates & application baseline (#26) * feat: creating sample Go module * feat: example error handling * refactor: random example communication message * feat: example map data type (slice) & test cases * Template for suggested experimental expectations (#24) * feat: draft variable packet size experiment * docs: new section for project replicability * docs: markdown diagram (system control flow) + blockquote highlight * refactor: utility to insights + diode collection script * fix: text cache source location * Delete `message` directory * Delete `example` directory * bump: latest Go milestone (minor release) --- .github/workflows/go.yml | 2 +- .gitignore | 3 +++ Makefile | 2 +- README.md | 38 ++++++++++++++++-------------- diode.go | 7 +++--- diode_test.go | 6 ++--- docs/SOP.md | 22 +++++++++++++++++ go.mod | 7 ++++-- go.sum | 10 ++++++++ {utility => insights}/benchmark.go | 4 ++-- insights/experiment.go | 38 ++++++++++++++++++++++++++++++ insights/observability.sh | 29 +++++++++++++++++++++++ 12 files changed, 137 insertions(+), 31 deletions(-) create mode 100644 docs/SOP.md rename {utility => insights}/benchmark.go (85%) create mode 100644 insights/experiment.go create mode 100755 insights/observability.sh diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 211f7a1..9efed08 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -18,7 +18,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "1.22" + go-version: "stable" - name: Install dependencies run: go get . diff --git a/.gitignore b/.gitignore index 3b735ec..240c040 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,6 @@ # Go workspace file go.work + +# xperimental results +*.txt diff --git a/Makefile b/Makefile index ee670c2..8e0efcd 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ build: - go build -o diode -ldflags="-X main.SemVer=0.0.6" diode.go + go build -o diode -ldflags="-X main.SemVer=0.0.7" diode.go test: go test -v diff --git a/README.md b/README.md index 27a4531..9310f75 100644 --- a/README.md +++ b/README.md @@ -4,20 +4,19 @@ Scripts for verifying TCP passthrough functionality. ## Development Instructions -> [!NOTE] +> [!TIP] > This project utilizes [`go`](https://go.dev/) for module management. -> You can find installation instructions for `1.22.0` via https://go.dev/doc/install. +> You can find installation instructions via https://go.dev/doc/install. - Clone repository: `gh repo clone acep-uaf/data-diode` - Source navigation: `cd data-diode` - Build binary: `make` - CLI: `./diode [options...]` -#### Architecture Diagram - -###### Energy Testbed +#### Branch Management -###### Device Configuration +- `main` → production ready environment. +- `dev` → testing changes to be merged into `main`. #### Directory Structure @@ -29,8 +28,10 @@ Scripts for verifying TCP passthrough functionality. ├── diode_test.go ├── docker-compose.yaml ├── Dockerfile +├── docs ├── go.mod ├── go.sum +├── insights ├── Makefile ├── mqtt ├── Pipfile @@ -39,10 +40,21 @@ Scripts for verifying TCP passthrough functionality. ├── sample └── utility -4 directories, 11 files +``` + +#### Architecture Diagram (WIP) +```mermaid +graph LR + A("Publish (MQTT)") --> B(TCP Client) + B --> C(Data Diode) + C --> D(TCP Server) + D --> E("Subscribe (MQTT)") ``` +> [!NOTE] +> Operational Technology (OT) vs. Information Technology (IT) system boundaries. + ## User Stories #### Scenario Planning @@ -60,18 +72,8 @@ Scripts for verifying TCP passthrough functionality. ## System Benchmarking -#### Risk Matrix ([5x5](https://safetyculture.com/topics/risk-assessment/5x5-risk-matrix/)) - -| ↔ Probability
Impact ↕ | **Insignificant** | **Minor** | **Significant** | **Major** | **Severe** | -| --------------------------- | ----------------- | --------- | --------------- | --------- | ---------- | -| **Almost Certain** | R01 | R02 | R03 | R04 | R05 | -| **Likely** | R06 | R07 | R08 | R09 | R10 | -| **Moderate** | R11 | R12 | R13 | R14 | R15 | -| **Unlikely** | R16 | R17 | R18 | R19 | R20 | -| **Rare** | R21 | R22 | R23 | R24 | R25 | - #### Experimental Design -- [data/logbook.ipynb](data/logbook.ipynb) +###### [Device Configuration](docs/SOP.md) [^1]: https://csrc.nist.gov/glossary/term/tactics_techniques_and_procedures diff --git a/diode.go b/diode.go index 95676ae..fee73a3 100644 --- a/diode.go +++ b/diode.go @@ -13,6 +13,7 @@ import ( "os" "time" + "github.com/acep-uaf/data-diode/insights" "github.com/acep-uaf/data-diode/utility" "github.com/urfave/cli/v2" "gopkg.in/yaml.v2" @@ -42,8 +43,7 @@ type Configuration struct { func sampleMetrics(server string, port int) { fmt.Println(">> Local time: ", time.Now()) fmt.Println(">> UTC time: ", time.Now().UTC()) - fmt.Println(">> Value: ", utility.Value()) - // utility.Client(server, port) + fmt.Println(">> Value: ", analysis.Value()) } func main() { @@ -105,8 +105,7 @@ func main() { Usage: "Testing state synchronization via diode I/O", Action: func(tCtx *cli.Context) error { fmt.Println("----- TEST -----") - example := utility.Checksum() - fmt.Printf(">> Checksum: %x\n", example) + analysis.Validation() return nil }, }, diff --git a/diode_test.go b/diode_test.go index 5ada02c..df2afc8 100644 --- a/diode_test.go +++ b/diode_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - "github.com/acep-uaf/data-diode/utility" + insights "github.com/acep-uaf/data-diode/insights" ) func TestCLI(t *testing.T) { @@ -26,8 +26,8 @@ func TestConfiguration(t *testing.T) { } func TestFileContents(t *testing.T) { - got := fmt.Sprintf("%x", utility.Checksum()) - want := "ed03bb5d7385010c645c2c72ceabea3b15806db757005071309745c59933586f" + got := fmt.Sprintf("%x", insights.Checksum()) + want := "477076c6fd8cf48ff2d0159b22bada27588c6fa84918d1c4fc20cd9ddd291dbd" if got != want { t.Errorf("got %q, want %q", got, want) diff --git a/docs/SOP.md b/docs/SOP.md new file mode 100644 index 0000000..ae6e131 --- /dev/null +++ b/docs/SOP.md @@ -0,0 +1,22 @@ +# Standard Operating Procedures + +## System Control Flow + +> [!CAUTION] +> Unidirectional data flow from the source to the destination. + +## Research Question + +#### State Synchronization + +#### System Replication + +## System Analysis + +#### Latency + +#### Bandwidth + +#### Throughput + +## Data Integrity diff --git a/go.mod b/go.mod index 0ff8e2c..3a430ae 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,10 @@ module github.com/acep-uaf/data-diode -go 1.22.0 +go 1.22.1 require ( github.com/eclipse/paho.mqtt.golang v1.4.3 + github.com/olekukonko/tablewriter v0.0.5 github.com/urfave/cli/v2 v2.27.1 gopkg.in/yaml.v2 v2.4.0 ) @@ -11,8 +12,10 @@ require ( require ( github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/gorilla/websocket v1.5.1 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect - golang.org/x/net v0.21.0 // indirect + golang.org/x/net v0.22.0 // indirect golang.org/x/sync v0.6.0 // indirect ) diff --git a/go.sum b/go.sum index 21a03d9..8142b1f 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,14 @@ github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQ github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= @@ -12,6 +20,8 @@ github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7v github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/utility/benchmark.go b/insights/benchmark.go similarity index 85% rename from utility/benchmark.go rename to insights/benchmark.go index b1edf1f..80cd4f8 100644 --- a/utility/benchmark.go +++ b/insights/benchmark.go @@ -1,4 +1,4 @@ -package utility +package analysis import ( "crypto/sha256" @@ -9,7 +9,7 @@ import ( ) func Checksum() [32]byte { - location := "https://www.gutenberg.org/cache/epub/2701/pg2701.txt" + location := "https://www.gutenberg.org/cache/epub/84/pg84.txt" resp, err := http.Get(location) diff --git a/insights/experiment.go b/insights/experiment.go new file mode 100644 index 0000000..191b195 --- /dev/null +++ b/insights/experiment.go @@ -0,0 +1,38 @@ +package analysis + +import ( + "fmt" + "os" + + "github.com/olekukonko/tablewriter" +) + +func Isolation() { + data := [][]string{ + {"Objective", "Vary the packet size in a one packet per second test to observe the impact on bandwidth and latency."}, + {"Expectation", "Low data rate (small packets) will deliver poor bandwidth but good latency, high data rate (large packets) will deliver good bandwidth but poor latency."}, + {"Scenario", "Investigate what happens if more data per second is sent than the diode can forward."}, + {"Question", "Is the excess data queued or dropped?"}, + } + + table := tablewriter.NewWriter(os.Stdout) + table.SetHeader([]string{"Experiment", "Description"}) + + for _, v := range data { + table.Append(v) + } + + table.Render() +} + +func Validation() { + fmt.Println(">> Variable Packet Size") + + example := []string{ + "Latency", "Throughput", "Bandwidth", "Packet Queue", + } + + for _, v := range example { + fmt.Println("* ", v) + } +} diff --git a/insights/observability.sh b/insights/observability.sh new file mode 100755 index 0000000..45fe4d4 --- /dev/null +++ b/insights/observability.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +START=`date +%Y-%m-%d-%k:%m:%S` +COLLECTION=`date +%Y-%m-%d` +LOGFILE="insights/ACEP_CAMIO_SEDOID_RESULTS-${COLLECTION}.txt" + +function log() { + echo "diode: $@" + echo "$@" >> $LOGFILE +} + +TARGET_LOCATION="localhost" +VARIABLE_SIZE=(64 128 256 512 1024 2048) # packets +TEST_DURATION=10 # seconds + +run_experiment() { + local packet_size=$1 + echo ">> Running trial with $packet_size bytes" + + ping -c $((TEST_DURATION)) -s $packet_size $TARGET_LOCATION >> $LOGFILE + + sleep 5 +} + +for iteration in ${VARIABLE_SIZE[@]}; do + run_experiment $iteration +done + +echo ">> Experiment complete. Results: $LOGFILE"