My frontend proxy for Kubernetes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Patrick Spek 893a8945a6
Add charset and proxy headers
5 months ago
bin Bump version to 0.2.0 5 months ago
lib/Kubernetes/FrontendProxy Add charset and proxy headers 5 months ago
resources Convert 4-space indents to tabs 6 months ago
t Add support for suppressing security headers 5 months ago
.editorconfig Initial commit 6 months ago
.gitignore Initial commit 6 months ago
.gitlab-ci.yml Initial commit 6 months ago Add charset and proxy headers 5 months ago
Dockerfile Add support for suppressing security headers 5 months ago
META6.json Bump version to 0.2.0 5 months ago
README.pod6 Add charset and proxy headers 5 months ago


=begin pod

=NAME Kubernetes::FrontendProxy
=AUTHOR Patrick Spek <>
=VERSION 0.2.0

=head1 Description

A frontend proxy server for use with L<Kubernetes|>, using
L<Perl 6|> for configuration and automatisation,
L<Nginx|> for the webserver and
L<Certbot|> for dealing with TLS certificates.

=head1 Installation

This module is intended to be run as a Kubernetes pod, but should be usable as a
natively-ran program as well. It is available as a Docker image under the name
C<tyil/frontend-proxy>, which can be used in a Kubernetes deployment. It will
need a service to be exposed to the outside world.

It is also recommended to add 2 PersistentVolumes. One for endpoint
configuration, and one for the LetsEncrypt certificates. These should be mounted
on C</etc/feproxy/hosts> and C</etc/letsencrypt> respectively.

=head2 Kubernetes deployment

This deployment is I<just> the bare basics to get the frontend proxy to run. You
will need to add endpoint configurations for it to generate usable Nginx

=begin code
apiVersion: v1
kind: Service
name: frontend
type: ClusterIP
intent: frontend
- name: http
protocol: TCP
port: 80
targetPort: 80
- name: https
protocol: TCP
port: 443
targetPort: 443

apiVersion: apps/v1
kind: Deployment
name: feproxy
replicas: 1
intent: feproxy
app: feproxy
intent: frontend
- name: feproxy
image: tyil/frontend-proxy:latest
- containerPort: 80
- containerPort: 443
=end code

=head1 Configuration

Some aspects of the application are configured through environment variables.
Other than that, you will need a Persistent Volume containing configurations for
all the endpoints you wish to expose through the frontend proxy.

=head2 Environment variables


The C<FEPROXY_HOSTS> variable indicates the directory that will contain the
configuration for the hosts and their endpoints. It defaults to


B<Required>. This is the email address to use when requesting new certificates
through C<certbot>.


This is the interval in which C<certbot> is instructed to renew the
certificates, in seconds. This defaults to C<21600>, which is 6 hours.

=head2 Endpoint configurations

The endpoints are configured using L<TOML|>
files in the directory specified by C<$FEPROXY_HOSTS>. The recommended layout is
a directory per hostname, and a file per endpoint.

=begin code
│ ├── api.toml
│ └── www.toml
└── main.toml
=end code

The structure laid out above is not enforced. I<All> files in the hosts
directory (and any directory below it) are attempted to be parsed as TOML files
containing possible endpoint configurations. Any files that fail to parse or
validate will generate a warning.

Each TOML file requires an C<[endpoint]> section, and an additional section
depending on the type of endpoint. The C<[endpoint]> section must have the
C<host>, C<path> and C<type> keys:

=begin code
host = ""
path = "/"
type = "service"
=end code

=head3 Headers

This block is completely optional, but can be used to adjust the headers sent by
nginx. These headers are used to enhance security on the endpoints you expose,
and are used only by I<Services>. If you find that an application you're
running requires some of these headers to be turned off, you can specify those
in this section. All the headers default to C<true>.

=begin code
csp = true
rp = true
uir = true
xcto = true
xfo = true
xxp = true
xpcdp = true
=end code

Z<Change this into =defn blocks, once they're supported>
=item1 C<csp> Content-Security-Policy
=item1 C<rp> Referrer-Policy
=item1 C<uir> Upgrade-Insecure-Requests
=item1 C<xcto> X-Content-Type-Options
=item1 C<xfo> X-Frame-Options
=item1 C<xxp> X-XSS-Protection
=item1 C<xpcdp> X-Permitted-Cross-Domain-Policies

=head3 Service

A service type requires a C<[service]> section, which must have a C<name> key.
Optionally, they can also use keys for C<protocol> and C<port>. The C<protocol>
is C<http> by default. The C<port> is C<80> by default.

=begin code
name = "tyil-blog"
=end code

=head4 name

B<Required>. The name of the Kubernetes service you want to create an endpoint

=head4 protocol

The protocol to use to access the service. This defaults to C<http>.

=head4 port

The port to use to access the service. This defaults to C<80>.

=head4 charset

The character set to use for the content served on this endpoint. This defaults
to C<utf-8>.

=head3 Redirect

A redirect type requires a C<[redirect]> section, which can have the following

=begin code
host = ""
=end code

=head4 host

B<Required>. The name of the host to redirect to.

=head4 status

The HTTP status code to use for the redirect. This defaults to C<301>.

=head4 protocol

The protocol to redirect to. This defaults to C<https>.

=head4 path

The path to add to the URI to redirect to. It defaults to the Nginx value of
C<$request_uri>, which is the part after the first C</>. This makes it so the
redirect points to the same location as was requested, but with a different

=head1 License

This module is distributed under the terms of the AGPL-3.0.

=end pod