Skip to content

Commit

Permalink
max queue element size
Browse files Browse the repository at this point in the history
  • Loading branch information
reddec committed Jul 24, 2020
1 parent 91e31e7 commit 882246a
Show file tree
Hide file tree
Showing 14 changed files with 104 additions and 124 deletions.
3 changes: 1 addition & 2 deletions application/lambda/initializer.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ import (
// Create dummy public lambda in defined path with manifest based on execution specified binary with args
func DummyPublic(path string, bin string, args ...string) (*localLambda, error) {
var manifest = types.Manifest{
Public: true,
Run: append([]string{bin}, args...),
Run: append([]string{bin}, args...),
}
err := manifest.SaveAs(filepath.Join(path, internal.ManifestFile))
if err != nil {
Expand Down
29 changes: 3 additions & 26 deletions application/lambda/lambda.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ package lambda
import (
"context"
"fmt"
"github.com/reddec/trusted-cgi/internal"
"github.com/reddec/trusted-cgi/types"
"io"
"io/ioutil"
"net"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"
"sync"
"time"

"github.com/reddec/trusted-cgi/internal"
"github.com/reddec/trusted-cgi/types"
)

type localLambda struct {
Expand Down Expand Up @@ -66,10 +66,6 @@ func (local *localLambda) Invoke(ctx context.Context, request types.Request, res
defer local.lock.RUnlock()
defer request.Body.Close()

if !local.passSecurityCheck(&request) {
return fmt.Errorf("security checks failed")
}

if local.staticDir != "" && request.Method == http.MethodGet {
return local.writeStaticFile(request.Path, response)
}
Expand Down Expand Up @@ -180,25 +176,6 @@ func (local *localLambda) readIgnore() ([]string, error) {
return nil, fmt.Errorf("read ignore file: %w", err)
}

func (local *localLambda) passSecurityCheck(req *types.Request) bool {
manifest := local.manifest
host, _, _ := net.SplitHostPort(req.RemoteAddress)
if len(manifest.AllowedIP) > 0 && !manifest.AllowedIP.Has(host) {
return false
}
if len(manifest.AllowedOrigin) > 0 && !manifest.AllowedOrigin.Has(req.Headers["Origin"]) {
return false
}

if !manifest.Public {
_, ok := manifest.Tokens[req.Headers["Authorization"]]
if !ok {
return false
}
}
return true
}

func (local *localLambda) writeStaticFile(path string, out io.Writer) error {
if path == "" {
path = "index.html"
Expand Down
6 changes: 4 additions & 2 deletions application/policy/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package policy

import (
"fmt"
"sync"

"github.com/reddec/trusted-cgi/application"
"github.com/reddec/trusted-cgi/types"
"sync"
)

// Store contains policies configuration for reload
Expand Down Expand Up @@ -37,7 +38,8 @@ func (policies *policiesImpl) load() error {
return err
}
for _, item := range list {
policies.policiesByID[item.ID] = &item
cp := item
policies.policiesByID[item.ID] = &cp
for lambda := range item.Lambdas {
policies.policiesByLambda[lambda] = item.ID
}
Expand Down
14 changes: 10 additions & 4 deletions application/queuemanager/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ package queuemanager
import (
"context"
"fmt"
"github.com/reddec/trusted-cgi/application"
"github.com/reddec/trusted-cgi/queue"
"github.com/reddec/trusted-cgi/types"
"io"
"io/ioutil"
"log"
"os"
"sort"
"sync"
"time"

"github.com/reddec/trusted-cgi/application"
"github.com/reddec/trusted-cgi/queue"
"github.com/reddec/trusted-cgi/types"
)

// Store contains queues configuration for reload
Expand Down Expand Up @@ -69,14 +71,18 @@ func (qm *queueManager) init() error {
func (qm *queueManager) Put(queue string, request *types.Request) error {
qm.lock.RLock()
defer qm.lock.RUnlock()
defer request.Body.Close()
stream := request.Body
defer stream.Close()
q, ok := qm.queues[queue]
if !ok {
return fmt.Errorf("queue %s does not exist", queue)
}
if err := qm.validator.Inspect(q.Target, request); err != nil {
return fmt.Errorf("put: security validation failed: %w", err)
}
if q.MaxElementSize > 0 {
request.Body = ioutil.NopCloser(io.LimitReader(stream, q.MaxElementSize))
}
return q.queue.Put(qm.ctx, request)
}

Expand Down
12 changes: 7 additions & 5 deletions application/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package application

import (
"encoding/json"
"github.com/reddec/trusted-cgi/types"
"os"

"github.com/reddec/trusted-cgi/types"
)

type Definition struct {
Expand Down Expand Up @@ -50,10 +51,11 @@ func (cfg *Config) ReadFile(file string) error {
}

type Queue struct {
Name string `json:"name"`
Target string `json:"target"`
Retry int `json:"retry"` // number of additional attempts
Interval types.JsonDuration `json:"interval"` // delay between attempts
Name string `json:"name"`
Target string `json:"target"`
Retry int `json:"retry"` // number of additional attempts
MaxElementSize int64 `json:"max_element_size"` // max request size
Interval types.JsonDuration `json:"interval"` // delay between attempts
}

type PolicyDefinition struct {
Expand Down
4 changes: 0 additions & 4 deletions clients/ts/lambda_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ export interface Manifest {
path_env: string | null
time_limit: JsonDuration | null
maximum_payload: number | null
allowed_ip: JsonStringSet | null
allowed_origin: JsonStringSet | null
public: boolean
tokens: any | null
cron: Array<Schedule> | null
static: string | null
}
Expand Down
4 changes: 0 additions & 4 deletions clients/ts/project_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ export interface Manifest {
path_env: string | null
time_limit: JsonDuration | null
maximum_payload: number | null
allowed_ip: JsonStringSet | null
allowed_origin: JsonStringSet | null
public: boolean
tokens: any | null
cron: Array<Schedule> | null
static: string | null
}
Expand Down
1 change: 1 addition & 0 deletions clients/ts/queues_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface Queue {
name: string
target: string
retry: number
max_element_size: number
interval: JsonDuration
}

Expand Down
69 changes: 69 additions & 0 deletions docs/administrating/policies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
layout: default
title: Policies
parent: Administrating
nav_order: 2
---
# Policies

Before `0.3.5` most security settings were in manifest.

Policy is a combination of restrictions described below, however, they can be applied to
several objects.

For example, you can make one policy called `my-customer-1`, that will contain several tokens,
IP restrictions etc.., and apply it to several lambdas, keeping access information in one place.

Currently, lambda can be linked to only one policy, but one policy could be linked to multiple lambdas.

## Checks

Security checks aimed to restrict access to function to the limited group of clients.

All security checks performed after application resolution. Each rule combined by AND operator.
For example, if restrictions by IP defined as well as restrictions by Origin, both limitations will
be applied for a client request.

In case of failure the 403 Access Deny will be returned.

UI:

1. click to any created application
2. click to security tab

### Tokens

Restrict incoming requests by `Authorization` header.

Header should contain one of defined tokens.

If `public` flag is true, the setting will be ignored.

By default, UI generates tokens by UUIDv4 algorithm, however arbitrary text could be used and defined during setup.

The performance almost not impacted regardless number of tokens.

### Origin

Restrict access by `Origin` header. Useful to from where (domains) browser clients could access
function.

If at least one origin defined, the security check becomes mandatory.

By standard, the field should contain a domain with protocol (ex: https://example.com) however backend is
not checking validity of the content and arbitrary text could be used and defined during setup.

Wildcards not supported.

The performance almost not impacted regardless number of origins.

### IP

Restrict access by a client IP.

**Not working properly in docker container**: docker proxies all requests, so client IP will be a docker IP
instead of real address.

Should be defined in default notation `XXX.YYY.ZZZ.TTT`, IPv6 has to be supported but not tested.

The performance almost not impacted regardless number of IP.
4 changes: 0 additions & 4 deletions docs/api/lambda_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,10 +312,6 @@ EOF
| path_env | `string` | |
| time_limit | `JsonDuration` | |
| maximum_payload | `int64` | |
| allowed_ip | `JsonStringSet` | |
| allowed_origin | `JsonStringSet` | |
| public | `bool` | |
| tokens | `map[string]string` | |
| cron | `[]Schedule` | |
| static | `string` | |

Expand Down
3 changes: 3 additions & 0 deletions docs/api/queues_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ EOF
| name | `string` | |
| target | `string` | |
| retry | `int` | |
| max_element_size | `int64` | |
| interval | `types.JsonDuration` | |

### Token
Expand Down Expand Up @@ -120,6 +121,7 @@ EOF
| name | `string` | |
| target | `string` | |
| retry | `int` | |
| max_element_size | `int64` | |
| interval | `types.JsonDuration` | |

### Token
Expand Down Expand Up @@ -159,6 +161,7 @@ EOF
| name | `string` | |
| target | `string` | |
| retry | `int` | |
| max_element_size | `int64` | |
| interval | `types.JsonDuration` | |

### Token
Expand Down
63 changes: 2 additions & 61 deletions docs/usage/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,66 +4,7 @@ title: Security
parent: Usage
nav_order: 5
---
# Security

Security checks aimed to restrict access to function to the limited group of clients.

All security checks performed after application resolution. Each rule combined by AND operator.
For example, if restrictions by IP defined as well as restrictions by Origin, both limitations will
be applied for a client request.

In case of failure the 403 Access Deny will be returned.

UI:

1. click to any created application
2. click to security tab

### Tokens

Restrict incoming requests by `Authorization` header.

Header should contain one of defined tokens.

If `public` flag is true, the setting will be ignored.

By default, UI generates tokens by UUIDv4 algorithm, however arbitrary text could be used and defined during setup.

The performance almost not impacted regardless number of tokens.

### Origin

Restrict access by `Origin` header. Useful to from where (domains) browser clients could access
function.

If at least one origin defined, the security check becomes mandatory.

By standard, the field should contain a domain with protocol (ex: https://example.com) however backend is
not checking validity of the content and arbitrary text could be used and defined during setup.

Wildcards not supported.

The performance almost not impacted regardless number of origins.

### IP

Restrict access by client IP.

**Not working properly in docker container**: docker proxies all requests, so client IP will be a docker IP
instead of real address.

Should be defined in default notation `XXX.YYY.ZZZ.TTT`, IPv6 has to be supported but not tested.

The performance almost not impacted regardless number of IP.

# Policies

Since `0.3.5` most security migrated to separate entity - Policy.

Policy is a combination of restrictions described above, however, they can be applied to
several objects.

For example, you can make one policy called `my-customer-1`, that will contain several tokens,
IP restrictions etc.., and apply it to several lambdas, keeping access information in one place.
# Security

Currently, lambda can be linked to only one policy, but one policy could be linked to multiple lambdas.
Since `0.3.5` most security migrated to separate entity - [Policy](../administrating/policies.md).
4 changes: 0 additions & 4 deletions templates/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ Replace url to the real
`,
Run: []string{"./venv/bin/python3", "app.py"},
TimeLimit: types.JsonDuration(time.Second),
Public: true,
MaximumPayload: 8192,
OutputHeaders: map[string]string{
"Content-Type": "application/json",
Expand Down Expand Up @@ -136,7 +135,6 @@ Replace url to the real
`,
Run: []string{"node", "app.js"},
TimeLimit: types.JsonDuration(time.Second),
Public: true,
MaximumPayload: 8192,
OutputHeaders: map[string]string{
"Content-Type": "application/json",
Expand All @@ -156,7 +154,6 @@ Replace url to the real
`,
Run: []string{"php", "app.php"},
TimeLimit: types.JsonDuration(time.Second),
Public: true,
MaximumPayload: 8192,
OutputHeaders: map[string]string{
"Content-Type": "application/json",
Expand All @@ -181,7 +178,6 @@ Replace url to the real
`,
Run: []string{"./bin/lambda"},
TimeLimit: types.JsonDuration(time.Second),
Public: true,
MaximumPayload: 8192,
OutputHeaders: map[string]string{
"Content-Type": "application/json",
Expand Down
Loading

0 comments on commit 882246a

Please sign in to comment.