# hnakra

The successor to HLHV. More stable and capable than ever!

Hnakra is similar to an HTTP reverse proxy, but it uses a custom protocol to
allow services to connect to the router instead of the other way around. This
approach provides a greater level of security and ease of setup, and allows
services to do cool things like hide behind a firewall on a completely different
network.

Hnakra is also designed to be multi-protocol, so services can make their content
and functionality available over HTTP, HTTPS, gemini, etc. In theory, any
request/response based protocol that uses URLs could be integrated into Hnakra.
Currently, only HTTPS is supported, but other protocols are coming soon.

## Security features

Hnakra has a highly configurable user/permission system for dictating what
services are allowed to do what. Services authenticate the identity of the
router using its TLS certificate, and the router authenticates the identity of
connecting services using a supplied username/key combination. This is so each
service can be given limited access to a particular portion of the site.

## Router server

This module comes with a basic router implementation, located at `cmd/router`.
It can be configured using `/etc/hnakra/hnakra.conf`. Each line in the
configuration file can be blank, a command, or a comment. A list of available
commands:

### `alias <alias> -> <target>`
When a request comes in with a host matching `alias`, it is replaced with
`target` before being routed to the appropriate service. If `(fallback)` is
specified as `alias`, any host that doesn't match a pre-existing alias will be
rewritten as `target`. By default, hosts equivalent to `localhost` are aliased
to the target `@`. It is reccomended to alias your domain name to `@` as well so
you don't need to hard-code it into your services.

### `unalias <alias>`
`unalias` undoes an alias that was created previously.

### `keyPath <path>`
`keyPath` specifies the location of the TLS key to load.

### `certPath <path>`
`certPath` specifies the location of the TLS certificate to load.

### `rcon`
This command enables the remote console, which lets you monitor the state of the
router from a webpage. It is available at `https://@/debug/rcon`. Before
accessing it, you must set up at least one user with rcon access.

### `router <port>`
This command specifies the port that services will connect to. If not specified,
the value of `$HNAKRA_ROUTER_PORT` will be used. If that is also blank, it will
default to a value of `2048`.

### `https [port]`
This command enables the HTTPS protocol. If the port is left blank, the value of
`$HNAKRA_HTTPS_PORT` will be used. If that is also blank, it will default to a
value of `443`.

### `http [port]`
This command enables the insecure HTTP protocol. If the port is left blank, the
value of `$HNAKRA_HTTP_PORT` will be used. If that is also blank, it will
default to a value of `80`.

### `gemini [port]`
This command enables the gemini protocol. If the port is left blank, the value
of `$HNAKRA_GEMINI_PORT` will be used. If that is also blank, it will defaul to
a value of `1965`.

### `noSecurity I AM NOT USING THIS IN PRODUCTION.`
This command disables username/key authentication entirely and lets any service
mount anywhere. For this to work, it must be typed exactly as shown above.

### `user <name>:<key hash> -> <capability>, ...`
The `user` command creates a new user under the specified name, with the
specified bcrypt key hash. Following the user is a `->` symbol, then a
comma-separated list of capabilities that user has. A capability can be a mount
point pattern, or the value `(rcon)`. Mount point patterns are interpreted as
follows:

- A singular glob, `*`, allows the user to mount services on any host or path.
- A URL pattern without any globs or trailing slashes (such as `https://@/path`)
  allows the user to mount services on that exact path only.
- If the host component of the pattern is prefixed with a `.`, it will match
  subdomains of that host as well as the host itself.
- If the host component of the pattern is prefixed with a `*`, it will match any
  host ending in the host component (not including the glob).
- If the path component of the pattern is affixed with a `/`, it will match any
  paths under it, as well as the path itself.
- If the path component of the pattern is affixed with a `*`, it will match any
  path that starts with the path component (not including the glob).

For example, the pattern `https://.@/static/` allows a user to mount services on
`@` (or any subdomain of `@`) at `/static` (or anything underneath `/static`) on
the HTTPS protocol.

Specifiying a value as `(rcon)` as opposed to a mount point pattern will allow
access to the rcon panel (if it is enabled) by logging in with this user's
credentials.

## Service package

This module also comes with a package that allows you to easily create a service
in just a few lines of code. Some examples can be found in the `examples`
directory.
