Initial version of the magic ssh server

This commit is contained in:
Tom Wiesing 2020-07-29 14:44:31 +02:00
parent f44693f1f2
commit a7c4ded7e9
No known key found for this signature in database
GPG key ID: DC1F29F2BC78AB15
15 changed files with 84 additions and 7 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
authorized_keys
.vagrant .vagrant
.env .env
*.zip *.zip

View file

@ -69,6 +69,11 @@ These are:
- Security is not enabled at the moment. - Security is not enabled at the moment.
- See [distillery/resources/compose/triplestore](distillery/resources/compose/triplestore) for implementation details. - See [distillery/resources/compose/triplestore](distillery/resources/compose/triplestore) for implementation details.
- [proxyssh](https://github.com/tkw1536/proxyssh) - an ssh server that delegates client connections to different WissKIs
- It is configured to run inside a docker container
- Uses a global configurable authorized_keys file.
- Also allows users to write their own authorized_keys files.
To manage multiple docker containers, this script makes heavy use of [docker-compose](https://docs.docker.com/compose/). To manage multiple docker containers, this script makes heavy use of [docker-compose](https://docs.docker.com/compose/).
Setting up these steps is fully automatic. Setting up these steps is fully automatic.
@ -231,6 +236,10 @@ MAILTO="some-admin-email@example.com"
0 9 * * 6 /bin/bash /distillery/backup.sh 0 9 * * 6 /bin/bash /distillery/backup.sh
``` ```
## SSH Access
- to be documented
## License ## License
This project and associated files in this repository are licensed as follows: This project and associated files in this repository are licensed as follows:

7
Vagrantfile vendored
View file

@ -5,10 +5,11 @@ Vagrant.configure("2") do |config|
# use an iamge of debian, in this case buster 64 # use an iamge of debian, in this case buster 64
config.vm.box = "debian/buster64" config.vm.box = "debian/buster64"
# forward ports 80 and 443 to the host system # forward ports 80, 443 and 2222 to the host system
# this will allow accessing the webserver from the real system. # this will allow accessing the webserver from the real system.
config.vm.network "forwarded_port", guest: 80, host: 80 config.vm.network "forwarded_port", guest: 80, host: 8080
config.vm.network "forwarded_port", guest: 443, host: 443 config.vm.network "forwarded_port", guest: 443, host: 4443
config.vm.network "forwarded_port", guest: 2222, host: 2223
# share the factory folder in /factory/ # share the factory folder in /factory/
config.vm.synced_folder "distillery/", "/distillery/" config.vm.synced_folder "distillery/", "/distillery/"

View file

@ -41,4 +41,7 @@ DISTILLERY_BOOKKEEPING_TABLE=distillery
# Various components use password-based-authentication. # Various components use password-based-authentication.
# These passwords are generated automatically. # These passwords are generated automatically.
# This variable can be used to determine their length. # This variable can be used to determine their length.
PASSWORD_LENGTH=64 PASSWORD_LENGTH=64
# A file to be used for global authorized_keys for the ssh server.
GLOBAL_AUTHORIZED_KEYS_FILE=/distillery/authorized_keys

View file

@ -85,6 +85,15 @@ function is_valid_https_url() {
fi fi
} }
# 'is_valid_file' checks that the value passed is an existing file
function is_valid_file() {
if [[ -f "$1" ]]; then
return 0;
else
return 1;
fi
}
# The 'DEPLOY_ROOT' variable must be an absolute path. # The 'DEPLOY_ROOT' variable must be an absolute path.
if ! is_valid_abspath "$DEPLOY_ROOT"; then if ! is_valid_abspath "$DEPLOY_ROOT"; then
log_error "Variable 'DEPLOY_ROOT' is missing or not a valid path. "; log_error "Variable 'DEPLOY_ROOT' is missing or not a valid path. ";
@ -178,11 +187,21 @@ else
SELF_REDIRECT="https://gitlab.cs.fau.de/AGFD/wisski-distillery" SELF_REDIRECT="https://gitlab.cs.fau.de/AGFD/wisski-distillery"
fi fi
# The 'GLOBAL_AUTHORIZED_KEYS_FILE' should point to a real file
if ! is_valid_file "$GLOBAL_AUTHORIZED_KEYS_FILE"; then
log_error "Variable 'GLOBAL_AUTHORIZED_KEYS_FILE' is not a valid file. ";
log_info "The variable is currently set to '$GLOBAL_AUTHORIZED_KEYS_FILE'. "
log_info "You might want to create this file to get rid of the error message. "
log_info "Please verify that it is set correctly in '.env'";
exit 1;
fi;
# paths to composer things # paths to composer things
DEPLOY_WEB_DIR="$DEPLOY_ROOT/core/web" DEPLOY_WEB_DIR="$DEPLOY_ROOT/core/web"
DEPLOY_SELF_DIR="$DEPLOY_ROOT/core/self" DEPLOY_SELF_DIR="$DEPLOY_ROOT/core/self"
DEPLOY_TRIPLESTORE_DIR="$DEPLOY_ROOT/core/triplestore" DEPLOY_TRIPLESTORE_DIR="$DEPLOY_ROOT/core/triplestore"
DEPLOY_SQL_DIR="$DEPLOY_ROOT/core/sql" DEPLOY_SQL_DIR="$DEPLOY_ROOT/core/sql"
DEPLOY_SSH_DIR="$DEPLOY_ROOT/core/ssh"
DEPLOY_INSTANCES_DIR="$DEPLOY_ROOT/instances" DEPLOY_INSTANCES_DIR="$DEPLOY_ROOT/instances"
DEPLOY_BACKUP_DIR="$DEPLOY_ROOT/backups" DEPLOY_BACKUP_DIR="$DEPLOY_ROOT/backups"

View file

@ -52,11 +52,12 @@ curl -X POST \
--header "X-GraphDB-Password: $GRAPHDB_PASSWORD" \ --header "X-GraphDB-Password: $GRAPHDB_PASSWORD" \
-d @- -d @-
log_info " => Creating local directory '$INSTANCE_BASE_DIR'" log_info " => Creating local directory structure at '$INSTANCE_BASE_DIR'"
mkdir -p "$INSTANCE_BASE_DIR" mkdir -p "$INSTANCE_BASE_DIR"
mkdir -p "$INSTANCE_DATA_DIR" mkdir -p "$INSTANCE_DATA_DIR"
mkdir -p "$INSTANCE_DATA_DIR/.composer" mkdir -p "$INSTANCE_DATA_DIR/.composer"
mkdir -p "$INSTANCE_DATA_DIR/data" mkdir -p "$INSTANCE_DATA_DIR/data"
touch "$INSTANCE_DATA_DIR/authorized_keys"
# Generate some more random credentials, this time for drupal. # Generate some more random credentials, this time for drupal.
# We again make use of the randompw alias. # We again make use of the randompw alias.
@ -77,6 +78,7 @@ sql_bookkeep_insert \
log_info " => Writing configuration file" log_info " => Writing configuration file"
load_template "docker-env/barrel" \ load_template "docker-env/barrel" \
"REAL_PATH" "${INSTANCE_DATA_DIR}" \ "REAL_PATH" "${INSTANCE_DATA_DIR}" \
"GLOBAL_AUTHORIZED_KEYS_FILE" "${GLOBAL_AUTHORIZED_KEYS_FILE}" \
"VIRTUAL_HOST" "${INSTANCE_DOMAIN}" \ "VIRTUAL_HOST" "${INSTANCE_DOMAIN}" \
"SLUG" "${SLUG}" \ "SLUG" "${SLUG}" \
"LETSENCRYPT_HOST" "${LETSENCRYPT_HOST}" \ "LETSENCRYPT_HOST" "${LETSENCRYPT_HOST}" \

View file

@ -18,6 +18,9 @@ fi;
# Read everything from the database # Read everything from the database
read -r INSTANCE_BASE_DIR MYSQL_DATABASE MYSQL_USER GRAPHDB_REPO GRAPHDB_USER <<< "$(sql_bookkeep_load "${SLUG}" "filesystem_base,sql_database,sql_user,graphdb_repository,graphdb_user" | tail -n +2)" read -r INSTANCE_BASE_DIR MYSQL_DATABASE MYSQL_USER GRAPHDB_REPO GRAPHDB_USER <<< "$(sql_bookkeep_load "${SLUG}" "filesystem_base,sql_database,sql_user,graphdb_repository,graphdb_user" | tail -n +2)"
log_info " => Touching authorized_keys file"
touch "$INSTANCE_BASE_DIR/data/authorized_keys"
log_info " => Updating compose files" log_info " => Updating compose files"
install_resource_dir "compose/barrel" "$INSTANCE_BASE_DIR" install_resource_dir "compose/barrel" "$INSTANCE_BASE_DIR"

View file

@ -77,5 +77,8 @@ CMD ["apache2-foreground"]
# Add the provision script # Add the provision script
ADD scripts/provision_container.sh /provision_container.sh ADD scripts/provision_container.sh /provision_container.sh
# Add the user_shell.sh
ADD scripts/user_shell.sh /user_shell.sh
# expose port 8080 # expose port 8080
EXPOSE 8080 EXPOSE 8080

View file

@ -4,6 +4,7 @@ services:
barrel: barrel:
build: . build: .
restart: always restart: always
hostname: ${VIRTUAL_HOST}
environment: environment:
# port and hostname for this image to use # port and hostname for this image to use
VIRTUAL_HOST: ${VIRTUAL_HOST} VIRTUAL_HOST: ${VIRTUAL_HOST}
@ -16,11 +17,14 @@ services:
# label it with the current slug # label it with the current slug
labels: labels:
eu.wiss-ki.barrel.slug: ${SLUG} eu.wiss-ki.barrel.slug: ${SLUG}
eu.wiss-ki.barrel.authfile: /var/www/.ssh/authorized_keys,/var/www/.ssh/global_authorized_keys
# the volumes to # volumes that are mounted
volumes: volumes:
- ${GLOBAL_AUTHORIZED_KEYS_FILE}:/var/www/.ssh/global_authorized_keys:ro
- ${REAL_PATH}/.composer:/var/www/.composer - ${REAL_PATH}/.composer:/var/www/.composer
- ${REAL_PATH}/data:/var/www/data - ${REAL_PATH}/data:/var/www/data
- ${REAL_PATH}/authorized_keys:/var/www/.ssh/authorized_keys
networks: networks:
default: default:

View file

@ -0,0 +1,5 @@
#!/bin/bash
# This script is used to start a user shell inside the docker container.
cd "/var/www/data/project"
sudo -u www-data /bin/bash "$@"

View file

@ -0,0 +1,17 @@
version: "3.7"
services:
ssh:
image: tkw01536/proxyssh
command: -hostkey /keys/hostkey -shell /user_shell.sh -keylabel eu.wiss-ki.barrel.authfile -userlabel eu.wiss-ki.barrel.slug -L triplestore:7200
ports:
- "2222:2222"
volumes:
- './data/keys:/keys'
- '/var/run/docker.sock:/var/run/docker.sock:ro'
restart: always
networks:
default:
external:
name: distillery

View file

@ -5,3 +5,5 @@ VIRTUAL_HOST=${VIRTUAL_HOST}
LETSENCRYPT_HOST=${LETSENCRYPT_HOST} LETSENCRYPT_HOST=${LETSENCRYPT_HOST}
LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL} LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
GLOBAL_AUTHORIZED_KEYS_FILE=${GLOBAL_AUTHORIZED_KEYS_FILE}

View file

@ -24,4 +24,4 @@ read -r INSTANCE_BASE_DIR MYSQL_DATABASE MYSQL_USER GRAPHDB_REPO GRAPHDB_USER <<
cd "$INSTANCE_BASE_DIR" cd "$INSTANCE_BASE_DIR"
# and open a www-data shell # and open a www-data shell
docker-compose exec barrel /bin/bash -c "cd /var/www/data/project; sudo -u www-data /bin/bash" docker-compose exec barrel /user_shell.sh

View file

@ -49,6 +49,7 @@ log_info "=> Creating docker-compose directories"
mkdir -p "$DEPLOY_INSTANCES_DIR" mkdir -p "$DEPLOY_INSTANCES_DIR"
mkdir -p "$DEPLOY_WEB_DIR" mkdir -p "$DEPLOY_WEB_DIR"
mkdir -p "$DEPLOY_SELF_DIR" mkdir -p "$DEPLOY_SELF_DIR"
mkdir -p "$DEPLOY_SSH_DIR"
mkdir -p "$DEPLOY_TRIPLESTORE_DIR" mkdir -p "$DEPLOY_TRIPLESTORE_DIR"
mkdir -p "$DEPLOY_SQL_DIR" mkdir -p "$DEPLOY_SQL_DIR"
mkdir -p "$DEPLOY_BACKUP_INPROGRESS_DIR" mkdir -p "$DEPLOY_BACKUP_INPROGRESS_DIR"
@ -68,6 +69,9 @@ load_template "docker-env/web" \
log_info "=> Creating 'docker-compose' files for the 'self'. " log_info "=> Creating 'docker-compose' files for the 'self'. "
install_resource_dir "compose/self" "$DEPLOY_SELF_DIR" install_resource_dir "compose/self" "$DEPLOY_SELF_DIR"
log_info "=> Creating 'docker-compose' files for the 'ssh'. "
install_resource_dir "compose/ssh" "$DEPLOY_SSH_DIR"
# setup the lesencrypt host for the default domain # setup the lesencrypt host for the default domain
if [ -n "$LETSENCRYPT_HOST" ]; then if [ -n "$LETSENCRYPT_HOST" ]; then
LETSENCRYPT_HOST="$DEFAULT_DOMAIN" LETSENCRYPT_HOST="$DEFAULT_DOMAIN"

View file

@ -12,6 +12,10 @@ update_stack "$DEPLOY_WEB_DIR"
log_info "=> Rebuilding and restarting 'self' stack" log_info "=> Rebuilding and restarting 'self' stack"
update_stack "$DEPLOY_SELF_DIR" update_stack "$DEPLOY_SELF_DIR"
# build and start the ssh server
log_info "=> Rebuilding and restarting 'ssh' stack"
update_stack "$DEPLOY_SSH_DIR"
# build and start the triplestore # build and start the triplestore
log_info "=> Rebuilding and restarting 'triplestore' stack" log_info "=> Rebuilding and restarting 'triplestore' stack"
update_stack "$DEPLOY_TRIPLESTORE_DIR" update_stack "$DEPLOY_TRIPLESTORE_DIR"