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
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.
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: 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 - locking the screen
- sending chat messages - sending chat messages
- deleting data - deleting data
@@ -9,18 +9,28 @@ gokill is designed for activists, journalists, and individuals who require robus
- destroying encrypted partitions - destroying encrypted partitions
- ect - ect
#### documentation
A full list of Triggers and Actions with all their configuration options can be found here:
## usage ## 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 ``` bash
# Clone the gokill repository # Clone the gokill repository
git clone https://github.com/k4lipso/gokill git clone https://github.com/k4lipso/gokill
cd gokill cd gokill
# Build gokill # Build gokill - requires libolm
go build github.com/k4lipso/gokill go build github.com/k4lipso/gokill
# Create a config.json and run gokill # Create a config.json and run gokill
./gokill -c config.json ./gokill -c config.json
# Running gokill manually is annoying, it is acutally meant to run as systemd unit.
``` ```
## Config Example ## Config Example
@@ -78,9 +88,10 @@ actions that will be executed once triggered.
``` ```
## nix support ## nix support
gokill enjoys full nix support. gokill exposes a nix flakes that outputs a gokill package, a nixosModule and more. 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. That means you can super easily incorporate gokill into your existing nixosConfigurations.
### NixOS Module
Here is a small example config: Here is a small example config:
``` nix ``` 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 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. ``` bash
but that means everyone needs to figure it out for themselves, and eventually make mistakes. nix run github:k4lipso/gokill#docs
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.
--- ### Run integrations tests
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
``` bash
nix flake check github:k4lipso/gokill
```
## todos ## todos

View File

@@ -121,6 +121,7 @@ func GetAllActions() []DocumentedAction {
return []DocumentedAction{ return []DocumentedAction{
Command{}, Command{},
Printer{}, Printer{},
RemoveFiles{},
ShellScript{}, ShellScript{},
Shutdown{}, Shutdown{},
SendMatrix{}, 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 { func (p Command) GetDescription() string {
return "Invoces given command using exec." return "Invokes given command using exec."
} }
func (p Command) GetExample() string { func (p Command) GetExample() string {

View File

@@ -36,7 +36,7 @@ func (s ReceiveTelegram) Listen() {
for update := range updates { for update := range updates {
if update.Message != nil { // If we got a message if update.Message != nil { // If we got a message
if(update.Message.Chat.ID != chatId) { 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 continue
} }
@@ -52,7 +52,6 @@ func (s ReceiveTelegram) Listen() {
} }
func CreateReceiveTelegram(config internal.KillSwitchConfig) (ReceiveTelegram, error) { func CreateReceiveTelegram(config internal.KillSwitchConfig) (ReceiveTelegram, error) {
result := ReceiveTelegram{ result := ReceiveTelegram{
ChatId: 0, ChatId: 0,