diff --git a/.gitignore b/.gitignore index dfe420c..668bdd6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +authorized_keys .vagrant .env *.zip \ No newline at end of file diff --git a/README.md b/README.md index 3319003..9c1ee10 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,11 @@ These are: - Security is not enabled at the moment. - 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/). 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 ``` +## SSH Access + +- to be documented + ## License This project and associated files in this repository are licensed as follows: diff --git a/Vagrantfile b/Vagrantfile index 15767d9..5460d18 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -5,10 +5,11 @@ Vagrant.configure("2") do |config| # use an iamge of debian, in this case buster 64 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. - config.vm.network "forwarded_port", guest: 80, host: 80 - config.vm.network "forwarded_port", guest: 443, host: 443 + config.vm.network "forwarded_port", guest: 80, host: 8080 + config.vm.network "forwarded_port", guest: 443, host: 4443 + config.vm.network "forwarded_port", guest: 2222, host: 2223 # share the factory folder in /factory/ config.vm.synced_folder "distillery/", "/distillery/" diff --git a/distillery/.env.sample b/distillery/.env.sample index a28014b..c76c9ad 100644 --- a/distillery/.env.sample +++ b/distillery/.env.sample @@ -41,4 +41,7 @@ DISTILLERY_BOOKKEEPING_TABLE=distillery # Various components use password-based-authentication. # These passwords are generated automatically. # This variable can be used to determine their length. -PASSWORD_LENGTH=64 \ No newline at end of file +PASSWORD_LENGTH=64 + +# A file to be used for global authorized_keys for the ssh server. +GLOBAL_AUTHORIZED_KEYS_FILE=/distillery/authorized_keys \ No newline at end of file diff --git a/distillery/lib/10_config.sh b/distillery/lib/10_config.sh index 85f4d9e..709628a 100644 --- a/distillery/lib/10_config.sh +++ b/distillery/lib/10_config.sh @@ -85,6 +85,15 @@ function is_valid_https_url() { 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. if ! is_valid_abspath "$DEPLOY_ROOT"; then 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" 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 DEPLOY_WEB_DIR="$DEPLOY_ROOT/core/web" DEPLOY_SELF_DIR="$DEPLOY_ROOT/core/self" DEPLOY_TRIPLESTORE_DIR="$DEPLOY_ROOT/core/triplestore" DEPLOY_SQL_DIR="$DEPLOY_ROOT/core/sql" +DEPLOY_SSH_DIR="$DEPLOY_ROOT/core/ssh" DEPLOY_INSTANCES_DIR="$DEPLOY_ROOT/instances" DEPLOY_BACKUP_DIR="$DEPLOY_ROOT/backups" diff --git a/distillery/provision.sh b/distillery/provision.sh index 16231e2..dfb4d73 100755 --- a/distillery/provision.sh +++ b/distillery/provision.sh @@ -52,11 +52,12 @@ curl -X POST \ --header "X-GraphDB-Password: $GRAPHDB_PASSWORD" \ -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_DATA_DIR" mkdir -p "$INSTANCE_DATA_DIR/.composer" mkdir -p "$INSTANCE_DATA_DIR/data" +touch "$INSTANCE_DATA_DIR/authorized_keys" # Generate some more random credentials, this time for drupal. # We again make use of the randompw alias. @@ -77,6 +78,7 @@ sql_bookkeep_insert \ log_info " => Writing configuration file" load_template "docker-env/barrel" \ "REAL_PATH" "${INSTANCE_DATA_DIR}" \ + "GLOBAL_AUTHORIZED_KEYS_FILE" "${GLOBAL_AUTHORIZED_KEYS_FILE}" \ "VIRTUAL_HOST" "${INSTANCE_DOMAIN}" \ "SLUG" "${SLUG}" \ "LETSENCRYPT_HOST" "${LETSENCRYPT_HOST}" \ diff --git a/distillery/rebuild.sh b/distillery/rebuild.sh index abb8d25..0708e3e 100644 --- a/distillery/rebuild.sh +++ b/distillery/rebuild.sh @@ -18,6 +18,9 @@ fi; # 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)" +log_info " => Touching authorized_keys file" +touch "$INSTANCE_BASE_DIR/data/authorized_keys" + log_info " => Updating compose files" install_resource_dir "compose/barrel" "$INSTANCE_BASE_DIR" diff --git a/distillery/resources/compose/barrel/Dockerfile b/distillery/resources/compose/barrel/Dockerfile index 1d045ce..d0013b7 100644 --- a/distillery/resources/compose/barrel/Dockerfile +++ b/distillery/resources/compose/barrel/Dockerfile @@ -77,5 +77,8 @@ CMD ["apache2-foreground"] # Add the provision script 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 8080 \ No newline at end of file diff --git a/distillery/resources/compose/barrel/docker-compose.yml b/distillery/resources/compose/barrel/docker-compose.yml index 5c0df32..d9795cc 100644 --- a/distillery/resources/compose/barrel/docker-compose.yml +++ b/distillery/resources/compose/barrel/docker-compose.yml @@ -4,6 +4,7 @@ services: barrel: build: . restart: always + hostname: ${VIRTUAL_HOST} environment: # port and hostname for this image to use VIRTUAL_HOST: ${VIRTUAL_HOST} @@ -16,11 +17,14 @@ services: # label it with the current slug labels: 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: + - ${GLOBAL_AUTHORIZED_KEYS_FILE}:/var/www/.ssh/global_authorized_keys:ro - ${REAL_PATH}/.composer:/var/www/.composer - ${REAL_PATH}/data:/var/www/data + - ${REAL_PATH}/authorized_keys:/var/www/.ssh/authorized_keys networks: default: diff --git a/distillery/resources/compose/barrel/scripts/user_shell.sh b/distillery/resources/compose/barrel/scripts/user_shell.sh new file mode 100755 index 0000000..8ebf53d --- /dev/null +++ b/distillery/resources/compose/barrel/scripts/user_shell.sh @@ -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 "$@" \ No newline at end of file diff --git a/distillery/resources/compose/ssh/docker-compose.yml b/distillery/resources/compose/ssh/docker-compose.yml new file mode 100644 index 0000000..1bc7af8 --- /dev/null +++ b/distillery/resources/compose/ssh/docker-compose.yml @@ -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 diff --git a/distillery/resources/templates/docker-env/barrel b/distillery/resources/templates/docker-env/barrel index 2c881ea..e30c954 100644 --- a/distillery/resources/templates/docker-env/barrel +++ b/distillery/resources/templates/docker-env/barrel @@ -5,3 +5,5 @@ VIRTUAL_HOST=${VIRTUAL_HOST} LETSENCRYPT_HOST=${LETSENCRYPT_HOST} LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL} + +GLOBAL_AUTHORIZED_KEYS_FILE=${GLOBAL_AUTHORIZED_KEYS_FILE} \ No newline at end of file diff --git a/distillery/shell.sh b/distillery/shell.sh index 5ccc352..f75a189 100644 --- a/distillery/shell.sh +++ b/distillery/shell.sh @@ -24,4 +24,4 @@ read -r INSTANCE_BASE_DIR MYSQL_DATABASE MYSQL_USER GRAPHDB_REPO GRAPHDB_USER << cd "$INSTANCE_BASE_DIR" # 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 diff --git a/distillery/system_install.sh b/distillery/system_install.sh index d361a5f..bdc8214 100755 --- a/distillery/system_install.sh +++ b/distillery/system_install.sh @@ -49,6 +49,7 @@ log_info "=> Creating docker-compose directories" mkdir -p "$DEPLOY_INSTANCES_DIR" mkdir -p "$DEPLOY_WEB_DIR" mkdir -p "$DEPLOY_SELF_DIR" +mkdir -p "$DEPLOY_SSH_DIR" mkdir -p "$DEPLOY_TRIPLESTORE_DIR" mkdir -p "$DEPLOY_SQL_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'. " 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 if [ -n "$LETSENCRYPT_HOST" ]; then LETSENCRYPT_HOST="$DEFAULT_DOMAIN" diff --git a/distillery/system_update.sh b/distillery/system_update.sh index 920b701..159a331 100755 --- a/distillery/system_update.sh +++ b/distillery/system_update.sh @@ -12,6 +12,10 @@ update_stack "$DEPLOY_WEB_DIR" log_info "=> Rebuilding and restarting 'self' stack" 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 log_info "=> Rebuilding and restarting 'triplestore' stack" update_stack "$DEPLOY_TRIPLESTORE_DIR"