Skip to content

Commit

Permalink
Merge pull request #36 from SatoshiPortal/release
Browse files Browse the repository at this point in the history
Release v0.1.0-rc.1
  • Loading branch information
Kexkey authored Dec 28, 2018
2 parents 557163f + 50a4c80 commit f238827
Show file tree
Hide file tree
Showing 106 changed files with 7,631 additions and 702 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "install/SatoshiPortal/dockers"]
path = install/SatoshiPortal/dockers
url = https://github.com/SatoshiPortal/dockers.git
14 changes: 7 additions & 7 deletions api_auth_docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
FROM nginx:alpine

RUN apk add --update --no-cache \
bash \
git \
openssl \
fcgiwrap \
spawn-fcgi \
curl \
jq
jq \
su-exec

COPY auth.sh /etc/nginx/conf.d
COPY auth.sh /etc/nginx/conf.d/
COPY default-ssl.conf /etc/nginx/conf.d/default.conf
COPY statuspage.html /etc/nginx/conf.d/status/
COPY entrypoint.sh entrypoint.sh
COPY keys.properties /etc/nginx/conf.d
COPY api.properties /etc/nginx/conf.d
COPY trace.sh /etc/nginx/conf.d
COPY tests.sh /etc/nginx/conf.d
COPY ip-whitelist.conf /etc/nginx/conf.d
COPY trace.sh /etc/nginx/conf.d/
COPY tests.sh /etc/nginx/conf.d/

RUN chmod +x /etc/nginx/conf.d/auth.sh entrypoint.sh

Expand Down
24 changes: 22 additions & 2 deletions api_auth_docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,27 @@

So all the other containers are in the Docker Swarm and we want to expose a real HTTP/S interface to clients outside of the Swarm, that makes sense. Clients have to get an API key first.

## Build
## Pull our Cyphernode image

```shell
docker pull cyphernode/gatekeeper:latest
```

## Build yourself the image

```shell
docker build -t cyphernode/gatekeeper:latest .
```

## Run image

If you are using it independantly from the Docker stack (docker-compose.yml), you can run it like that:

```shell
docker run -d --rm --name gatekeeper -p 80:80 -p 443:443 --network cyphernodenet -v "~/cyphernode-ssl/certs:/etc/ssl/certs" -v "~/cyphernode-ssl/private:/etc/ssl/private" --env-file env.properties cyphernode/gatekeeper:latest `id -u cyphernode`:`id -g cyphernode`
```

## Prepare

### Create your API key and put it in keys.properties

Expand All @@ -23,7 +43,7 @@ dd if=/dev/urandom bs=32 count=1 2> /dev/null | xxd -ps -c 32
Put the id, key and groups in keys.properties and give the id and key to the client. The key is a secret. keys.properties looks like this:

```property
#kappiid="id";kapi_key="key";kapi_groups="group1,group2";leave the rest intact
# kapi_id="id";kapi_key="key";kapi_groups="group1,group2";leave the rest intact
kapi_id="001";kapi_key="2df1eeea370eacdc5cf7e96c2d82140d1568079a5d4d87006ec8718a98883b36";kapi_groups="watcher";eval ugroups_${kapi_id}=${kapi_groups};eval ukey_${kapi_id}=${kapi_key}
kapi_id="002";kapi_key="50c5e483b80964595508f214229b014aa6c013594d57d38bcb841093a39f1d83";kapi_groups="watcher";eval ugroups_${kapi_id}=${kapi_groups};eval ukey_${kapi_id}=${kapi_key}
kapi_id="003";kapi_key="b9b8d527a1a27af2ad1697db3521f883760c342fc386dbc42c4efbb1a4d5e0af";kapi_groups="watcher,spender";eval ugroups_${kapi_id}=${kapi_groups};eval ukey_${kapi_id}=${kapi_key}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# The file api.properties generated by the installer should look like this.

# Watcher can:
action_watch=watcher
Expand All @@ -10,7 +11,7 @@ action_gettransaction=watcher
action_ln_getinfo=watcher
action_ln_create_invoice=watcher

# Spender can do what the watcher can do plus:
# Spender can do what the watcher can do, plus:
action_getbalance=spender
action_getnewaddress=spender
action_spend=spender
Expand All @@ -20,10 +21,13 @@ action_deriveindex=spender
action_derivepubpath=spender
action_ln_pay=spender
action_ln_newaddr=spender
action_ots_stamp=spender
action_ots_getfile=spender

# Admin can do what the spender can do plus:
# Admin can do what the spender can do, plus:


# Should be called from inside the Swarm:
# Should be called from inside the Docker network only:
action_conf=internal
action_executecallbacks=internal
action_ots_backoffice=internal
34 changes: 18 additions & 16 deletions api_auth_docker/auth.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ verify_sign()
if [ ${exp} -gt ${current} ]; then
trace "[verify_sign] Not expired, let's validate signature"
local id=$(echo ${payload} | jq ".id" | tr -d '"')
trace "[verify_sign] id=${id}"
trace "[verify_sign] id=${id}"

# Check for code injection
# id will usually be an int, but can be alphanum... nothing else
case $id in (*[![:alnum:]]*|"")
trace "[verify_sign] Potential code injection, exiting"
return 1
esac
# Check for code injection
# id will usually be an int, but can be alphanum... nothing else
case $id in (*[![:alnum:]]*|"")
trace "[verify_sign] Potential code injection, exiting"
return 1
esac

# It is so much faster to include the keys here instead of grep'ing the file for key.
. ./keys.properties
Expand Down Expand Up @@ -87,16 +87,16 @@ verify_group()
trace "[verify_group] Verifying group..."

local id=${1}
# REQUEST_URI should look like this: /watch/2blablabla
local action=$(echo "${REQUEST_URI:1}" | cut -d '/' -f1)
# REQUEST_URI should look like this: /v0/watch/2blablabla
local action=$(echo "${REQUEST_URI#\/}" | cut -d '/' -f2)
trace "[verify_group] action=${action}"

# Check for code injection
# action can be alphanum... and _ and - but nothing else
local actiontoinspect=$(echo "$action" | tr -d '_-')
case $actiontoinspect in (*[![:alnum:]]*|"")
trace "[verify_group] Potential code injection, exiting"
return 1
trace "[verify_group] Potential code injection, exiting"
return 1
esac

# It is so much faster to include the keys here instead of grep'ing the file for key.
Expand All @@ -121,15 +121,17 @@ verify_group()


# $HTTP_AUTHORIZATION = Bearer <token>
# Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjAwMyIsImV4cCI6MTU0MjE0OTMyNH0=.b811067cf79c7009a0a38f110a6e3bf82cc4310aa6afae75b9d915b9febf13f7
# If this is not found in header, we leave
trace "[auth.sh] HTTP_AUTHORIZATION=${HTTP_AUTHORIZATION}"
if [ "${HTTP_AUTHORIZATION:0:6}" = "Bearer" ]; then
token="${HTTP_AUTHORIZATION:6}"
# /bin/sh on debian points to dash, which does not support substring in the form ${var:offset:length}
if [ "-${HTTP_AUTHORIZATION%% *}" = "-Bearer" ]; then
token="${HTTP_AUTHORIZATION#Bearer }"

if [ -n "$token" ]; then
trace "[auth.sh] Valid format for authorization header"
verify_sign "${token}"
[ "$?" -eq "0" ] && return
trace "[auth.sh] Valid format for authorization header"
verify_sign "${token}"
[ "$?" -eq "0" ] && return
fi
fi

Expand Down
13 changes: 10 additions & 3 deletions api_auth_docker/default-ssl.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@ server {
listen 443 ssl;
server_name localhost;

include /etc/nginx/conf.d/ip-whitelist.conf;
#include /etc/nginx/conf.d/ip-whitelist.conf;

ssl_certificate /etc/ssl/certs/cert.pem;
ssl_certificate_key /etc/ssl/private/key.pem;

location / {
location /status {
auth_basic "status";
auth_basic_user_file conf.d/status/htpasswd;
root /etc/nginx/conf.d;
index statuspage.html;
}

location /v0/ {
auth_request /auth;
proxy_pass http://cyphernode:8888;
proxy_pass http://proxy:8888/;
}

location /auth {
Expand Down
6 changes: 3 additions & 3 deletions api_auth_docker/default.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ server {
listen 80;
server_name localhost;

include /etc/nginx/conf.d/ip-whitelist.conf;
#include /etc/nginx/conf.d/ip-whitelist.conf;

location / {
location /v0/ {
auth_request /auth;
proxy_pass http://cyphernode:8888;
proxy_pass http://proxy:8888/;
}

location /auth {
Expand Down
16 changes: 14 additions & 2 deletions api_auth_docker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
#!/bin/sh
#!/bin/bash

spawn-fcgi -s /var/run/fcgiwrap.socket -u nginx -g nginx -U nginx -- /usr/bin/fcgiwrap
user='nginx'

if [[ $1 ]]; then
IFS=':' read -ra arr <<< "$1"

if [[ ${arr[0]} ]]; then
user=${arr[0]};
fi

fi

spawn-fcgi -M 0660 -s /var/run/fcgiwrap.socket -u $user -g nginx -U $user -- `which fcgiwrap`
chmod -R g+rw /var/run/fcgiwrap.socket /etc/nginx/conf.d/*
chown -R :nginx /etc/nginx/conf.d/*
nginx -g "daemon off;"
8 changes: 0 additions & 8 deletions api_auth_docker/ip-whitelist.conf

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#kappiid="id";kapi_key="key";kapi_groups="group1,group2";leave the rest intact
# The file keys.properties generated by the installer should look like this.

# kapi_id="id";kapi_key="key";kapi_groups="group1,group2";leave the rest intact
kapi_id="001";kapi_key="2df1eeea370eacdc5cf7e96c2d82140d1568079a5d4d87006ec8718a98883b36";kapi_groups="watcher";eval ugroups_${kapi_id}=${kapi_groups};eval ukey_${kapi_id}=${kapi_key}
kapi_id="002";kapi_key="50c5e483b80964595508f214229b014aa6c013594d57d38bcb841093a39f1d83";kapi_groups="watcher";eval ugroups_${kapi_id}=${kapi_groups};eval ukey_${kapi_id}=${kapi_key}
kapi_id="003";kapi_key="b9b8d527a1a27af2ad1697db3521f883760c342fc386dbc42c4efbb1a4d5e0af";kapi_groups="watcher,spender";eval ugroups_${kapi_id}=${kapi_groups};eval ukey_${kapi_id}=${kapi_key}
Expand Down
58 changes: 58 additions & 0 deletions api_auth_docker/statuspage.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
$(function() {
installation_status();
});

function httpget(url) {
return fetch(url, { method: "GET" })
.catch(err => {
console.log('HTTP GET Error: ' + err.message + ' :: STACK : ' + err.stack);
$("#result").text((JSON.stringify(err.message)));
return Promise.reject(err.message);
})
.then(res => {
if (!res.ok) {
return res.json().then(data => {
console.log('HTTP GET Error: ' + data.error.message);
$("#result").text(JSON.stringify(data.error.message));
return Promise.reject(data.error.message);
});
}
return res.json();
})
.then(data => Promise.resolve(JSON.stringify(data)))
}

function installation_status() {
httpget("installation.json")
.then(result => {
$("#result").text(result);
});
}

</script>
</head>
<body>
<div id="hello">
<h1>Hello World from Cyphernode!</h1>
<h2>If you are here, it means you successfully deployed Cyphernode. Congratulations, fellow Cyphernode Operator!</h2>
</div>
<hr/>
<div id="files">
<h2>The following files have been encrypted with your configuration passphrase and your client keys passphrase, respectively:</h2>
<ul>
<li><a href="config.7z">Download your Cyphernode <b>configurations</b>, can be used for another Cyphernode deployment</a></li>
<li><a href="client.7z">Download Client <b>API ID's and keys</b>, needed in your client apps</a></li>
</ul>
</div>
<div id="Status">
<h2>This is the status of Cyphernode's installation and running components</h2>
<pre lang="xml" id="result" style="white-space: pre-wrap"></pre>
</div>
</body>
</html>
Loading

0 comments on commit f238827

Please sign in to comment.