Compare commits

..

No commits in common. "6fad3098a1485e706c7b7b9df0ed75d9ced646f7" and "5548466c054496feade2c5af5f2bb85060f08280" have entirely different histories.

19 changed files with 114 additions and 275 deletions

@ -1,8 +1,5 @@
0.5.0 - 2023-11-00
* Configurable access to /dev/kvm
* Reverse Port via curl sf/port
* Token via curl sf/set -dtoken=<NAME>
* per LG traffic shaping
0.5.0 - 2023-10-00
* Access to /dev/kvm (for token users).
0.4.9p3 - 2023-09-20
* Helix (hx)

@ -73,25 +73,7 @@ http {
rewrite /net /net/;
rewrite /wg /wg/;
rewrite /dmesg /dmesg/;
rewrite /port /port/;
rewrite /set /set/;
location ~* ^/set/.* {
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param REQUEST_BODY $request_body;
fastcgi_param FCGI_CMD set;
fastcgi_param SCRIPT_FILENAME /cgi-bin/rpc;
fastcgi_pass unix:/dev/shm/sf/master/fcgiwrap.socket;
}
location ~* ^/port/.* {
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param REQUEST_BODY $request_body;
fastcgi_param FCGI_CMD port;
fastcgi_param SCRIPT_FILENAME /cgi-bin/rpc;
fastcgi_pass unix:/dev/shm/sf/master/fcgiwrap.socket;
}
location ~* ^/net/.* {
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REQUEST_URI $request_uri;

@ -13,25 +13,20 @@
#SF_USER_MEMORY_LIMIT=256m
#SF_USER_MEMORY_AND_SWAP_LIMIT= # Not set=no swap. Example =4g
#SF_USER_PIDS_LIMIT=128
#SF_USER_CPU_SHARE=8 # 2..1024. docker's default is 1024. 2048 gives 2x and 512 half.
#SF_USER_CPU_SHARE=8 # 2..1024. docker's default is 1024. 2048 gives 2x and 512 half.
#SF_USER_OOM_SCORE=500
#SF_USER_NICE_SCORE=10 #-20 (most often scheduled) to 19 (least often scheduled)
#SF_ULIMIT_NOFILE="8192" # Number of open files 16384:65536" _per_ container
#SF_USER_NICE_SCORE=10 #-20 (most often scheduled) to 19 (least often scheduled)
#SF_ULIMIT_NOFILE="1024:8192"
#SF_USER_BLKIO_WEIGHT=100 # Reduced to 10 during DoS
#SF_MAX_STRAIN=100
#SF_SHM_SIZE= # Hard limit is USER_MEMORY_LIMIT
#SF_CPUS= # automatic between 1..4 depending on host's cpu count
#SF_TOKEN_PROHIBITED= # Prohibit the use of TOKENS
#SF_USER_SYN_BURST=8196 # Can send 8k tcp sync packets
#SF_USER_SYN_LIMIT=1 # Thereafter refill with 1 syn/second, 0=unlimited
#SF_USER_UL_RATE= # Limit LG egress speed (10Mbit, 20Mbit, ...)
#SF_SYN_BURST=10000 # Global limit. (0-10000)
#SF_SYN_LIMIT=200 # Global Limit. 0=unlimited
#SF_RPORT=1 # Enable reverse ports for users.
#SF_RPORT_ON_LOGIN= # Auto-assign a reverse port on log in. Implies SF_RPORT=1.
## Per user limit of root filesystem /
#SF_USER_ROOT_FS_SIZE= # e.g. 16MB, 2GB, 0=unlimited. Not set=read-only
#SF_USER_ROOT_FS_INODE=65536 # Inode Limit. Only enforced if FS_SIZE > 0
@ -43,7 +38,6 @@
#SF_USER_DEV_KVM= # =1 to allow access to /dev/kvm (Warning: User can DoS PHY)
#SF_ALLOW_SRC_TOR= # =1 to allow connections from TOR
#SF_USER_IMMUNE= # =1 to not ban user by lgban
# Limit to 8 concurrently running servers per IP
#SF_LIMIT_SERVER_BY_IP=8

@ -15,11 +15,10 @@ while [[ $i -gt 0 ]]; do
rsync -ral "${h}":/sf/config/db/banned "${h}":/sf/config/db/token "${h}":/sf/config/db/limits .
done
echo "==[DOWN done. Press Enter to start UP]=================================================="
read
echo "===================================================="
i=0
for h in "${HOSTS[@]}"; do
echo "#$i Syncing ${h} UP"
rsync -ral banned token limits "${h}":'/sf/config/db'
((i++))
done
done

@ -44,7 +44,6 @@ services:
- "${SF_BASEDIR:-.}/config/etc/sf:/config/etc/sf:ro"
- "${SF_BASEDIR:-.}/data:/encfs/raw"
- "${SF_SHMDIR:-/dev/shm/sf}/encfs-sec:/encfs/sec:shared"
- "${SF_SHMDIR:-/dev/shm/sf}/run:/sf/run:ro"
- "${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"
@ -254,7 +253,7 @@ services:
- "${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"
# entrypoint: sleep infinity # FIXME-TESTING
# entrypoint: sleep infinity # FIXME-2022
mullvad:
@ -422,7 +421,6 @@ services:
- SF_NORDVPN_IP=${SF_NORDVPN_IP:?}
- SF_CRYPTOSTORM_IP=${SF_CRYPTOSTORM_IP:?}
- SF_MULLVAD_IP=${SF_MULLVAD_IP:?}
- SF_GUEST_MTU=${SF_GUEST_MTU:-1420}
volumes:
- "${SF_SHMDIR:-/dev/shm/sf}/run/vpn:/sf/run/vpn"
- "${SF_BASEDIR:-.}/config/etc/sf:/config/host/etc/sf:ro"
@ -460,7 +458,6 @@ services:
- SF_MULLVAD_ROUTE=${SF_MULLVAD_ROUTE:?}
- SF_DNS=${SF_NET_VPN_DNS_IP}
- SF_NET_LG_ROUTER_IP=${SF_NET_LG_ROUTER_IP:?}
- SF_HOST_MTU=${SF_HOST_MTU:-1500}
volumes:
- "${SF_SHMDIR:-/dev/shm/sf}:/dev/shm/sf"
- "${SF_BASEDIR:-.}/config/db:/config/db"
@ -641,7 +638,7 @@ services:
- SF_DIRECT
- SF_DEBUG
- SF_BACKING_FS
# - SF_DEBUG_SSHD=1 # FIXME-TESTING sshd debug
# - SF_DEBUG_SSHD=1 # FIXME-2022 sshd debug
volumes:
- "${SF_BASEDIR:-.}/config:/config/host"
- "${SF_BASEDIR:-.}/data/share:/sf/share:ro"
@ -653,8 +650,8 @@ services:
- "/var/run/docker.sock:/var/run/docker.sock"
- "/var/lib/lxcfs:/var/lib/lxcfs:ro"
- "${SF_SHMDIR:-/dev/shm/sf}/run/redis/sock:/redis-sock"
# - /research/segfault/host/fs-root/bin/segfaultsh:/bin/segfaultsh:ro # FIXME-TESTING
# - /research/segfault/host:/host:ro # FIXME-TESTING sshd debug
# - /research/segfault/host/fs-root/bin/segfaultsh:/bin/segfaultsh:ro # FIXME-2022
# - /research/segfault/host:/host:ro # FIXME-2022 sshd debug
nginx:
image: nginx
@ -674,17 +671,9 @@ services:
- "${SF_BASEDIR:-.}/config/etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
networks:
# Force docker0
default:
driver: bridge
driver_opts:
com.docker.network.driver.mtu: ${SF_HOST_MTU:-1500}
vpn-net:
name: sf-vpn
driver: bridge
driver_opts:
com.docker.network.driver.mtu: ${SF_HOST_MTU:-1500}
ipam:
config:
- subnet: ${SF_NET_VPN:?}
@ -695,8 +684,6 @@ networks:
# expects all host traffic to arrive at SF_NET_DIRECT_ROUTE_IP.
name: A-sf-direct
driver: bridge
driver_opts:
com.docker.network.driver.mtu: ${SF_HOST_MTU:-1500}
ipam:
config:
- subnet: ${SF_NET_DIRECT:?}
@ -705,8 +692,6 @@ networks:
# sf-host and gsnc
name: sf-access
driver: bridge
driver_opts:
com.docker.network.driver.mtu: ${SF_HOST_MTU:-1500}
ipam:
config:
- subnet: ${SF_NET_ACCESS:?}
@ -714,8 +699,6 @@ networks:
dmz-net:
name: sf-dmz
driver: bridge
driver_opts:
com.docker.network.driver.mtu: ${SF_HOST_MTU:-1500}
ipam:
config:
- subnet: ${SF_NET_DMZ:?}
@ -723,8 +706,6 @@ networks:
dns-doh-net:
name: sf-dns-doh
driver: bridge
driver_opts:
com.docker.network.driver.mtu: ${SF_HOST_MTU:-1500}
ipam:
config:
- subnet: ${SF_NET_DOH:?}
@ -734,7 +715,7 @@ networks:
name: sf-guest
driver: bridge
driver_opts:
com.docker.network.driver.mtu: ${SF_GUEST_MTU:-1420}
com.docker.network.driver.mtu: 1420
# Can not use 'internal'. This will only remvoe the host's bridge
# but this also means we can not route via 10.11.0.* even if we can
# ping the router.

@ -31,7 +31,6 @@ stop_lg()
rm -f "/sf/run/pids/lg-${lid}.pid"
rm -f "/sf/run/ips/lg-${lid}.ip"
rm -rf "/config/self-for-guest/lg-${lid}"
rm -rf "/sf/run/users/lg-${lid}"
# Tear down container
[[ -n $is_container ]] && docker stop "lg-$lid" &>/dev/nuill

@ -124,6 +124,7 @@ encfs_mount_server()
load_limits()
{
local lid
local token
lid="$1"
unset SF_USER_FS_SIZE
@ -131,7 +132,16 @@ load_limits()
unset SF_USER_ROOT_FS_SIZE
unset SF_USER_ROOT_FS_INODE
source "/sf/run/users/lg-${lid}/limits.txt"
# First source global
[[ -f "/config/etc/sf/sf.conf" ]] && eval "$(grep ^SF_ "/config/etc/sf/sf.conf")"
# Then Token
[[ -f "/config/db/user/lg-${lid}/token" ]] && {
token=$(<"/config/db/user/lg-${lid}/token")
source "/config/db/token/token-${token,,}.conf" 2>/dev/null
}
# Then source user specific limits
[[ -f "/config/db/user/lg-${lid}/limits.conf" ]] && eval "$(grep ^SF_ "/config/db/user/lg-${lid}/limits.conf")"
}
dir2prjid()

@ -49,7 +49,6 @@ RUN /pkg-install.sh BASE apt-get install -y --no-install-recommends \
jq \
less \
openssh-sftp-server \
pipx \
python3-pip \
screen \
sharutils \
@ -228,6 +227,7 @@ RUN /pkg-install.sh LARGE apt-get install -y --no-install-recommends \
p7zip-full \
peass \
pip \
pipx \
proxychains \
python2-minimal \
python-is-python3 \

@ -253,9 +253,6 @@ lsg() {
ls -Alh --color=always | grep -i -E "$*"
}
noansi() { sed -e 's/\x1b\[[0-9;]*m//g'; }
alias nocol=noansi
[[ -f /usr/bin/fdfind ]] && alias fd=fdfind
[[ -z $LANG ]] && export LANG=en_US.UTF-8

@ -18,22 +18,13 @@ function cnf_preexec() {
cmd="$1"
# Remove any variable like in `FOO=blah duf`
# Test: X="FOO BAR" Y="hello world" Z=mememe whoami
while :; do
cmd="${cmd#"${cmd%%[^[:space:]]*}"}" # remove leading whitespace characters
[[ $cmd != *" "* ]] && break
# Check if first string before \s is a variable (contains '=')
# Check if first string before " " is a variable (contains '=')
[[ ${cmd%% *} != *"="* ]] && break
# HERE: It's a variable. X=foo, X="foo" or X="foo bar". Remove it for 'cmd'
[[ ${cmd%% *} != *"=\""* ]] && {
# HERE: variable without quotes
cmd=${cmd#* }
continue;
}
# HERE: X="foo" or X="foo bar"
cmd=${cmd#*=\"}
cmd=${cmd#*\" }
# HERE: It's a variable. Remove it for 'cmd'
cmd=${cmd#* }
done
typeset -g cnf_command="${cmd%% *}"
@ -41,7 +32,7 @@ function cnf_preexec() {
# HERE: command not found
[ -n "$cnf_once" ] && return
typeset -g cnf_once="1"
echo -en "💥 \e[0;31m"
echo -en "\e[0;31m"
}
function cnf_precmd() {
@ -51,7 +42,7 @@ function cnf_precmd() {
echo -en "\e[0m"
(($cnf_ret)) && [ -n "$cnf_command" ] && {
whence -- "${cnf_command}" >& /dev/null ||
echo -e "\e[0;34m[\e[0;33mSF\e[0;34m]\e[0m ¯\_(⊙︿⊙)_/¯ Like us to install \e[0;36m${cnf_command}\e[0m?\n\e[0;34m[\e[0;33mSF\e[0;34m] \e[1;37mTell us at https://t.me/thcorg\e[0m 🌈😘"
echo -e "\e[0;34m[\e[0;33mSF\e[0;34m]\e[0m ¯\_(⊙︿⊙)_/¯ Like us to install \e[0;36m${cnf_command}\e[0m?\n\e[0;34m[\e[0;33mSF\e[0;34m] \e[1;37mTell us at https://t.me/thcorg\e[0m"
unset cnf_command
}
}

@ -81,8 +81,7 @@ loc="${loc:0:15}"
IPPORT="${CDY}$(</config/self/reverse_ip):$(</config/self/reverse_port)"
[[ -f /config/self/reverse_geoip ]] && IPPORT+=" ${CF}($(<config/self/reverse_geoip))"
}
token_str="${CDC}${CF}Type ${CN}${CDC}curl sf/port${CN}"
[[ -z $IPPORT ]] && IPPORT="${CDC}Type ${CC}curl sf/port${CDC} for reverse port."
[[ -z $IPPORT ]] && IPPORT="${CDR}N/A${CN}"
### Always show when a Token is being used but obfuscate unless server creation
### or info is typed.

@ -84,7 +84,6 @@ xmkdir()
xln()
{
[[ -L "$2" ]] && return
[[ -e "$2" ]] && return
ln -s "$1" "$2"
}

@ -102,7 +102,6 @@ mk_userdir()
mk_userdir "${SF_RUN_DIR}/pids"
mk_userdir "${SF_RUN_DIR}/ips"
mk_userdir "${SF_RUN_DIR}/users"
[[ ! -d "${SF_RUN_DIR}/logs" ]] && mkdir -p "${SF_RUN_DIR}/logs"
chown 1000 "${SF_RUN_DIR}/logs"

@ -56,7 +56,7 @@ _log()
# Replace ' with '"'"'
str="${*//\'/\'\"\'\"\'}"
# NOTE: segfault.log must be owned 1000:1000
bash -c "{ echo -en '[$(date '+%F %T' -u)]${p:- }'; echo -e '[${CDM}${LID}${CN}] $str';} 2>/dev/null >>'${SF_RUN_DIR}/logs/segfault.log'"
bash -c "{ echo -en '[$(date '+%F %T' -u)]${p:- }'; echo -e '[${CDM}${LID}${CN}] $str';} 2>/dev/null >>'/sf/run/logs/segfault.log'"
}
LOG(){ _log "" "$@"; }
@ -197,12 +197,6 @@ exec_errnull()
fi
}
logpipe() {
[[ ! -e "${SF_RUN_DIR}/logpipe/logPipe.sock" ]] && return
echo "$*" | exec_devnull unix-socket-client
}
# Overcoming a restricted shell. Write $1 to file in $2
# tofile "foobar \$HOME \"|';id;" world.txt
tofile()
@ -325,7 +319,7 @@ init_vars()
init_defaults
init_emu
[[ -f "${SF_RUN_DIR}/logs/segfault.log" ]] && IS_LOGGING=1
[[ -f "/sf/run/logs/segfault.log" ]] && IS_LOGGING=1
NOW="$(date +%s)"
[[ -z $YOUR_IP ]] && {
@ -347,13 +341,11 @@ init_vars()
SF_USER_DB_DIR="${db_dir}/user/lg-${LID}"
SF_BLACKLIST_DIR="${db_dir}/banned"
SF_TOKEN_DIR="${db_dir}/token"
SF_LIMITS_DIR="${db_dir}/limits"
HNLID_DIR="${db_dir}/hn"
SF_RUN_DIR="/sf/run"
SF_RUN_DIR="/sf/run/"
LG_PID_DIR="${SF_RUN_DIR}/pids"
LG_PID_FILE="${LG_PID_DIR}/pid-${LID}.$$"
LG_RUN_DIR="${SF_RUN_DIR}/users/lg-${LID}"
TS_LOGOUT_FILE="${SF_USER_DB_DIR}/ts_logout"
TS_LOGIN_FILE="${SF_USER_DB_DIR}/ts_login"
TS_RUN_FILE="${SF_USER_DB_DIR}/ts_run"
@ -373,7 +365,6 @@ init_vars()
fi
fi
xmkdir "${LG_RUN_DIR}"
# 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
@ -383,6 +374,21 @@ init_vars()
trap cb_sighup SIGPIPE
}
mk_portforward()
{
local ipport
ipport=$(echo -e "DEL portd:response-${LID}\"\n\
RPUSH portd:blcmd \"getport ${LID}\"\n\
BLPOP portd:response-${LID} 5" | redr) || return
# DEBUGF "ipport='$ipport'"
ipport="${ipport##*$'\n'}"
[[ ! "${ipport##*:}" -gt 0 ]] && { DEBUGF "Failed to get Reverse Port Forward (ipport='$ipport')"; return; }
# The PortD add's a /sf/run/self/reverse_forward.
DEBUGF "Reverse Port Forward: $ipport"
}
# Called when a new server is created.
print_disclaimer()
{
@ -508,7 +514,7 @@ sshd_to_ns()
# Load PID of container's init process (uid=1000)
[[ -z $LG_PID ]] && {
LG_PID=$(<"${LG_PID_DIR}/lg-${LID}.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}"
@ -526,16 +532,12 @@ spawn_shell_exit()
sem_release
# Add a log entry into elastisearch using logpipe
logpipe "Type:Login|LID:${LID}|Hostname:${SF_HOSTNAME}||C_ISO:${YOUR_COUNTRY_ISO}|CONTINENT=${YOUR_CONTINENT_CODE}|"
# Update current IP:
tofile "${YOUR_IP_DISPLAY:?}" "/config/self-for-guest/lg-${LID}/ip"
tofile "${YOUR_IP:?}" "${SF_RUN_DIR}/ips/lg-${LID}.ip"
tofile "${YOUR_IP:?}" "/sf/run/ips/lg-${LID}.ip"
[[ -n $YOUR_GEOIP ]] && tofile "${YOUR_GEOIP}" "/config/self-for-guest/lg-${LID}/geoip"
# Request a reverse Port Forward
[[ -n $SF_RPORT_ON_LOGIN ]] && [[ -n $SF_RPORT ]] && [[ ! -f "/config/self-for-guest/lg-${LID}/reverse_ip" ]] && exec_devnull docker exec --user 0:0 "lg-${LID}" curl -s sf/port
[[ ! -f "/config/self-for-guest/lg-${LID}/reverse_ip" ]] && mk_portforward "${LID}"
# Warn user if this is the last server by IP (after semaphore has been released)
[[ -n $IS_SHOW_LAST_SERVER ]] && show_last_server "$IS_SHOW_LAST_SERVER"
@ -604,22 +606,13 @@ BLPOP \"encfs-$$-${LID}-X\" 10" | red) || return 255
return 0
}
load_limits_fn() {
local fn=$1
[[ ! -f "$fn" ]] && return
eval "$(<"${fn}")"
}
load_limits()
{
# Set the default values.
# No default for ROOT_FS limit. Should be set in sf.conf or if not set
# then root is mounted read-only
# SF_USER_ROOT_FS_SIZE=8g
# SF_USER_ROOT_FS_INODE=65536
# SF_USER_FS_SIZE=16g
# SF_USER_FS_INODE=65536
#SF_USER_ROOT_FS_SIZE=2GB
SF_USER_ROOT_FS_INODE=65536
SF_USER_MEMORY_LIMIT=256m
SF_USER_PIDS_LIMIT=128
SF_USER_CPU_SHARE=8
@ -627,12 +620,11 @@ load_limits()
SF_USER_NICE_SCORE=10
SF_LIMIT_SERVER_BY_IP=8
SF_USER_BLKIO_WEIGHT=100
SF_ULIMIT_NOFILE="8192"
SF_ULIMIT_NOFILE="1024:8192"
SF_USER_SYN_BURST=8196
SF_USER_SYN_LIMIT=1
SF_USER_DL_BURST=8gb
SF_USER_UL_BURST=8gb
SF_RPORT=1
# No new shells until load goes below STRAIN*NPROC.
# Should be larger than ContainerGuard's strain when CG starts killing
@ -642,13 +634,7 @@ load_limits()
# dd bs=1M count=10024 if=/dev/zero of=/dump.dat oflag=direct status=progress
# Source system wide limits
load_limits_fn "${SF_ETCSF_DIR}/sf.conf"
# Source continent specific limits
load_limits_fn "${SF_LIMITS_DIR}/limits-continent-${YOUR_CONTINENT_CODE}.conf"
# Source country specific limits
load_limits_fn "${SF_LIMITS_DIR}/limits-country-${YOUR_COUNTRY_ISO}.conf"
[[ -f "${SF_ETCSF_DIR}/sf.conf" ]] && eval "$(<"${SF_ETCSF_DIR}/sf.conf")"
# Then source token specific limits (and write TOKEN information)
if [[ -z $SF_TOKEN ]]; then
@ -680,17 +666,10 @@ load_limits()
}
# Then source user specific limits
load_limits_fn "${SF_USER_DB_DIR}/limits.conf"
[[ -f "${SF_USER_DB_DIR}/limits.conf" ]] && eval "$(<"${SF_USER_DB_DIR}/limits.conf")"
# Then source IP specific limits
load_limits_fn "${SF_ETCSF_DIR}/sf-${YOUR_IP}.conf"
# Add SF docker args to LG container.
# DISABLED: otherwise, an attacker with write access to token/limits (e.g. through a web user-management interface) could own the PHY.
# [[ ${#SF_USER_DOCKER_ARGS[@]} -gt 0 ]] && DOCKER_ARGS+=("${SF_USER_DOCKER_ARGS[@]}")
# User gets a reverse port on login
[[ -n $SF_RPORT_ON_LOGIN ]] && SF_RPORT=1
[[ -f "${SF_ETCSF_DIR}/sf-${YOUR_IP}.conf" ]] && eval "$(<"${SF_ETCSF_DIR}/sf-${YOUR_IP}.conf")"
# Set swap limit if not set in sf.conf
[[ -z $SF_USER_MEMORY_AND_SWAP_LIMIT ]] && SF_USER_MEMORY_AND_SWAP_LIMIT="$SF_USER_MEMORY_LIMIT"
@ -713,7 +692,7 @@ load_limits()
DOCKER_ARGS+=("--oom-score-adj=${SF_USER_OOM_SCORE}")
DOCKER_ARGS+=("--blkio-weight=${SF_USER_BLKIO_WEIGHT}")
[[ -n $SF_USER_DEV_KVM ]] && [[ -e /dev/kvm ]] && DOCKER_ARGS+=("--device=/dev/kvm")
[[ -n $SF_USER_DEV_KVM ]] && DOCKER_ARGS+=("--device=/dev/kvm")
if [[ -z $SF_USER_ROOT_FS_SIZE ]]; then
DOCKER_ARGS+=("--read-only")
@ -729,8 +708,6 @@ load_limits()
}
fi
write_lg_limits
# NOTE: This is no longer used because /dev/shm is now mounted as tmpfs to make UML work
# [[ -n $SF_SHM_SIZE ]] && DOCKER_ARGS+=("--shm-size=$SF_SHM_SIZE")
@ -739,15 +716,11 @@ load_limits()
setup_fs_limit || ERREXIT 202 "Can't configure XFS limit"
}
# Publish user limits to self/limits, human readable.
# Publish user limits to self/limits
write_guest_limits()
{
local is_token
local is_ro
local tx;
tx="${SF_USER_UL_RATE}"
[[ -z $SF_USER_UL_RATE ]] && tx="${SF_MAXOUT}"
is_token="no"
[[ -n $SF_TOKEN ]] && is_token="yes"
@ -764,7 +737,7 @@ SHM_SIZE=${SF_SHM_SIZE}
PIDS=${SF_USER_PIDS_LIMIT}
MEMORY=${SF_USER_MEMORY_LIMIT}
NOFILE=${SF_ULIMIT_NOFILE}
TX=${tx:-unlimited}
TX=${SF_MAXOUT}
RX=${SF_MAXIN:-unlimited}
SYN_BURST=${SF_USER_SYN_BURST}
SYN_RATE=${SF_USER_SYN_LIMIT}/sec
@ -772,18 +745,6 @@ SERVERS=${SF_LIMIT_SERVER_BY_IP}
GREETINGS='${SF_SYSCOP_MSG}'" "/config/self-for-guest/lg-${LID}/limits"
}
# Write limits to file that can be loaded by other processes (like rpc and encfsd)
write_lg_limits() {
tofile "\
SF_USER_ROOT_FS_SIZE=\"$SF_USER_ROOT_FS_SIZE\"
SF_USER_ROOT_FS_INODE=\"$SF_USER_ROOT_FS_INODE\"
SF_USER_FS_SIZE=\"$SF_USER_FS_SIZE\"
SF_USER_FS_INODE=\"$SF_USER_FS_INODE\"
SF_USER_UL_RATE=\"$SF_USER_UL_RATE\"
SF_RPORT=\"$SF_RPORT\"
SF_USER_IMMUNE=\"$SF_USER_IMMUNE\"" "${LG_RUN_DIR}/limits.txt"
}
check_banned()
{
local blfn
@ -1014,9 +975,6 @@ check_limit_server_by_ip()
mk_geoip()
{
local ip
local country
local country_iso
local continent_code
ip="${1}"
[[ ! -f /sf/share/GeoLite2-City.mmdb ]] && return
[[ -z ${ip} ]] && return
@ -1026,16 +984,6 @@ mk_geoip()
res=$(mmdbinspect --db /sf/share/GeoLite2-City.mmdb "${ip}")
[[ -z $SF_HIDEIP ]] && city=$(echo "$res" | jq -r '.[0].Records[0].Record.city.names.en | select(. != null)')
country=$(echo "$res" | jq -r '.[0].Records[0].Record.country.names.en | select(. != null)')
country_iso=$(echo "$res" | jq -r '.[0].Records[0].Record.country.iso_code | select(. != null)')
continent_code=$(echo "$res" | jq -r '.[0].Records[0].Record.country.iso_code | select(. != null)')
country_iso="${country_iso,,}"
country_iso="${country_iso//[^a-z]}"
YOUR_COUNTRY_ISO="${country_iso:0:2}"
continent_code="${continent_code,,}"
continent_code="${continent_code//[^a-z]}"
YOUR_CONTINENT_CODE="${continent_code:0:6}"
unset YOUR_GEOIP
if [[ -n $city ]] && [[ -n $country ]]; then
@ -1143,6 +1091,9 @@ export LID
[[ -z $SF_SEED ]] && ERREXIT 244 "SF_SEED= is not set."
# Show system messages
sysmsg "/config/host/etc/loginmsg-all.sh"
# Call init_vars() after LID is set
init_vars
# Load CPU/PID/OOM limits (systemwide or user specific)
@ -1151,10 +1102,6 @@ load_limits
check_banned
mk_hostname
# Show system messages
sysmsg "/config/host/etc/loginmsg-all.sh"
HNLID_FILE="${HNLID_DIR}/hn2lid-${SF_HOSTNAME}"
LG_SEM="sema:lg-$(( (SF_NUM + SF_RAND_OFS) % SF_HM_SIZE_LG ))"
@ -1206,8 +1153,6 @@ else
tofile "$SF_HOSTNAME" "${SF_USER_DB_DIR}/hostname"
[[ -d "${HNLID_DIR}" ]] || exec_devnull mkdir "${HNLID_DIR}"
tofile "$LID" "${HNLID_FILE}" || ERREXIT 231 "tofile: Failed to create hnlid_file"
# Add a log entry into elastisearch using logpipe
logpipe "Type:Create|LID:${LID}|Hostname:${SF_HOSTNAME}|C_ISO:${YOUR_COUNTRY_ISO}|CONTINENT=${YOUR_CONTINENT_CODE}|"
fi
DEBUGF "LID=${LID} SF_HOSTNAME=${SF_HOSTNAME}"
@ -1350,7 +1295,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:?}" "${LG_PID_DIR}/lg-${LID}.pid"
tofile "${LG_PID:?}" "/sf/run/pids/lg-${LID}.pid"
# Set up Root FS / inode limits and move encfsd to lg's cgroup
setup_encfsd || STOPEXIT "${LID}" 244 "Could not set FS quota."
@ -1363,7 +1308,7 @@ res=$(red SET "ip:${C_IP}" "${LID} ${CID} ${LG_PID}") || STOPEXIT "$LID" 252 "Fa
exec_devnull docker exec sf-router /user-limit.sh "${YOUR_IP_HASH}" "${YOUR_IP}" "${C_IP}" "$SF_USER_SYN_LIMIT" "$SF_USER_SYN_BURST" "$SF_USER_DL_RATE" "$SF_USER_DL_BURST" "$SF_USER_UL_RATE" "$SF_USER_UL_BURST" || STOPEXIT "${LID}" 251 "Faild to set syn-limit...";
# Ready container
exec_devnull docker exec sf-master /ready-lg.sh "${LID}" "${C_IP}" "${LG_PID}" "${SF_USER_DL_RATE}" "${SF_USER_UL_RATE}" || STOPEXIT "${LID}" 246 "Failed-#3 to ready guest container..."
exec_devnull docker exec sf-master /ready-lg.sh "${LID}" "${C_IP}" "${LG_PID}" || STOPEXIT "${LID}" 246 "Failed-#3 to ready guest container..."
# Setup container (within container's namespace)
unset WGNAME_UP
@ -1374,6 +1319,9 @@ tofile "${C_IP:?}" "/config/self-for-guest/lg-${LID}/c_ip"
echo_pty -e "....[${CG}OK${CN}]"
# Add a log entry into elastisearch using logpipe
echo "Type:Login|LID:${LID}|Hostname:${SF_HOSTNAME}|" | unix-socket-client &> /dev/null
# Spawn shell
spawn_shell_exit "$@"
# NOT REACHED

@ -6,7 +6,6 @@ WG_PORT_MIN=32768
WG_PORT_MAX=65535
WT_VER=1
COLOR="always"
ICON_ERROR=""
source /sf/bin/funcs.sh
source /sf/bin/funcs_redis.sh
@ -23,7 +22,7 @@ echo -en "Content-Type: text/plain\r\n\r\n"
# STDERR is logged.
BAIL()
{
echo -e "${ICON_ERROR}${RR}ERROR${N}: $1"
echo -e "$1"
[[ -n $2 ]] && echo -e >&2 "[${CB}${LID:-$REMOTE_ADDR}${CN}] ${CR}$2${CN}$3"
exit 255
@ -64,7 +63,6 @@ GetFormVars()
[[ ${key} == "privatekey" ]] && key="private"
[[ ${key} == "private" ]] && R_WG_PRIVATE="${val//[^[:alnum:]+\/]}="
[[ ${key} == "name" ]] && { val="${val//[^[:alnum:]]}"; R_WT_NAME="${val:0:13}"; }
[[ ${key} == "token" ]] && { val="${val//[^a-zA-Z0-9@]}"; val="${val##*@}"; TOKEN_NAME="${val:0:64}"; }
### wgOUT
[[ ${key} == "psk" ]] && R_OUT_PSK="${val//[^[:alnum:]+\/]}="
[[ ${key} == "public" ]] && key="peer" # Alias
@ -104,7 +102,7 @@ load_config()
{
source /dev/shm/config.txt && return
BAIL "Not ready. SF is still booting up..." "Failed to load: " "/dev/shm/config.txt"
BAIL "${R}ERROR${N}: Not ready. SF is still booting up..." "Failed to load: " "/dev/shm/config.txt"
}
GenSecret()
@ -311,10 +309,10 @@ net_init()
local arr
arr=($(echo "${LID_WGDIR}/wg-"*))
[[ ${#arr[@]} -gt 16 ]] && BAIL "To many Peers. You must delete some first.
[[ ${#arr[@]} -gt 16 ]] && BAIL "${R}ERROR${N}: To many Peers. You must delete some first.
Use ${C}curl sf/net/list${N} to see them all.
Use ${C}curl sf/net/del -d name=<NAME>${N} to delete <NAME>.
Use ${C}curl sf/net/del -d name=all${N} to delete them all." "${RR}PEERS-MAX${N} " "Limit: ${#arr[@]}"
Use ${C}curl sf/net/del -d name=all${N} to delete them all." "${R}PEERS-MAX${N} " "Limit: ${#arr[@]}"
[[ -n ${R_PORTSECRET} ]] && cmd_net_init_move "${R_PORTSECRET}"
@ -347,7 +345,10 @@ Port ${R_PORT} is already in use. You can assign it to this server like so:\
write_portfile
}
[[ -e "/config/db/wg/wg-${R_WT_NAME}" ]] && BAIL "'$R_WT_NAME' already exists. Delete it first with ${C}curl sf/net/del -d name=${R_WT_NAME}${N}"
[[ -e "/config/db/wg/wg-${R_WT_NAME}" ]] && {
echo -e "${R}ERROR${N}: '$R_WT_NAME' already exists. Delete it first with ${C}curl sf/net/del -d name=${R_WT_NAME}${N}"
exit
}
# We do not need the peer's private key but it is more convenient
# to the user to show him one complete ./wiretap command line.
@ -493,7 +494,7 @@ cmd_net_del()
exit
fi
[[ ! -f "${LID_WGDIR}/wg-${R_WT_NAME}" ]] && BAIL "${RR}Not found${N}: ${R_WT_NAME}"
[[ ! -f "${LID_WGDIR}/wg-${R_WT_NAME}" ]] && BAIL "${R}Not found${N}: ${R_WT_NAME}"
xrm "/config/db/wg/wg-${R_WT_NAME}" "${LID_WGDIR}/wg-${R_WT_NAME}"
echo -en "\
@ -551,7 +552,7 @@ Use ${C}curl sf/net/up${N} to enable a new Exit Node."
[[ -e "${LID_WGNAME_FN}" ]] && {
name=$(<"${LID_WGNAME_FN}")
str="${F}[${G}connected${N}${F}]${N}"
[[ -n $is_not_connected ]] && str="${F}[${N}${RR}EXIT Node is not connected${N}${F}]${N}"
[[ -n $is_not_connected ]] && str="${F}[${N}${R}EXIT Node is not connected${N}${F}]${N}"
echo -e "\n${YY}Name${N}: ${Y}${name:-UNKNOWN}${N} ${str}"
### gvisor's DNAT used by WT is BROKEN
### https://github.com/sandialabs/wiretap/issues/18#issuecomment-1583106554
@ -608,25 +609,18 @@ CheckGoodKey()
[[ -z $key ]] && return
[[ ${#key} -eq 44 ]] && return
BAIL "Bad Key for ${opt}="
}
# Load LG specific configuration (by source IP)
load_lg() {
local arr;
# Retrieve (LID CID PID)
arr=($(redr GET "ip:${REMOTE_ADDR}")) || BAIL "Bad Value" "Bad Value: " "ret=$?, ${#arr[@]}"
[[ ${#arr[@]} -ne 3 ]] && BAIL "Value != 3" "Value != 3: " "${#arr[@]}"
LID="${arr[0]}"
# CID="${arr[1]}"
PID="${arr[2]}"
BAIL "${R}ERROR${N}: Bad Key for ${opt}="
}
wg_net_init()
{
local arr
local IFS
load_lg
# Retrieve (LID CID PID)
arr=($(redr GET "ip:${REMOTE_ADDR}")) || BAIL "Bad Value" "Bad Value: " "ret=$?, ${#arr[@]}"
[[ ${#arr[@]} -ne 3 ]] && BAIL "Value != 3" "Value != 3: " "${#arr[@]}"
LID="${arr[0]}"
LID_WGDIR="/config/db/user/lg-${LID}/wg"
[[ ! -d "${LID_WGDIR}" ]] && mkdir "${LID_WGDIR}"
LID_PROMPT_FN="/dev/shm/sf/self-for-guest/lg-${LID}/prompt"
@ -637,64 +631,31 @@ wg_net_init()
USER_DB_WGNAME_UP_FN="/config/db/user/lg-${LID}/wg/name_up"
# USER_DB_WGCLIENT_FN="/config/db/user/lg-${LID}/wg/client"
# CID="${arr[1]}"
PID="${arr[2]}"
# Split into arguments
IFS=/ read -r -a ARGS <<< "${REQUEST_URI:1}" # Ignore first '/'. Split into arguements.
# Load CLIENT config
# source "${USER_DB_WGCLIENT_FN}" 2>/dev/null
}
ERR_wg_help_exit()
{
echo -e "${RR}ERROR${N}: $1"
echo -e "${R}ERROR${N}: $1"
cmd_wg_help
exit
}
cmd_port() {
local ipport
load_lg
source "/dev/shm/sf/run/users/lg-${LID}/limits.txt"
[[ -z $SF_RPORT ]] && BAIL "💥 ${RR}ERROR${CN}: ${M}Please contact a SysCop to enable this feature for you.${N}"
red RPUSH portd:cmd "remport ${lid}" >/dev/null
sleep 1 # Stop DoS attack: flood-requesting reverse ports
ipport=$(echo -e "DEL portd:response-${LID}\"\n\
RPUSH portd:blcmd \"getport ${LID}\"\n\
BLPOP portd:response-${LID} 5" | redr) || return
# DEBUGF "ipport='$ipport'"
ipport="${ipport##*$'\n'}"
[[ ! "${ipport##*:}" -gt 0 ]] && { DEBUGF "Failed to get Reverse Port Forward (ipport='$ipport')"; return; }
# The PortD add's a /sf/run/self/reverse_forward.
echo -en "\
${M}Tip${N}: Type ${C}cat /config/self/reverse_*${N}
${G}👾 New reverse Port is ${Y}${ipport}${CN}"
# portd.sh automaticaly adds this to /config/self/reverse_*
exit
}
cmd_token() {
local token_fn="/config/db/token/token-${TOKEN_NAME,,}.conf"
load_lg
source "/dev/shm/sf/run/users/lg-${LID}/limits.txt"
[[ -n $SF_TOKEN_PROHIBITED ]] && BAIL "${M}Please contact a SysCop to enable this feature for you.${N}"
[[ ! -f "${token_fn}" ]] && { sleep 1; BAIL "${M}Token '${R}${TOKEN_NAME}${M}' does not exist.${N}"; }
echo "${TOKEN_NAME}" >"/config/db/user/lg-${LID}/token"
echo -en "${G}🦋 Token set. ${N}Type ${C}halt${N} and log back in."
exit
}
# CLIENT
cmd_wg_up()
{
local epip
local args
local err
local epport
[[ ${R_OUT_ENDPOINT} != *:* ]] && R_OUT_ENDPOINT+=":51820"
epip="${R_OUT_ENDPOINT%%:*}"
@ -710,10 +671,10 @@ cmd_wg_up()
# Delete any EXIT or OUT
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip link delete group 31337 2>/dev/null
err=$(nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip link add "${WG_DEV}" type wireguard 2>&1) || BAIL "Failed: ip link add '${WG_DEV}' (${err:0:64})." "Failed ${WG_DEV}" ": $err"
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip link set "${WG_DEV}" group 31337 || BAIL "ip link set FAILED."
[[ -n $R_OUT_IP4 ]] && { nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip address add dev "${WG_DEV}" "${R_OUT_IP4}" || BAIL "Failed to assign IPv4 address '${R_OUT_IP4}'."; }
[[ -n $R_OUT_IP6 ]] && { nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip -6 address add dev "${WG_DEV}" "${R_OUT_IP6}" || BAIL "Failed to assign IPv6 address '${R_OUT_IP6}'."; }
err=$(nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip link add "${WG_DEV}" type wireguard 2>&1) || BAIL "${R}ERROR${N}: Failed: ip link add '${WG_DEV}' (${err:0:64})." "Failed ${WG_DEV}" ": $err"
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip link set "${WG_DEV}" group 31337 || BAIL "${R}ERROR${N}: ip link set FAILED."
[[ -n $R_OUT_IP4 ]] && { nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip address add dev "${WG_DEV}" "${R_OUT_IP4}" || BAIL "${R}ERROR${N}: Failed to assign IPv4 address '${R_OUT_IP4}'."; }
[[ -n $R_OUT_IP6 ]] && { nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip -6 address add dev "${WG_DEV}" "${R_OUT_IP6}" || BAIL "${R}ERROR${N}: Failed to assign IPv6 address '${R_OUT_IP6}'."; }
args=()
[[ -n $R_OUT_PSK ]] && {
@ -721,9 +682,9 @@ cmd_wg_up()
echo "$R_OUT_PSK" >"/dev/shm/psk.$$"
}
echo "$R_WG_PRIVATE" >"/dev/shm/private.$$"
err=$(nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n wg set "$WG_DEV" private-key "/dev/shm/private.$$" peer "$R_OUT_PEER" "${args[@]}" endpoint "${R_OUT_ENDPOINT}" persistent-keepalive 25 allowed-ips 0.0.0.0/0,::/0 2>&1) || BAIL "Failed: wg set (${err:0:128})"
err=$(nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n wg set "$WG_DEV" private-key "/dev/shm/private.$$" peer "$R_OUT_PEER" "${args[@]}" endpoint "${R_OUT_ENDPOINT}" persistent-keepalive 25 allowed-ips 0.0.0.0/0,::/0 2>&1) || BAIL "${R}ERROR${N}: Failed: wg set (${err:0:128})"
rm -f "/dev/shm/private.$$" "/dev/shm/psk.$$"
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip link set mtu $((SF_HOST_MTU - 80 - 80)) up dev "${WG_DEV}"
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip link set mtu $((1500 - 80 - 80)) up dev "${WG_DEV}"
# Route to WG endpoint:
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add "${epip}" via "${SF_NET_LG_ROUTER_IP}" 2>/dev/null
@ -789,8 +750,7 @@ GetFormVars
# COLOR is set (to 'always')
Y=$CDY
C=$CDC
R=$CDR
RR=$CR
R=$CR
G=$CDG
B=$CB
M=$CDM
@ -798,7 +758,6 @@ GetFormVars
W=$CW
N=$CN
F=$CF
ICON_ERROR="💥 "
}
@ -808,12 +767,6 @@ GetFormVars
exit
}
[[ "${FCGI_CMD}" == "port" ]] && cmd_port
[[ "${FCGI_CMD}" == "set" ]] && {
[[ -n $TOKEN_NAME ]] && cmd_token
BAIL "${M}Setting not found.${N}"
}
[[ -n $SF_DEBUG ]] && [[ "${FCGI_CMD}" == "env" ]] && { env; exit; }
wg_net_init
@ -845,7 +798,7 @@ wg_net_init
CheckGoodKey "$R_WT_PRIVATE" "--exit_private"
CheckGoodKey "$R_WT_PUBLIC" "--exit_public"
[[ -n $R_WT_PRIVATE ]] && [[ -n $R_WT_PUBLIC ]] && BAIL "Set either PRIVATE or PUBLIC but not both."
[[ -n $R_WT_PRIVATE ]] && [[ -n $R_WT_PUBLIC ]] && BAIL "${R}ERROR${N}: Set either PRIVATE or PUBLIC but not both."
# Sanitize 0.4.8rc1 bug where '172...' was '"172...' in .env
WG_IPS="${WG_IPS//[^a-fx0-9\/,:.]}"
@ -873,11 +826,14 @@ wg_net_init
[[ ${ARGS[1]} == 'list' ]] && cmd_net_list
# NOT 'up' -> EXIT
[[ ${ARGS[1]} != 'up' ]] && { echo -e "${RR}ERROR${N}: Unknown command."; cmd_net_help; }
[[ ${ARGS[1]} != 'up' ]] && { echo -e "${R}ERROR${N}: Unknown command."; cmd_net_help; }
WT_NAME="$R_WT_NAME"
[[ -n $IS_NOCREAT ]] && [[ -n $WT_NAME ]] && [[ ! -f "${LID_WGDIR}/wg-${WT_NAME}" ]] && BAIL "EXIT '${WT_NAME}' does not exist."
[[ -n $IS_NOCREAT ]] && [[ -n $WT_NAME ]] && [[ ! -f "${LID_WGDIR}/wg-${WT_NAME}" ]] && {
echo -e "${R}ERROR${N}: EXIT '${WT_NAME}' does not exist."
exit
}
if [[ -z $WT_NAME ]] && [[ -f "${LID_WGNAME_FN}" ]]; then
is_already_up=1
@ -895,7 +851,7 @@ wg_net_init
# HERE: No name supplied. Another WG is already UP.
# nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip l sh "${WG_DEV}" &>/dev/null && {
name=$(<"${LID_WGNAME_FN}")
echo -e "${RR}ERROR${N}: Exit Node ${G}${name}${N} is already UP."
echo -e "${R}ERROR${N}: Exit Node ${G}${name}${N} is already UP."
net_print_example "${name}"
net_print_commands "${name}"
exit 255
@ -916,18 +872,18 @@ wg_net_init
# _far_ more efficient.)
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip link delete group 31337 2>/dev/null
err=$(nsenter -t "${WG_PID}" -n ip link add "${WG_DEV}" type wireguard 2>&1) || BAIL "Failed: ip link add ${WG_DEV} (${err:0:32})." "Failed ${WG_DEV}" ": $err"
nsenter -t "${WG_PID}" -n ip link set "${WG_DEV}" group 31337 || BAIL "ip link set FAILED."
err=$(nsenter -t "${WG_PID}" -n ip link add "${WG_DEV}" type wireguard 2>&1) || BAIL "${R}ERROR${N}: Failed: ip link add ${WG_DEV} (${err:0:32})." "Failed ${WG_DEV}" ": $err"
nsenter -t "${WG_PID}" -n ip link set "${WG_DEV}" group 31337 || BAIL "${R}ERROR${N}: ip link set FAILED."
echo "$WG_PRIVATE" >"/dev/shm/private.$$"
err=$(nsenter -t "${WG_PID}" -n wg set "${WG_DEV}" listen-port "${WG_PORT}" private-key "/dev/shm/private.$$" peer "${WT_PUBLIC}" allowed-ips 0.0.0.0/0,::/0 2>&1) || BAIL "Failed: wg set (${err:0:128})"
err=$(nsenter -t "${WG_PID}" -n wg set "${WG_DEV}" listen-port "${WG_PORT}" private-key "/dev/shm/private.$$" peer "${WT_PUBLIC}" allowed-ips 0.0.0.0/0,::/0 2>&1) || BAIL "${R}ERROR${N}: Failed: wg set (${err:0:128})"
rm -f "/dev/shm/private.$$"
# Move Interface to user's container:
err=$(nsenter -t "${WG_PID}" -n ip link set "${WG_DEV}" netns "${PID}" 2>&1) || BAIL "Failed to move ${WG_DEV}." "Failed ${WG_DEV} netns $PID" ": $err"
err=$(nsenter -t "${WG_PID}" -n ip link set "${WG_DEV}" netns "${PID}" 2>&1) || BAIL "${R}ERROR${N}: Failed to move ${WG_DEV}." "Failed ${WG_DEV} netns $PID" ": $err"
# Configure interface after moving
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip -4 address add "${WG_IP}" dev "${WG_DEV}"
err=$(nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip -6 address add "${WG_IP6}" dev "${WG_DEV}" 2>&1) || echo >&2 "${RR}ERROR${N}: ip -6: $err"
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip link set mtu $((SF_HOST_MTU - 80)) up dev "${WG_DEV}"
err=$(nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip -6 address add "${WG_IP6}" dev "${WG_DEV}" 2>&1) || echo >&2 "${CR}ERROR${CN}: ip -6: $err"
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip link set mtu 1420 up dev "${WG_DEV}"
set_route

@ -14,8 +14,6 @@ source /dev/shm/config-lg.txt || exit 255
LID="$1"
C_IP="$2"
LG_PID="$3"
USER_DL_RATE="$4"
USER_UL_RATE="$5"
LID_PROMPT_FN="/dev/shm/sf/self-for-guest/lg-${LID}/prompt"
# Create 'empty' for ZSH's prompt to show WG EXIT
@ -32,12 +30,7 @@ nsenter.u1000 -t "${LG_PID:?}" --setuid 0 --setgid 0 -n arp -s "${SF_RPC_IP}"
# 255.0.0.1 always points to guest's localhost: user can now set up a ssh -D1080 and connect with browser to
# 255.0.0.1 and reach guest's 127.0.0.1.
# iptables is u+s and does not need --setuid
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
# Set egress limits per LG
[[ -n $USER_UL_RATE ]] && nsenter.u1000 -t "${LG_PID:?}" --setuid 0 --setgid 0 -n tc qdisc add dev eth0 root cake bandwidth "${USER_UL_RATE}" dsthost
set +e
exit 0

@ -29,7 +29,6 @@ SF_BASEDIR=${HOME}/segfault
## Example: Germany:::<BLAHQCY26Tnz7KzDo9JPvBrzEzV+Z7RG1Hx/rXGgmH4=:::none:::10.65.13.37
#SF_MULLVAD_CONFIG=
#SF_HOST_MTU=1500
SF_TOR_IP=172.20.0.111
SF_NORDVPN_IP=172.20.0.254
SF_CRYPTOSTORM_IP=172.20.0.253

@ -246,10 +246,9 @@ ipt_set()
#
# The only way around this is to advertise a smaller MSS for TCP and hope for the best
# for all other protocols. Ultimately we need bad routers on the Internet to disappear.
# 1500 - 80 - 40
iptables -A FORWARD -i "${DEV_LG}" -o "${DEV_GW}" -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss $((SF_GUEST_MTU - 40))
iptables -A FORWARD -i "${DEV_LG}" -o "${DEV_GW}" -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1380
# Mode when TOR goes via VPN (rarely used)
iptables -A FORWARD -i "${DEV_GW}" -o "${DEV_GW}" -s "${TOR_IP}" -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss $((SF_GUEST_MTU - 40))
iptables -A FORWARD -i "${DEV_GW}" -o "${DEV_GW}" -s "${TOR_IP}" -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1380
# -----BEGIN DIRECT SSH-----
# Note: The IP addresses are FLIPPED because we use DNAT/SNAT/MASQ in PREROUTING

@ -154,8 +154,6 @@ warn_outdated()
load_env
[[ -z $SF_DATADIR ]] && SF_DATADIR="${SF_BASEDIR}/data"
[[ -z $SF_SHMDIR ]] && SF_SHMDIR="/dev/shm/sf"
[[ -z $SF_HOST_MTU ]] && SF_HOST_MTU=1500
export SF_GUEST_MTU=$((SF_HOST_MTU - 80))
[[ ! -d "${SF_DATADIR}/user" ]] && mkdir -p "${SF_DATADIR}/user"
[[ ! -d "${SF_DATADIR}/share" ]] && mkdir -p "${SF_DATADIR}/share"
@ -181,7 +179,6 @@ export SF_GUEST_MTU=$((SF_HOST_MTU - 80))
==> Generate your own list (see THC's Tips & Tricks).
==> Use ${CDC}touch ${SF_BASEDIR}/config/etc/relay-exit-nodes-global.txt${CN} to stop this warning."
}
chmod 644 "${SF_BASEDIR}/config/etc/relay-exit-nodes-global.txt" 2>/dev/null
[[ -z $SF_OVERLAYDIR ]] && [[ -d "${SF_BASEDIR}/docker/overlay2" ]] && export SF_OVERLAYDIR="${SF_BASEDIR}/docker/overlay2"