diff --git a/.env.example b/.env.example index f7c76f6..57b502f 100644 --- a/.env.example +++ b/.env.example @@ -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 diff --git a/README.md b/README.md index 3180928..6cddcd6 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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: diff --git a/auth_root_page.html b/auth_root_page.html new file mode 100644 index 0000000..7879984 --- /dev/null +++ b/auth_root_page.html @@ -0,0 +1,16 @@ + + +
+There is no content here. You probably meant to visit one of these sites: +
+ + + diff --git a/compose.yml b/compose.yml index 55062e0..978068f 100644 --- a/compose.yml +++ b/compose.yml @@ -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 @@ -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: @@ -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 diff --git a/proxy.conf.example b/proxy.conf.example index 543767c..15a9bcf 100644 --- a/proxy.conf.example +++ b/proxy.conf.example @@ -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; @@ -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; } }