Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Move examples from ingress and fix 404
  • Loading branch information
jcmoraisjr committed Oct 13, 2017
1 parent 87ea604 commit c06351c
Show file tree
Hide file tree
Showing 23 changed files with 1,672 additions and 9 deletions.
18 changes: 9 additions & 9 deletions README.md
Expand Up @@ -20,8 +20,8 @@ a beta-quality or a development version.

Usage docs are maintained on Ingress repository:

* Start with [deployment](https://github.com/kubernetes/ingress/tree/master/examples/deployment/haproxy) instructions
* See [TLS termination](https://github.com/kubernetes/ingress/tree/master/examples/tls-termination/haproxy) on how to enable `https`
* Start with [deployment](/examples/deployment) instructions
* See [TLS termination](/examples/tls-termination) on how to enable `https`

# Reload strategy

Expand All @@ -48,11 +48,11 @@ The following annotations are supported:
||Name|Data|Usage|
|---|---|---|:---:|
|`[0]`|[`ingress.kubernetes.io/affinity`](#affinity)|affinity type|-|
||`ingress.kubernetes.io/auth-type`|"basic"|[doc](https://github.com/kubernetes/ingress/tree/master/examples/auth/basic/haproxy)|
||`ingress.kubernetes.io/auth-secret`|secret name|[doc](https://github.com/kubernetes/ingress/tree/master/examples/auth/basic/haproxy)|
||`ingress.kubernetes.io/auth-realm`|realm string|[doc](https://github.com/kubernetes/ingress/tree/master/examples/auth/basic/haproxy)|
|`[0]`|`ingress.kubernetes.io/auth-tls-error-page`|url|[doc](https://github.com/kubernetes/ingress/tree/master/examples/auth/client-certs/haproxy)|
||`ingress.kubernetes.io/auth-tls-secret`|namespace/secret name|[doc](https://github.com/kubernetes/ingress/tree/master/examples/auth/client-certs/haproxy)|
||`ingress.kubernetes.io/auth-type`|"basic"|[doc](/examples/auth/basic)|
||`ingress.kubernetes.io/auth-secret`|secret name|[doc](/examples/auth/basic)|
||`ingress.kubernetes.io/auth-realm`|realm string|[doc](/examples/auth/basic)|
|`[0]`|`ingress.kubernetes.io/auth-tls-error-page`|url|[doc](/examples/auth/client-certs)|
||`ingress.kubernetes.io/auth-tls-secret`|namespace/secret name|[doc](/examples/auth/client-certs)|
|`[1]`|[`ingress.kubernetes.io/limit-connections`](#limit)|qty|-|
|`[1]`|[`ingress.kubernetes.io/limit-rps`](#limit)|rate per second|-|
|`[1]`|[`ingress.kubernetes.io/limit-whitelist`](#limit)|cidr list|-|
Expand All @@ -61,8 +61,8 @@ The following annotations are supported:
||`ingress.kubernetes.io/secure-verify-ca-secret`|secret name|-|
|`[0]`|[`ingress.kubernetes.io/session-cookie-name`](#affinity)|cookie name|-|
||`ingress.kubernetes.io/ssl-passthrough`|[true\|false]|-|
||`ingress.kubernetes.io/ssl-redirect`|[true\|false]|[doc](https://github.com/kubernetes/ingress/tree/master/examples/rewrite/haproxy)|
||`ingress.kubernetes.io/app-root`|/url|[doc](https://github.com/kubernetes/ingress/tree/master/examples/rewrite/haproxy)|
||`ingress.kubernetes.io/ssl-redirect`|[true\|false]|[doc](/examples/rewrite)|
||`ingress.kubernetes.io/app-root`|/url|[doc](/examples/rewrite)|
||`ingress.kubernetes.io/whitelist-source-range`|CIDR|-|
|`[1]`|[`ingress.kubernetes.io/rewrite-target`](#rewrite-target)|path string|-|
|`[0]`|[`ingress.kubernetes.io/server-alias`](#server-alias)|domain name or regex|-|
Expand Down
165 changes: 165 additions & 0 deletions examples/PREREQUISITES.md
@@ -0,0 +1,165 @@
# Prerequisites

Many of the examples in this directory have common prerequisites.

## Deploying a controller

You need to deploy HAProxy Ingress controller before running these examples.
You can do so following [these instructions](/examples/deployment).

## Firewall rules

If you're using a generic controller, eg the HAProxy Ingress controller, you
will need to create a firewall rule that targets port 80/443 on the specific VMs
the HAProxy controller is running on. On cloudproviders, the respective backend
will auto-create firewall rules for your Ingress.

## TLS certificates

Unless otherwise mentioned, the TLS secret used in examples is a 2048 bit RSA
key/cert pair with an arbitrarily chosen hostname, created as follows

```console
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=localhost"
Generating a 2048 bit RSA private key
................+++
................+++
writing new private key to 'tls.key'
-----

$ kubectl create secret tls tls-secret --key tls.key --cert tls.crt
secret "tls-secret" created
```

## CA Authentication
You can act as your very own CA, or use an existing one. As an exercise / learning, we're going to generate our
own CA, and also generate a client certificate.

These instructions are based on CoreOS OpenSSL [instructions](https://coreos.com/kubernetes/docs/latest/openssl.html)

### Generating a CA

First of all, you've to generate a CA. This is going to be the one who will sign your client certificates.
In real production world, you may face CAs with intermediate certificates, as the following:

```console
$ openssl s_client -connect www.google.com:443
[...]
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
i:/C=US/O=Google Inc/CN=Google Internet Authority G2
1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority

```

To generate our CA Certificate, we've to run the following commands:

```console
$ openssl genrsa -out ca.key 2048
$ openssl req -x509 -new -nodes -key ca.key -days 10000 -out ca.crt -subj "/CN=example-ca"
```

This will generate two files: A private key (ca.key) and a public key (ca.crt). This CA is valid for 10000 days.
The ca.crt can be used later in the step of creation of CA authentication secret.

### Generating the client certificate

The following steps generate a client certificate signed by the CA generated above. This client can be
used to authenticate in a tls-auth configured ingress.

First, we need to generate an 'openssl.cnf' file that will be used while signing the keys:

```
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
```

Then, a user generates his very own private key (that he needs to keep secret)
and a CSR (Certificate Signing Request) that will be sent to the CA to sign and generate a certificate.

```console
$ openssl genrsa -out client1.key 2048
$ openssl req -new -key client1.key -out client1.csr -subj "/CN=client1" -config openssl.cnf
```

As the CA receives the generated 'client1.csr' file, it signs it and generates a client.crt certificate:

```console
$ openssl x509 -req -in client1.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client1.crt -days 365 -extensions v3_req -extfile openssl.cnf
```

Then, you'll have 3 files: the client.key (user's private key), client.crt (user's public key) and client.csr (disposable CSR).

### Creating the CA Authentication secret

If you're using the CA Authentication feature, you need to generate a secret containing
all the authorized CAs. You must download them from your CA site in PEM format (like the following):

```
-----BEGIN CERTIFICATE-----
[....]
-----END CERTIFICATE-----
```

You can have as many certificates as you want. If they're in the binary DER format,
you can convert them as the following:

```console
$ openssl x509 -in certificate.der -inform der -out certificate.crt -outform pem
```

Then, you've to concatenate them all in only one file, named 'ca.crt' as the following:


```console
$ cat certificate1.crt certificate2.crt certificate3.crt >> ca.crt
```

The final step is to create a secret with the content of this file. This secret is going to be used in
the TLS Auth directive:

```console
$ kubectl create secret generic caingress --namespace=default --from-file=ca.crt=<ca.crt>
```

Note: You can also generate the CA Authentication Secret along with the TLS Secret by using:
```console
$ kubectl create secret generic caingress --namespace=default --from-file=ca.crt=<ca.crt> --from-file=tls.crt=<tls.crt> --from-file=tls.key=<tls.key>
```

## Ingress Class

If you have multiple Ingress controllers in a single cluster, you can pick one
by specifying the `ingress.class` annotation, eg creating an Ingress with an
annotation like

```yaml
metadata:
name: foo
annotations:
kubernetes.io/ingress.class: "gce"
```

will target the GCE controller, forcing the HAProxy controller to ignore it, while
an annotation like

```yaml
metadata:
name: foo
annotations:
kubernetes.io/ingress.class: "haproxy"
```

will target the HAProxy controller, forcing the GCE controller to ignore it.

__Note__: Deploying multiple ingress controller and not specifying the
annotation will result in both controllers fighting to satisfy the Ingress.
5 changes: 5 additions & 0 deletions examples/README.md
@@ -0,0 +1,5 @@
# Ingress examples

This directory contains a catalog of examples on how to run, configure and
scale Ingress. Please review the [prerequisites](PREREQUISITES.md) before
trying them.
99 changes: 99 additions & 0 deletions examples/auth/basic/README.md
@@ -0,0 +1,99 @@
# HAProxy Ingress Basic Authentication

This example demonstrates how to configure
[Basic Authentication](https://tools.ietf.org/html/rfc2617) on
HAProxy Ingress controller.

## Prerequisites

This document has the following prerequisites:

* Deploy [HAProxy Ingress controller](/examples/deployment/haproxy), you should
end up with controller, a sample web app and an ingress resource to the `foo.bar`
domain

## Using Basic Authentication

HAProxy Ingress read user and password from `auth` file stored on secrets, one user
and password per line. Secret name, realm and type are configured with annotations
in the ingress resource:

* `ingress.kubernetes.io/auth-type`: the only supported type is `basic`
* `ingress.kubernetes.io/auth-realm`: an optional string with authentication realm
* `ingress.kubernetes.io/auth-secret`: name of the secret

Each line of the `auth` file should have:

* user and insecure password separated with a pair of colons: `<username>::<plain-text-passwd>`; or
* user and an encrypted password separated with colons: `<username>:<encrypted-passwd>`

HAProxy evaluates encrypted passwords with
[crypt](http://man7.org/linux/man-pages/man3/crypt.3.html) function. Use `mkpasswd` or
`makepasswd` to create it. `mkpasswd` can be found on Alpine Linux container.

## Configure

Create a secret to our users:

* `john` and password `admin` using insecure plain text password
* `jane` and password `guest` using encrypted password

```console
$ mkpasswd -m des ## a short, des encryption, syntax from Busybox on Alpine Linux
Password: (type 'guest' and press Enter)
E5BrlrQ5IXYK2

$ cat >auth <<EOF
john::admin
jane:E5BrlrQ5IXYK2
EOF

$ kubectl create secret generic mypasswd --from-file auth
$ rm -fv auth
```

Annotate the ingress resource created on a [previous step](/examples/deployment/haproxy):

```console
$ kubectl annotate ingress/app \
ingress.kubernetes.io/auth-type=basic \
ingress.kubernetes.io/auth-realm="My Server" \
ingress.kubernetes.io/auth-secret=mypasswd
```

Test without user and password:

```console
$ curl -i 172.17.4.99:30876 -H 'Host: foo.bar'
HTTP/1.0 401 Unauthorized
Cache-Control: no-cache
Connection: close
Content-Type: text/html
WWW-Authenticate: Basic realm="My Server"

<html><body><h1>401 Unauthorized</h1>
You need a valid user and password to access this content.
</body></html>
```

Send a valid user:

```console
$ curl -i -u 'john:admin' 172.17.4.99:30876 -H 'Host: foo.bar'
HTTP/1.1 200 OK
Server: nginx/1.9.11
Date: Sun, 05 Mar 2017 19:22:33 GMT
Content-Type: text/plain
Transfer-Encoding: chunked

CLIENT VALUES:
client_address=10.2.18.5
command=GET
real path=/
query=nil
request_version=1.1
request_uri=http://foo.bar:8080/
```

Using `jane:guest` user/passwd should have the same output.

0 comments on commit c06351c

Please sign in to comment.