Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(#174): bastion Dockerfile and compose file #177

Merged
merged 46 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
6fc82e5
Create a bastion Dockerfile and compose file per #174
mrjones-plip Oct 25, 2024
9a6816b
Pair down files and config to minimum happy path
mrjones-plip Oct 25, 2024
8ddfa3c
go to latest alpine, move auth keys to original location
mrjones-plip Oct 26, 2024
ef6f5c2
revert port 22222 internally, add hack for auth keys :(
mrjones-plip Oct 26, 2024
3e98fea
add todo about no sonar
mrjones-plip Oct 26, 2024
d6eebc1
stop exposing postgres port, truncate readme, add sample tunnel in re…
mrjones-plip Oct 26, 2024
9321c16
change bastion shell to /bin/false, update MOTD
mrjones-plip Oct 26, 2024
96322cb
break out pgadmin, remove service from couchdb
mrjones-plip Oct 26, 2024
dd4621c
implement prototype AuthorizedKeysCommand logic, exclude authorized_k…
mrjones-plip Oct 26, 2024
1f9a83d
give up on logging, update MOTD, try dymamic auth from GH keys
mrjones-plip Oct 28, 2024
6886aee
add postgres ports to pgadmin as dev friendly port exposing
mrjones-plip Oct 28, 2024
9ebf183
merge main
mrjones-plip Oct 28, 2024
4f0ea69
update Dockerfile with sonarcloud deep link
mrjones-plip Oct 29, 2024
344178d
finalize basic functionality around authorized keys
mrjones-plip Nov 8, 2024
ad21199
Merge branch 'main' into 174-bastion-postgres-access
mrjones-plip Nov 15, 2024
31b5dbd
add missing pgadmin to expose postgres ports in CI e2e
mrjones-plip Nov 15, 2024
e94c013
first pass at e2e tests
mrjones-plip Nov 16, 2024
3bf0f59
add 'test:e2e:local' script for local testing with container cleanup …
Nov 18, 2024
81aa458
remove dbt env variables
Nov 18, 2024
04f6b0f
fix eslint
Nov 18, 2024
5bfbcce
increase wait for dbt
Nov 18, 2024
c20e809
rename private key file, remove unused file from Dockerfile, image bu…
mrjones-plip Nov 18, 2024
c314729
WIP - but failed attempt at SSH is great progress!
mrjones-plip Nov 19, 2024
fecef5f
remove script to align with CI test behavior
Nov 19, 2024
d960552
fix missing compose file in `docker compose down`
lorerod Nov 19, 2024
ec946f9
got e2e working \o/
mrjones-plip Nov 20, 2024
729222a
add cleanup todo
mrjones-plip Nov 20, 2024
6f9908e
add waitForCondition logic and wait-for-couchdb script
Nov 20, 2024
6bf335b
use waitForCondition in downtime scenario
Nov 20, 2024
4e388a3
decrease timeout
Nov 20, 2024
405869a
adding again the wait for dbt
Nov 20, 2024
238de52
trying only with delay again
Nov 20, 2024
7914098
fix schema name typo
Nov 20, 2024
fd2a7d3
fix eslint
Nov 20, 2024
740e3ab
skipping downtime handles temporarly
Nov 20, 2024
f06dde8
fix error couchdb so _users is created, bump couch image version, rem…
mrjones-plip Nov 20, 2024
52919ac
move downtime tests to be last to execute
Nov 22, 2024
5cbfdfc
fix lint
Nov 22, 2024
8f39179
remove default values
Nov 22, 2024
2bc6476
merge changes in from #187
mrjones-plip Nov 22, 2024
000c14e
merge moaaarrrr changes in from #187
mrjones-plip Nov 22, 2024
9c05dd8
remove unused vars and commented out code
mrjones-plip Nov 22, 2024
0fb3301
break out mocha test, use kill instead of down
mrjones-plip Nov 23, 2024
21207e2
resolve conflicts with main in package.json
mrjones-plip Nov 25, 2024
65a5052
wait 60 seconds for DBT, close out bastion tunnel
mrjones-plip Nov 25, 2024
ef7d0ac
only use half of tuple to pass lint/unit tests
mrjones-plip Nov 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ node_modules
/.eslintcache
/tests/data/json_docs
/deploy/cht_sync/values.yaml
/bastion/authorized_keys
31 changes: 31 additions & 0 deletions bastion/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# NOSONAR for "don't run docker images as root" - because sshd requires root https://superuser.com/a/1548482 :(
# Deep link to Sonar "safe": https://sonarcloud.io/project/security_hotspots?status=SAFE&pullRequest=177&id=medic_cht-sync&tab=activity

FROM alpine:3.20

ARG HOME=/var/lib/bastion

ARG USER=bastion
ARG GROUP=bastion
ARG UID=4096
ARG GID=4096

ENV HOST_KEYS_PATH_PREFIX="/usr"
ENV HOST_KEYS_PATH="${HOST_KEYS_PATH_PREFIX}/etc/ssh"

COPY bastion /usr/sbin/bastion

RUN addgroup -S -g ${GID} ${GROUP} \
&& adduser -D -h ${HOME} -s /bin/false -g "${USER} service" \
-u ${UID} -G ${GROUP} ${USER} \
&& sed -i "s/${USER}:!/${USER}:*/g" /etc/shadow \
&& set -x \
&& apk add --no-cache openssh-server curl \
&& echo -e "\nLogin Successful! \n\nHowever, interactive sessions not allowed. Use \"-N\" with ssh tunnel command instead: \n" > /etc/motd \
&& echo -e "\tssh -N -L 5432:CONTAINER-NAME:5432 bastion@PUBLIC-IP-OR-DNS -p 22222\n" >> /etc/motd \
&& chmod +x /usr/sbin/bastion \
&& mkdir -p ${HOST_KEYS_PATH} \
&& mkdir /etc/ssh/auth_principals \
&& echo "bastion" > /etc/ssh/auth_principals/bastion

ENTRYPOINT ["bastion"]
21 changes: 21 additions & 0 deletions bastion/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2018 Mark

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
9 changes: 9 additions & 0 deletions bastion/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
This project hard forked from [docker-bastion](https://github.com/binlab/docker-bastion/tree/master) at version [1.2.0](https://github.com/binlab/docker-bastion/releases/tag/v1.2.0)

Per MIT license, copyright of this `bastion` sub-directory is Mark/binlab/mark.binlab@gmail.com and MIT license file persists.

Sample SSH tunnel to connect to container called `cht-sync-postgres-1` on remote server with IP `44.33.22.11`:

```shell
ssh -N -L 5432:cht-sync-postgres-1:5432 bastion@44.33.22.11 -p 22222
```
1 change: 1 addition & 0 deletions bastion/authorized_keys.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# add external users' keys here
52 changes: 52 additions & 0 deletions bastion/bastion
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env sh

HOST_KEYS_PATH_PREFIX="${HOST_KEYS_PATH_PREFIX:='/'}"
HOST_KEYS_PATH="${HOST_KEYS_PATH:='/etc/ssh'}"

if [ -n "$TRUSTED_USER_CA_KEYS" ]; then
CONFIG_TRUSTED_USER_CA_KEYS="-o TrustedUserCAKeys=$TRUSTED_USER_CA_KEYS"
CONFIG_AUTHORIZED_PRINCIPALS_FILE="-o AuthorizedPrincipalsFile=/etc/ssh/auth_principals/%u"
fi

if [ ! -f "$HOST_KEYS_PATH/ssh_host_rsa_key" ]; then
/usr/bin/ssh-keygen -A -f "$HOST_KEYS_PATH_PREFIX"
fi

if [ -n "$LISTEN_ADDRESS" ]; then
CONFIG_LISTEN_ADDRESS="-o ListenAddress=$LISTEN_ADDRESS"
else
CONFIG_LISTEN_ADDRESS="-o ListenAddress=0.0.0.0"
fi

if [ -n "$LISTEN_PORT" ]; then
CONFIG_LISTEN_PORT="-o Port=$LISTEN_PORT"
else
CONFIG_LISTEN_PORT="-o Port=22"
fi

# todo - original project has this as "assumes your authorized_keys file with 644 permissions
# and mounted under /var/lib/bastion/authorized_keys." - but this simply doesn't work
# without this hack
cp /var/lib/bastion/authorized_keys-tmp /var/lib/bastion/authorized_keys
chown bastion /var/lib/bastion/authorized_keys
chmod 600 /var/lib/bastion/authorized_keys

/usr/sbin/sshd -D -e -4 \
-o "HostKey=$HOST_KEYS_PATH/ssh_host_rsa_key" \
-o "HostKey=$HOST_KEYS_PATH/ssh_host_ecdsa_key" \
-o "HostKey=$HOST_KEYS_PATH/ssh_host_ed25519_key" \
-o "PasswordAuthentication=no" \
-o "PermitEmptyPasswords=no" \
-o "PermitRootLogin=no" \
-o "X11Forwarding=no" \
-o "AllowAgentForwarding=yes" \
-o "GatewayPorts=yes" \
-o "PermitTunnel=yes" \
-o "PubkeyAuthentication=yes" \
-o "AllowTcpForwarding=yes" \
-o "AuthorizedKeysFile=/var/lib/bastion/authorized_keys" \
-o "AuthorizedKeysCommandUser=nobody" \
$CONFIG_TRUSTED_USER_CA_KEYS \
$CONFIG_AUTHORIZED_PRINCIPALS_FILE \
$CONFIG_LISTEN_ADDRESS \
$CONFIG_LISTEN_PORT
12 changes: 12 additions & 0 deletions docker-compose.bastion.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
services:
bastion:
build: ./bastion/
restart: unless-stopped
ports:
- ${BASTION_PORT:-22222}:22/tcp
volumes:
- ${BASTION_AUTHORIZED_KEYS_FILE:-$PWD/bastion/authorized_keys}:/var/lib/bastion/authorized_keys-tmp
- bastion:/usr/etc/ssh:rw

volumes:
bastion:
13 changes: 13 additions & 0 deletions docker-compose.pgadmin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
services:
postgres:
ports:
- 5432:${POSTGRES_PORT:-5432}

pgadmin:
image: dpage/pgadmin4
environment:
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:-pgadmin4@pgadmin.org}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-admin}
PGADMIN_CONFIG_SERVER_MODE: 'False'
ports:
- "${PGADMIN_PORT:-5050}:80"
13 changes: 1 addition & 12 deletions docker-compose.postgres.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,11 @@ services:
postgres:
image: postgres:16
restart: always
ports:
- 5432:5432
volumes:
- ./postgres/init-dbt-resources.sh:/docker-entrypoint-initdb.d/init-dbt-resources.sh:z
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_TABLES=${COUCHDB_DBS}
- POSTGRES_SCHEMA=${POSTGRES_SCHEMA}

pgadmin:
image: dpage/pgadmin4
environment:
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:-pgadmin4@pgadmin.org}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-admin}
PGADMIN_CONFIG_SERVER_MODE: 'False'
ports:
- "${PGADMIN_PORT:-5050}:80"
- POSTGRES_SCHEMA=${POSTGRES_SCHEMA}
3 changes: 3 additions & 0 deletions env.template
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ COUCHDB_SECURE=false

# (Optional) project wide
#COMPOSE_PROJECT_NAME=cht-sync

#BASTION_PORT=22222 # default is 22222 uncomment to change
#BASTION_AUTHORIZED_KEYS_FILE= # uncomment to change
106 changes: 100 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
"main": "",
"scripts": {
"postinstall": "cd couch2pg && npm ci",
"test:e2e": "npm run test:e2e-data && npm run test:e2e-containers && mocha tests/**/*.spec.js --timeout 50000 && npm run test:e2e-stop-containers ",
"test:e2e": "npm run test:e2e-data && npm run test:e2e-stop-containers && npm run test:e2e-containers && npm run test:e2e-mocha && npm run test:e2e-stop-containers ",
"test:e2e-mocha": "mocha tests/**/*.spec.js --timeout 50000",
"lint": "eslint --color --cache .",
"test:e2e-stop-containers": "docker compose --env-file ./tests/.e2e-env -f docker-compose.yml -f docker-compose.couchdb.yml -f docker-compose.postgres.yml -f tests/dbt/docker-compose.yml down -v",
"test:e2e-containers": "docker compose --env-file ./tests/.e2e-env -f docker-compose.yml -f docker-compose.couchdb.yml -f docker-compose.postgres.yml -f tests/dbt/docker-compose.yml up -d --build --force-recreate && npm run wait-for-couchdb",
"test:e2e-stop-containers": "docker compose --env-file ./tests/.e2e-env -f docker-compose.yml -f docker-compose.couchdb.yml -f docker-compose.postgres.yml -f tests/dbt/docker-compose.yml -f docker-compose.bastion.yml kill && docker compose --env-file ./tests/.e2e-env -f docker-compose.yml -f docker-compose.couchdb.yml -f docker-compose.postgres.yml -f tests/dbt/docker-compose.yml -f docker-compose.bastion.yml rm -f",
"test:e2e-containers": "docker compose --env-file ./tests/.e2e-env -f docker-compose.yml -f docker-compose.couchdb.yml -f docker-compose.postgres.yml -f tests/dbt/docker-compose.yml -f docker-compose.bastion.yml up -d --build --force-recreate && npm run wait-for-couchdb",
"test:e2e-data": "cd tests/data && rm -rf ./json_docs && cht csv-to-docs",
"test": "cd couch2pg && npm run test",
"wait-for-couchdb": "bash -c 'until nc -z localhost 5984; do sleep 1; done; echo \"CouchDB is ready\"'"
Expand Down Expand Up @@ -36,6 +37,7 @@
"pouchdb-adapter-http": "^8.0.1",
"pouchdb-core": "^8.0.1",
"sinon": "^18.0.0",
"tunnel-ssh": "^5.1.2",
"uuid": "^9.0.1"
},
"private": true
Expand Down
Loading