feat: support TLS auth

This commit is contained in:
geek 2017-08-01 17:38:20 -05:00 committed by Sérgio Ramos
parent f896569f4c
commit e5bbdadd6a
10 changed files with 139 additions and 21 deletions

View File

@ -21,7 +21,7 @@
"joi": "^10.6.0", "joi": "^10.6.0",
"joyent-cp-gql-schema": "^1.2.0", "joyent-cp-gql-schema": "^1.2.0",
"piloted": "^3.1.1", "piloted": "^3.1.1",
"portal-api": "^1.3.2", "portal-api": "^1.3.3",
"toppsy": "^1.1.0", "toppsy": "^1.1.0",
"triton": "^5.2.0" "triton": "^5.2.0"
} }

View File

@ -5,7 +5,7 @@ FROM node:8-alpine
# Install dependencies # Install dependencies
RUN set -x \ RUN set -x \
&& apk update \ && apk update \
&& apk add --update curl bash build-base git nginx python \ && apk add --update curl bash build-base git nginx python openssl \
&& apk upgrade \ && apk upgrade \
&& rm -rf /var/cache/apk/* && rm -rf /var/cache/apk/*

View File

@ -1,8 +1,27 @@
#!/bin/sh #!/bin/bash
# Render Nginx configuration template using values from Consul, # Render Nginx configuration template using values from Consul,
# but do not reload because Nginx has't started yet # but do not reload because Nginx has't started yet.
# Install key files for TLS auth in nginx
preStart() { preStart() {
# Copy creds from env vars to files on disk
if [ -n ${!NGINX_CA_CRT} ] \
&& [ -n ${!NGINX_SERVER_KEY} ] \
&& [ -n ${!NGINX_SERVER_CRT} ]
then
local nginx_path=/etc/nginx/certs
mkdir -p $nginx_path
mkdir -p $nginx_path/ca
mkdir -p $nginx_path/server
echo -e "${NGINX_CA_CRT}" | tr '#' '\n' > $nginx_path/ca/ca.crt
echo -e "${NGINX_SERVER_KEY}" | tr '#' '\n' > $nginx_path/server/server.key
echo -e "${NGINX_SERVER_CRT}" | tr '#' '\n' > $nginx_path/server/server.crt
chmod 444 $nginx_path/ca/ca.crt
chmod 444 $nginx_path/server/server.key
chmod 444 $nginx_path/server/server.crt
fi
consul-template \ consul-template \
-once \ -once \
-consul localhost:8500 \ -consul localhost:8500 \

View File

@ -37,8 +37,8 @@
once: 'exitSuccess' once: 'exitSuccess'
}, },
health: { health: {
exec: '/usr/bin/curl -o /dev/null --fail -s http://localhost:{{.PORT}}', exec: 'pstree nginx',
interval: 5, interval: 10,
ttl: 25 ttl: 25
} }
}, },

View File

@ -25,6 +25,15 @@ events {
http { http {
index index.html index.htm; index index.html index.htm;
server {
server_name _;
listen 80;
listen [::]:80;
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
{{ if service "api" }} {{ if service "api" }}
upstream api_hosts { upstream api_hosts {
{{range service "api"}} {{range service "api"}}
@ -33,10 +42,19 @@ http {
}{{ end }} }{{ end }}
server { server {
server_name _; listen 443 ssl;
listen {{ env "PORT" }} default_server; listen [::]:443 ssl;
listen [::]:{{ env "PORT" }} default_server;
root /opt/app/packages/cp-frontend/build; root /opt/app/packages/cp-frontend/build;
ssl_certificate /etc/nginx/certs/server/server.crt;
ssl_certificate_key /etc/nginx/certs/server/server.key;
ssl_client_certificate /etc/nginx/certs/ca/ca.crt;
ssl_verify_client on;
ssl_session_timeout 1d;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';
location / { location / {
try_files $uri /index.html; try_files $uri /index.html;
} }
@ -44,7 +62,9 @@ http {
rewrite /api/(.*) /$1 break; rewrite /api/(.*) /$1 break;
proxy_pass http://api_hosts; proxy_pass http://api_hosts;
proxy_redirect off; proxy_redirect off;
proxy_set_header Host $host; proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Client-Dn $ssl_client_s_dn;
} }
} }

View File

@ -51,13 +51,17 @@ frontend:
mem_limit: 512m mem_limit: 512m
links: links:
- consul:consul - consul:consul
env_file:
- _env
environment: environment:
- CONSUL=consul - CONSUL=consul
- PORT=80 - PORT=443
- REACT_APP_GQL_HOSTNAME=localhost - REACT_APP_GQL_HOSTNAME=workshop.host
- REACT_APP_GQL_PORT=80 - REACT_APP_GQL_PORT=443
- REACT_APP_GQL_PROTOCOL=https
ports: ports:
- "80:80" - "80:80"
- "443:443"
dns: dns:
- 127.0.0.1 - 127.0.0.1

View File

@ -13,9 +13,9 @@ const GLOBAL =
} }
}; };
const GQL_PORT = process.env.REACT_APP_GQL_PORT || 80; const GQL_PORT = process.env.REACT_APP_GQL_PORT || 443;
const GQL_HOSTNAME = const GQL_HOSTNAME = process.env.REACT_APP_GQL_HOSTNAME || GLOBAL.location.hostname;
process.env.REACT_APP_GQL_HOSTNAME || GLOBAL.location.hostname; const GQL_PROTOCOL = process.env.REACT_APP_GQL_PROTOCOL || 'https';
export const client = new ApolloClient({ export const client = new ApolloClient({
dataIdFromObject: o => { dataIdFromObject: o => {
@ -31,7 +31,7 @@ export const client = new ApolloClient({
return `${o.__typename}:${id}`; return `${o.__typename}:${id}`;
}, },
networkInterface: createNetworkInterface({ networkInterface: createNetworkInterface({
uri: `http://${GQL_HOSTNAME}:${GQL_PORT}/api/graphql` uri: `${GQL_PROTOCOL}://${GQL_HOSTNAME}:${GQL_PORT}/api/graphql`
}) })
}); });

View File

@ -1,6 +1,6 @@
{ {
"name": "joyent-cp-gql-schema", "name": "joyent-cp-gql-schema",
"version": "1.2.0", "version": "1.3.0",
"license": "MPL-2.0", "license": "MPL-2.0",
"repository": "github:yldio/joyent-portal", "repository": "github:yldio/joyent-portal",
"main": "index.js", "main": "index.js",

View File

@ -1,6 +1,6 @@
{ {
"name": "portal-api", "name": "portal-api",
"version": "1.3.2", "version": "1.3.3",
"description": "", "description": "",
"main": "./lib/index.js", "main": "./lib/index.js",
"scripts": { "scripts": {
@ -40,7 +40,7 @@
"force-array": "^3.1.0", "force-array": "^3.1.0",
"graphi": "^2.2.1", "graphi": "^2.2.1",
"hoek": "^4.1.1", "hoek": "^4.1.1",
"joyent-cp-gql-schema": "^1.0.4", "joyent-cp-gql-schema": "^1.3.0",
"lodash.find": "^4.6.0", "lodash.find": "^4.6.0",
"lodash.flatten": "^4.4.0", "lodash.flatten": "^4.4.0",
"lodash.get": "^4.4.2", "lodash.get": "^4.4.2",

View File

@ -3,7 +3,7 @@ set -e -o pipefail
help() { help() {
echo echo
echo 'Usage ./setup.sh ~/path/to/TRITON_PRIVATE_KEY' echo 'Usage ./setup.sh ~/path/to/TRITON_PRIVATE_KEY ~/path/to/CA_CRT ~/path/to/SERVER_KEY ~/path/to/SERVER_CRT'
echo echo
echo 'Checks that your Triton and Docker environment is sane and configures' echo 'Checks that your Triton and Docker environment is sane and configures'
echo 'an environment file to use.' echo 'an environment file to use.'
@ -39,6 +39,75 @@ check() {
# Assign args to named vars # Assign args to named vars
TRITON_PRIVATE_KEY_PATH=$1 TRITON_PRIVATE_KEY_PATH=$1
if [ -z "$2" ]; then
tput rev # reverse
tput bold # bold
echo 'Please provide a path to the NGINX CA crt file.'
tput sgr0 # clear
help
exit 1
fi
if [ ! -f "$2" ]; then
tput rev # reverse
tput bold # bold
echo 'CA certificate for NGINX is unreadable.'
tput sgr0 # clear
help
exit 1
fi
NGINX_CA_CRT_PATH=$2
if [ -z "$3" ]; then
tput rev # reverse
tput bold # bold
echo 'Please provide a path to the server key file.'
tput sgr0 # clear
help
exit 1
fi
if [ ! -f "$3" ]; then
tput rev # reverse
tput bold # bold
echo 'Server key file for NGINX is unreadable.'
tput sgr0 # clear
help
exit 1
fi
NGINX_SERVER_KEY_PATH=$3
if [ -z "$4" ]; then
tput rev # reverse
tput bold # bold
echo 'Please provide a path to the server crt file.'
tput sgr0 # clear
help
exit 1
fi
if [ ! -f "$4" ]; then
tput rev # reverse
tput bold # bold
echo 'Server crt file for NGINX is unreadable.'
tput sgr0 # clear
help
exit 1
fi
NGINX_SERVER_CRT_PATH=$4
command -v docker >/dev/null 2>&1 || { command -v docker >/dev/null 2>&1 || {
echo echo
tput rev # reverse tput rev # reverse
@ -83,8 +152,14 @@ check() {
echo TRITON_KEY_PATH=${TRITON_CREDS_PATH}/key.pem >> _env echo TRITON_KEY_PATH=${TRITON_CREDS_PATH}/key.pem >> _env
echo TRITON_CERT=$(cat "${DOCKER_CERT_PATH}"/cert.pem | tr '\n' '#') >> _env echo TRITON_CERT=$(cat "${DOCKER_CERT_PATH}"/cert.pem | tr '\n' '#') >> _env
echo TRITON_CERT_PATH=${TRITON_CREDS_PATH}/cert.pem >> _env echo TRITON_CERT_PATH=${TRITON_CREDS_PATH}/cert.pem >> _env
echo SDC_KEY=$(cat "${TRITON_PRIVATE_KEY_PATH}" | tr '\n' '#') >> _env echo SDC_KEY=$(cat "${TRITON_PRIVATE_KEY_PATH}" | tr '\n' '#') >> _env
echo SDC_KEY_PUB=$(cat "${TRITON_PRIVATE_KEY_PATH}.pub" | tr '\n' '#') >> _env echo SDC_KEY_PUB=$(cat "${TRITON_PRIVATE_KEY_PATH}.pub" | tr '\n' '#') >> _env
echo NGINX_CA_CRT=$(cat "${NGINX_CA_CRT_PATH}" | tr '\n' '#') >> _env
echo NGINX_SERVER_KEY=$(cat "${NGINX_SERVER_KEY_PATH}" | tr '\n' '#') >> _env
echo NGINX_SERVER_CRT=$(cat "${NGINX_SERVER_CRT_PATH}" | tr '\n' '#') >> _env
echo >> _env echo >> _env
} }