Skip to content

Commit

Permalink
feat: new Tailscale module
Browse files Browse the repository at this point in the history
The `tailscale` module can be used to add an ot-sim device (bare metal,
VM, Docker container, etc) to a Tailscale tailnet at the underlying OS
level. It does so by shelling out to start the `tailscaled` daemon and
then shelling out to `tailscale up` to add the device to the tailnet.

A Tailscale auth key must be provided, either in the XML config or via
an environment variable. A hostname to use for the device on the tailnet
can also be provided. If not provided, the underlying OS hostname is
used.

```
<tailscale>
  <auth-key>tskey-auth-...</auth-key>
  <hostname>foobar</hostname>
  <accept-dns>false</accept-dns>
</tailscale>
```

The `OTSIM_TAILSCALE_AUTHKEY` environment variable can be used instead
of the `<auth-key>` configuration element if needed.

Note that the underlying OS (bare metal, VM, Docker container) must
already have the `tailscaled` and `tailscale` executables installed. See
the main OT-sim Dockerfile for an example of how to install the
Tailscale executables.

Also note that, in order for Tailscale to work in a Docker container,
the `NET_ADMIN` capability must be added and the `/dev/net/tun` and
`/lib/modules` volumes must be mounted (`/lib/modules` can be mounted
read-only).
  • Loading branch information
activeshadow committed Mar 11, 2024
1 parent c1e7efb commit 014bab7
Show file tree
Hide file tree
Showing 4 changed files with 381 additions and 8 deletions.
12 changes: 12 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ RUN apt update && apt install -y \
bash-completion curl git tmux tree vim wget xz-utils \
libczmq4 libsodium23 libxml2 libzmq5 python3-pip

RUN curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg \
| tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null \
&& curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list \
| tee /etc/apt/sources.list.d/tailscale.list \
&& apt update && apt install -y tailscale

WORKDIR /root

ADD install-node-red.sh .
Expand Down Expand Up @@ -86,6 +92,12 @@ RUN apt update && apt install -y \
bash-completion curl git mbpoll tmux tree vim wget xz-utils \
build-essential cmake libczmq4 libsodium23 libxml2 libzmq5 python3-dev python3-pip

RUN curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg \
| tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null \
&& curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list \
| tee /etc/apt/sources.list.d/tailscale.list \
&& apt update && apt install -y tailscale

RUN wget -O hivemind.gz https://github.com/DarthSim/hivemind/releases/download/v1.1.0/hivemind-v1.1.0-linux-amd64.gz \
&& gunzip --stdout hivemind.gz > /usr/local/bin/hivemind \
&& chmod +x /usr/local/bin/hivemind \
Expand Down
23 changes: 15 additions & 8 deletions src/go/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ MSGBUS_SOURCES := $(shell find msgbus \( -name '*.go' \))
clean:
$(RM) bin/*

all: bin/ot-sim-cpu-module bin/ot-sim-logic-module bin/ot-sim-modbus-module bin/ot-sim-mqtt-module bin/ot-sim-node-red-module bin/ot-sim-telnet-module
all: bin/ot-sim-cpu-module bin/ot-sim-logic-module bin/ot-sim-modbus-module bin/ot-sim-mqtt-module bin/ot-sim-node-red-module bin/ot-sim-tailscale-module bin/ot-sim-telnet-module

CPU_SOURCES := $(shell find cpu \( -name '*.go' \))

Expand Down Expand Up @@ -46,17 +46,24 @@ bin/ot-sim-node-red-module: $(NODERED_SOURCES)
mkdir -p bin
GOOS=linux go build -a -ldflags="-s -w" -trimpath -o bin/ot-sim-node-red-module cmd/ot-sim-node-red-module/main.go

TAILSCALE_SOURCES := $(shell find tailscale \( -name '*.go' \))

bin/ot-sim-tailscale-module: $(TAILSCALE_SOURCES) $(MSGBUS_SOURCES)
mkdir -p bin
GOOS=linux go build -a -ldflags="-s -w" -trimpath -o bin/ot-sim-tailscale-module cmd/ot-sim-tailscale-module/main.go

TELNET_SOURCES := $(shell find telnet \( -name '*.go' \))

bin/ot-sim-telnet-module: $(TELNET_SOURCES) $(MSGBUS_SOURCES)
mkdir -p bin
GOOS=linux go build -a -ldflags="-s -w" -trimpath -o bin/ot-sim-telnet-module cmd/ot-sim-telnet-module/main.go

.PHONY: install
install: bin/ot-sim-cpu-module bin/ot-sim-logic-module bin/ot-sim-modbus-module bin/ot-sim-mqtt-module bin/ot-sim-node-red-module bin/ot-sim-telnet-module
cp bin/ot-sim-cpu-module $(prefix)/bin/ot-sim-cpu-module
cp bin/ot-sim-logic-module $(prefix)/bin/ot-sim-logic-module
cp bin/ot-sim-modbus-module $(prefix)/bin/ot-sim-modbus-module
cp bin/ot-sim-mqtt-module $(prefix)/bin/ot-sim-mqtt-module
cp bin/ot-sim-node-red-module $(prefix)/bin/ot-sim-node-red-module
cp bin/ot-sim-telnet-module $(prefix)/bin/ot-sim-telnet-module
install: bin/ot-sim-cpu-module bin/ot-sim-logic-module bin/ot-sim-modbus-module bin/ot-sim-mqtt-module bin/ot-sim-node-red-module bin/ot-sim-tailscale-module bin/ot-sim-telnet-module
cp bin/ot-sim-cpu-module $(prefix)/bin/ot-sim-cpu-module
cp bin/ot-sim-logic-module $(prefix)/bin/ot-sim-logic-module
cp bin/ot-sim-modbus-module $(prefix)/bin/ot-sim-modbus-module
cp bin/ot-sim-mqtt-module $(prefix)/bin/ot-sim-mqtt-module
cp bin/ot-sim-node-red-module $(prefix)/bin/ot-sim-node-red-module
cp bin/ot-sim-tailscale-module $(prefix)/bin/ot-sim-tailscale-module
cp bin/ot-sim-telnet-module $(prefix)/bin/ot-sim-telnet-module
53 changes: 53 additions & 0 deletions src/go/cmd/ot-sim-tailscale-module/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package main

import (
"context"
"errors"
"fmt"
"os"

otsim "github.com/patsec/ot-sim"
"github.com/patsec/ot-sim/util"
"github.com/patsec/ot-sim/util/sigterm"

// This will cause the Tailscale module to register itself with the otsim
// package so it gets run by the otsim.Start function below.
_ "github.com/patsec/ot-sim/tailscale"
)

func main() {
if len(os.Args) != 2 {
panic("path to config file not provided")
}

if err := otsim.ParseConfigFile(os.Args[1]); err != nil {
fmt.Printf("Error parsing config file: %v\n", err)
os.Exit(util.ExitNoRestart)
}

ctx := sigterm.CancelContext(context.Background())

if err := otsim.Start(ctx); err != nil {
fmt.Printf("Error starting Tailscale module: %v\n", err)

var exitErr util.ExitError
if errors.As(err, &exitErr) {
os.Exit(exitErr.ExitCode)
}

os.Exit(1)
}

<-ctx.Done()

if err := ctx.Err(); err != nil && !errors.Is(err, context.Canceled) {
fmt.Printf("Error running Tailscale module: %v\n", err)

var exitErr util.ExitError
if errors.As(err, &exitErr) {
os.Exit(exitErr.ExitCode)
}

os.Exit(1)
}
}
Loading

0 comments on commit 014bab7

Please sign in to comment.