Compare commits
6 Commits
a08de8a553
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 3a4c42f9c0 | |||
| 99529579fe | |||
| 49f6a3d26a | |||
| 60598566d0 | |||
| 15f8793e2f | |||
| d574902919 |
63
README.md
63
README.md
@@ -1,7 +1,7 @@
|
||||
# gokill
|
||||
|
||||
|
||||
gokill is designed for activists, journalists, and individuals who require robust protection for their data, ensuring it remains inaccessible under any circumstances. It belongs to the category of anti-forensic tools, providing a means to safeguard against potential repression. gokill is a [software dead man's switch](https://en.wikipedia.org/wiki/Dead_man%27s_switch#Software) that empowers users to configure various events. If these events occur, they trigger predefined actions. It is specifically crafted for worst-case scenarios, such as when intruders gain physical access to a device. In these intense situations, gokill automatically performs tasks to enhance your security:
|
||||
gokill is a [software dead man's switch](https://en.wikipedia.org/wiki/Dead_man%27s_switch#Software) that empowers users to configure various events. If these events occur, they trigger predefined actions.
|
||||
The tool is designed for activists, journalists, and individuals who require robust protection for their data, ensuring it remains inaccessible under any circumstances. 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:
|
||||
- locking the screen
|
||||
- sending chat messages
|
||||
- deleting data
|
||||
@@ -9,18 +9,28 @@ gokill is designed for activists, journalists, and individuals who require robus
|
||||
- destroying encrypted partitions
|
||||
- ect
|
||||
|
||||
#### documentation
|
||||
A full list of Triggers and Actions with all their configuration options can be found here:
|
||||
|
||||
## 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. This is supposed to change.
|
||||
Iam currently working/researching on publishing gokill as [ppa](https://help.launchpad.net/Packaging/PPA) and as snap.
|
||||
If you have other recommendations let me know.
|
||||
|
||||
|
||||
``` bash
|
||||
# Clone the gokill repository
|
||||
git clone https://github.com/k4lipso/gokill
|
||||
cd gokill
|
||||
|
||||
# Build gokill
|
||||
# Build gokill - requires libolm
|
||||
go build github.com/k4lipso/gokill
|
||||
|
||||
# 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
|
||||
@@ -36,7 +46,7 @@ actions that will be executed once triggered.
|
||||
"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",
|
||||
@@ -46,17 +56,15 @@ actions that will be executed once triggered.
|
||||
"stage": 2 // defines the order in which actions are triggered.
|
||||
},
|
||||
{
|
||||
"type": "sendMail",
|
||||
"options": {
|
||||
"smtpserver": "domain.org",
|
||||
"port": 667,
|
||||
"recipients": [ "mail1@host.org", "mail2@host.org" ],
|
||||
"message": "kill switch was triggered",
|
||||
"attachments": [ "/path/atachments" ],
|
||||
"pubkeys": "/path/to/keys.pub"
|
||||
},
|
||||
"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
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -64,7 +72,7 @@ actions that will be executed once triggered.
|
||||
"name": "Second Trigger",
|
||||
"options": {
|
||||
"interfaceName": "eth0",
|
||||
}
|
||||
},
|
||||
"actions": [
|
||||
{
|
||||
"name": "unixCommand",
|
||||
@@ -78,9 +86,10 @@ actions that will be executed once triggered.
|
||||
```
|
||||
|
||||
## 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:
|
||||
|
||||
``` nix
|
||||
@@ -109,23 +118,17 @@ Here is a small example config:
|
||||
|
||||
This will automatically configure and enable a systemd running gokill as root user in the background
|
||||
|
||||
## --
|
||||
### Build Documentation locally
|
||||
|
||||
the tasks gokill executes could be done by hand using shellscripts, cronjobs, daemons ect.
|
||||
but that means everyone needs to figure it out for themselves, and eventually make mistakes.
|
||||
the idea of gokill is to provide a wide variarity of possibilities out of the box while making sure they are well tested
|
||||
and relatively easy to setup.
|
||||
``` bash
|
||||
nix run github:k4lipso/gokill#docs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
actions and triggers should be easy to extend and handled like plugins. they
|
||||
also should be self documenting.
|
||||
every action and trigger should be testable at anytime as a 'dry-run'.
|
||||
actions can have a 'stage' defined. the lowest stage is started first,
|
||||
and only when all actions on that stage are finished next stage is triggered
|
||||
|
||||
gokill should run as daemon. config should be read from /etc/somename/config.json
|
||||
### Run integrations tests
|
||||
|
||||
``` bash
|
||||
nix flake check github:k4lipso/gokill
|
||||
```
|
||||
|
||||
## todos
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@ func GetAllActions() []DocumentedAction {
|
||||
return []DocumentedAction{
|
||||
Command{},
|
||||
Printer{},
|
||||
RemoveFiles{},
|
||||
ShellScript{},
|
||||
Shutdown{},
|
||||
SendMatrix{},
|
||||
|
||||
130
actions/remove_files.go
Normal file
130
actions/remove_files.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package actions
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
|
||||
"github.com/k4lipso/gokill/internal"
|
||||
)
|
||||
|
||||
type RemoveFiles struct {
|
||||
Files []string `json:"files"`
|
||||
Directories []string `json:"directories"`
|
||||
ActionChan ActionResultChan
|
||||
}
|
||||
|
||||
func (c RemoveFiles) getRemoveCommand() string {
|
||||
command := "srm"
|
||||
isAvailable := isCommandAvailable(command)
|
||||
|
||||
if !isAvailable {
|
||||
internal.LogDoc(c).Warningf("Command %s not found, falling back to 'rm'", command)
|
||||
command = "rm"
|
||||
}
|
||||
|
||||
return command
|
||||
}
|
||||
|
||||
func (c RemoveFiles) DryExecute() {
|
||||
internal.LogDoc(c).Infof("Test Execute")
|
||||
|
||||
command := c.getRemoveCommand()
|
||||
internal.LogDoc(c).Info("The following commands would have been executed:")
|
||||
|
||||
for _, file := range c.Files {
|
||||
internal.LogDoc(c).Noticef("%s -f %s", command, file)
|
||||
}
|
||||
|
||||
for _, dir := range c.Directories {
|
||||
internal.LogDoc(c).Noticef("%s -rf %s", command, dir)
|
||||
}
|
||||
|
||||
c.ActionChan <- nil
|
||||
}
|
||||
|
||||
func (c RemoveFiles) Execute() {
|
||||
internal.LogDoc(c).Infof("Execute")
|
||||
|
||||
command := c.getRemoveCommand()
|
||||
|
||||
for _, file := range c.Files {
|
||||
cmd := exec.Command(command, "-fv", file)
|
||||
|
||||
stdout, err := cmd.Output()
|
||||
|
||||
if err != nil {
|
||||
internal.LogDoc(c).Errorf("%s", err.Error())
|
||||
}
|
||||
|
||||
internal.LogDoc(c).Notice(string(stdout))
|
||||
}
|
||||
|
||||
for _, dir := range c.Directories {
|
||||
cmd := exec.Command(command, "-rfv", dir)
|
||||
|
||||
stdout, err := cmd.Output()
|
||||
|
||||
if err != nil {
|
||||
internal.LogDoc(c).Errorf("%s", err.Error())
|
||||
}
|
||||
|
||||
internal.LogDoc(c).Notice(string(stdout))
|
||||
}
|
||||
|
||||
c.ActionChan <- nil
|
||||
}
|
||||
|
||||
func CreateRemoveFiles(config internal.ActionConfig, c ActionResultChan) (RemoveFiles, error) {
|
||||
result := RemoveFiles{}
|
||||
|
||||
err := json.Unmarshal(config.Options, &result)
|
||||
|
||||
if err != nil {
|
||||
return RemoveFiles{}, fmt.Errorf("Error parsing RemoveFiles: %s", err)
|
||||
}
|
||||
|
||||
result.ActionChan = c
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (cc RemoveFiles) Create(config internal.ActionConfig, c ActionResultChan) (Action, error) {
|
||||
return CreateRemoveFiles(config, c)
|
||||
}
|
||||
|
||||
func (p RemoveFiles) GetName() string {
|
||||
return "RemoveFiles"
|
||||
}
|
||||
|
||||
func (p RemoveFiles) GetDescription() string {
|
||||
return `
|
||||
RemoveFiles deletes the given files and directories.
|
||||
If available "srm" is used, otherwise RemoveFiles falls back to "rm"
|
||||
`
|
||||
}
|
||||
|
||||
func (p RemoveFiles) GetExample() string {
|
||||
return `
|
||||
{
|
||||
"type": "RemoveFiles",
|
||||
"options": {
|
||||
"files": [
|
||||
"/home/user/secrets.txt"
|
||||
],
|
||||
"directories": [
|
||||
"/home/user/.gpg",
|
||||
"/home/user/.ssh",
|
||||
"/home/user/.thunderbird"
|
||||
]
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
func (p RemoveFiles) GetOptions() []internal.ConfigOption {
|
||||
return []internal.ConfigOption{
|
||||
{"files", "[]string", "list of absolute paths of files that should be deleted.", ""},
|
||||
{"directories", "[]string", "list of absolute paths of directories that should be deleted.", ""},
|
||||
}
|
||||
}
|
||||
@@ -108,7 +108,7 @@ func (p Command) GetName() string {
|
||||
}
|
||||
|
||||
func (p Command) GetDescription() string {
|
||||
return "Invoces given command using exec."
|
||||
return "Invokes given command using exec."
|
||||
}
|
||||
|
||||
func (p Command) GetExample() string {
|
||||
|
||||
BIN
docbuilder
BIN
docbuilder
Binary file not shown.
@@ -36,7 +36,7 @@ func (s ReceiveTelegram) Listen() {
|
||||
for update := range updates {
|
||||
if update.Message != nil { // If we got a message
|
||||
if(update.Message.Chat.ID != chatId) {
|
||||
internal.LogDoc(s).Debugf("ReceiveTelegram received wrong ChatId. Got %s, wanted %s", update.Message.Chat.ID, s.ChatId)
|
||||
internal.LogDoc(s).Debugf("ReceiveTelegram received wrong ChatId. Got %d, wanted %d", update.Message.Chat.ID, s.ChatId)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@ func (s ReceiveTelegram) Listen() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
func CreateReceiveTelegram(config internal.KillSwitchConfig) (ReceiveTelegram, error) {
|
||||
result := ReceiveTelegram{
|
||||
ChatId: 0,
|
||||
|
||||
Reference in New Issue
Block a user