Skip to content

Commit

Permalink
Allow a separate domain name for auth
Browse files Browse the repository at this point in the history
Let the auth (keycloak) configuration live at a separate domain name
from the web (PDC implementation) domain name. Separate certificates
are now expected by the `.env.example`, `compose.yml`, and
`proxy.conf.example` files. This change creates a logical separation
of concerns but keeps the implementation on the same host for now. In
future a change of (tangible) hosting for either backend service can
be made with minimal disruption from a user perspective.

Issue #66 Deploy Keycloak at auth.pdco
  • Loading branch information
bickelj committed Mar 2, 2023
1 parent 968820e commit b838c20
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 28 deletions.
10 changes: 8 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,15 @@ PG_DB=pdc
PG_PORT=5432
WEB_CONTAINER_USER=902
REVERSE_PROXY_CONTAINER_USER=903
# Permission issues can be avoided by creating the following files prior to
# launching the compose script. For the certificate pairs, one could get started
# with a single self-signed certificate for both web and auth.
NGINX_CONF=/home/reverse-proxy/proxy.conf
NGINX_CERT=/home/reverse-proxy/cert.pem
NGINX_KEY=/home/reverse-proxy/key.pem
WEB_CERT=/home/reverse-proxy/web-cert.pem
WEB_KEY=/home/reverse-proxy/web-key.pem
AUTH_CERT=/home/reverse-proxy/auth-cert.pem
AUTH_KEY=/home/reverse-proxy/auth-key.pem
AUTH_ROOT_PAGE=/home/reverse-proxy/auth_root_page.html
AUTH_CONTAINER_USER=904
KEYCLOAK_PG_INITDB_SCRIPT=/home/deploy/keycloakInitDb.sh
KEYCLOAK_PG_PASSWORD=you_should_replace_this_with_your_own_keycloak_db_passphrase
Expand Down
26 changes: 18 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ Make sure there is a `conf/conf.d` directory under the database directory:

This directory can contain additional postgresql settings in `*.conf` files.

Copy `auth_root_page.html` to `/home/reverse-proxy/` or wherever your `.env`
expects to find it via `AUTH_ROOT_PAGE`.

## Other considerations

Because the `docker` commands (with vanilla Docker) essentially grant root
Expand All @@ -95,14 +98,21 @@ For example, to create and save the letsencrypt state in the reverse-proxy home:
sudo docker run -ti --rm -p 80:80 \
-v "/home/reverse-proxy/letsencrypt:/etc/letsencrypt" \
-v "/home/reverse-proxy/letsencrypt:/var/lib/letsencrypt" \
certbot/certbot:v1.30.0 certonly

And then to copy the key and certificate:

sudo cp /home/reverse-proxy/letsencrypt/live/domain.name/fullchain.pem \
/home/reverse-proxy/cert.pem
sudo cp /home/reverse-proxy/letsencrypt/live/domain.name/privkey.pem \
/home/reverse-proxy/key.pem
certbot/certbot:v1.32.2 certonly

Repeat the above step for both the auth service and web service domain names.
Then copy the keys and certificates:

export AUTH_DOMAIN=my_domain_name_hosting_the_auth_service
sudo cp /home/reverse-proxy/letsencrypt/live/${AUTH_DOMAIN}/fullchain.pem \
/home/reverse-proxy/auth-cert.pem
sudo cp /home/reverse-proxy/letsencrypt/live/${AUTH_DOMAIN}/privkey.pem \
/home/reverse-proxy/auth-key.pem
export WEB_DOMAIN=my_domain_hosting_the_back-end_web_service
sudo cp /home/reverse-proxy/letsencrypt/live/${WEB_DOMAIN}/fullchain.pem \
/home/reverse-proxy/auth-cert.pem
sudo cp /home/reverse-proxy/letsencrypt/live/${WEB_DOMAIN}/privkey.pem \
/home/reverse-proxy/auth-key.pem

Reload or restart the reverse proxy container to use the certificate:

Expand Down
16 changes: 16 additions & 0 deletions auth_root_page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<title>Philanthropy Data Commons</title>
</head>
<body>
<h1>Philanthropy Data Commons</h1>
<p>There is no content here. You probably meant to visit one of these sites:
<ul>
<li><a href="https://www.philanthropydatacommons.org">https://www.philanthropydatacommons.org</a></li>
<li><a href="https://pilot.philanthropydatacommons.org">https://pilot.philanthropydatacommons.org</a></li>
<li><a href="https://api.philanthropydatacommons.org">https://api.philanthropydatacommons.org</a></li>
</ul>
</p>
</body>
</html>
15 changes: 12 additions & 3 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ services:
- "443:8443"
volumes:
- ${NGINX_CONF}:/opt/bitnami/nginx/conf/server_blocks/vhost.conf:ro
- ${NGINX_CERT}:/opt/bitnami/nginx/conf/server.crt:ro
- ${NGINX_KEY}:/opt/bitnami/nginx/conf/server.key:ro
# The web service may run on a separate subdomain from the auth service
- ${WEB_CERT}:/opt/bitnami/nginx/conf/web-cert.pem:ro
- ${WEB_KEY}:/opt/bitnami/nginx/conf/web-key.pem:ro
# The auth service may run on a separate subdomain from the web service
- ${AUTH_CERT}:/opt/bitnami/nginx/conf/auth-cert.pem:ro
- ${AUTH_KEY}:/opt/bitnami/nginx/conf/auth-key.pem:ro
# A page to show when someone visits the auth service directly
- ${AUTH_ROOT_PAGE}:/app/auth_root_page.html:ro
depends_on:
web:
condition: service_healthy
Expand Down Expand Up @@ -42,6 +48,7 @@ services:
database:
image: bitnami/postgresql:14.7.0-debian-11-r5
user: ${DATABASE_CONTAINER_USER}
# For local development it can be useful to expose `ports: 5432:${PG_PORT}`.
volumes:
- ${PG_DATA}:/bitnami/postgresql
# In order for psql to use an arbitrary user above:
Expand Down Expand Up @@ -82,7 +89,9 @@ services:
- KEYCLOAK_ADMIN_PASSWORD=${KEYCLOAK_ADMIN_PASSWORD}
- KEYCLOAK_MANAGEMENT_USER=management
- KEYCLOAK_MANAGEMENT_PASSWORD=${KEYCLOAK_MANAGEMENT_PASSWORD}
- KEYCLOAK_EXTRA_ARGS=--proxy=edge --hostname-path=/auth --http-relative-path=/auth --hostname-strict=false
# For local development it can be useful to add the following to
# KEYCLOAK_EXTRA_ARGS: --hostname-path=/auth --http-relative-path=/auth
- KEYCLOAK_EXTRA_ARGS=--proxy=edge --hostname-strict=false
depends_on:
database:
condition: service_healthy
Expand Down
56 changes: 41 additions & 15 deletions proxy.conf.example
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
server {
listen 0.0.0.0:8443 ssl;
server_name # You will want more server names here.
server_name # Add your domain name for the back-end web service here.
reverse-proxy # This is the within-docker name.
localhost 127.0.0.1;
ssl_certificate /opt/bitnami/nginx/conf/server.crt;
ssl_certificate_key /opt/bitnami/nginx/conf/server.key;
# Volumes mounted in the compose.yml
ssl_certificate /opt/bitnami/nginx/conf/web-cert.pem;
ssl_certificate_key /opt/bitnami/nginx/conf/web-key.pem;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
Expand All @@ -13,29 +14,54 @@ server {
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;

# The root path goes to the PDC API implementation, the web service.
# The PDC API implementation, the web service.
location / {
proxy_pass http://web:3000;
}
}

server {
listen 0.0.0.0:8443 ssl;
server_name # Add your domain name for the auth service here.
# Volumes mounted in the compose.yml
ssl_certificate /opt/bitnami/nginx/conf/auth-cert.pem;
ssl_certificate_key /opt/bitnami/nginx/conf/auth-key.pem;

# The /auth paths go to the authentication and authorization service.
location /auth/admin/ {
proxy_pass http://auth:8080/auth/admin/;
# Keycloak can set large cookies and headers
proxy_buffer_size 16k;
proxy_buffers 8 16k;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;

# The authentication and authorization service.
location /admin/ {
proxy_pass http://auth:8080/admin/;
}

location /auth/js/ {
proxy_pass http://auth:8080/auth/js/;
location /js/ {
proxy_pass http://auth:8080/js/;
}

location /auth/realms/ {
proxy_pass http://auth:8080/auth/realms/;
location /realms/ {
proxy_pass http://auth:8080/realms/;
}

location /auth/resources/ {
proxy_pass http://auth:8080/auth/resources/;
location /resources/ {
proxy_pass http://auth:8080/resources/;
}

location /auth/robots.txt {
proxy_pass http://auth:8080/auth/robots.txt;
location /robots.txt {
proxy_pass http://auth:8080/robots.txt;
}

# A fallback page in case someone visits directly.
# Volume mounted in compose.yml at default root /app directory.
location / {
index auth_root_page.html;
}
}

0 comments on commit b838c20

Please sign in to comment.