Compare commits
6 commits
405cf8dfed
...
46c414e2cc
Author | SHA1 | Date | |
---|---|---|---|
Felix Niederwanger | 46c414e2cc | ||
5f297ff006 | |||
Felix Niederwanger | f1de88e478 | ||
Felix Niederwanger | 355381e584 | ||
Felix Niederwanger | d486f8176d | ||
Felix Niederwanger | eee10c16ad |
24
README.md
24
README.md
|
@ -16,20 +16,26 @@ Webooks are defined via a yaml file. See [weblug.yml](weblug.yml) for an example
|
|||
|
||||
### Caveats
|
||||
|
||||
1. `weblug` does not support https encryption
|
||||
1. `weblug` should not face the open internet
|
||||
|
||||
weblug is expected to run behind a http reverse proxy (e.g. `apache` or `nginx`) which handles transport encryption. The program it self does not support https, nor are there any plans to implement this in the near future.
|
||||
weblug is expected to run behind a http reverse proxy (e.g. `apache` or `nginx`).
|
||||
While the program itself does support tls, to avoid a whole class of security issues, `weblug` should never run on the open internet without a http reverse proxy.
|
||||
|
||||
CAVE: Don't expose secrets and credentials by running this without any transport encryption!
|
||||
|
||||
2. Do not run this without reverse proxy
|
||||
|
||||
`weblug` relies on the standart go http implementation. To avoid a whole class of security issues, `weblug` should never run on the open internet without a http reverse proxy.
|
||||
|
||||
3. `weblug` runs as root, when using custom UID/GIDs
|
||||
2. `weblug` runs as root, when using custom UID/GIDs
|
||||
|
||||
In it's current implementation, `weblug` requires to remain running as root without dropping privileges when using custom UID/GIDs.
|
||||
|
||||
### TLS
|
||||
|
||||
`weblug` now supports tls. To generate self-signed keys
|
||||
|
||||
```
|
||||
openssl genrsa -out weblug.key 2048
|
||||
openssl req -new -x509 -sha256 -key weblug.key -out weblug1.pem -days 365
|
||||
```
|
||||
|
||||
Then configure the `weblug.yml` file accordingly. You can use multiple keys/certificates.
|
||||
|
||||
## Build
|
||||
|
||||
make # Build weblug
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
"os/exec"
|
||||
|
@ -79,10 +80,12 @@ func cmdSplit(command string) []string {
|
|||
return ret
|
||||
}
|
||||
|
||||
// Run executes the given command and return it's return code. It also respects the given concurrency number and will block until resources are free
|
||||
func (hook *Hook) Run() error {
|
||||
// Run executes the given command and return it's return code.
|
||||
// Will pass the given input string to the command
|
||||
// It also respects the given concurrency number and will block until resources are free
|
||||
func (hook *Hook) Run(buffer []byte) ([]byte, error) {
|
||||
if hook.Command == "" {
|
||||
return nil
|
||||
return make([]byte, 0), nil
|
||||
}
|
||||
|
||||
split := cmdSplit(hook.Command)
|
||||
|
@ -102,12 +105,8 @@ func (hook *Hook) Run() error {
|
|||
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
}
|
||||
if hook.Output {
|
||||
buf, ret := cmd.Output()
|
||||
fmt.Println(string(buf))
|
||||
return ret
|
||||
}
|
||||
return cmd.Run()
|
||||
cmd.Stdin = bytes.NewReader(buffer)
|
||||
return cmd.Output()
|
||||
}
|
||||
|
||||
func isAddressInList(addr string, addrList []string) (bool, error) {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"log"
|
||||
|
@ -179,8 +180,7 @@ func CreateTLSListener(cf Config) (net.Listener, error) {
|
|||
|
||||
// Create self-signed certificate, when no keyfile and no certificates are present
|
||||
if len(cf.Settings.TLS.Keypairs) == 0 {
|
||||
// TODO
|
||||
return nil, fmt.Errorf("creating self-signed certificates is not yet supported")
|
||||
return nil, fmt.Errorf("no keypairs provided")
|
||||
} else {
|
||||
// Load key/certificates keypairs
|
||||
tlsConfig.Certificates = make([]tls.Certificate, len(cf.Settings.TLS.Keypairs))
|
||||
|
@ -300,13 +300,24 @@ func createHandler(hook Hook) Handler {
|
|||
return
|
||||
}
|
||||
|
||||
// Input buffer used to pass the headers to the process
|
||||
var buffer bytes.Buffer
|
||||
for k, v := range r.Header {
|
||||
buffer.WriteString(fmt.Sprintf("%s:%s\n", k, strings.Join(v, ",")))
|
||||
}
|
||||
buffer.WriteString("\n")
|
||||
|
||||
if hook.Background { // Execute command in background
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
w.WriteHeader(200)
|
||||
fmt.Fprintf(w, "{\"status\":\"ok\"}")
|
||||
go func() {
|
||||
defer hook.Unlock()
|
||||
if err := hook.Run(); err != nil {
|
||||
buffer, err := hook.Run(buffer.Bytes())
|
||||
if hook.Output {
|
||||
fmt.Println(string(buffer))
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("Hook \"%s\" failed: %s", hook.Name, err)
|
||||
} else {
|
||||
log.Printf("Hook \"%s\" completed", hook.Name)
|
||||
|
@ -314,7 +325,11 @@ func createHandler(hook Hook) Handler {
|
|||
}()
|
||||
} else {
|
||||
defer hook.Unlock()
|
||||
if err := hook.Run(); err != nil {
|
||||
buffer, err := hook.Run(buffer.Bytes())
|
||||
if hook.Output {
|
||||
fmt.Println(string(buffer))
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("ERR: \"%s\" exec failure: %s", hook.Name, err)
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
w.WriteHeader(500)
|
||||
|
|
|
@ -250,6 +250,21 @@ func TestTLSWebserver(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Tests the run hook commands
|
||||
func TestRunHook(t *testing.T) {
|
||||
testText := "hello Test"
|
||||
hook := Hook{Name: "hook", Command: "/usr/bin/cat"}
|
||||
|
||||
buffer, err := hook.Run([]byte(testText))
|
||||
if err != nil {
|
||||
t.Fatalf("running test hook failed: %s", err)
|
||||
}
|
||||
ret := string(buffer)
|
||||
if ret != testText {
|
||||
t.Error("returned string mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
func generateKeypair(keyfile string, certfile string, hostnames []string) error {
|
||||
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
|
|
|
@ -11,9 +11,10 @@ settings:
|
|||
readtimeout: 10 # if set, maximum number of seconds to receive the full request
|
||||
writetimeout: 10 # if set, maximum number of seconds to send the full response
|
||||
maxheadersize: 4096 # maximum header size
|
||||
# Enable TLS here here
|
||||
# Enable TLS
|
||||
# Note that it is not recommended to run weblug on the open internet without using a reverse proxy
|
||||
tls:
|
||||
enabled: true
|
||||
enabled: false
|
||||
# Minimum and maximum required TLS version. By default TLS1.2 is the minimum
|
||||
minversion: '1.2'
|
||||
maxversion: ''
|
||||
|
|
Loading…
Reference in a new issue