Compare commits

..

4 Commits

Author SHA1 Message Date
49f6a3d26a [triggers/receive_telegram] fix type 2023-11-11 22:04:53 +01:00
60598566d0 [readme] update 2023-11-11 22:04:44 +01:00
15f8793e2f [actions/unix_command] fix typo 2023-11-11 22:04:31 +01:00
d574902919 [actions/remove_files] init 2023-11-11 22:03:26 +01:00
5 changed files with 156 additions and 21 deletions

View File

@@ -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
@@ -78,9 +88,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 +120,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

View File

@@ -121,6 +121,7 @@ func GetAllActions() []DocumentedAction {
return []DocumentedAction{
Command{},
Printer{},
RemoveFiles{},
ShellScript{},
Shutdown{},
SendMatrix{},

130
actions/remove_files.go Normal file
View 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.", ""},
}
}

View File

@@ -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 {

View File

@@ -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,