gokill

gokill is a software dead man's switch. It belongs to the category of anti-forensic tools, providing a means to safeguard against potential repression. It is specifically crafted for worst-case scenarios, such as when intruders gain physical access to a device. In these intense situations, gokill can automatically perform tasks to enhance your security. Those could be:

  • deleting data
  • sending chat messages
  • encrypting partitions
  • destroying encrypted partitions
  • locking the screen
  • ect

documentation

A full list of Triggers and Actions with all their configuration options can be found here: https://k4lipso.github.io/gokill/

usage

If you use NixOS gokill can easily be integrated into your system configuration - scroll down for more info on that.

For all other linux distributions gokill currently needs to be built and setup manually.

# Clone the gokill repository
git clone https://github.com/k4lipso/gokill
cd gokill

# Build gokill - requires libolm
go build cmd/gokill/gokill.go

# Create a config.json and run gokill
./gokill -c config.json
# Running gokill manually is annoying, it is acutally meant to run as systemd unit.

Config Example

gokill is configured using a json file. it consists of a list of triggers, where each of the triggers as a list of actions that will be executed once triggered.

[ //list of triggers
    {
		"type": "UsbDisconnect", //triggers when the given device is disconnected
		"name": "First Trigger",
		"options": {
			"deviceId": "ata-Samsung_SSD_860_EVO_1TB_S4AALKWJDI102",
			"waitTillConnected": true //only trigger when usb drive was actually attached before
		},
        "actions": [ //list of actions that will be executed when triggered
            {
                "name": "unixCommand",
                "options": {
                    "command": "shutdown -h now"
                },
                "stage": 2 // defines the order in which actions are triggered.
            },
            {
		        "type": "SendTelegram",
		        "options": {
		        	"token": "3345823487:FFGdEFxc1pA18d02Akslw-lkwjdA92KAH2",
		        	"chatId": -832325872,
		        	"message": "attention, intruders got my device!",
		        	"testMessage": "this is just a test, no worries"
		        },
                "stage": 1 //this event is triggered first, then the shutdown
            }
        ]
    },
    {
		"type": "EthernetDisconnect",
		"name": "Second Trigger",
		"options": {
			"interfaceName": "eth0",
		},
        "actions": [
            {
                "name": "unixCommand",
                "options": {
                    "command": "env DISPLAY=:0 sudo su -c i3lock someUser" //example of locking someUser's screen as root
                }
            }
        ]
    }
]

nix support

gokill enjoys full nix support. gokill exposes a nix flakes that outputs a gokill package, a nixosModule and more. That means you can super easily incorporate gokill into your existing nixosConfigurations.

NixOS Module

Here is a small example config:

{
  services.gokill.enable = true;
  services.gokill.triggers = [
    {
      type = "EthernetDisconnect";
      name = "MainTrigger";
      options = {
        interfaceName = "eth1";
      };
      actions = [
        {
            type = "Command";
            options = {
                command = "echo hello world";
            };
            stage = 1;
        }
      ];
    }
  ];
}

This will automatically configure and enable a systemd running gokill as root user in the background

Build Documentation locally

nix run github:k4lipso/gokill#docs

Run integrations tests

nix flake check github:k4lipso/gokill

Triggers

Triggers wait for certain events and execute the actions defined for them. There are different Triggers for different use cases. For example UsbDisconnect is triggered when a certain Usb Drive is unplugged. If you want your actions to be triggered when an ethernet cable is pulled use EthernetDisconnect instead.

Triggers have the following syntax:

{
  "type": "SomeTrigger",
  "name": "MyFirstTrigger",
  "loop": true, //optional (default=false); restart after it got triggered
  "options": { //each trigger defines its own options
    "firstOption": 23,
    "secondOption": "foo"
  },
  "actions": [] //list actions that should be executed here
}

EthernetDisconnect

Triggers if Ethernetcable is disconnected.

Example:


	{
		"type": "EthernetDisconnect",
		"name": "Example Trigger",
		"options": {
			"interfaceName": "eth0",
			"waitTillConnected": true
		},
		"actions": [
		]
	}
	

Options:

waitTillConnected

Only trigger when device was connected before

Type: bool

Default: true

interfaceName

Name of ethernet adapter

Type: string

Default: ""

ReceiveTelegram

Waits for a specific message in a given chat. Once the message is received, the trigger fires.

Example:


	{
		"type": "ReceiveTelegram",
		"options": {
			"token": "5349923487:FFGrETxa0pA29d02Akslw-lkwjdA92KAH2",
			"chatId": -832345892,
			"message": "secretmessagethatfiresthetrigger"
		}
	}
	

Options:

token

telegram bot token (ask botfather)

Type: string

Default: ""

chatId

chatId of group or chat you want the message be received from.

Type: int

Default: ""

message

actual message that, when received, fires the trigger

Type: string

Default: ""

Timeout

Triggers after given duration. Mostly used for debugging.

Example:


	{
		"type": "Timeout",
		"name": "Example Trigger",
		"options": {
			"duration": 5
		},
		"actions": [
		]
	}
	

Options:

duration

duration in seconds

Type: int

Default: 0

UsbDisconnect

Triggers when given usb drive is disconnected. Currently it simply checks that the file /dev/disk/by-id/$deviceId exists.

Example:


	{
		"type": "UsbDisconnect",
		"name": "Example Trigger",
		"options": {
			"deviceId": "ata-Samsung_SSD_860_EVO_1TB_S4AALKWJDI102",
			"waitTillConnected": true
		},
		"actions": [
		]
	}
	

Options:

waitTillConnected

Only trigger when device was connected before

Type: bool

Default: true

deviceId

Name of device under /dev/disk/by-id/

Type: string

Default: ""

Actions

Actions are executed when their parent Trigger got triggered. They then perform some certain task depending on the specific action. Those can vary from shutding down the machine, removing a file or running a bash command. Some Actions may cause permanent damage to the system. This is intended but should be used with caution.

Actions can have a Stage assigned to define in which order they should run. The lowest stage is executed first and only when finished the next stage is executed. Actions on the same Stage run concurrently.

Actions have the following syntax:

{
  "type": "SomeAction",
  "options": { //each action defines its own options
    "firstOption": "someValue",
    "stage": 2 //this (positive) number defines the order of multiple actions
  }
}

Command

Invokes given command using exec.

Example:


	{
		"type": "Command",
		"options": {
			"command": "srm /path/to/file"
		}
	}
	

Options:

command

command to execute

Type: string

Default: ""

Print

Prints a given message to stdout. This action is mostly used for debugging purposes.

Example:


		{
			type: "Print",
			"options": {
				"message": "Hello World!"
			}
		}
	

Options:

message

Message that should be printed

Type: string

Default: ""

RemoveFiles

RemoveFiles deletes the given files and directories. If available "srm" is used, otherwise RemoveFiles falls back to "rm"

Example:


	{
		"type": "RemoveFiles",
		"options": {
			"files": [
				"/home/user/secrets.txt"
			],
			"directories": [
				"/home/user/.gpg",
				"/home/user/.ssh",
				"/home/user/.thunderbird"
			]
		}
	}
	

Options:

files

list of absolute paths of files that should be deleted.

Type: []string

Default: ""

directories

list of absolute paths of directories that should be deleted.

Type: []string

Default: ""

ShellScript

Executes the given shell script.

Example:


	{
		"type": "ShellScript",
		"options": {
			"path": "/path/to/file.sh"
		}
	}
	

Options:

path

path to script to execute

Type: string

Default: ""

Shutdown

Shutsdown the machine by perfoming a shutdown -h now

Example:


	{
		"type": "Shutdown",
		"options": {
			"time": "+5" //wait 5 minutes before shutdown
		}
	}
	

Options:

time

TIME parameter passed to shutdown as follows shutdown -h TIME

Type: string

Default: now

SendMatrix

Sends a message to a given room. The user needs to be part of that room already.

Example:


	{
		"type": "SendMatrix",
		"options": {
			"homeserver": "matrix.org",
			"username": "testuser",
			"token": "syt_AHAuYW1pA2Rac2NvamRkamVzZaVc_bXaMfbXzzbIvtXKlealN_2jtbs8",
			"deviceId": "ZDBLQAQLJH",
			"database": "/etc/gokill/matrix.db",
			"roomId": "!Balrthajskensaw:matrix.org",
			"message": "attention, intruders got my device!",
			"testMessage": "this is just a test, no worries"
		}
	}
	

Options:

homeserver

homeserver address.

Type: string

Default: ""

username

username (localpart, wihout homeserver address)

Type: string

Default: ""

password

password in clear text

Type: string

Default: ""

token

access token in clear text

Type: string

Default: ""

deviceId

A device id. Example: ZDBLQAQLJH

Type: string

Default: ""

database

path to database file, will be created if not existing. this is necessary to sync keys for encryption.

Type: string

Default: ""

roomId

Type: string

Default: ""

message

actual message that should be sent

Type: string

Default: ""

testMessage

message sent during test run

Type: string

Default: ""

SendTelegram

Sends a message to a given room. The user needs to be part of that room already.

Example:


	{
		"type": "SendTelegram",
		"options": {
			"token": "5349923487:FFGrETxa0pA29d02Akslw-lkwjdA92KAH2",
			"chatId": -832345892,
			"message": "attention, intruders got my device!",
			"testMessage": "this is just a test, no worries"
		}
	}
	

Options:

token

telegram bot token (ask botfather)

Type: string

Default: ""

chatId

chatId of group or chat you want the message be sent to.

Type: int

Default: ""

message

actual message that should be sent

Type: string

Default: ""

testMessage

message sent during test run

Type: string

Default: ""

Timeout

Waits given duration in seconds. This can be used to wait a certain amount of time before continuing to the next Stage

Example:


	{
		"type": "Timeout",
		"options": {
			"duration": 5
		}
	}
	

Options:

duration

duration in seconds

Type: int

Default: 0