diff --git a/ChangeLog b/ChangeLog index ab07aff..85719d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +0.4.4 - 2022-03-00 + * SSHD master/NameSpace fix + * Redis via unix domain socket only 0.4.3 - 2022-02-21 * kali-linux-everything * sshd to user's network namespace diff --git a/Makefile b/Makefile index 73a08a8..b352569 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VER := 0.4.3rc2 +VER := 0.4.4a all: make -C router diff --git a/config/etc/redis/redis.conf b/config/etc/redis/redis.conf index e6bc58d..cba6e34 100644 --- a/config/etc/redis/redis.conf +++ b/config/etc/redis/redis.conf @@ -5,5 +5,6 @@ rename-command CONFIG "" rename-command MONITOR "" # COMMAND DOCS causes huge network traffic: redis-cli issues this for every connect. DENY IT. rename-command COMMAND "" -#unixsocket /dev/shm/redis/redis.sock +unixsocketperm 777 +unixsocket /redis-sock/redis.sock diff --git a/docker-compose.yml b/docker-compose.yml index cc54386..abf31b5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,15 +10,11 @@ services: cgroup_parent: sf.slice environment: - SF_REDIS_AUTH=${SF_REDIS_AUTH} - networks: - redis-net: - ipv4_address: ${SF_REDIS_IP} - master-net: - ipv4_address: ${SF_NET_MASTER_REDIS_IP} + network_mode: none command: [ "redis-server", "/redis.conf", "--save", "\"\"", "--appendonly", "no", "--requirepass", "${SF_REDIS_AUTH}" ] volumes: - "${SF_BASEDIR:-.}/config/etc/redis/redis.conf:/redis.conf:ro" - # - "${SF_SHMDIR:-/dev/shm/sf}/redis:/dev/shm/redis" + - "${SF_SHMDIR:-/dev/shm/sf}/run/redis/sock:/redis-sock" sf-encfsd: build: encfsd @@ -37,12 +33,11 @@ services: # NOTE: _MUST_ not run in host's pid space because we use 'pgrep' to find lg's encfsd pid. environment: - SF_REDIS_AUTH=${SF_REDIS_AUTH} - - SF_REDIS_IP=${SF_REDIS_IP} + # - SF_REDIS_IP=${SF_REDIS_IP} - SF_SEED=${SF_SEED} - SF_DEBUG command: ["/encfsd.sh"] - networks: - redis-net: + network_mode: none devices: - "/dev/fuse:/dev/fuse" volumes: @@ -53,6 +48,7 @@ services: - "${SF_SHMDIR:-/dev/shm/sf}/run/encfsd/user:/sf/run/encfsd/user" - "${SF_BASEDIR:-.}/sfbin:/sf/bin:ro" - "${SF_OVERLAYDIR:-/var/lib/docker/overlay2}:/var/lib/docker/overlay2:ro" + - "${SF_SHMDIR:-/dev/shm/sf}/run/redis/sock:/redis-sock" - "/sys/fs/cgroup:/sys/fs/cgroup" # Note: If this one fails to start then most likelly bad ENCFS password. @@ -72,12 +68,10 @@ services: - apparmor:unconfined environment: - SF_REDIS_AUTH=${SF_REDIS_AUTH:?} - - SF_REDIS_IP=${SF_REDIS_IP} - SF_DEBUG pid: "service:sf-encfsd" command: ["/destructor.sh"] - networks: - redis-net: + network_mode: none devices: - "/dev/fuse:/dev/fuse" volumes: @@ -85,6 +79,7 @@ services: - "${SF_BASEDIR:-.}/data:/encfs/raw" - "${SF_SHMDIR:-/dev/shm/sf}/encfs-sec:/encfs/sec:shared" - "${SF_SHMDIR:-/dev/shm/sf}/run/encfsd/user/:/sf/run/encfsd/user" + - "${SF_SHMDIR:-/dev/shm/sf}/run/redis/sock:/redis-sock" - "/var/run/docker.sock:/var/run/docker.sock" - "${SF_BASEDIR:-.}/sfbin:/sf/bin:ro" @@ -97,9 +92,10 @@ services: pid: "host" cap_add: - SYS_PTRACE # access to /proc//root/dev/pts/* to send messages to user. + network_mode: none volumes: - "/var/run/docker.sock:/var/run/docker.sock" - - "/var/run/containerd/io.containerd.runtime.v2.task:/var/run/containerd/io.containerd.runtime.v2.task" + - "/var/run/containerd/io.containerd.runtime.v2.task:/var/run/containerd/io.containerd.runtime.v2.task:ro" - "${SF_BASEDIR:-.}/config:${SF_BASEDIR:-.}/config" - "/sys/fs/cgroup:/sys/fs/cgroup" @@ -113,13 +109,12 @@ services: - sf-redis environment: - SF_REDIS_AUTH=${SF_REDIS_AUTH} - - SF_REDIS_IP=${SF_REDIS_IP} - SF_DEBUG command: ["/portd.sh"] - networks: - redis-net: + network_mode: none volumes: - "${SF_SHMDIR:-/dev/shm/sf}/self-for-guest:/config/self-for-guest" + - "${SF_SHMDIR:-/dev/shm/sf}/run/redis/sock:/redis-sock" - "/var/run/docker.sock:/var/run/docker.sock" - "${SF_BASEDIR:-.}/sfbin:/sf/bin:ro" @@ -168,14 +163,10 @@ services: - PRE_DOWN=/sf/bin/vpn_wg2status.sh /sf/run/vpn/status-nordvpn.log down %i - RECONNECT=604800 # Re-Connect every 7 days - SF_REDIS_AUTH=${SF_REDIS_AUTH} - - SF_REDIS_IP=${SF_REDIS_IP} - SF_DEBUG networks: vpn-net: ipv4_address: ${SF_NORDVPN_IP} - redis-net: - extra_hosts: - - "sf-redis:${SF_REDIS_IP}" sysctls: - net.ipv6.conf.all.disable_ipv6=1 - net.ipv4.conf.all.rp_filter=2 @@ -184,6 +175,7 @@ services: volumes: - "${SF_SHMDIR:-/dev/shm/sf}/run/vpn:/sf/run/vpn" # Between all VPNs - "${SF_SHMDIR:-/dev/shm/sf}/config-for-guest:/config/guest" # vpn_status to guest + - "${SF_SHMDIR:-/dev/shm/sf}/run/redis/sock:/redis-sock" - "${SF_BASEDIR:-.}/sfbin:/sf/bin:ro" cryptostorm: @@ -206,14 +198,10 @@ services: - PRE_DOWN=/sf/bin/vpn_wg2status.sh /sf/run/vpn/status-cryptostorm.log down %i - RECONNECT=604800 # Re-Connect every 7 days - SF_REDIS_AUTH=${SF_REDIS_AUTH} - - SF_REDIS_IP=${SF_REDIS_IP} - SF_DEBUG networks: vpn-net: ipv4_address: ${SF_CRYPTOSTORM_IP} - redis-net: - extra_hosts: - - "sf-redis:${SF_REDIS_IP}" sysctls: - net.ipv6.conf.all.disable_ipv6=1 - net.ipv4.conf.all.rp_filter=2 @@ -221,6 +209,7 @@ services: volumes: - "${SF_SHMDIR:-/dev/shm/sf}/run/vpn:/sf/run/vpn" # Between all VPNs - "${SF_SHMDIR:-/dev/shm/sf}/config-for-guest:/config/guest" # vpn_status to guest + - "${SF_SHMDIR:-/dev/shm/sf}/run/redis/sock:/redis-sock" - "${SF_BASEDIR:-.}/sfbin:/sf/bin:ro" mullvad: @@ -242,14 +231,10 @@ services: - PRE_DOWN=/sf/bin/vpn_wg2status.sh /sf/run/vpn/status-mullvad.log down %i - RECONNECT=604800 # Re-Connect every 7 days - SF_REDIS_AUTH=${SF_REDIS_AUTH} - - SF_REDIS_IP=${SF_REDIS_IP} - SF_DEBUG networks: vpn-net: ipv4_address: ${SF_MULLVAD_IP} - redis-net: - extra_hosts: - - "sf-redis:${SF_REDIS_IP}" sysctls: - net.ipv6.conf.all.disable_ipv6=1 - net.ipv4.conf.all.rp_filter=2 @@ -257,6 +242,7 @@ services: volumes: - "${SF_SHMDIR:-/dev/shm/sf}/run/vpn:/sf/run/vpn" # Between all VPNs - "${SF_SHMDIR:-/dev/shm/sf}/config-for-guest:/config/guest" # vpn_status to guest + - "${SF_SHMDIR:-/dev/shm/sf}/run/redis/sock:/redis-sock" - "${SF_BASEDIR:-.}/sfbin:/sf/bin:ro" router: @@ -336,10 +322,7 @@ services: cgroup_parent: sf.slice depends_on: - sf-redis - # network_mode: none # FIXME: Make redis available via shared socket so we dont need network on 'master'. - networks: - master-net: - # dns: 255.255.255.255 + network_mode: none cap_add: - NET_ADMIN - SYS_ADMIN # For nsenter @@ -349,7 +332,6 @@ services: - SF_DEBUG - SF_FQDN=${SF_FQDN:-SF_FQDN-NOT-SET.hack.segfault.net} - SF_REDIS_AUTH=${SF_REDIS_AUTH} - - SF_REDIS_IP=${SF_NET_MASTER_REDIS_IP} - SF_RPC_IP=${SF_RPC_IP:?} - SF_TOR_IP=${SF_TOR_IP:?} - SF_DNS=${SF_NET_VPN_DNS_IP} @@ -357,14 +339,13 @@ services: volumes: - "${SF_SHMDIR:-/dev/shm/sf}/master:/dev/shm/master" - "${SF_BASEDIR:-.}/config/db:/config/db" - # - "${SF_SHMDIR:-/dev/shm/sf}/redis:/dev/shm/redis" + - "${SF_SHMDIR:-/dev/shm/sf}/run/redis/sock:/redis-sock" - "${SF_BASEDIR:-.}/config/etc/sf:/config/host/etc/sf:ro" - "${SF_BASEDIR:-.}/sfbin:/sf/bin:ro" - "/var/run/docker.sock:/var/run/docker.sock" entrypoint: ["/init-master.sh"] rpc: - # image: fabiocicerchia/nginx-lua image: nginx container_name: sf-rpc restart: ${SF_RESTART:-on-failure} @@ -493,7 +474,6 @@ services: # WARNING: sshd's port forward/socks can access those networks. access-net: ipv4_address: ${SF_SSHD_IP} - redis-net: dns: ${SF_NET_ACCESS_DNS_IP} cap_add: - NET_ADMIN # need to set default route via sf-router @@ -516,9 +496,9 @@ services: - SF_USER_PASSWORD=${SF_USER_PASSWORD:-segfault} - SF_FQDN=${SF_FQDN:-SF_FQDN-NOT-SET.hack.segfault.net} - SF_REDIS_AUTH=${SF_REDIS_AUTH} - - SF_REDIS_IP=${SF_REDIS_IP} - SF_RPC_IP=${SF_RPC_IP} - SF_SEED=${SF_SEED} + - SF_HM_SIZE_LG=8 - SF_DEBUG volumes: - "${SF_BASEDIR:-.}/config:/config/host" @@ -529,6 +509,8 @@ services: - "${SF_SHMDIR:-/dev/shm/sf}/config-for-guest:/config/guest" - "${SF_SHMDIR:-/dev/shm/sf}/self-for-guest:/config/self-for-guest:shared" - "/var/run/docker.sock:/var/run/docker.sock" + - "${SF_SHMDIR:-/dev/shm/sf}/run/redis/sock:/redis-sock" + # - /research/segfault/host/fs-root/bin/segfaultsh:/bin/segfaultsh:ro # FIXME-2022 nginx: image: nginx @@ -542,8 +524,6 @@ services: dmz-net: ipv4_address: ${SF_NGINX_IP} dns: 255.255.255.255 - # cap_add: - # - NET_ADMIN # need to set default route volumes: - "${SF_BASEDIR:-.}/sfbin/wait_semaphore.sh:/sf/bin/wait_semaphore.sh:ro" - "${SF_SHMDIR:-/dev/shm/sf}/encfs-sec/www-root:/sec:slave,ro" @@ -582,22 +562,6 @@ networks: config: - subnet: ${SF_NET_DMZ} - redis-net: - name: sf-redis-net - driver: bridge - internal: true - ipam: - config: - - subnet: ${SF_NET_REDIS} - - master-net: - name: sf-master-net - driver: bridge - internal: true - ipam: - config: - - subnet: ${SF_NET_MASTER} - dns-doh-net: name: sf-dns-doh driver: bridge diff --git a/encfsd/destructor.sh b/encfsd/destructor.sh index 4ba58d0..45fd586 100755 --- a/encfsd/destructor.sh +++ b/encfsd/destructor.sh @@ -28,6 +28,7 @@ stop_lg() red RPUSH portd:cmd "remport ${lid}" >/dev/null rm -f "/sf/run/encfsd/user/lg-${lid}" + rm -f "/sf/run/pids/lg-${lid}.pid" # Tear down container [[ -n $is_container ]] && docker stop "lg-$lid" &>/dev/nuill diff --git a/guest/Dockerfile b/guest/Dockerfile index 2d54ce1..1b40cfa 100644 --- a/guest/Dockerfile +++ b/guest/Dockerfile @@ -497,6 +497,7 @@ RUN /pkg-install.sh EMU apt-get install -y --no-install-recommends \ fs-uae fs-uae-arcade \ vice RUN /pkg-install.sh HUGE apt-get install -y --no-install-recommends \ + maven \ rust-src RUN /pkg-install.sh HACK ghbin shadow1ng/fscan 'amd64$' fscan \ && /pkg-install.sh HACK ghbin 'theaog/spirit' 'spirit.tgz$' spirit \ @@ -523,7 +524,7 @@ RUN /pkg-install.sh HACK ghbin shadow1ng/fscan 'amd64$' fscan \ && /pkg-install.sh HACK ghbin 'hahwul/dalfox' 'inux_amd64' dalfox \ && /pkg-install.sh HACK ghbin 'pwnesia/dnstake' 'linux_amd64' dnstake \ && /pkg-install.sh HACK bash -c '{ curl -sf https://gobinaries.com/gwen001/gitlab-subdomains | PREFIX=/usr/bin sh; }' \ - && /pkg-install.sh HACK bash -c '{ curl -sf https://gobinaries.com/gwen001/github-endpoints | PREFIX=/usr/bin sh; }' \ + && /pkg-install.sh HACK bash -c '{ curl -sf https://gobinaries.com/gwen001/github-endpoints | PREFIX=/usr/bin sh; }' RUN sed 's/deb-src.*//' -i /etc/apt/sources.list \ && apt-get update diff --git a/host/fs-root/bin/docker_sshd.sh b/host/fs-root/bin/docker_sshd.sh index 6a6a3f2..e596ee3 100755 --- a/host/fs-root/bin/docker_sshd.sh +++ b/host/fs-root/bin/docker_sshd.sh @@ -1,11 +1,12 @@ #! /bin/bash +source /sf/bin/funcs_redis.sh + # CY="\e[1;33m" # yellow CR="\e[1;31m" # red # CC="\e[1;36m" # cyan CN="\e[0m" # none - SLEEPEXIT() { local s @@ -64,6 +65,8 @@ LG_PID_DIR="${SF_RUN_DIR}/pids" [[ -d "${LG_PID_DIR}" ]] && rm -rf "${LG_PID_DIR}" mkdir -p "${LG_PID_DIR}" chown 1000 "${LG_PID_DIR}" || SLEEPEXIT 255 5 "${CR}Not found: ${LG_PID_DIR}${CN}" +[[ -d "${SF_RUN_DIR}/logs" ]] && chown 1000 "${SF_RUN_DIR}/logs" +chmod 777 "/sf/run/redis/sock/redis.sock" # Wait for systemwide encryption to be available. # Note: Do not need to wait for /everyone because no other service @@ -105,6 +108,13 @@ chmod 644 "${SF_CFG_HOST_DIR}/etc/ssh/id_ed25519" cp "${SF_CFG_HOST_DIR}/etc/ssh/id_ed25519" "${SF_CFG_GUEST_DIR}/id_ed25519" # [[ ! -f "${SF_CFG_GUEST_DIR}/id_ed25519" ]] && cp "${SF_CFG_HOST_DIR}/etc/ssh/id_ed25519" "${SF_CFG_GUEST_DIR}/id_ed25519" +# Create semaphore (buckets) +i=0 +while [[ $i -lt $SF_HM_SIZE_LG ]]; do + echo -e "DEL 'sema:lg-$i'\nRPUSH 'sema:lg-$i' 1" | red + ((i++)) +done + # 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 @@ -115,12 +125,14 @@ SF_DNS=\"${SF_DNS}\" SF_TOR_IP=\"${SF_TOR_IP}\" SF_SEED=\"${SF_SEED}\" SF_REDIS_AUTH=\"${SF_REDIS_AUTH}\" -SF_REDIS_IP=\"${SF_REDIS_IP}\" SF_RPC_IP=\"${SF_RPC_IP}\" SF_USER=\"${SF_USER}\" SF_DEBUG=\"${SF_DEBUG}\" SF_BASEDIR=\"${SF_BASEDIR}\" SF_SHMDIR=\"${SF_SHMDIR}\" +SF_RAND_OFS=\"$RANDOM\" +SF_HM_SIZE_LG=\"$SF_HM_SIZE_LG\" +SF_NS_NET=\"$(readlink /proc/self/ns/net)\" SF_FQDN=\"${SF_FQDN}\"" >/dev/shm/env.txt # Note: Any host added here also needs to be added in segfaultsh with --add-host diff --git a/host/fs-root/bin/segfaultsh b/host/fs-root/bin/segfaultsh index 8296b4b..15bbcd7 100755 --- a/host/fs-root/bin/segfaultsh +++ b/host/fs-root/bin/segfaultsh @@ -3,6 +3,9 @@ # This is called by SSHD inside SF-HOST docker. # - All environments have been cleared by SSHD. # - Redirects not allowed in restricted shells. +# - bash's 'source' is prohibited (use 'eval' instead) +# - This script might be executed inside the LG's network namespace +# (if 'ssh -M -S ~/.ssh/foobar' and 'ssh -S ~/.ssh/foobar' is used for multiplexing/Mastering) # # This script can be run from the source directory for testing. # SF_BASEDIR must point to the source directory. @@ -10,10 +13,8 @@ # export SF_BASEDIR=/home/sf-user/x/segfault-0.2.2a # cd /segfault/host/fs-root/bin # SF_DEBUG=1 SF_EMU=1 SF_SEED=foobar3 ./segfaultsh -# + # Load/restore environment variables from file -# `source' is prohibited from outside directory 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 @@ -21,7 +22,7 @@ SSH_SF_DEBUG="${SF_DEBUG}" # Set by SSH client [[ -z $SF_DEBUG ]] && SF_DEBUG="${SSH_SF_DEBUG}" unset SSH_SF_DEBUG eval "$(/dev/null >>'/sf/run/logs/segfault.log'" + bash -c "{ echo -en '[$(date '+%F %T' -u)]${p:- }'; echo -e '[${LID}][$$] $str';} 2>/dev/null >>'/sf/run/logs/segfault.log'" } LOG(){ _log "" "$@"; } -LOG_E() { _log "${CR}ERROR${CN}" "$@";} -LOG_W() { _log "${CDY}WARN${CN}" "$@";} +LOG_E() { _log " ${CR}ERROR${CN} " "$@";} +LOG_W() { _log " ${CDY}WARN${CN} " "$@";} + +# NOTE: This function might get called from ERREXIT and before all variables are set. +logout() +{ + local fn + local pid + local is_last + # bash signal race condition: Might be called twice if signal arrives while + # in this function. + trap '' SIGHUP + trap '' SIGTERM + touch "${TS_LOGOUT_FILE:?}" + [[ -f "${LG_PID_FILE:?}" ]] && rm -f "${LG_PID_FILE}" + # Delete IS_LOGGED_IN_FILE if this is the last session to exit. + is_last=1 + for fn in "${LG_PID_DIR:?}/pid-${LID:?}."*; do + [[ ! -f "$fn" ]] && break # No pid file exists for this LID + pid=${fn##*.} + [[ ! -d "/proc/${pid}" ]] && { + # FIXME: This should never happen...but it does + # (e.g. when 'Failed to set up guest instance' is triggered) + LOG_E "Stale: pid-${LID}.${pid} [removed]" + rm -f "${fn}" + continue + } + unset is_last + done + + [[ -n $is_last ]] && { + LOG "Last PID" + [[ -f "${IS_LOGGED_IN_FILE:?}" ]] && rm -f "${IS_LOGGED_IN_FILE}" + } +} + +sem_wait() +{ + redq BLPOP "${LG_SEM:?}" 15 || ERREXIT 238 "Could not get lock: ${LG_SEM}" + IS_SEM_WAIT=1 +} + +sem_release() +{ + [[ -z $IS_SEM_WAIT ]] && return + unset IS_SEM_WAIT + echo -e "DEL '${LG_SEM}'\nRPUSH '${LG_SEM}' 1" | red1 || ERREXIT 237 "Could not release lock: ${LG_SEM}" +} ERREXIT() { @@ -68,9 +115,12 @@ ERREXIT() shift 1 [[ -n $1 ]] && echo -e >&2 "${CR}ERROR:${CN} $*" + logout + sem_release exit "$code" } + if [[ -z $SF_DEBUG ]]; then DEBUGF(){ :;} SF_DOCKER_LOG="none" @@ -230,23 +280,6 @@ init_defaults() SF_ENCFS_SEC_DIR="${SF_SHMDIR}/encfs-sec" } -logout() -{ - # bash signal race condition: Might be called twice if signal arrives while - # in this function. - trap '' SIGHUP - trap '' SIGTERM - touch "${TS_LOGOUT_FILE:?}" - rm -f "${LG_PID_FILE:?}" - # Delete IS_LOGGED_IN_FILE if this is the last session to exit. - for fn in "${LG_PID_DIR}/pid-${LID}."*; do - [[ -f "$fn" ]] && break - # HERE: Last pid file for this lid. - LOG "Last PID" - rm -f "${IS_LOGGED_IN_FILE:?}" - break - done -} # shellcheck disable=SC2317 # Not reachable cb_sighup() @@ -304,6 +337,10 @@ init_vars() CPUS=4 fi + # Check if we are still in sshd's Network Namespace + IS_SSHD_NS_NET=1 + [[ ${SF_NS_NET:?} != "$(readlink /proc/self/ns/net)" ]] && unset IS_SSHD_NS_NET # Already inside LG's Network Namespace + trap cb_sighup SIGHUP trap cb_sigterm SIGTERM } @@ -417,39 +454,22 @@ echo_pty() } -wait_file_exist() -{ - local fn - local max_sec - local n - max_sec="$1" - fn="$2" - - n=0 - while [[ $n -lt $max_sec ]]; do - [[ -f "$fn" ]] && return 0 # True - ((n++)) - sleep 1 - done - - return 255 -} - - sshd_to_ns() { - local upid + # local upid local str - # Find PID of sleep process (uid=1000) - str=$(docker top "lg-${LID}" -o uid,pid | grep ^"1000 ") - upid="${str##* }" - [[ -z $upid ]] && ERREXIT 222 "Oops. Cant find pid of sleep process." - ln -s "/proc/${upid}/ns/net" "/dev/shm/ns-net-${PPID}" - DEBUGF "Moving SSHD(=$PPID) to net-NS(=$upid)" - kill -USR1 $PPID || ERREXIT 221 "Oops. Could not signal SSHD ($PPID)." -} + [[ -z $IS_SSHD_NS_NET ]] && return # Already in LG's network namespace? + # Load PID of container's init process (uid=1000) + [[ -z $LG_PID ]] && { + LG_PID=$(<"/sf/run/pids/lg-${LID}.pid") + [[ -z $LG_PID ]] && ERREXIT 222 "Init PID not found." + } + ln -sf "/proc/${LG_PID}/ns/net" "/dev/shm/ns-net-${PPID}" + DEBUGF "Moving SSHD(=$PPID) to net-NS(=$LG_PID)" + kill -USR1 "$PPID" || ERREXIT 221 "Oops. Could not signal SSHD ($PPID)." +} spawn_shell_exit() { @@ -459,10 +479,7 @@ spawn_shell_exit() # Move SSHD to guest's network namespace (for -L/-R to work) sshd_to_ns - wait_file_exist 20 "${LG_SEMA_INIT_DONE_FN}" || { - exec_devnull docker stop "lg-${LID}" - ERREXIT 237 "Oops. Found a stale lock file." - } + sem_release # Update current IP: tofile "${YOUR_IP:?}" "/config/self-for-guest/lg-${LID}/ip" @@ -618,7 +635,7 @@ check_banned() echo -e "${CR}@@@@@ YOUR IP (${YOUR_IP}) HAS BEEN BANNED. Contact us if you feel that this is wrong. @@@@@${CN}" fi sleep 30 - exit 0 + exit 255 } # wait_for_conn_limit @@ -856,7 +873,7 @@ check_banned mk_hostname HNLID_FILE="${HNLID_DIR}/hn2lid-${SF_HOSTNAME}" -LG_SEMA_INIT_DONE_FN="${SF_USER_DB_DIR}/init-done" +LG_SEM="sema:lg-$(( (SF_NUM + SF_RAND_OFS) % SF_HM_SIZE_LG ))" # Keep guest waiting until there are sufficient resources wait_for_resources @@ -933,6 +950,9 @@ res=$(echo -e "RPUSH encfs \"$$ ${LID} M ${encfspass}\"\n\ BLPOP \"encfs-$$-${LID}-M\" 20" | red) || ERREXIT 230 "Can't reach EncFSD" echo_pty -n "...." +# Only one LG at a time (and wait any other connection to call 'docker exec' until it's fully running. +sem_wait + # Attach to container if already running [[ -n $IS_TRY_EXISTING ]] && { # If state is not running then stop it. @@ -967,10 +987,6 @@ echo_pty -n "...." selfdir="/config/self-for-guest/lg-${LID}" xmkdir "${selfdir}" -# Give docker-run and following command 5 seconds to complete -# before allowing any docker-exec to spawn user shell. -[[ -f "${LG_SEMA_INIT_DONE_FN}" ]] && rm -f "${LG_SEMA_INIT_DONE_FN:?}" - # Note: cgroup-parents: with cgroup-v1 the full path needs to be specified (e.g. sf.slice/sf-guest.slice) whereas with # cgroup-v2 only sf-guest.slice need to be specified. exec_devnull docker run \ @@ -1009,8 +1025,8 @@ exec_devnull docker run \ -v "${SF_ENCFS_SEC_DIR}/www-root/www/${SF_HOSTNAME,,}:/onion:slave" \ --user 1000:1000 \ -d \ - "sf-guest${SF_GUEST_CONTAINER_NAME_SUFFIX}" bash -c "exec -a '[init-${LID}-${SF_HOSTNAME}]' sleep infinity" || ERREXIT 251 "Failed to set up guest container..." -# Note: Run 'sleep' as user 1000:1000 so that sf-host's SSHD can move itself into this guest's + "sf-guest${SF_GUEST_CONTAINER_NAME_SUFFIX}" bash -c "exec -a '[init-${LID}-${SF_HOSTNAME}]' sleep infinity" || ERREXIT 251 "Failed-#1 to set up guest container..." +# Note: Run 'init/sleep' as user 1000:1000 so that sf-host's SSHD can move itself into this guest's # network namespace. echo_pty -n ".." @@ -1041,6 +1057,7 @@ CID=${arr[0]} LG_PID=${arr[1]} C_IP=${arr[2]} [[ -z $C_IP ]] && ERREXIT 249 "Could not get container's IP address." +tofile "${LG_PID:?}" "/sf/run/pids/lg-${LID}.pid" # Set up Root FS / inode limits and move encfsd to lg's cgroup setup_encfsd || ERREXIT 244 "Could not set FS quota." @@ -1057,15 +1074,12 @@ res=$(red SET "ip:${C_IP}" "${LID} ${CID} ${LG_PID}") || ERREXIT 252 "Failed to exec_devnull docker exec sf-master bash -c "nsenter.u1000 -t \"${LG_PID}\" -n iptables -t nat -A OUTPUT -p tcp --dst 255.0.0.1 -j DNAT --to-destination 127.0.0.1" # Setup container -exec_devnull docker exec --user 0:0 "lg-${LID}" /sf/bin/sf-setup.sh || ERREXIT 252 "Failed to set up guest container..." +exec_devnull docker exec --user 0:0 "lg-${LID}" /sf/bin/sf-setup.sh || ERREXIT 252 "Failed-#2 to set up guest container..." touch "/config/self-for-guest/lg-${LID}/THIS-DIRECTORY-IS-IN-MEMORY-ONLY" tofile "${C_IP:?}" "/config/self-for-guest/lg-${LID}/c_ip" echo_pty -e "....[${CG}OK${CN}]" -# Mark as init-complete: -touch "${LG_SEMA_INIT_DONE_FN}" - # Show help how to connect elegantly [[ -n $IS_NEW_SERVER ]] && print_ssh_access diff --git a/host/fs-root/etc/ssh/sshd_config b/host/fs-root/etc/ssh/sshd_config old mode 100644 new mode 100755 diff --git a/sfbin/funcs_redis.sh b/sfbin/funcs_redis.sh index 23e81ff..377326b 100644 --- a/sfbin/funcs_redis.sh +++ b/sfbin/funcs_redis.sh @@ -1,29 +1,48 @@ # BUG-ARP-CACHE, _must_ use IP address -[[ -z $SF_REDIS_IP ]] && { echo >&2 "SF_REDIS_IP= not set"; return 255; } +# [[ -z $SF_REDIS_IP ]] && { echo >&2 "SF_REDIS_IP= not set"; return 255; } # SF_REDIS_SERVER="${SF_REDIS_SERVER:-sf-redis}" -REDCMD=("redis-cli" "--raw" "-h" "${SF_REDIS_IP}") +# REDCMD=("redis-cli" "--raw" "-h" "${SF_REDIS_IP}") +REDCMD=("redis-cli" "--raw" "-s" "/redis-sock/redis.sock") export REDISCLI_AUTH="${SF_REDIS_AUTH}" # Redis Retrieve redr() { local res - bash -c "{ echo '[###] [$(date '+%F %T' -u)] #######################'; ip l sh dev eth1; ip a s dev eth1; arp -n; } 2>>'/dev/shm/lg-${LID}.err' >>'/dev/shm/lg-${LID}.log'" + res=$("${REDCMD[@]}" "$@") || return 255 [[ -z $res ]] && return 200 echo "$res" return 0 } -# Redis Set +# Quiete retrieve +redq() +{ + local res + res=$("${REDCMD[@]}" "$@") || return 255 + [[ -z $res ]] && return 200 + return 0 +} + +# Redis Set, Last line is "OK" on success. red() { local res res=$("${REDCMD[@]}" "$@") || return 255 [[ -z $res || "${res##*$'\n'}" != "OK" ]] && return 200 - # echo "$res" + return 0 +} + +# Redis Set, last line is "1" on success. +red1() +{ + local res + + res=$("${REDCMD[@]}" "$@") || return 255 + [[ -z $res || "${res##*$'\n'}" != "1" ]] && return 200 return 0 } diff --git a/sfbin/sf b/sfbin/sf index 956bd05..b75ba47 100755 --- a/sfbin/sf +++ b/sfbin/sf @@ -217,6 +217,10 @@ WARN_ENTER # Delete stale run files.. [[ -d "${SF_SHMDIR}/run/encfsd/user" ]] && rm -rf "${SF_SHMDIR}/run/encfsd/user" +[[ ! -d "${SF_SHMDIR}/run/redis/sock" ]] && mkdir -p "${SF_SHMDIR}/run/redis/sock" +chmod 700 "${SF_SHMDIR}/run/redis" +chown 999 "${SF_SHMDIR}/run/redis/sock" # docker/redis user +chmod 711 "${SF_SHMDIR}/run/redis/sock" # exec docker-compose "$@" docker-compose "$@" ret=$?