Skip to content

Commit ee29897

Browse files
author
Doug Davis
committed
add auth/nginx sample
Signed-off-by: Doug Davis <[email protected]>
1 parent 4c13b0b commit ee29897

File tree

10 files changed

+175
-0
lines changed

10 files changed

+175
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ is demonstrating.
100100
- [helloworld](helloworld)<br>
101101
Similar to [hello](hello) except this is written in golang and adds a few
102102
bells-n-whistles to allow you to control what it does when invoked.
103+
- [auth](auth)<br>
104+
This shows how to setup an nginx proxy in-front of a private application
105+
to ensure that only authorized people can access it.
103106
- [bind-app](bind-app)<br>
104107
This will create an instance of DB2 in the IBM Cloud and then ask Code
105108
Engine to bind it to an Application so we can access it from the App. The

auth/Dockerfile.app

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM golang:alpine
2+
COPY app.go /
3+
RUN go build -o /app /app.go
4+
5+
# Copy the exe into a smaller base image
6+
FROM alpine
7+
COPY --from=0 /app /app
8+
CMD /app

auth/Dockerfile.nginx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# A special NGINX image due to current limitations, that should be removed soon
2+
FROM nginxinc/nginx-unprivileged
3+
USER 101
4+
5+
# call-ngninx is just a script that'll replace "NS" in the config file with
6+
# the proper project ID
7+
COPY call-nginx /
8+
9+
# htpasswd contains the user/password info - for auth
10+
COPY htpasswd /etc/apache2/.htpasswd
11+
12+
# Use our custom nginx config file
13+
COPY nginx.conf /etc/nginx/conf.d/default.conf
14+
15+
# At runtime, call the wrapper script to do the "NS" substitutions
16+
CMD ["/call-nginx"]

auth/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Authentication Proxy
2+
3+
This sample will show how to setup an application using `nginx` that acts
4+
as proxy, and authentication checker, for a secondary application. The
5+
secondary application is not exposed to the internet (it is "cluster local"),
6+
to ensure that only authorized users can access it.
7+
8+
The nginx authentication checks are done by checking the username and password
9+
values that are stored in the `htpasswd` file.
10+
11+
There is a bit of a trick here in that we need to modify our nginx config
12+
file to include the Code Engine subdomain name (ie. kubernetes namespace)
13+
as part of the proxy configuration. To do that, we'll wrapper the call to
14+
`nginx` at runtime with a bash script that will replace all `NS` strings
15+
in the nginx config file with the subdomain value we pick up from the
16+
`CE_SUBDOMAIN` environment variable.
17+
18+
- - -
19+
20+
As noted in [the main README](../README.md), this sample has two pieces:
21+
22+
- a `build` script which will build the container image(s) used
23+
- a `run` script which deploys resources that use those images
24+
25+
The main purpose of this example is the `run` script, but the `build`
26+
script is included for complete educational (and reuse) purposes.
27+

auth/app.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
)
7+
8+
// This func will handle all incoming HTTP requests
9+
func HandleHTTP(w http.ResponseWriter, r *http.Request) {
10+
fmt.Fprintf(w, "You made it to the real app!\n")
11+
}
12+
13+
func main() {
14+
fmt.Printf("Listening on port 8080\n")
15+
http.HandleFunc("/", HandleHTTP)
16+
http.ListenAndServe(":8080", nil)
17+
}

auth/build

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash
2+
3+
# Env Vars:
4+
# REGISTRY: name of the image registry/namespace to store the images
5+
# NOCACHE: set this to "--no-cache" to turn off the Docker build cache
6+
#
7+
# NOTE: to run this you MUST set the REGISTRY environment variable to
8+
# your own image registry/namespace otherwise the `docker push` commands
9+
# will fail due to an auth failure. Which means, you also need to be logged
10+
# into that registry before you run it.
11+
12+
set -ex
13+
export REGISTRY=${REGISTRY:-ibmcom}
14+
15+
# Build the images
16+
docker build ${NOCACHE} -f Dockerfile.nginx -t ${REGISTRY}/auth-proxy .
17+
docker build ${NOCACHE} -f Dockerfile.app -t ${REGISTRY}/auth-app .
18+
19+
# And push them
20+
docker push ${REGISTRY}/auth-proxy
21+
docker push ${REGISTRY}/auth-app

auth/call-nginx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/bash
2+
3+
set -ex
4+
5+
# Replace all "NS" in the config file with the Code Engine subdomain (k8s ns)
6+
sed -i "s/NS/$CE_SUBDOMAIN/g" /etc/nginx/conf.d/default.conf
7+
8+
# Now run nginx
9+
nginx-debug -g "daemon off;"

auth/htpasswd

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Sample basic auth user/password file. The values are:
2+
# admin:letmein
3+
# user:please
4+
5+
admin:$apr1$YH9W13n4$u9DCsxvaObzIprCR4hb37/
6+
user:$apr1$LxEps0ig$6kMGGh5fdKxx.mzbGzs3U/

auth/nginx.conf

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
access_log /dev/stdout main;
2+
server {
3+
listen 8080 ;
4+
server_name *.codeengine.appdomain.cloud ;
5+
6+
location / {
7+
# Send request on to Application called "app"
8+
# The "NS" will be replaced by the "call-nginx" script at runtime
9+
proxy_pass http://auth-app.NS.svc.cluster.local ;
10+
11+
# We need the Host header to point to the right Application
12+
proxy_set_header Host auth-app.NS.svc.cluster.local ;
13+
14+
# Set some other headers
15+
proxy_set_header X-Real-IP $remote_addr ;
16+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ;
17+
18+
# Websocket stuff
19+
proxy_http_version 1.1 ;
20+
proxy_set_header Upgrade $http_upgrade ;
21+
proxy_set_header Connection "upgrade" ;
22+
proxy_set_header X-Scheme $scheme ;
23+
24+
# Misc stuff
25+
proxy_cache_bypass $http_upgrade ;
26+
proxy_redirect off ;
27+
28+
# Setup our Basic Auth stuff
29+
auth_basic "Protected Area" ;
30+
auth_basic_user_file /etc/apache2/.htpasswd ;
31+
}
32+
}

auth/run

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/bin/bash
2+
3+
function clean() {
4+
set +ex
5+
echo Cleaning...
6+
(
7+
ibmcloud ce app delete -n auth-proxy -f
8+
ibmcloud ce app delete -n auth-app -f
9+
rm -f out
10+
) > /dev/null 2>&1
11+
}
12+
13+
clean
14+
[[ "$1" == "clean" ]] && exit 0
15+
16+
set -ex
17+
18+
export REGISTRY=${REGISTRY:-ibmcom}
19+
20+
# Create our business logic app - don't expose it on the internet
21+
ibmcloud ce app create -n auth-app --image $REGISTRY/auth-app --cluster-local
22+
23+
# Now create our proxy/authorization app, this one is exposed on the internet
24+
ibmcloud ce app create -n auth-proxy --image $REGISTRY/auth-proxy
25+
26+
# Get its URL
27+
URL=$(ibmcloud ce app get -n auth-proxy -o url)
28+
29+
# Now call the proxy app twice, first with proper credentials...
30+
curl -fqu user:please $URL
31+
32+
# Now call again w/o credential, it should fail
33+
curl -fq $URL && echo "It was supposed to fail" && exit 1
34+
35+
# Clean up
36+
clean

0 commit comments

Comments
 (0)