iceberg

module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 4, 2020 License: MIT

README

iceberg

Description

iceberg is a file server that uses client certificate authentication and policy-based access control. iceberg requires the use of client certificates verified with the certificate authority chain configured at startup.

Iceberg is built in Go. Iceberg uses the net/http and crypto/tls packages in the Go standard library to secure communication. By default, iceberg supports TLS 1.0 to 1.3 and all the CipherSuites implemented by net/http, excluding those with known security issues. The TLS configuration can be modified using command line flags.

Iceberg is an alternative to configuring the Apache HTTP Server or NGINX to serve files while requiring client certificates. Iceberg does not attempt to be on parity with other file servers, but is designed to be a file server that is simple to manage and secure by default.

Usage

The iceberg program has 5 sub commands: defaults, help, serve, validate-access-policy, and version. Use iceberg serve to launch the server and iceberg validate-access-policy to validate a policy file. Use iceberg defaults [tls-cipher-suites|tls-curve-preferences] to show default configuration. Use iceberg version to show the current version.

Below is the usage for the iceberg serve command.

start the iceberg server

Usage:
  iceberg serve [flags]

Flags:
-p, --access-policy string              path to the policy file.
-f, --access-policy-format string       format of the policy file (default "json")
-a, --addr string                       address that iceberg will listen on (default ":8080")
    --behavior-not-found string         default behavior when a file is not found.  One of: redirect,none (default "none")
    --client-ca string                  path to CA bundle for client authentication
    --client-ca-format string           format of the CA bundle for client authentication, either pkcs7 or pem (default "pkcs7")
    --client-crl string                 path to CRL bundle for client authentication
    --client-crl-format string          format of the CRL bundle for client authentication, either der, der.zip, or pem (default "der")
    --dry-run                           exit after checking configuration
-h, --help                              help for serve
-l, --log string                        path to the log output.  Defaults to stdout. (default "-")
    --public-location string            the public location of the server used for redirects
    --redirect string                   address that iceberg will listen to and redirect requests to the public location
-r, --root string                       path to the document root served
    --server-cert string                path to server public cert
    --server-key string                 path to server private key
-t, --template string                   path to the template file used during directory listing
    --timeout-idle string               maximum amount of time to wait for the next request when keep-alives are enabled (default "5m")
    --timeout-read string               maximum duration for reading the entire request (default "15m")
    --timeout-write string              maximum duration before timing out writes of the response (default "5m")
    --tls-cipher-suites string          list of supported cipher suites for TLS versions up to 1.2 (TLS 1.3 is not configureable)
    --tls-curve-preferences string      curve preferences (default "X25519,CurveP256,CurveP384,CurveP521")
    --tls-max-version string            maximum TLS version accepted for requests (default "1.3")
    --tls-min-version string            minimum TLS version accepted for requests (default "1.0")
    --tls-prefer-server-cipher-suites   prefer server cipher suites
Network Encryption

iceberg requires the use of a server certificate and client certificate authentication. The server certificate is loaded from a PEM-encoded x509 key pair using the LoadX509KeyPair function. The location of the key pair is specified using the --server-cert and --server-key command line flags.

The client certificate authorities can be loaded from a PKCS#7 or PEM-encoded file. The Parse function in go.mozilla.org/pkcs7 is used to parse the PKCS#7-encoded data loaded from a .p7b file. The AppendCertsFromPEM method is used to parse PEM-encoded data loaded from a .pem file. The location of the client certificate authorities is specified using the client-ca and client-ca-format command line flags.

You can use the tls-* flags to customize the server TLS configuration. Options are very limited for TLS 1.3.

For example, you could configure the server to only support TLS version 1.2 and specific ciphers using --tls-min-version, --tls-max-version, and --tls-cipher-suites.

iceberg serve ... --tls-min-version 1.2 --tls-max-version 1.2 --tls-cipher-suites 'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256'

Mozilla keeps a Security/Server Side TLS document up to date on the best practices for configuring a server for TLS.

Access Policy Document

An access policy document is a list of statements that are evaluate when determining whether a user can access a given file path. By default, users have no privileges. The access policy document can be serialized as a JSON or YAML document.

{
  "statements": [...]
}

The policy statements are evaluated sequentially. If the first policy statement allows access, the other statements are still evaluated. If any statement denies access, then the user is denied access.

Each statement requires the effect, paths, and users/not_users to be set. The id is optional and not used during evaluation. The effect is either allow or deny.

{
  "id": "DefaultAllow",
  "effect": "allow",
  "paths": [...],
  "users": [...],
  "not_users": [],
}

The values for paths includes an array of paths from the root directory as set during startup, e.g., /shared. Paths can start or end with a wildcard, eg., /shared/* or *.jpg.

{
  "paths": [
    "/shared/",
    "/shared/*"
  ]
}

The value for paths can be set to ["*"] to apply to all file paths.

{
  "paths": ["*"]
}

The values included in users or not_users includes an array of distinguished names derived from the the subject of the client certificate provided by the connecting client. The value of not_users means the statement effect is applied to any user not in the array. For example.

{
  "users": [
    "/C=US/O=Atlantis/OU=Atlantis Digital Service/OU=CONTRACTOR/CN=LAST.FIRST.MIDDLE.ID"
  ]
}

The value for users can be set to ["*"] to apply to all users.

{
  "users": ["*"]
}
Directory Listing Template

The template provided during server startup is used to render directory listings using the native Go template rendering engine in the html/template package. The template is provided the following context.

struct {
  Up        string
  Directory string
  Files     []struct {
    ModTime string
    Size    int64
    Type    string
    Path    string
  }
})

In addition to the default functions available, the prefix and suffix template functions are also available. For example, the suffix function can be used to conditionally write an html element based on the file extension.

{{if .Path | suffix ".mp4"}}Video{{else}}Other{{end}}

Examples

Below are the example commands and files needed to run a server that, by default allows access to all files, but limits access to the /secure path to a limited set of users identified by their client certificate subject distinguished name.

iceberg serve \
--access-policy examples/conf/example.json \
--client-ca temp/certs.p7b \
--root examples/public \
--server-cert temp/server.crt \
--server-key temp/server.key \
--template examples/conf/template.html \
--behavior-not-found redirect

The below policy statement allows access to any authenticated user and then limits access to /secure to a limited set of users.

{
  "statements": [
    {
      "id": "DefaultAllow",
      "effect": "allow",
      "paths": [
        "*"
      ],
      "users": [
        "*"
      ]
    },
    {
      "id": "ProtectSecure",
      "effect": "deny",
      "paths": [
        "/secure",
        "/secure/*"
      ],
      "not_users": [
        "/C=US/O=Atlantis/OU=Atlantis Digital Service/OU=CONTRACTOR/CN=LAST.FIRST.MIDDLE.ID",
      ]
    }
  ]
}

Building

iceberg is written in pure Go, so the only dependency needed to compile the server is Go. Go can be downloaded from https://golang.org/dl/.

This project uses direnv to manage environment variables and automatically adding the bin and scripts folder to the path. Install direnv and hook it into your shell. The use of direnv is optional as you can always call iceberg directly with bin/iceberg.

If using macOS, follow the macOS instructions below.

To build a binary for your local operating system you can use make bin/iceberg. To build for a release, you can use make build_release. Additionally, you can call go build directly to support specific use cases.

macOS

You can install go on macOS using homebrew with brew install go.

To install direnv on macOS use brew install direnv. If using bash, then add eval \"$(direnv hook bash)\" to the ~/.bash_profile file . If using zsh, then add eval \"$(direnv hook zsh)\" to the ~/.zshrc file.

Contributing

We'd love to have your contributions! Please see CONTRIBUTING.md for more info.

Security

Please see SECURITY.md for more info.

License

This project constitutes a work of the United States Government and is not subject to domestic copyright protection under 17 USC § 105. However, because the project utilizes code licensed from contributors and other third parties, it therefore is licensed under the MIT License. See LICENSE file for more information.

Directories

Path Synopsis
cmd
pkg
certs
Package certs inclues functions for parsing certificate files.
Package certs inclues functions for parsing certificate files.
log
Package log inclues a simple logger that logs using JSON lines.
Package log inclues a simple logger that logs using JSON lines.
policy
Package policy inclues a simple policy document and methods for evaluation.
Package policy inclues a simple policy document and methods for evaluation.
server
Package server inclues functions for serving content.
Package server inclues functions for serving content.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL