mirror of
https://github.com/hackerschoice/segfault.git
synced 2024-06-27 09:18:41 +00:00
initial
This commit is contained in:
parent
cb925b32ca
commit
9b49809433
1
Makefile
Normal file → Executable file
1
Makefile
Normal file → Executable file
@ -1,3 +1,4 @@
|
||||
all:
|
||||
make -C guest
|
||||
make -C host
|
||||
make -C encfs
|
||||
|
@ -1,4 +1,4 @@
|
||||
# l0pht
|
||||
# segfault
|
||||
|
||||
Regional Cluster design:
|
||||
```mermaid
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: "3.1"
|
||||
version: "3.7"
|
||||
services:
|
||||
dns-doh:
|
||||
container_name: cloudflared
|
||||
@ -25,6 +25,7 @@ services:
|
||||
|
||||
tor:
|
||||
image: osminogin/tor-simple
|
||||
container_name: sf-tor
|
||||
networks:
|
||||
guest-net:
|
||||
ipv4_address: 172.24.0.4
|
||||
@ -33,29 +34,23 @@ services:
|
||||
depends_on:
|
||||
- dnsmasq
|
||||
|
||||
l0pht:
|
||||
container_name: l0pht-host
|
||||
segfault:
|
||||
container_name: sf-host
|
||||
build: host
|
||||
depends_on:
|
||||
- dnsmasq
|
||||
restart: always
|
||||
init: true
|
||||
dns: 255.255.255.255
|
||||
ports:
|
||||
- "2222:2222"
|
||||
- "${PORT}:2222"
|
||||
env_file:
|
||||
.env
|
||||
volumes:
|
||||
- "~/l0pht/cfg/etc/ssh:/etc/ssh/l0pht:ro"
|
||||
- "${SF_BASEDIR}/config:/config:ro"
|
||||
- "${SF_BASEDIR}/config/db:/config/db"
|
||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||
|
||||
# init: true
|
||||
# secrets:
|
||||
|
||||
# volumes:
|
||||
# guest-data:
|
||||
# type: bind
|
||||
# - driver: local
|
||||
# device: ~/research/l0pht/guest/l0pht-guest
|
||||
# external: true
|
||||
|
||||
networks:
|
||||
dns-doh-net:
|
||||
driver: bridge
|
||||
@ -64,6 +59,7 @@ networks:
|
||||
- subnet: 172.23.0.0/24
|
||||
|
||||
guest-net:
|
||||
name: sf_guest-net
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
|
12
encfs/Dockerfile
Normal file
12
encfs/Dockerfile
Normal file
@ -0,0 +1,12 @@
|
||||
FROM alpine:latest
|
||||
|
||||
RUN \
|
||||
apk add --no-cache --upgrade && \
|
||||
apk add --no-cache \
|
||||
docker-cli \
|
||||
bash \
|
||||
encfs
|
||||
|
||||
ADD mount.sh /
|
||||
|
||||
CMD ["/mount.sh"]
|
3
encfs/Makefile
Executable file
3
encfs/Makefile
Executable file
@ -0,0 +1,3 @@
|
||||
all: Dockerfile
|
||||
docker build -t sf-encfs .
|
||||
|
33
encfs/mount.sh
Executable file
33
encfs/mount.sh
Executable file
@ -0,0 +1,33 @@
|
||||
#! /bin/bash
|
||||
|
||||
RAWDIR="/encfs/raw/user-${LID}"
|
||||
SECDIR="/encfs/sec/user-${LID}"
|
||||
mkdir -p "${RAWDIR}" "${SECDIR}" 2>/dev/null
|
||||
if [[ -n $MARKFILE ]]; then
|
||||
if [[ -n $CHECKFILE ]]; then
|
||||
n=0
|
||||
while [[ -f "${SECDIR}/${MARKFILE}" ]]; do
|
||||
[[ $n -gt 0 ]] && sleep 2 || sleep 0.1
|
||||
n=$((n+1))
|
||||
[[ $n -gt 5 ]] && exit 253 # "Could not create /sec..."
|
||||
done
|
||||
# echo "encrypted" >/sec/.encrypted
|
||||
exit 0 # /sec created
|
||||
fi
|
||||
touch "${SECDIR}/${MARKFILE}" || exit 255
|
||||
echo "Failed to set up encrypted drive. DO NOT USE THIS DIRECTORY" >"${SECDIR}/${MARKFILE}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
encfs --standard -o nonempty -o allow_other --extpass="echo \"${LENCFS_PASS}\"" "${RAWDIR}" "${SECDIR}"
|
||||
|
||||
# Unmount when no instance is running anymore.
|
||||
sleep 5
|
||||
while :; do
|
||||
docker container inspect "lg-${LID}" -f '{{.State.Status}}' || break
|
||||
sleep 10
|
||||
done
|
||||
|
||||
echo "Unmounting lg-${LID} [${SECDIR}]"
|
||||
fusermount -zuq /encfs/sec || echo "fusermount: Error ($?)"
|
||||
echo "DONE"
|
@ -30,10 +30,9 @@ RUN apt install -y --no-install-recommends \
|
||||
RUN apt install -y --no-install-recommends \
|
||||
zsh zsh-syntax-highlighting zsh-autosuggestions
|
||||
|
||||
|
||||
COPY /fs-root/ /
|
||||
COPY setup.sh /tmp
|
||||
RUN /tmp/setup.sh && \
|
||||
rm -f /tmp/setup.sh
|
||||
COPY setup.sh /
|
||||
RUN /setup.sh && \
|
||||
rm -f /setup.sh
|
||||
|
||||
CMD ["zsh", "-il"]
|
@ -1,3 +1,3 @@
|
||||
all: Dockerfile
|
||||
docker build -t l0pht-guest .
|
||||
docker build -t sf-guest .
|
||||
|
||||
|
@ -1,5 +0,0 @@
|
||||
# source'd during interactive shell login.
|
||||
|
||||
# Trampoline to this script:
|
||||
[[ -e /usr/local/l0pht-guest/bin/l0pht-motd.sh ]] && /usr/local/l0pht-guest/bin/l0pht-motd.sh
|
||||
|
5
guest/fs-root/etc/profile.d/segfault.sh
Normal file
5
guest/fs-root/etc/profile.d/segfault.sh
Normal file
@ -0,0 +1,5 @@
|
||||
# source'd during interactive shell login to SF-GUEST.
|
||||
|
||||
# Trampoline to this script:
|
||||
[[ -e /usr/local/sf-guest/bin/sf-motd.sh ]] && /usr/local/sf-guest/bin/sf-motd.sh
|
||||
|
5
guest/fs-root/sbin/halt
Executable file
5
guest/fs-root/sbin/halt
Executable file
@ -0,0 +1,5 @@
|
||||
#! /bin/sh
|
||||
|
||||
# In docker this will 'halt' (hard crash) the instance.
|
||||
kill 1
|
||||
|
@ -1,7 +1,19 @@
|
||||
FROM alpine:latest
|
||||
|
||||
ENV LUSER=user
|
||||
ENV LGUESTDIR=/research/l0pht/guest/l0pht-guest
|
||||
# SF-HOST
|
||||
|
||||
# SSHD clears all environment variable before spwaning shell.
|
||||
# Any variable that needs to be available inside shell 'segfaultsh'
|
||||
# needs to be added to docker_sshd.sh
|
||||
ENV LUSER="${LUSER:-root}"
|
||||
ENV LUSERPASSWORD="${LUSERPASSWORD:-segfault}"
|
||||
ENV LDNS="${LDNS:-172.24.0.2}"
|
||||
ENV SF_FQDN="${SF_FQDN:-segfault.thc.org}"
|
||||
ENV LENCFS_SECDIR="${LENCFS_SECDIR:-/dev/shm/encfs-sec}"
|
||||
ENV LENCFS_RAWDIR="${LENCFS_RAWDIR:-/dev/shm}"
|
||||
ENV SF_SRCDIR="${SF_SRCDIR:-/dev/null}"
|
||||
ENV SF_DEBUG="${SF_DEBUG}"
|
||||
ENV SF_BASEDIR="${SF_BASEDIR:-/dev/null}"
|
||||
|
||||
RUN \
|
||||
apk add --no-cache --upgrade && \
|
||||
@ -12,9 +24,9 @@ RUN \
|
||||
|
||||
COPY /fs-root/ /
|
||||
|
||||
COPY setup.sh /tmp
|
||||
RUN /tmp/setup.sh && \
|
||||
rm -f /tmp/setup.sh
|
||||
COPY setup.sh /
|
||||
RUN /setup.sh && \
|
||||
rm -f /setup.sh
|
||||
|
||||
CMD ["/bin/docker_sshd.sh"]
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
all: Dockerfile
|
||||
docker build -t l0pht-host .
|
||||
docker build -t sf-host .
|
||||
|
||||
|
@ -1,26 +1,92 @@
|
||||
#! /bin/bash
|
||||
|
||||
# This is the entry point for L0PHT-HOST (e.g. host/Dockerfile)
|
||||
# Fix ownership if mounted from within vbox
|
||||
[[ -e /etc/ssh/l0pht/ssh_host_rsa_key ]] || {
|
||||
echo -e \
|
||||
"\033[1;31mSSH Key not found in /etc/ssh/l0pht\033[00m. You must create them first and the
|
||||
start docker with the additional '-v' option below:
|
||||
CY="\033[1;33m" # yellow
|
||||
CR="\033[1;31m" # red
|
||||
CC="\033[1;36m" # cyan
|
||||
CN="\033[0m" # none
|
||||
|
||||
mkdir -p ~/l0pht/cfg/etc/ssh && ssh-keygen -A ~/l0pht/cfg && \\
|
||||
docker run --r -p 22:2222 -v /var/run/docker.sock:/var/run/docker.sock \\
|
||||
-v ~/l0pht/cfg/etc/ssh:/etc/ssh/l0pht:ro \\
|
||||
--name l0pht-host -it l0pth-host"
|
||||
[[ -d /config ]] || {
|
||||
echo -e "${CR}Not found: /config${CN}
|
||||
--> Try -v ~/segfault/config:ro -v ~/segfault/config/db:/config/db"
|
||||
|
||||
sleep 5
|
||||
exit 255
|
||||
}
|
||||
|
||||
[[ -d /config/db ]] || {
|
||||
echo -e "${CR}Not found: /config/db${CN}
|
||||
--> Try -v ~/segfault/config:ro -v ~/segfault/config/db:/config/db"
|
||||
|
||||
sleep 5
|
||||
exit 255
|
||||
}
|
||||
|
||||
# This is the entry point for SF-HOST (e.g. host/Dockerfile)
|
||||
# Fix ownership if mounted from within vbox
|
||||
[[ -e /config/etc/ssh/ssh_host_rsa_key ]] || {
|
||||
echo -e "\
|
||||
${CR}SSH Key not found in /config/etc/ssh/${CN}. You must create them first:
|
||||
--> ${CC}mkdir -p ~/segfault/config/etc/ssh && ssh-keygen -A -f ~/segfault/config${CN}"
|
||||
|
||||
sleep 5
|
||||
exit 255
|
||||
}
|
||||
|
||||
[[ -e /config/etc/ssh/id_ed25519 ]] || {
|
||||
echo -e "\
|
||||
${CR}SSH Login Key not found in /config/etc/ssh/id_ed25519${CN}. You must create them first:
|
||||
--> ${CC}ssh-keygen -q -t ed25519 -C \"\" -N \"\" -f ~/segfault/config/etc/ssh/id_ed25519${CN}"
|
||||
|
||||
sleep 5
|
||||
exit 255
|
||||
}
|
||||
|
||||
# Copy login-key to fake root's home directory
|
||||
[[ -e /home/root/.ssh/authorized_keys ]] || {
|
||||
[[ -d /home/root/.ssh ]] || { mkdir /home/root/.ssh; chown root:nobody /home/root/.ssh; }
|
||||
cp /config/etc/ssh/id_ed25519.pub /home/root/.ssh/authorized_keys
|
||||
chown root:nobody /home/root/.ssh/authorized_keys
|
||||
}
|
||||
|
||||
# Make a copy so that sf-hosts's root(uid=1000) can access the file.
|
||||
cp /config/etc/ssh/id_ed25519 /var/run/id_ed25519.luser
|
||||
chmod 444 /var/run/id_ed25519.luser
|
||||
|
||||
# SSHD resets the environment variables. The environment variables relevant to the guest
|
||||
# are stored in a file here and then read by `segfaultsh'.
|
||||
# Edit 'segfaultsh' and add them to 'docker run --env' to pass any of these
|
||||
# variables to the user's docker instance (sf-guest)
|
||||
echo "LDNS=\"${LDNS}\"
|
||||
LENCFS_SECDIR=\"${LENCFS_SECDIR}\"
|
||||
LENCFS_RAWDIR=\"${LENCFS_RAWDIR}\"
|
||||
SF_SRCDIR=\"${SF_SRCDIR}\"
|
||||
LUSER=\"${LUSER}\"
|
||||
SF_DEBUG=\"${SF_DEBUG}\"
|
||||
SF_BASEDIR=\"${SF_BASEDIR}\"
|
||||
SF_FQDN=\"${SF_FQDN}\"" >/var/run/lhost-config.txt
|
||||
|
||||
# The owner of the original socket is not known at 'docker build' time. Thus
|
||||
# we need to dynamically add it so that the shell started by SSHD can
|
||||
# spwan ther L0PHT-GUEST docker.
|
||||
[[ ! -e /var/run/docker.sock ]] && { echo "Not found: /var/run/docker.sock"; echo "Try -v -v /var/run/docker.sock:/var/run/docker.sock"; exit 255; }
|
||||
# spwan ther SF-GUEST instance.
|
||||
[[ ! -e /var/run/docker.sock ]] && { echo "Not found: /var/run/docker.sock"; echo "Try -v /var/run/docker.sock:/var/run/docker.sock"; exit 255; }
|
||||
echo "docker:x:$(stat -c %g /var/run/docker.sock):${LUSER}" >>/etc/group && \
|
||||
chmod 770 /var/run/docker.sock && \
|
||||
/usr/sbin/sshd -u0 -p 2222
|
||||
|
||||
exec sleep infinite
|
||||
# SSHD's user (normally "root" with uid 1000) needs write access to /config/db
|
||||
# That directory is mounted from the outside and we have no clue what the
|
||||
# group owner or permission is. Need to add our root(uid=1000) to that group:
|
||||
dbgid="$(stat -c %g /config/db)"
|
||||
[[ "$dbgid" -eq 0 ]] && {
|
||||
echo -e "${CY}WARNING:${CN} /config/db has group owner of 'root'.
|
||||
--> Better try: ${CC}chgrp nogroup ~/segfault/config/db${CN}"
|
||||
}
|
||||
addgroup -g $(stat -c %g /config/db) sf-dbrw 2>/dev/null # Ignore if already exists.
|
||||
addgroup root sf-dbrw 2>/dev/null # Ignore if already exists.
|
||||
chmod g+wx /config/db || exit $?
|
||||
|
||||
# This will execute 'segfaultsh' on login
|
||||
/usr/sbin/sshd -u0 -p 2222 -D
|
||||
# /usr/sbin/sshd -u0 -p 2222
|
||||
|
||||
tail -f /dev/null
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
#! /bin/bash -r
|
||||
|
||||
# This is called by SSHD inside L0PHT-HOST docker.
|
||||
# Find out if SSHD allocated a TTY
|
||||
# - Redirects not allowed in restricted shells.
|
||||
# - Execute `tty' in unrestricted shell (one day a clever hacker will exploit this)
|
||||
# - Set docker arguments if this is a TTY session.
|
||||
bash -c "tty >/dev/null" && { ARG="-it"; PARAM=("-il"); } || { ARG="-i"; PARAM=(); }
|
||||
|
||||
# Connect to existing session
|
||||
[[ -n $LID ]] && [[ ${#LID} -eq 12 ]] && {
|
||||
docker exec -it "lg-${LID}" zsh "${PARAM[@]}" "$@" || { echo "SESSION GONE"; exit 255; }
|
||||
}
|
||||
|
||||
LID="$(head -c 1024 /dev/urandom | tr -dc '[:alpha:]' | head -c 12)"
|
||||
HID="$(head -c 1024 /dev/urandom | tr -dc '[:alpha:]' | head -c 6)"
|
||||
LVER="1.1"
|
||||
docker run \
|
||||
--hostname "l0pht-${HID}" \
|
||||
--rm \
|
||||
"$ARG" \
|
||||
--name "lg-${LID}" \
|
||||
--init \
|
||||
--net l0pht_guest-net \
|
||||
--dns 172.24.0.2 \
|
||||
--env LID="${LID}" \
|
||||
--env LVER="${LVER}" \
|
||||
--log-driver none \
|
||||
-v "l0pht_guest-data:/usr/local/l0pht-guest:ro" \
|
||||
l0pht-guest zsh "${PARAM[@]}" "$@"
|
||||
|
284
host/fs-root/bin/segfaultsh
Executable file
284
host/fs-root/bin/segfaultsh
Executable file
@ -0,0 +1,284 @@
|
||||
#! /bin/bash -r
|
||||
|
||||
# This is called by SSHD inside SF-HOST docker.
|
||||
# - All environments have been cleared by SSHD.
|
||||
# - Redirects not allowed in restricted shells.
|
||||
|
||||
# Load/restore environment variables from file
|
||||
# `source' is prohibited in restricted bash shell (bash -r)
|
||||
# use `eval' trick to load environemnt variables into a restricted shell
|
||||
# SF_DEBUG can be set by ssh-client with -o SetEnv SF_DEBUG=1 or by
|
||||
# docker compose '.env' file.
|
||||
SSH_SF_DEBUG="${SF_DEBUG}" # Set by SSH client
|
||||
[[ -f /var/run/lhost-config.txt ]] && eval "$(cat /var/run/lhost-config.txt)"
|
||||
[[ -z $SF_DEBUG ]] && SF_DEBUG="${SSH_SF_DEBUG}"
|
||||
unset SSH_SF_DEBUG
|
||||
|
||||
CY="\033[1;33m" # yellow
|
||||
CR="\033[1;31m" # red
|
||||
CC="\033[1;36m" # cyan
|
||||
CG="\033[1;32m" # green
|
||||
CDC="\033[0;36m" # cyan
|
||||
CDR="\033[0;31m" # red
|
||||
CN="\033[0m" # none
|
||||
CW="\033[1;37m" # white
|
||||
CF="\033[2m" # faint
|
||||
|
||||
ERREXIT()
|
||||
{
|
||||
local code
|
||||
code="$1"
|
||||
[[ -z $code ]] && code=99
|
||||
|
||||
shift 1
|
||||
[[ -n $1 ]] && echo -e >&2 "${CR}ERROR:${CN} $*"
|
||||
|
||||
exit "$code"
|
||||
}
|
||||
|
||||
if [[ -z $SF_DEBUG ]]; then
|
||||
DEBUGF(){ :;}
|
||||
SF_DOCKER_LOG="none"
|
||||
else
|
||||
DEBUGF(){ echo -e 1>&2 "${CY}DEBUG:${CN} $*";}
|
||||
SF_DOCKER_LOG="local"
|
||||
fi
|
||||
|
||||
# The current 'restricted shell' does not allow for stdout redirection to /dev/null.
|
||||
# Thus execute in unrestricted shell with 'exec_devnull' and redirect stdout to /dev/null.
|
||||
exec_devnull()
|
||||
{
|
||||
if [[ -z $SF_DEBUG ]]; then
|
||||
bash -c "exec $* 2>/dev/null >/dev/null"
|
||||
else
|
||||
# HERE: DEBUG is enabled. Show STDOUT/STDERR
|
||||
$*
|
||||
fi
|
||||
}
|
||||
|
||||
exec_errnull()
|
||||
{
|
||||
if [[ -z $SF_DEBUG ]]; then
|
||||
bash -c "exec $* 2>/dev/null"
|
||||
else
|
||||
# HERE: DEBUG is enabled. Show STDOUT/STDERR
|
||||
$*
|
||||
fi
|
||||
}
|
||||
|
||||
print_ssh_access()
|
||||
{
|
||||
echo 1>&2 -e "\
|
||||
:Cut & Paste these lines to your workstation's shell to retain access:
|
||||
######################################################################
|
||||
${CDC}cat >~/.ssh/id_ed25519-lg-${LID} ${CDR}<<__EOF__
|
||||
${CN}${CF}$(cat /var/run/id_ed25519.luser)
|
||||
${CDR}__EOF__
|
||||
${CDC}cat >>~/.ssh/config ${CDR}<<${CDR}__EOF__
|
||||
${CN}${CF}host ${HOSTNAME,,}.${SF_FQDN//./-}
|
||||
HostName ${SF_FQDN}
|
||||
IdentityFile ~/.ssh/id_ed25519-lg-${LID}
|
||||
SetEnv SECRET=${LSEC}
|
||||
${CDR}__EOF__
|
||||
${CDC}chmod 600 ~/.ssh/config ~/.ssh/id_ed25519-lg-${LID}${CN}
|
||||
######################################################################
|
||||
Thereafter use this command to connect to your server:
|
||||
--> ${CDC}ssh root@${HOSTNAME,,}.${SF_FQDN//./-}${CN}
|
||||
----------------------------------------------------------------------"
|
||||
}
|
||||
|
||||
echo_pty()
|
||||
{
|
||||
[[ -n $IS_PTY ]] || return
|
||||
echo $@
|
||||
}
|
||||
|
||||
# Find out if SSHD allocated a TTY
|
||||
# - Execute `tty' in unrestricted shell (one day a clever hacker will exploit this)
|
||||
# - Set docker arguments to login-shell if this is a TTY session.
|
||||
bash -c "tty >/dev/null" && { ARG="-it"; PARAM=("-il"); IS_PTY=1; } || { ARG="-i"; PARAM=(); }
|
||||
|
||||
# Connect to existing session
|
||||
if [[ -n $SECRET ]] && [[ ${#SECRET} -eq 12 ]] && [[ ! "${SECRET}" =~ [^a-zA-Z0-9] ]]; then
|
||||
IS_TRY_EXISTING=1
|
||||
LSEC="${SECRET}"
|
||||
else
|
||||
LSEC="$(head -c 1024 /dev/urandom | tr -dc '[:alpha:]' | head -c 12)"
|
||||
fi
|
||||
|
||||
LID=$(echo -n "LID ${LSEC}" | sha512sum | base64 | tr -dc '[:alpha:]' | head -c 10)
|
||||
|
||||
LVER="1.1"
|
||||
# MARKFILE="THIS-DIRECTORY-IS-NOT-ENCRYPTED--DO-NOT-USE-$(date +%s-%N).txt"
|
||||
MARKFILE="THIS-DIRECTORY-IS-NOT-ENCRYPTED--DO-NOT-USE-$(date +%s-%N).txt"
|
||||
|
||||
if [[ -d "/config/db/db-${LID}" ]]; then
|
||||
echo_pty -n "Connecting to server. Please wait..."
|
||||
else
|
||||
echo_pty -n "Creating new server. Please wait...."
|
||||
IS_NEW_SERVER=1
|
||||
|
||||
mkdir -p "/config/db/db-${LID}" || ERREXIT
|
||||
touch "/config/db/db-${LID}/created.txt" || ERREXIT
|
||||
fi
|
||||
|
||||
DEBUGF "LID=${LID}"
|
||||
|
||||
if [[ "$(exec_errnull docker container inspect "encfs-${LID}" -f '{{.State.Status}}')" != "running" ]]; then
|
||||
LENCFS_PASS=$(echo -n "EncFS-PASS ${LSEC}" | sha512sum | base64 | tr -dc '[:alpha:]' | head -c 16)
|
||||
# HERE: encfs is not already running for this instance...
|
||||
# 1st EncFS to put warning into mount-point that it is cleartext (until it's mounted!).
|
||||
DEBUGF "EncFS-${LID} is not yet running..."
|
||||
docker run \
|
||||
--rm \
|
||||
--env MARKFILE="${MARKFILE}" \
|
||||
--env LID="${LID}" \
|
||||
--env SF_DEBUG="${SF_DEBUG}" \
|
||||
-v "${LENCFS_SECDIR}:/encfs/sec:shared" \
|
||||
sf-encfs || ERREXIT 250 "Could not create /sec..."
|
||||
|
||||
# 2nd EncFS to mount encrypted to mount-point.
|
||||
# Run in background (-d)
|
||||
# Use exec_devnull to redirect Container-ID to /dev/null (docker run -d).
|
||||
exec_devnull docker run \
|
||||
--rm \
|
||||
--name "encfs-${LID}" \
|
||||
--cap-add SYS_ADMIN \
|
||||
--device /dev/fuse \
|
||||
--security-opt apparmor:unconfined \
|
||||
--env LENCFS_PASS="${LENCFS_PASS}" \
|
||||
--env LID="${LID}" \
|
||||
--env SF_DEBUG="${SF_DEBUG}" \
|
||||
--log-driver "${SF_DOCKER_LOG}" \
|
||||
-v "${LENCFS_RAWDIR}:/encfs/raw" \
|
||||
-v "${LENCFS_SECDIR}:/encfs/sec:shared" \
|
||||
-v "/var/run/docker.sock:/var/run/docker.sock" \
|
||||
-d \
|
||||
sf-encfs || ERREXIT 251 "Could not create /sec..."
|
||||
fi
|
||||
echo_pty -n ".."
|
||||
|
||||
# Wait until sf-encf has mounted the secure drive...or otherwise this
|
||||
# will show an insecure directory:
|
||||
# ssh user@segfault.thc.org "ls -al /sec"
|
||||
# This will loop until the MARKFILE is gone (e.g. encfs mounted a directory over it)
|
||||
# NOTE: It would be quicker to have /encfs/sec available in this sf-host instance
|
||||
# but this may also pose a security risk: A vulnerability in SSHD would
|
||||
# expose all encrypted drives. Doing it with 'docker run' means that
|
||||
# the hacker would to to break docker - which is easy enough given that the
|
||||
# docker-socket is available in this context but still a step harder.
|
||||
DEBUGF "Waiting until /sec becomes available..."
|
||||
docker run \
|
||||
--rm \
|
||||
--env MARKFILE="${MARKFILE:-UNKNOWN.TXT}" \
|
||||
--env CHECKFILE="1" \
|
||||
--env LID="${LID}" \
|
||||
--env SF_DEBUG="${SF_DEBUG}" \
|
||||
-v "${LENCFS_SECDIR}:/encfs/sec:shared" \
|
||||
sf-encfs || ERREXIT 244 "Failed to set up /sec..."
|
||||
|
||||
echo_pty -n ".."
|
||||
|
||||
# Generate a mnemonic hostname from LID (e.g. ButterflyCat)
|
||||
NUM=$(echo "ibase=16; $(echo "$LID" | md5sum | cut -f1 -d" " | tr 'a-z' A-Z)" | bc)
|
||||
readarray -t english </etc/english.txt
|
||||
HOSTNAME="UnknownUnknown"
|
||||
if [[ "${#english[@]}" -eq 2048 ]]; then
|
||||
HOSTNAME="${english[$((NUM % 2048))]}"
|
||||
HOSTNAME+="${english[$(( (NUM / 2048) % 2048 ))]}"
|
||||
fi
|
||||
DEBUGF "HOSTNAME=$HOSTNAME"
|
||||
unset NUM
|
||||
unset english
|
||||
|
||||
# Attach to instance if already running
|
||||
[[ -n $IS_TRY_EXISTING ]] && {
|
||||
DEBUGF "Attaching to existing instance lg-${LID}..."
|
||||
exec_devnull docker container inspect "lg-${LID}" -f '{{.State.Status}}' && {
|
||||
echo_pty -e "..........................[${CG}OK${CN}]"
|
||||
docker exec "$ARG" "lg-${LID}" zsh "${PARAM[@]}" "$@"
|
||||
exit $?
|
||||
}
|
||||
echo_pty -n ".."
|
||||
|
||||
DEBUGF "FAILED to attached to lg-${LID}"
|
||||
# HERE: Instance does not exists.
|
||||
}
|
||||
|
||||
# Starting GUEST shell
|
||||
# Challenge: Keep user processes running that got spawned in the background
|
||||
# even when first instance terminates. Also do not terminate instance
|
||||
# when there are still shells using it ('docker exec').
|
||||
# Solution: Spawn a docker in the background that monitors the number of
|
||||
# processes and use 'docker exec' for every connection.
|
||||
exec_devnull docker run \
|
||||
--hostname "sf-${HOSTNAME}" \
|
||||
--rm \
|
||||
--init \
|
||||
--name "lg-${LID}" \
|
||||
--init \
|
||||
--net sf_guest-net \
|
||||
--dns "${LDNS:-BAD}" \
|
||||
--env LSEC="${LSEC}" \
|
||||
--env LVER="${LVER}" \
|
||||
--env LUSER="${LUSER}" \
|
||||
--env SF_FQDN="${SF_FQDN}" \
|
||||
--env SF_DEBUG="${SF_DEBUG}" \
|
||||
-e SSH_CONNECTION \
|
||||
-e SSH_CLIENT \
|
||||
--log-driver "${SF_DOCKER_LOG}" \
|
||||
--mount type=bind,source="${SF_BASEDIR}/config/etc/ssh/id_ed25519,target=/config/id_ed25519,readonly" \
|
||||
-v "${SF_BASEDIR}/guest/sf-guest:/usr/local/sf-guest:ro" \
|
||||
-v "${LENCFS_SECDIR}/user-${LID}:/sec:shared" \
|
||||
-d \
|
||||
sf-guest /usr/local/sf-guest/bin/sf-destructor.sh || ERREXIT 251 "Failed to set up guest instance..."
|
||||
|
||||
[[ -n $IS_PTY ]] && echo -n ".."
|
||||
|
||||
DEBUGF "Instance started..."
|
||||
|
||||
# Wait for detached docker shell to become available...
|
||||
n=0
|
||||
while :; do
|
||||
str="$(exec_errnull docker container inspect "lg-${LID}" -f '{{.State.Status}}')"
|
||||
rc="$?"
|
||||
DEBUGF "rc=$rc status=$str"
|
||||
[[ "$rc" -eq 0 ]] && [[ "$str" = "running" ]] && break
|
||||
DEBUGF "#${n} Waiting for sf-guest to be ready..."
|
||||
[[ $n -gt 0 ]] && sleep 5 || sleep 0.1
|
||||
n=$((n+1))
|
||||
[[ $n -gt 2 ]] && ERREXIT 253 "Could not create instance..."
|
||||
done
|
||||
[[ -n $IS_PTY ]] && echo -n ".."
|
||||
|
||||
# Setup instance
|
||||
docker exec "lg-${LID}" /usr/local/sf-guest/bin/sf-setup.sh || ERREXIT 252 "Failed to set up guest instance..."
|
||||
|
||||
echo_pty -e "....................[${CG}OK${CN}]"
|
||||
|
||||
# Output help of how to connect elegantly
|
||||
[[ -n $IS_NEW_SERVER ]] && print_ssh_access
|
||||
|
||||
# Spawn shell
|
||||
docker exec "$ARG" "lg-${LID}" zsh "${PARAM[@]}" "$@"
|
||||
ret="$?" # save return value and exit this script later with same return value.
|
||||
|
||||
# Output GOODBYE message with infos how to connect back to this shell
|
||||
if [[ -n $IS_PTY ]]; then
|
||||
# Restricted shell (-r) wont let us redirect stderr - use a bash-exec trick
|
||||
n="$(bash -c "docker exec \"lg-${LID}\" ps --no-headers aux 2>/dev/null|wc -l")"
|
||||
DEBUGF "Processes running: $n"
|
||||
if [[ "$n" -gt 4 ]]; then
|
||||
echo -e "\
|
||||
${CY}WARNING: Another shell or background process is still running.${CN}
|
||||
-------> The encrypted filesystem in /sec will remain mounted until
|
||||
-------> the last shell exits and all background processes terminate.
|
||||
-------> Type ${CC}halt${CN} instead to unmount the encrypted filesystem
|
||||
-------> in /sec and to halt this instance."
|
||||
fi
|
||||
echo -e "\
|
||||
Access with : ${CDC}ssh -o \"SetEnv SECRET=${LSEC:-UNKNOWN}\" ${LUSER}@${SF_FQDN:-UNKNOWN}${CN}
|
||||
GOODBYE : ${CW}Join us on Telegram - https://t.me/thcorg${CN}"
|
||||
fi
|
||||
|
||||
exit "$ret"
|
2048
host/fs-root/etc/english.txt
Normal file
2048
host/fs-root/etc/english.txt
Normal file
File diff suppressed because it is too large
Load Diff
18
host/fs-root/etc/ssh/sshd_config
Normal file → Executable file
18
host/fs-root/etc/ssh/sshd_config
Normal file → Executable file
@ -15,9 +15,9 @@
|
||||
#ListenAddress 0.0.0.0
|
||||
#ListenAddress ::
|
||||
|
||||
HostKey /etc/ssh/l0pht/ssh_host_rsa_key
|
||||
HostKey /etc/ssh/l0pht/ssh_host_ecdsa_key
|
||||
HostKey /etc/ssh/l0pht/ssh_host_ed25519_key
|
||||
HostKey /config/etc/ssh/ssh_host_rsa_key
|
||||
HostKey /config/etc/ssh/ssh_host_ecdsa_key
|
||||
HostKey /config/etc/ssh/ssh_host_ed25519_key
|
||||
|
||||
# Ciphers and keying
|
||||
#RekeyLimit default none
|
||||
@ -30,7 +30,9 @@ HostKey /etc/ssh/l0pht/ssh_host_ed25519_key
|
||||
|
||||
#LoginGraceTime 2m
|
||||
#PermitRootLogin prohibit-password
|
||||
#StrictModes yes
|
||||
# FIXME: Disable strict mode to allow sshd to read ssh keys from vboxfs (rwxrwx---)
|
||||
StrictModes no
|
||||
##StrictModes yes
|
||||
#MaxAuthTries 6
|
||||
#MaxSessions 10
|
||||
|
||||
@ -39,6 +41,7 @@ HostKey /etc/ssh/l0pht/ssh_host_ed25519_key
|
||||
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
|
||||
# but this is overridden so installations will only check .ssh/authorized_keys
|
||||
AuthorizedKeysFile .ssh/authorized_keys
|
||||
#AuthorizedKeysFile /config/etc/ssh/id_ed25519.pub
|
||||
|
||||
#AuthorizedPrincipalsFile none
|
||||
|
||||
@ -90,13 +93,14 @@ X11Forwarding no
|
||||
#X11UseLocalhost yes
|
||||
#PermitTTY yes
|
||||
PrintMotd no
|
||||
AcceptEnv LID
|
||||
AcceptEnv SF_DEBUG
|
||||
AcceptEnv SECRET
|
||||
#PrintLastLog yes
|
||||
#TCPKeepAlive yes
|
||||
#PermitUserEnvironment no
|
||||
#Compression delayed
|
||||
#ClientAliveInterval 0
|
||||
#ClientAliveCountMax 3
|
||||
ClientAliveInterval 15
|
||||
ClientAliveCountMax 3
|
||||
#UseDNS no
|
||||
#PidFile /run/sshd.pid
|
||||
#MaxStartups 10:30:100
|
||||
|
25
host/setup.sh
Normal file → Executable file
25
host/setup.sh
Normal file → Executable file
@ -1,18 +1,27 @@
|
||||
#! /bin/bash
|
||||
|
||||
echo "/bin/l0phtsh" >>/etc/shells && \
|
||||
adduser -D ${LUSER} -s /bin/l0phtsh && \
|
||||
sed -i 's/user\:!/user\:$6$nND1o68YSDG8heUr$wx\/FpC3\/TCZlhs3LsJ7ll5YVlPfICNN7yHmyppR6MqedvZ9Vgbq6SV3TlMFaFZAiYePNFaY477Xrb0fOMo24p0/g' /etc/shadow && \
|
||||
# Docker sf-host setup script (docker build)
|
||||
|
||||
ROOTUSER="root"
|
||||
# Default is for user to use 'ssh root@segfault.net' but this can be changed
|
||||
# in .env to any other user name. In case it is 'root' then we need to move
|
||||
# the true root out of the way for the docker-sshd to work.
|
||||
if [[ "$LUSER" = "root" ]]; then
|
||||
# rename root user
|
||||
sed -i 's/^root/toor/' /etc/passwd
|
||||
sed -i 's/^root/toor/' /etc/shadow
|
||||
fi
|
||||
echo "/bin/segfaultsh" >>/etc/shells && \
|
||||
adduser -D ${LUSER} -G nobody -s /bin/segfaultsh && \
|
||||
echo "${LUSER}:${LUSERPASSWORD}" | chpasswd
|
||||
# sed -i 's/#PermitEmptyPasswords no/PermitEmptyPasswords yes/g' /etc/ssh/sshd_config && \
|
||||
# sed -i 's/#PrintMotd yes/ no/PermitEmptyPasswords yes/g' /etc/ssh/sshd_config && \
|
||||
|
||||
# Need to set correct permission which may have gotten skewed when building
|
||||
# docker inside vmbox from shared host drive (rwxrwx--- root:vobxsf)
|
||||
chown -R root:root /etc/ssh && \
|
||||
chown -R "${ROOTUSER}":"${ROOTUSER}" /etc/ssh && \
|
||||
chmod 700 /etc/ssh && \
|
||||
chown root:root /bin/l0phtsh && \
|
||||
chmod 755 /bin/l0phtsh && \
|
||||
chown "${ROOTUSER}":"${ROOTUSER}" /bin/segfaultsh && \
|
||||
chmod 755 /bin/segfaultsh && \
|
||||
chmod 755 /bin /etc && \
|
||||
echo DONE
|
||||
|
||||
|
||||
|
14
provision/env.example
Executable file
14
provision/env.example
Executable file
@ -0,0 +1,14 @@
|
||||
# EXAMPLE docker-compose .env file
|
||||
SF_BASEDIR=${HOME}/segfault
|
||||
# Source
|
||||
SF_SRCDIR=${HOME}/segfault
|
||||
# SF_SRCDIR=${SF_BASEDIR}
|
||||
#LENCFS_RAWDIR=/home/sf-user/segfault/encfs-raw
|
||||
LENCFS_RAWDIR=${SF_BASEDIR}/encfs-raw
|
||||
PORT=22
|
||||
#SF_DEBUG=1
|
||||
#LENCFS_SECDIR=/dev/shm/encfs-sec
|
||||
#LUSER=root
|
||||
#LUSERPASSWORD=segfault
|
||||
#SF_FQDN=CHANGEME.segfault-net
|
||||
#LDNS=172.24.0.2
|
71
provision/funcs
Normal file
71
provision/funcs
Normal file
@ -0,0 +1,71 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
# shellcheck disable=SC2034 # unused variable warning for ansi colors
|
||||
|
||||
CY="\033[1;33m" # yellow
|
||||
CG="\033[1;32m" # green
|
||||
CR="\033[1;31m" # red
|
||||
CC="\033[1;36m" # cyan
|
||||
CM="\033[1;35m" # magenta
|
||||
CW="\033[1;37m" # magenta
|
||||
CF="\033[2m" # faint
|
||||
CN="\033[0m" # none
|
||||
|
||||
CBG="\033[42;1m" # Background Green
|
||||
|
||||
# night-mode
|
||||
CDY="\033[0;33m" # yellow
|
||||
CDG="\033[0;32m" # green
|
||||
CDR="\033[0;31m" # red
|
||||
CDC="\033[0;36m" # cyan
|
||||
CDM="\033[0;35m" # magenta
|
||||
|
||||
# Clear from cursor to end of line
|
||||
CL="\033[0K"
|
||||
|
||||
if [[ -z $SF_DEBUG ]]; then
|
||||
DEBUGF(){ :;}
|
||||
DEBUGF_R(){ :;}
|
||||
else
|
||||
DEBUGF(){ echo -e "${CY}DEBUG:${CN} $*";}
|
||||
DEBUGF_R(){ echo -e "${CY}DEBUG:${CN} ${CR}$*${CN}";}
|
||||
fi
|
||||
|
||||
ERREXIT()
|
||||
{
|
||||
local code
|
||||
code="$1"
|
||||
[[ $? -ne 0 ]] && code="$?"
|
||||
[[ -z $code ]] && code=99
|
||||
|
||||
shift 1
|
||||
[[ -n $1 ]] && echo -e >&2 "${CR}ERROR:${CN} $*"
|
||||
|
||||
exit "$code"
|
||||
}
|
||||
|
||||
WARN()
|
||||
{
|
||||
local code
|
||||
code="$1"
|
||||
[[ -z $code ]] && code=255
|
||||
|
||||
shift 1
|
||||
echo -e >&2 "${CY}WARNING(${code}):${CN} $*"
|
||||
}
|
||||
|
||||
INFO()
|
||||
{
|
||||
echo -e "--> ${CM}$*${CN}"
|
||||
}
|
||||
|
||||
|
||||
NEED_ROOT()
|
||||
{
|
||||
[[ "$(id -u)" -ne 0 ]] && ERREXIT 255 "Error: Run this scrpt as root"
|
||||
}
|
||||
|
||||
IS_APT_INSTALLED()
|
||||
{
|
||||
[[ "$(apt -qq list "$*" 2>/dev/null)" = *"[installed]" ]] && return 0 || return 1
|
||||
}
|
69
provision/init-nordvpn.sh
Executable file
69
provision/init-nordvpn.sh
Executable file
@ -0,0 +1,69 @@
|
||||
#! /bin/bash
|
||||
|
||||
# Install NordVPN and configure it.
|
||||
|
||||
SFI_BASEDIR="$(cd "$(dirname "${0}")" || exit; pwd)"
|
||||
source "${SFI_BASEDIR}/funcs"
|
||||
NEED_ROOT
|
||||
|
||||
# Exit if already installed (nordvpn status return TRUE even when not connected)
|
||||
nordvpn status 2>/dev/null && { WARN 1 "NordVPN already installed. SKIPPING."; exit 0; }
|
||||
# command -v nordvpn >/dev/null && { WARN 23 "NordVPN already installed. SKIPPING"; exit 0; }
|
||||
|
||||
[[ -z $SF_VPN_LOGIN ]] && ERREXIT 255 "SF_VPN_LOGIN= not set"
|
||||
[[ -z $SF_VPN_PASSWORD ]] && ERREXIT 254 "SF_VPN_PASSWORD= not set"
|
||||
[[ -z $SF_HOST_USER ]] && ERREXIT 253 "SF_HOST_USER= not set"
|
||||
|
||||
|
||||
# AWS ubuntu 22 doesnt have this symlink
|
||||
[[ ! -e /usr/bin/systemd-resolve ]] && [[ /usr/bin/resolvectl ]] && ln -s resolvectl /usr/bin/systemd-resolv
|
||||
|
||||
if ! command -v nordvpn >/dev/null; then
|
||||
BASE_URL=https://repo.nordvpn.com/
|
||||
KEY_PATH=/gpg/nordvpn_public.asc
|
||||
REPO_PATH_DEB=/deb/nordvpn/debian
|
||||
RELEASE="stable main"
|
||||
|
||||
PUB_KEY=${BASE_URL}${KEY_PATH}
|
||||
REPO_URL_DEB=${BASE_URL}${REPO_PATH_DEB}
|
||||
|
||||
apt update -y
|
||||
apt -y install --no-install-recommends ca-certificates \
|
||||
curl \
|
||||
gnupg \
|
||||
lsb-release \
|
||||
apt-transport-https
|
||||
|
||||
[[ -s /etc/apt/trusted.gpg.d/nordvpn_public.asc ]] || {
|
||||
curl -s "${PUB_KEY}" | tee /etc/apt/trusted.gpg.d/nordvpn_public.asc >/dev/null
|
||||
[[ -s /etc/apt/trusted.gpg.d/nordvpn_public.asc ]] || ERREXIT
|
||||
}
|
||||
|
||||
[[ -s /etc/apt/sources.list.d/nordvpn.list ]] || {
|
||||
echo "deb ${REPO_URL_DEB} ${RELEASE}" | tee /etc/apt/sources.list.d/nordvpn.list >/dev/null
|
||||
[[ -s /etc/apt/sources.list.d/nordvpn.list ]] || ERREXIT
|
||||
}
|
||||
|
||||
apt -y update
|
||||
apt -y install --no-install-recommends nordvpn \
|
||||
net-tools
|
||||
fi
|
||||
|
||||
usermod -aG nordvpn "${SF_HOST_USER}"
|
||||
|
||||
nordvpn login --username "${SF_VPN_LOGIN}" --password "${SF_VPN_PASSWORD:-PASSWORD-MISSING}"
|
||||
|
||||
# Find out source IP to whitelist
|
||||
[[ -z $SF_IP_WHITELIST ]] && {
|
||||
SF_IP_WHITELIST="$(echo "$SSH_CONNECTION" | cut -f1 -d" ")"
|
||||
[[ -z $SF_IP_WHITELIST ]] && ERREXIT 253 "SF_VPN_WHITELIST= not set."
|
||||
}
|
||||
|
||||
nordvpn whitelist add subnet "${SF_IP_WHITELIST}/32" || ERREXIT 254 "SF_IP_WHITELIST=${SF_IP_WHITELIST}/32"
|
||||
# We poll in sf-fw.sh until NordVPN is connected.
|
||||
# nordvpn set autoconnect on
|
||||
# Do not allow NordVPN to manage my firewall
|
||||
nordvpn set firewall off
|
||||
|
||||
|
||||
|
166
provision/init-ubuntu.sh
Executable file
166
provision/init-ubuntu.sh
Executable file
@ -0,0 +1,166 @@
|
||||
#! /bin/bash
|
||||
|
||||
# Installs & Bootstraps 'Segfault Hosting Solution' onto a vanilla Linux Server.
|
||||
#
|
||||
# See https://www.thc.org/segfault/deploy to install with a single command.
|
||||
#
|
||||
# Environment variables:
|
||||
# SF_HOST_USER - The user on the server under which 'segfault' is installed. (e.g. /home/ubuntu)
|
||||
|
||||
SFI_SRCDIR="$(cd "$(dirname "${0}")/.." || exit; pwd)"
|
||||
source "${SFI_SRCDIR}/provision/funcs" || exit 255
|
||||
NEED_ROOT
|
||||
|
||||
DEBUGF "SFI_SRCDIR=${SFI_SRCDIR}"
|
||||
|
||||
SUDO_SF()
|
||||
{
|
||||
sudo -u "${SF_HOST_USER}" bash -c "$*"
|
||||
}
|
||||
|
||||
# INIT: Find valid user to use for installation
|
||||
[[ -z $SF_HOST_USER ]] && {
|
||||
# EC2 default is 'ubuntu'. Fall-back to 'sf-user' otherwise.
|
||||
id -u ubuntu &>/dev/null && SF_HOST_USER="ubuntu" || SF_HOST_USER="sf-user"
|
||||
}
|
||||
export SF_HOST_USER # init-nordvpn.sh etc needs this.
|
||||
|
||||
# Create user if it does not exist
|
||||
useradd "${SF_HOST_USER}" -s /bin/bash 2>/dev/null
|
||||
[[ -d "/home/${SF_HOST_USER}" ]] || {
|
||||
cp -a /etc/skel "/home/${SF_HOST_USER}"
|
||||
chown -R "${SF_HOST_USER}:${SF_HOST_USER}" "/home/${SF_HOST_USER}"
|
||||
}
|
||||
|
||||
SF_HOST_USER_ID="$(id -u "$SF_HOST_USER")"
|
||||
DEBUGF "SF_HOST_USER_ID=${SF_HOST_USER_ID} (SF_HOST_USER=${SF_HOST_USER})"
|
||||
|
||||
# INIT: Find good location for dynamic configuration
|
||||
[[ -z $SF_BASEDIR ]] && {
|
||||
SUDO_SF "mkdir -p ~/segfault"
|
||||
SF_BASEDIR="$(cd "/home/${SF_HOST_USER}/segfault" || exit; pwd)"
|
||||
}
|
||||
DEBUGF "SF_BASEDIR=${SF_BASEDIR}"
|
||||
|
||||
[[ ! -d "${SF_BASEDIR}/config" ]] && SUDO_SF "mkdir \"${SF_BASEDIR}/config\""
|
||||
[[ ! -d "${SF_BASEDIR}/config/db" ]] && SUDO_SF "mkdir \"${SF_BASEDIR}/config/db\""
|
||||
|
||||
# Configure SSHD
|
||||
[[ -z $SF_SSH_PORT ]] && SF_SSH_PORT=22
|
||||
[[ -z $SF_SSH_PORT_MASTER ]] && SF_SSH_PORT_MASTER=64222
|
||||
|
||||
# Move original SSH server out of the way...
|
||||
[[ "$SF_SSH_PORT" -eq 22 ]] && {
|
||||
sed -i "s/#Port ${SF_SSH_PORT}/Port ${SF_SSH_PORT_MASTER}/g" /etc/ssh/sshd_config
|
||||
DEBUGF "Restarting SSHD"
|
||||
service sshd restart
|
||||
}
|
||||
|
||||
# Add docker repository to APT
|
||||
[[ -s /usr/share/keyrings/docker-archive-keyring.gpg ]] || {
|
||||
apt update -y
|
||||
apt -y install --no-install-recommends ca-certificates \
|
||||
curl \
|
||||
gnupg \
|
||||
lsb-release \
|
||||
apt-transport-https
|
||||
|
||||
[[ -s /usr/share/keyrings/docker-archive-keyring.gpg ]] || {
|
||||
rm -rf /usr/share/keyrings/docker-archive-keyring.gpg 2>/dev/null # Delete in case it is zero bytes
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
|
||||
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
}
|
||||
|
||||
apt-get update -y
|
||||
}
|
||||
|
||||
apt-get install -y --no-install-recommends \
|
||||
docker-ce docker-ce-cli containerd.io docker-compose \
|
||||
net-tools make || ERREXIT
|
||||
|
||||
# SSHD's login user (normally 'root' with uid 1000) needs to start docker instances
|
||||
usermod -a -G docker "${SF_HOST_USER}"
|
||||
|
||||
# NOTE: Only needed if source is mounted into vmbox (for testing)
|
||||
[[ "$(stat -c %G /segfault 2>/dev/null)" = "vboxsf" ]] && usermod -a -G vboxsf "${SF_HOST_USER}"
|
||||
|
||||
# SNAPSHOT #2 (2022-05-09)
|
||||
|
||||
# Create guest, encfs and other docker images.
|
||||
SUDO_SF "cd ${SFI_SRCDIR} && make" || exit
|
||||
|
||||
# Create SSH-KEYS and directories.
|
||||
[[ -d "${SF_BASEDIR}/config/db" ]] || SUDO_SF "mkdir -p \"${SF_BASEDIR}/config/db\""
|
||||
[[ -d "${SF_BASEDIR}/config/etc/ssh" ]] || SUDO_SF "mkdir -p \"${SF_BASEDIR}/config/etc/ssh\" && ssh-keygen -A -f ~/segfault/config"
|
||||
[[ -f "${SF_BASEDIR}/config/etc/ssh/id_ed25519" ]] || SUDO_SF "ssh-keygen -q -t ed25519 -C \"\" -N \"\" -f \"${SF_BASEDIR}/config/etc/ssh/id_ed25519\""
|
||||
|
||||
# Find out my own hostname unless SF_FQDN is set (before NordVPN is runnning)
|
||||
[[ -z $SF_FQDN ]] && {
|
||||
# Find out my own hostname
|
||||
IP="$(curl ifconfig.me 2>/dev/null)"
|
||||
HOST="$(host "$IP")" && HOST="$(echo "$HOST" | sed -E 's/.*name pointer (.*)\.$/\1/g')" || HOST="$(hostname -f)"
|
||||
|
||||
# To short or contains illegal characters?
|
||||
[[ "$HOST" =~ ^[a-zA-Z0-9.-]{4,61}$ ]] || unset HOST
|
||||
|
||||
SF_FQDN="${HOST:-UNKNOWN}"
|
||||
unset ip
|
||||
unset HOST
|
||||
}
|
||||
|
||||
DEBUGF "SF_FQDN=${SF_FQDN}"
|
||||
# Create '.env' file for docker-compose
|
||||
SF_BASEDIR_ESC="${SF_BASEDIR//\//\\/}"
|
||||
SF_SRCDIR_ESC="${SFI_SRCDIR//\//\\/}"
|
||||
SF_FQDN_ESC="${SF_FQDN//\//\\/}"
|
||||
ENV="${SFI_SRCDIR}/.env"
|
||||
[[ -e "${ENV}" ]] && { WARN 4 "Using existing .env file"; } || {
|
||||
SUDO_SF "cp \"${SFI_SRCDIR}/provision/env.example\" \"${ENV}\" && \
|
||||
sed -i 's/^SF_BASEDIR.*/SF_BASEDIR=${SF_BASEDIR_ESC}/' \"${ENV}\" && \
|
||||
sed -i 's/^SF_SRCDIR.*/SF_SRCDIR=${SF_SRCDIR_ESC}/' \"${ENV}\" && \
|
||||
sed -i 's/.*SF_FQDN.*/SF_FQDN=${SF_FQDN_ESC}/' \"${ENV}\" && \
|
||||
sed -i 's/PORT=.*/PORT=${SF_SSH_PORT}/' \"${ENV}\"" || ERREXIT 120 failed
|
||||
}
|
||||
|
||||
# SUDO_SF "cd ${SF_BASEDIR} && docker-compose -f \"${SFI_SRCDIR}/docker-compose.yml\" up -d --build --force-recreate --quiet-pull" || ERREXIT
|
||||
cd ${SFI_SRCDIR} && docker-compose up -d --build --force-recreate --quiet-pull || ERREXIT
|
||||
|
||||
# This directory will be mounted[read-only] into sf-guest (user's shell)
|
||||
[[ -d "${SF_BASEDIR}/guest" ]] || SUDO_SF "mkdir -p \"${SF_BASEDIR}/guest\"" || ERREXIT
|
||||
# Copy supporting files that sf-guest needs (like /etc/skel, vpn_status, sf-motd, etc).
|
||||
SUDO_SF "cp -r \"${SFI_SRCDIR}/guest/sf-guest\" \"${SF_BASEDIR}/guest\""
|
||||
|
||||
# Set up NordVPN
|
||||
${SFI_SRCDIR}/provision/init-nordvpn.sh
|
||||
command -v nordvpn >/dev/null && {
|
||||
DEBUGF "Installing Segfault Services..."
|
||||
[[ -z $SF_BASEDIR_ESC ]] && ERREXIT 11 "SF_BASEDIR_ESC not set???"
|
||||
# Create supporting directories
|
||||
mkdir "${SF_BASEDIR}/system" 2>/dev/null
|
||||
|
||||
### Set up NordVPN Status-Update/Monitoring script
|
||||
cp "${SFI_SRCDIR}/system/sf-monitor.sh" "${SF_BASEDIR}/system/sf-monitor.sh"
|
||||
chmod 750 "${SF_BASEDIR}/system/sf-monitor.sh"
|
||||
|
||||
cp "${SFI_SRCDIR}/provision/sf-monitor.service" /etc/systemd/system/sf-monitor.service
|
||||
chmod 640 /etc/systemd/system/sf-monitor.service
|
||||
sed -i "s/@SF_BASEDIR@/${SF_BASEDIR_ESC}/" /etc/systemd/system/sf-monitor.service
|
||||
systemctl enable sf-monitor
|
||||
systemctl start sf-monitor
|
||||
|
||||
### Set up firewall script (for NordVPN)
|
||||
cp "${SFI_SRCDIR}/system/sf-fw.sh" "${SF_BASEDIR}/system/sf-fw.sh"
|
||||
chmod 750 "${SF_BASEDIR}/system/sf-fw.sh"
|
||||
|
||||
cp "${SFI_SRCDIR}/provision/sf-fw.service" /etc/systemd/system/sf-fw.service
|
||||
chmod 640 /etc/systemd/system/sf-fw.service
|
||||
sed -i "s/@SF_BASEDIR@/${SF_BASEDIR_ESC}/" /etc/systemd/system/sf-fw.service
|
||||
systemctl enable sf-fw
|
||||
systemctl start sf-fw
|
||||
|
||||
} || WARN 2 "Skipping NordVPN"
|
||||
|
||||
|
||||
|
||||
|
12
provision/sf-fw.service
Executable file
12
provision/sf-fw.service
Executable file
@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Segfault Firewall Script
|
||||
Requires=nordvpnd.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
Environment="SF_BASEDIR=@SF_BASEDIR@"
|
||||
ExecStart=@SF_BASEDIR@/system/sf-fw.sh
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
11
provision/sf-monitor.service
Executable file
11
provision/sf-monitor.service
Executable file
@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Segfault Monitoring and VPN Status Updater
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Environment="SF_BASEDIR=@SF_BASEDIR@"
|
||||
ExecStart=@SF_BASEDIR@/system/sf-monitor.sh
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
Loading…
Reference in New Issue
Block a user