Skip to content

Commit 083f1fb

Browse files
committed
Merge branch 'master' into pr/rhansen/310
2 parents 79ff50c + 86266a0 commit 083f1fb

19 files changed

Lines changed: 401 additions & 55 deletions

.defaults.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ vouch:
1515
# whiteList:
1616
# teamWhitelist:
1717

18+
tls:
19+
# cert:
20+
# key:
21+
profile: intermediate
22+
1823
jwt:
1924
# secret:
2025
issuer: Vouch

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ config/config.yml_orig
1111
.dockerignore
1212
Dockerfile
1313
handlers/rice-box.go
14+
certs
15+
.cover/*

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ config/secret
99
!config/testing/*
1010
pkg/model/storage-test.db
1111
.vscode/*
12+
certs/*
1213
coverage.out
1314
coverage.html.env_google
1415
.env*
16+
.cover

.whitesource

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"scanSettings": {
3+
"baseBranches": []
4+
},
5+
"checkRunSettings": {
6+
"vulnerableCheckRunConclusionLevel": "failure",
7+
"displayMode": "diff"
8+
},
9+
"issueSettings": {
10+
"minSeverityLevel": "LOW"
11+
}
12+
}

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ RUN ./do.sh install
2020
FROM scratch
2121
LABEL maintainer="vouch@bnf.net"
2222
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
23-
COPY templates/ templates/
24-
COPY .defaults.yml .defaults.yml
23+
COPY templates /templates
24+
COPY .defaults.yml /.defaults.yml
2525
# see note for /static in main.go
2626
COPY static /static
2727
COPY --from=builder /go/bin/vouch-proxy /vouch-proxy

Dockerfile.alpine

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,23 @@ WORKDIR ${GOPATH}/src/github.com/vouch/vouch-proxy
99

1010
COPY . .
1111

12-
# RUN go-wrapper download # "go get -d -v ./..."
13-
# RUN ./do.sh build # see `do.sh` for vouch build details
14-
# RUN go-wrapper install # "go install -v ./..."
15-
1612
RUN ./do.sh goget
1713
RUN ./do.sh gobuildstatic # see `do.sh` for vouch-proxy build details
1814
RUN ./do.sh install
1915

2016
FROM alpine:latest
2117
LABEL maintainer="vouch@bnf.net"
18+
ENV VOUCH_ROOT=/
2219
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
23-
COPY templates/ templates/
24-
COPY .defaults.yml .defaults.yml
20+
COPY templates /templates
21+
COPY .defaults.yml /.defaults.yml
2522
# see note for /static in main.go
2623
COPY static /static
24+
25+
# do.sh requires bash
26+
RUN apk add --no-cache bash
2727
COPY do.sh /do.sh
28+
2829
COPY --from=builder /go/bin/vouch-proxy /vouch-proxy
2930
EXPOSE 9090
3031
ENTRYPOINT ["/vouch-proxy"]

README.md

Lines changed: 88 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
An SSO solution for Nginx using the [auth_request](http://nginx.org/en/docs/http/ngx_http_auth_request_module.html) module. Vouch Proxy can protect all of your websites at once.
1010

11-
Vouch Proxy supports many OAuth login providers and can enforce authentication to...
11+
Vouch Proxy supports many OAuth and OIDC login providers and can enforce authentication to...
1212

1313
- Google
1414
- [GitHub](https://developer.github.com/apps/building-integrations/setting-up-and-registering-oauth-apps/about-authorization-options-for-oauth-apps/)
@@ -30,6 +30,29 @@ Please do let us know when you have deployed Vouch Proxy with your preffered IdP
3030

3131
If Vouch is running on the same host as the Nginx reverse proxy the response time from the `/validate` endpoint to Nginx should be less than 1ms
3232

33+
---
34+
35+
## Table of Contents
36+
37+
- [What Vouch Proxy Does...](#what-vouch-proxy-does)
38+
- [Installation and Configuration](#installation-and-configuration)
39+
- [Configuring Vouch Proxy using Environmental Variables](#configuring-vouch-proxy-using-environmental-variables)
40+
- [More advanced configurations](#more-advanced-configurations)
41+
- [Scopes and Claims](#scopes-and-claims)
42+
- [Running from Docker](#running-from-docker)
43+
- [Kubernetes Nginx Ingress](#kubernetes-nginx-ingress)
44+
- [Compiling from source and running the binary](#compiling-from-source-and-running-the-binary)
45+
- [/login and /logout endpoint redirection](#-login-and--logout-endpoint-redirection)
46+
- [Troubleshooting, Support and Feature Requests](#troubleshooting--support-and-feature-requests--read-this-before-submitting-an-issue-at-github-)
47+
(Read this before submitting an issue at GitHub)
48+
- [I'm getting an infinite redirect loop which returns me to my IdP (Google/Okta/GitHub/...)](#i-m-getting-an-infinite-redirect-loop-which-returns-me-to-my-idp--google-okta-github--)
49+
- [Okay, I looked at the issues and have tried some things with my configs but it's still not working](#okay--i-looked-at-the-issues-and-have-tried-some-things-with-my-configs-but-it-s-still-not-working)
50+
- [submitting a Pull Request for a new feature](#submitting-a-pull-request-for-a-new-feature)
51+
- [Advanced Authorization Using OpenResty](#advanced-authorization-using-openresty)
52+
- [The flow of login and authentication using Google Oauth](#the-flow-of-login-and-authentication-using-google-oauth)
53+
54+
---
55+
3356
## What Vouch Proxy Does...
3457

3558
Vouch Proxy (VP) forces visitors to login and authenticate with an [IdP](https://en.wikipedia.org/wiki/Identity_provider) (such as one of the services listed above) before allowing them access to a website.
@@ -173,17 +196,45 @@ The variable `VOUCH_CONFIG` can be used to set an alternate location for the con
173196

174197
## More advanced configurations
175198

199+
All Vouch Proxy configuration items are documented in [config/config.yml_example](https://github.com/vouch/vouch-proxy/blob/master/config/config.yml_example)
200+
176201
- [cacheing of the Vouch Proxy validation response in Nginx](https://github.com/vouch/vouch-proxy/issues/76#issuecomment-464028743)
177202
- [handleing `OPTIONS` requests when protecting an API with Vouch Proxy](https://github.com/vouch/vouch-proxy/issues/216)
178203
- [validation by GitHub Team or GitHub Org](https://github.com/vouch/vouch-proxy/pull/205)
179204
- [running on a Raspberry Pi using the ARM based Docker image](https://github.com/vouch/vouch-proxy/pull/247)
180205
- [Kubernetes architecture post ingress](https://github.com/vouch/vouch-proxy/pull/263#issuecomment-628297832)
181206
- [set `HTTP_PROXY` to relay Vouch Proxy IdP requests through an outbound proxy server](https://github.com/vouch/vouch-proxy/issues/291)
182207
- [Reverse Proxy for Google Cloud Run Services](https://github.com/karthikv2k/oauth_reverse_proxy)
208+
- [Enable native TLS in Vouch Proxy](https://github.com/vouch/vouch-proxy/pull/332#issue-522612010)
183209

184210
Please do help us to expand this list.
185211

186-
All Vouch Proxy configuration items are documented in [config/config.yml_example](https://github.com/vouch/vouch-proxy/blob/master/config/config.yml_example)
212+
### Scopes and Claims
213+
214+
With Vouch Proxy you can request various `scopes` (standard and custom) to obtain more information about the user or gain access to the provider's APIs. Internally, Vouch Proxy launches a requests to `user_info_url` after successful authentication. From the provider's response the required `claims` are extracted and stored in the vouch cookie.
215+
216+
⚠️ **Additional claims and tokens will be added to the VP cookie and can make it large**
217+
218+
The VP cookie may get split up into several cookies, but if you need it, you need it. Large cookies and headers require Nginx to be configured with larger buffers. See [large_client_header_buffers](http://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers) and [proxy_buffer_size](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size) for more information.
219+
220+
#### Setup `scopes` and `claims` in Vouch Proxy with Nginx
221+
222+
0. Configure Vouch Proxy for Nginx and your IdP as normal (See: [Installation and Configuration](#installation-and-configuration))
223+
224+
1. Set the necessary `scope`s in the `oauth` section of the vouch-proxy `config.yml` ([example config](config/config.yml_example_scopes_and_claims))
225+
1. set `idtoken: X-Vouch-IdP-IdToken` in the `headers` section of vouch-proxy's `config.yml`
226+
2. log in and call the `/validate` endpoint in a modern browser
227+
3. check the response header for a `X-Vouch-IdP-IdToken` header
228+
4. copy the value of the header into the debugger at https://jwt.io/ and ensure that the necessary claims are part of the jwt
229+
5. if they are not, you need to adjust the `scopes` in the `oauth` section of your `config.yml` or reconfigure your oauth provider
230+
2. Set the necessary `claims` in the `header` section of the vouch-proxy `config.yml`
231+
1. log in and call the `/validate` endpoint in a modern browser
232+
2. check the response headers for headers of the form `X-Vouch-Idp-Claims-<ClaimName>`
233+
3. If they are not there clear your cookies and cached browser data
234+
4. 🐞 If they are still not there but exist in the jwt (esp. custom claims) there might be a bug
235+
5. remove the `idtoken: X-Vouch-IdP-IdToken` from the `headers` section of vouch-proxy's `config.yml` if you don't need it
236+
3. Use `auth_request_set` after `auth_request` inside the protected location in the nginx [`server.conf`](examples/nginx/nginx_scopes_and_claims.conf)
237+
4. Consume the claim ([example nginx config](examples/nginx/nginx_scopes_and_claims.conf))
187238

188239
## Running from Docker
189240

@@ -219,7 +270,7 @@ Automated container builds for each Vouch Proxy release are available from [Dock
219270

220271
## Kubernetes Nginx Ingress
221272

222-
If you are using kubernetes with [nginx-ingress](https://github.com/kubernetes/ingress-nginx), you can configure your ingress with the following annotations (note quoting the auth-signin annotation):
273+
If you are using kubernetes with [nginx-ingress](https://github.com/kubernetes/ingress-nginx), you can configure your ingress with the following annotations (note quoting the `auth-signin` annotation):
223274

224275
```bash
225276
nginx.ingress.kubernetes.io/auth-signin: "https://vouch.yourdomain.com/login?url=$scheme://$http_host$request_uri&vouch-failcount=$auth_resp_failcount&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err"
@@ -244,7 +295,7 @@ Helm Charts are maintained by [halkeye](https://github.com/halkeye) and are avai
244295

245296
## /login and /logout endpoint redirection
246297

247-
As of `v0.11.0` we have put additional checks in place to reduce [the attack surface of url redirection](https://blog.detectify.com/2019/05/16/the-real-impact-of-an-open-redirect/).
298+
As of `v0.11.0` additional checks are in place to reduce [the attack surface of url redirection](https://blog.detectify.com/2019/05/16/the-real-impact-of-an-open-redirect/).
248299

249300
### /login?url=POST_LOGIN_URL
250301

@@ -320,14 +371,35 @@ If you continue to have trouble, try the following:
320371

321372
Please [submit a new issue](https://github.com/vouch/vouch-proxy/issues) in the following fashion..
322373

374+
TLDR:
375+
376+
- set `vouch.testing: true`
377+
- set `vouch.logLevel: debug`
378+
- conduct a full round trip of `./vouch-proxy` capturing the output..
379+
- VP startup
380+
- `/validate`
381+
- `/login` - even if the error is here
382+
- `/auth`
383+
- `/validate` - capture everything
384+
- put all your logs and config in a `gist`.
385+
- `./do.sh bug_report` is your friend
386+
387+
#### But read this anyways because we'll ask you to read it if you don't follow these instruction. :)
388+
323389
- **turn on `vouch.testing: true`** and set `vouch.logLevel: debug`.
324-
- use [hasteb.in](https://hasteb.in/), or another **paste service** or a [gist](https://gist.github.com/) to provide your logs and config. **_DO NOT PUT YOUR LOGS AND CONFIG INTO THE GITHUB ISSUE_**. Using a paste service is important as it will maintain spacing and will provide line numbers and formatting. We are hunting for needles in haystacks with setups with several moving parts, these features help considerably. Paste services save your time and our time and help us to help you quickly. You're more likely to get good support from us in a timely manner by following this advice.
325-
- run `./do.sh bug_report yourdomain.com [yourotherdomain.com]` which will create a redacted version of your config and logs
390+
- use a [gist](https://gist.github.com/) or another **paste service** such as [hasteb.in](https://hasteb.in/). **_DO NOT PUT YOUR LOGS AND CONFIG INTO THE GITHUB ISSUE_**. Using a paste service is important as it will maintain spacing and will provide line numbers and formatting. We are hunting for needles in haystacks with setups with several moving parts, these features help considerably. Paste services save your time and our time and help us to help you quickly. You're more likely to get good support from us in a timely manner by following this advice.
391+
- run `./do.sh bug_report secretdomain.com secretpass [anothersecret..]` which will create a redacted version of your config and logs removing each of those strings
326392
- and follow the instructions at the end to redact your Nginx config
327-
- all of those go into [hasteb.in](https://hasteb.in/) or a [gist](https://gist.github.com/)
393+
- all of those go into a [gist](https://gist.github.com/)
328394
- then [open a new issue](https://github.com/vouch/vouch-proxy/issues/new) in this repository
329395
- or visit our IRC channel [#vouch](irc://freenode.net/#vouch) on freenode
330396

397+
A bug report can be generated from a docker environment using the `voucher/vouch-proxy:alpine` image...
398+
399+
```!bash
400+
docker run --name vouch_proxy -v $PWD/config:/config -v $PWD/certs:/certs -it --rm --entrypoint /do.sh voucher/vouch-proxy:alpine bug_report yourdomain.com anotherdomain.com someothersecret
401+
```
402+
331403
### submitting a Pull Request for a new feature
332404

333405
I really love Vouch Proxy! I wish it did XXXX...
@@ -366,21 +438,21 @@ OpenResty and configs for a variety of scenarios are available in the [examples]
366438
- 401 NotAuthorized then
367439
- respond to Bob with a 302 redirect to `https://vouch.oursites.com/login?url=https://private.oursites.com`
368440

369-
- vouch `https://vouch.oursites.com/validate`
441+
- Vouch Proxy `https://vouch.oursites.com/validate`
370442

371443
- recieves the request for private.oursites.com from Bob via Nginx `proxy_pass`
372-
- it looks for a cookie named "oursitesSSO" that contains a JWT
444+
- looks for a cookie named "oursitesSSO" that contains a JWT
373445
- if the cookie is found, and the JWT is valid
374-
- returns 200 to Nginx, which will allow access (bob notices nothing)
446+
- returns `200 OK` to Nginx, which will allow access (bob notices nothing)
375447
- if the cookie is NOT found, or the JWT is NOT valid
376-
- return 401 NotAuthorized to Nginx (which forwards the request on to login)
448+
- return `401 NotAuthorized` to Nginx (which forwards the request on to login)
377449

378450
- Bob is first forwarded briefly to `https://vouch.oursites.com/login?url=https://private.oursites.com`
379451

380452
- clears out the cookie named "oursitesSSO" if it exists
381453
- generates a nonce and stores it in session variable \$STATE
382-
- stores the url `https://private.oursites.com` from the query string in session variable \$requestedURL
383-
- respond to Bob with a 302 redirect to Google's OAuth Login form, including the \$STATE nonce
454+
- stores the url `https://private.oursites.com` from the query string in session variable `$requestedURL`
455+
- respond to Bob with a 302 redirect to Google's OAuth Login form, including the `$STATE` nonce
384456

385457
- Bob logs into his Google account using Oauth
386458

@@ -389,13 +461,13 @@ OpenResty and configs for a variety of scenarios are available in the [examples]
389461

390462
- Bob is forwarded to `https://vouch.oursites.com/auth?state=$STATE`
391463
- if the \$STATE nonce from the url matches the session variable "state"
392-
- make a "third leg" request of google (server to server) to exchange the OAuth code for Bob's user info including email address bob@oursites.com
464+
- make a "third leg" request of Google (server to server) to exchange the OAuth code for Bob's user info including email address bob@oursites.com
393465
- if the email address matches the domain oursites.com (it does)
394466
- issue bob a JWT in the form of a cookie named "oursitesSSO"
395-
- retrieve the session variable $requestedURL and 302 redirect bob back to $requestedURL
467+
- retrieve the session variable `$requestedURL` and 302 redirect bob back to `https://private.oursites.com`
396468

397469
Note that outside of some innocuos redirection, Bob only ever sees `https://private.oursites.com` and the Google Login screen in his browser. While Vouch does interact with Bob's browser several times, it is just to set cookies, and if the 302 redirects work properly Bob will log in quickly.
398470

399471
Once the JWT is set, Bob will be authorized for all other sites which are configured to use `https://vouch.oursites.com/validate` from the `auth_request` Nginx module.
400472

401-
The next time Bob is forwarded to google for login, since he has already authorized the Vouch OAuth app, Google immediately forwards him back and sets the cookie and sends him on his merry way. Bob may not even notice that he logged in via Vouch.
473+
The next time Bob is forwarded to google for login, since he has already authorized the Vouch Proxy OAuth app, Google immediately forwards him back and sets the cookie and sends him on his merry way. In some browsers such as Chrome, Bob may not even notice that he logged in using Vouch Proxy.

config/config.yml_example

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ vouch:
5757
# - myOrg
5858
# - myOrg/myTeam
5959

60+
tls:
61+
# cert: /path/to/signed_cert_plus_intermediates # VOUCH_TLS_CERT
62+
# key: /path/to/private_key # VOUCH_TLS_KEY
63+
# profile - defines the TLS configuration profile (modern, intermediate, old, default)
64+
profile: intermediate # VOUCH_TLS_PROFILE
65+
6066
jwt:
6167
# secret - VOUCH_JWT_SECRET
6268
# a random string used to cryptographically sign the jwt
@@ -88,8 +94,10 @@ vouch:
8894

8995
# httpOnly: true # VOUCH_COOKIE_HTTPONLY
9096

91-
# Set cookie maxAge to 0 to delete the cookie every time the browser is closed. - VOUCH_COOKIE_MAXAGE
92-
maxAge: 14400
97+
# Number of minutes until session cookie expires - VOUCH_COOKIE_MAXAGE
98+
# Set cookie maxAge to 0 to delete the cookie every time the browser is closed.
99+
# Must not be longer than jwt.maxAge
100+
maxAge: 240
93101

94102
# Set SameSite attribute to restrict browser behaviour wrt sending the cookie along with cross-site requests. - VOUCH_COOKIE_SAMESITE
95103
# Possible attribute values lax, strict, none.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
vouch:
2+
# .... domain configuration goes here
3+
4+
headers:
5+
# The idtoken is used for debugging during configuration
6+
# use the idtoken to make sure the oauth provider returns the necessary claims
7+
idtoken: X-Vouch-IdP-IdToken
8+
9+
# make sure to list all the claims you need
10+
# Note: they will be stored in the cookie AND header and get sent with each request
11+
claims:
12+
- sub
13+
- name
14+
- email
15+
- email_verified
16+
17+
oauth:
18+
# .... your provider config goes here
19+
scopes:
20+
# make sure to set the required scopes
21+
- openid
22+
- email
23+
- profile

do.sh

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ SCRIPT=$(readlink -f "$0")
77
SDIR=$(dirname "$SCRIPT")
88
cd $SDIR
99

10-
export VOUCH_ROOT=${GOPATH}/src/github.com/vouch/vouch-proxy/
10+
if [ -z "$VOUCH_ROOT" ]; then
11+
export VOUCH_ROOT=${GOPATH}/src/github.com/vouch/vouch-proxy/
12+
fi
1113

1214
IMAGE=voucher/vouch-proxy:latest
1315
ALPINE=voucher/vouch-proxy:alpine
@@ -119,13 +121,13 @@ EOF
119121
trap _redact_exit SIGINT
120122
./vouch-proxy 2>&1 | _redact
121123

122-
123124
}
125+
124126
_redact_exit () {
125127
echo -e "\n\n-------------------------\n"
126128
echo -e "redact your nginx config with:\n"
127129
echo -e "\tcat nginx.conf | sed 's/yourdomain.com/DOMAIN.COM/g'\n"
128-
echo -e "Please upload both configs and some logs to https://hastebin.com/ and open an issue on GitHub at https://github.com/vouch/vouch-proxy/issues\n"
130+
echo -e "Please upload configs and logs to a gist and open an issue on GitHub at https://github.com/vouch/vouch-proxy/issues\n"
129131
}
130132

131133
_redact() {
@@ -318,6 +320,17 @@ gosec() {
318320
# segfault's without exec since it would just call this function infinitely :)
319321
exec gosec ./...
320322
}
323+
324+
selfcert() {
325+
# https://stackoverflow.com/questions/63588254/how-to-set-up-an-https-server-with-a-self-signed-certificate-in-golang
326+
set -e
327+
mkdir -p $SDIR/certs
328+
# openssl genrsa -out $SDIR/certs/server.key 2048
329+
openssl ecparam -genkey -name secp384r1 -out $SDIR/certs/server.key
330+
openssl req -new -x509 -sha256 -key $SDIR/certs/server.key -out $SDIR/certs/server.crt -days 3650
331+
echo -e "created self signed certs in '$SDIR/certs'\n"
332+
}
333+
321334
usage() {
322335
cat <<EOF
323336
usage:
@@ -327,6 +340,7 @@ usage() {
327340
$0 goget - get all dependencies
328341
$0 gofmt - gofmt the entire code base
329342
$0 gosec - gosec security audit of the entire code base
343+
$0 selfcert - calls openssl to create a self signed key and cert
330344
$0 dbuild - build docker container
331345
$0 drun [args] - run docker container
332346
$0 dbuildalpine - build docker container for alpine
@@ -360,6 +374,7 @@ case "$ARG" in
360374
|'install' \
361375
|'test' \
362376
|'goget' \
377+
|'selfcert' \
363378
|'gogo' \
364379
|'watch' \
365380
|'gobuildstatic' \

0 commit comments

Comments
 (0)