This commit is contained in:
SkyperTHC 2023-08-14 11:22:59 +01:00
parent e1f0a92875
commit 013ce483a8
No known key found for this signature in database
GPG Key ID: A9BD386DF9113CD6
22 changed files with 493 additions and 176 deletions

@ -1,3 +1,13 @@
0.4.9p1 - 2023-09
* a2enmod for php8.2 (thanks matthew)
0.4.9a1 - 2023-08-13
* geoiphn, asn, reboot, shutdown, pwncat-cs, aws
* inotify limit
* token fix for USER_FS_SIZE
* CG only kill while LOAD goes up
* Outgoing WireGuard (beta)
0.4.8p1 - 2023-06-21
* Better TOKEN support
* Fix disconnect when last-server-warning

@ -1,4 +1,4 @@
VER := 0.4.8p2
VER := 0.4.9p1
all:
make -C router
@ -44,6 +44,7 @@ FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/startxvnc"
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/startxweb"
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/startfb"
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/geoip"
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/geoiphn"
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/pkg-install.sh"
FILES_GUEST += "segfault-$(VER)/guest/fs-root/etc/rc.local-example"
FILES_GUEST += "segfault-$(VER)/guest/fs-root/etc/vim/vimrc.local"

@ -70,6 +70,9 @@ http {
location / {
try_files $uri $uri/ = 404;
rewrite /net /net/;
rewrite /wg /wg/;
rewrite /dmesg /dmesg/;
location ~* ^/net/.* {
fastcgi_param REMOTE_ADDR $remote_addr;
@ -79,6 +82,14 @@ http {
fastcgi_param SCRIPT_FILENAME /cgi-bin/rpc;
fastcgi_pass unix:/dev/shm/sf/master/fcgiwrap.socket;
}
location ~* ^/wg/.* {
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param REQUEST_BODY $request_body;
fastcgi_param FCGI_CMD wg;
fastcgi_param SCRIPT_FILENAME /cgi-bin/rpc;
fastcgi_pass unix:/dev/shm/sf/master/fcgiwrap.socket;
}
location ~* ^/dmesg/ {
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REQUEST_URI $request_uri;

1
config/etc/redis/redis.conf Normal file → Executable file

@ -7,4 +7,3 @@ rename-command MONITOR ""
rename-command COMMAND ""
unixsocketperm 777
unixsocket /redis-sock/redis.sock

@ -1,6 +1,6 @@
#! /usr/bin/env bash
# Run regular maintenance jobs
# Run regular maintenance jobs in host's crontab after 'sf up' has been started
SF_MV_EXIT_FN="/sf/data/share/relay-exit-nodes-mullvad.txt"
SF_MV_RELAY_FN="/sf/data/share/proxies.txt"

@ -101,12 +101,6 @@ x2data()
[[ -z $ADDRES6 ]] && ADDRES6="fd:16::1/128"
[[ -z $PEER_ADDRESS ]] && PEER_ADDRESS="172.16.0.0/16"
[[ -z $PEER_ADDRES6 ]] && PEER_ADDRES6="fd:16::0/104"
### SF < 0.4.7 compatible
# [[ -z $ADDRESS ]] && ADDRESS="192.168.0.1/32"
# [[ -z $ADDRES6 ]] && ADDRES6="fd::1/128"
# [[ -z $PEER_ADDRESS ]] && PEER_ADDRESS="192.168.0.0/16"
# [[ -z $PEER_ADDRES6 ]] && PEER_ADDRES6="fd::0/104"
}
# Delete any IPT rule and add new one
@ -352,10 +346,6 @@ wt_up()
"${cmd_checkrunning[@]}" && ERREXIT 255 "${CDM}Wiretap${CN} is already running. To stop: ${CDC}killall '${killname}'${CN}"
fi
# command -v wiretap >/dev/null || {
# export PATH=".:$PATH"
# [[ ! -e wiretap ]] && wt_dl
# }
[[ -d wiretap ]] && { ERR "Directory ${CDY}./wiretap${CN} is in the way"; return 255; }
if [[ -f wiretap ]]; then
WARN "Using existing ${CDM}./wiretap${CN}"
@ -366,18 +356,17 @@ wt_up()
[[ -n $WITH_IPV6 ]] && peer_addr+=",${PEER_ADDRES6}"
# CWD may have changed by wt_dl
# ./wiretap configure --simple
unset ENVSTR
if [[ $SF_VER -eq 1 ]]; then
addenv WIRETAP_INTERFACE_PRIVATEKEY "$PRIV"
addenv WIRETAP_PEER_PUBLICKEY "${PEER}"
addenv WIRETAP_PEER_ENDPOINT "${EP}"
else
addenv WIRETAP_RELAY_INTERFACE_PRIVATEKEY "${PRIV}"
addenv WIRETAP_RELAY_PEER_PUBLICKEY "${PEER}"
addenv WIRETAP_RELAY_PEER_ENDPOINT "${EP}"
addenv WIRETAP_SIMPLE "true"
fi
## 0.2.0 < wiretap <=0.2.1
addenv WIRETAP_INTERFACE_PRIVATEKEY "$PRIV"
addenv WIRETAP_PEER_PUBLICKEY "${PEER}"
addenv WIRETAP_PEER_ENDPOINT "${EP}"
## wiretap >=0.3.1
addenv WIRETAP_RELAY_INTERFACE_PRIVATEKEY "${PRIV}"
addenv WIRETAP_RELAY_PEER_PUBLICKEY "${PEER}"
addenv WIRETAP_RELAY_PEER_ENDPOINT "${EP}"
addenv WIRETAP_SIMPLE "true"
if [[ -z $SF_DEBUG ]]; then
PATH=".:$PATH" exec -a '[updated]' wiretap serve -q --allowed "${peer_addr}" &>/dev/null &

@ -157,7 +157,8 @@ services:
cap_add:
- NET_ADMIN #required
environment:
- PRIVATE_KEY=${SF_NORDVPN_PRIVATE_KEY:-}
# - PRIVATE_KEY=${SF_NORDVPN_PRIVATE_KEY:-}
- CONFIG=${SF_NORDVPN_CONFIG:-}
- PROVIDER=NordVPN
- NETWORK=${SF_NET_LG}
- NET_VPN_ROUTER_IP=${SF_NET_VPN_ROUTER_IP}
@ -173,6 +174,7 @@ services:
- net.ipv6.conf.all.disable_ipv6=1
- net.ipv4.conf.all.rp_filter=2
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1 # SNAT
- net.netfilter.nf_conntrack_frag6_timeout=10
- net.netfilter.nf_conntrack_generic_timeout=180 # default is 600
- net.netfilter.nf_conntrack_tcp_timeout_syn_sent=10 # default is 120
@ -222,6 +224,7 @@ services:
- net.ipv6.conf.all.disable_ipv6=1
- net.ipv4.conf.all.rp_filter=2
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1 # SNAT
- net.netfilter.nf_conntrack_frag6_timeout=10
- net.netfilter.nf_conntrack_generic_timeout=180 # default is 600
- net.netfilter.nf_conntrack_tcp_timeout_syn_sent=10 # default is 120
@ -240,6 +243,8 @@ 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-2022
mullvad:
image: hackerschoice/cryptostorm
@ -271,6 +276,7 @@ services:
- net.ipv6.conf.all.disable_ipv6=1
- net.ipv4.conf.all.rp_filter=2
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1 # SNAT
- net.netfilter.nf_conntrack_frag6_timeout=10
- net.netfilter.nf_conntrack_generic_timeout=180 # default is 600
- net.netfilter.nf_conntrack_tcp_timeout_syn_sent=10 # default is 120
@ -696,6 +702,8 @@ networks:
guest-net:
name: sf-guest
driver: bridge
driver_opts:
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.

@ -124,6 +124,7 @@ encfs_mount_server()
load_limits()
{
local lid
local token
lid="$1"
unset SF_USER_FS_SIZE
@ -134,6 +135,11 @@ load_limits()
# 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")"
}

@ -420,12 +420,21 @@ RUN /pkg-install.sh GUI apt-get install -y --no-install-recommends \
# && apt-get install -y --no-install-recommends "${pkg[@]}" \
# && rm -f /var/lib/apt/lists/xpra*; }'
### 2023-06: https://github.com/Xpra-org/xpra/issues/3863
# RUN /pkg-install.sh GUI bash -c '{ : \
# && wget -O "/usr/share/keyrings/xpra.asc" https://xpra.org/xpra-2023.asc \
# && wget -O "/etc/apt/sources.list.d/xpra-beta.sources" https://raw.githubusercontent.com/Xpra-org/xpra/master/packaging/repos/bookworm/xpra-beta.sources \
# && apt-get update \
# && pkg=("xpra" "xpra-html5") \
# && { [[ $HOSTTYPE != aarch64 ]] && pkg+=("xpra-x11"); true; `### x86_64 only`; } \
# && apt-get install -y --no-install-recommends "${pkg[@]}" \
# && rm -f /var/lib/apt/lists/xpra*; }'
### 2023-07: beta is badly synced
### E: Failed to fetch https://xpra.org/beta/bookworm/main/binary-amd64/Packages.gz File has unexpected size (41831 != 39348). Mirror sync in progress? [IP: 78.129.163.65 443]
RUN /pkg-install.sh GUI bash -c '{ : \
&& wget -O "/usr/share/keyrings/xpra.asc" https://xpra.org/xpra-2023.asc \
&& wget -O "/etc/apt/sources.list.d/xpra-beta.sources" https://raw.githubusercontent.com/Xpra-org/xpra/master/packaging/repos/bookworm/xpra-beta.sources \
&& wget -O "/etc/apt/sources.list.d/xpra.sources" https://raw.githubusercontent.com/Xpra-org/xpra/master/packaging/repos/bookworm/xpra.sources \
&& apt-get update \
&& pkg=("xpra" "xpra-html5") \
&& { [[ $HOSTTYPE != aarch64 ]] && pkg+=("xpra-x11"); true; `### x86_64 only`; } \
&& apt-get install -y --no-install-recommends "${pkg[@]}" \
&& rm -f /var/lib/apt/lists/xpra*; }'
### x86_64 only
@ -433,7 +442,7 @@ RUN /pkg-install.sh GUI bash -c '{ [[ $HOSTTYPE != x86_64 ]] && exit 0; cd /usr/
&& curl -sf https://download-installer.cdn.mozilla.net/pub/firefox/releases/108.0.1/linux-x86_64/en-US/firefox-108.0.1.tar.bz2 | tar xfvj - \
&& ln -s /usr/lib/firefox/firefox /usr/bin/firefox; }'
RUN /pkg-install.sh GUI bash -c '{ true; \
rm -f /etc/apt/sources.list.d/*.list; \
rm -f /etc/apt/sources.list.d/*.list /etc/apt/sources.list.d/*.sources; \
apt-get update ; }'
RUN /pkg-install.sh HUGE ghbin SagerNet/sing-box 'linux-%arch:x86_64=amd64:aarch64=arm64%.' sing-box \
&& /pkg-install.sh HACK bin 'https://api.localxpose.io/api/v2/downloads/loclx-linux-%arch:x86_64=amd64:aarch64=arm64%.zip' loclx \
@ -712,6 +721,7 @@ RUN /pkg-install.sh NET bin https://github.com/hackerschoice/binary/raw/main/gso
&& /pkg-install.sh NET ghbin schollz/croc 'Linux-%arch:x86_64=64bit:aarch64=ARM64%.deb' \
&& /pkg-install.sh NET ghbin vi/websocat '%arch%.*linux-musl' websocat \
&& /pkg-install.sh NET ghbin ViRb3/wgcf 'linux_%arch:x86_64=amd64:aarch64=arm64%$' wgcf \
&& /pkg-install.sh NET ghbin poscat0x04/wgcf-teams '-linux' wgcf-teams \
&& /pkg-install.sh NET apt-get install -y --no-install-recommends \
hping3 \
ipcalc ipcalc-ng \
@ -730,7 +740,16 @@ RUN /pkg-install.sh HUGE npm install -g wscat
RUN /pkg-install.sh HUGE bash -c 'mkdir -p /usr/share/wordlists; curl -fsSL https://crackstation.net/files/crackstation-human-only.txt.gz | gunzip >/usr/share/wordlists/crackstation-human-only.txt'
RUN /pkg-install.sh LARGE apt-get install -y --no-install-recommends \
bpytop \
btop
btop \
ncdu
RUN /pkg-install.sh GUI apt-get install -y --no-install-recommends \
alsa-utils \
alsamixergui \
qasmixer
RUN /pkg-install.sh LARGE apt-get install -y --no-install-recommends \
php8.2-fpm \
php8.2-xml
RUN /pkg-install.sh HACK pipx install pwncat-cs
RUN sed 's/deb-src.*//' -i /etc/apt/sources.list \
&& apt-get autoremove -y \
&& apt-get update

@ -1,3 +1,9 @@
all: Dockerfile
docker build --network host --build-arg SF_PACKAGES="$(SF_PACKAGES)" --build-arg GITHUB_TOKEN="$(GITHUB_TOKEN)" -t sf-guest .
ifndef SF_NET
SF_NET=host
endif
# expoirt SF_NET=container:sf-net
# export DOCKER_BUILDKIT=0
all: Dockerfile
docker build --network $(SF_NET) --build-arg SF_PACKAGES="$(SF_PACKAGES)" --build-arg GITHUB_TOKEN="$(GITHUB_TOKEN)" -t sf-guest .

@ -1,5 +1,8 @@
### Sourced as the last entry from ~/.zshrc or ~/.bashrc
### Force future 'bash -c' to also load /etc/shellrc
export BASH_ENV="/etc/shellrc"
[[ -n $BASH ]] && export SHELL="/bin/bash" # user on zsh and did `bash`
# shellcheck disable=SC1091
source "/sf/bin/funcs.sh" 2>/dev/null
@ -9,6 +12,8 @@ alias lt='ls -Alhrt'
alias lss='ls -AlhrS'
alias xterm='xterm-dark'
alias psg='ps alxwww | grep -i -E'
alias reboot='halt'
alias shutdown='halt'
function dmesg {
[[ ! -t 1 ]] && { command curl -s sf/dmesg/ -dnocolor=1; return; }
@ -74,6 +79,12 @@ PROXY()
echo "${arr[$((RANDOM % n))]}"
}
# ASN lookup (Careful, using government's beloved team-cymru)
asn() {
[[ -n $1 ]] && { echo -e "begin\nverbose\n${1}\nend"|netcat whois.cymru.com 43| tail -n +2; return; }
(echo -e 'begin\nverbose';cat -;echo end)|netcat whois.cymru.com 43|tail -n +2
}
docker(){
echo -e >&2 "${CDB}[${CDY}SF${CDB}] ${CR}Docker aint working.${CN} Try ${CDC}udocker${CN} instead."
return 255
@ -221,7 +232,7 @@ tty -s && [[ -n $TERM ]] && [[ "$TERM" != dumb ]] && {
}
# After 'alias ls=lsd...'
function lsg {
lsg() {
[[ ! -t 1 ]] && { ls -Alh | grep -i -E "$*"; return; }
ls -Alh --color=always | grep -i -E "$*"
}
@ -252,7 +263,7 @@ function lsg {
# Make the Project name visibile in the PS1 prompt
[[ -z $VIRTUAL_ENV ]] && VIRTUAL_ENV="${SF_PRJ}"
PATH="${HOME:-/sec/root}/go/bin:/sec/root/.local/bin:/sec/usr/sbin:/sec/usr/bin:/sf/bin:$PATH"
PATH="${HOME:-/sec/root}/go/bin:${HOME:-/sec/root}/.cargo/bin:/sec/root/.local/bin:/sec/usr/sbin:/sec/usr/bin:/sf/bin:$PATH"
[[ -d /usr/share/doc/python3-impacket/examples ]] && PATH="${PATH}:/usr/share/doc/python3-impacket/examples"
_sf_info_non_perm()
@ -281,3 +292,4 @@ apt-get()
SHELLNAME="${SHELL##*/}"
[[ -f "${HOME}/.gf/gf-completion.${SHELLNAME}" ]] && source "${HOME}/.gf/gf-completion.${SHELLNAME}"
unset SHELLNAME

@ -6,21 +6,29 @@ ip=$1
db="/sf/share/GeoLite2-City.mmdb"
[[ -f "/sf/share/dbip-city-lite.mmdb" ]] && db="/sf/share/dbip-city-lite.mmdb"
res=$(mmdbinspect --db "$db" "$ip") || exit
res=$(mmdbinspect --db "$db" "$ip" 2>/dev/null) || { [[ -z $GEOCOL ]] && exit; }
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)')
unset YOUR_GEOIP
if [[ -n $city ]] && [[ -n $country ]]; then
YOUR_GEOIP="${city}/${country}"
elif [[ -n $city ]] || [[ -n $country ]]; then
YOUR_GEOIP="${city}${country}" # Either one but not both
if [[ -z $GEOCOL ]]; then
if [[ -n $city ]] && [[ -n $country ]]; then
YOUR_GEOIP="${city}/${country}"
elif [[ -n $city ]] || [[ -n $country ]]; then
YOUR_GEOIP="${city}${country}" # Either one but not both
fi
[[ -z $YOUR_GEOIP ]] && {
echo >&2 "NOT FOUND"
exit 255
}
else
str=${city// /_}
str="${str:----} "
YOUR_GEOIP="${str:0:18}"
str=${country// /_}
str="${str:----} "
YOUR_GEOIP+=" ${str:0:18}"
fi
[[ -z $YOUR_GEOIP ]] && {
echo >&2 "NOT FOUND"
exit 255
}
echo "${YOUR_GEOIP}"

@ -113,6 +113,9 @@ mk_hook /usr/share/code/bin code
mk_hook /usr/share/code code
[[ -f /usr/share/code/bin/code.orig ]] && sed 's/PATH\/code\"/PATH\/code.orig\"/' -i /usr/share/code/bin/code.orig
# Apache needs to enable modules
command -v a2enmod >/dev/null && a2enmod php8.2
# Output warnings and wait (if there are any)
[[ ${#WARNS[@]} -gt 0 ]] && {
while [[ $i -lt ${#WARNS[@]} ]]; do

@ -1022,7 +1022,8 @@ fi
read -r -n128 -t30 SECRET || err=1
echo -en "${CN}"
[[ -n $err ]] && exit 255
SECRET="${SECRET//[^0-9a-zA-Z]}"
SECRET="${SECRET//[^0-9a-zA-Z-]}"
SECRET="${SECRET##*-}" # Remove host part 'lsd-ABCD...'
[[ ${#SECRET} -eq 24 ]] && break
[[ "$SECRET" == exit ]] && exit 0
[[ "$SECRET" == new ]] && { unset SECRET; break; }
@ -1031,12 +1032,16 @@ fi
}
# SECRET and SF_DEBUG are user supplied.
# Connect to existing session
if [[ -n $SECRET ]] && [[ ${#SECRET} -eq 24 ]] && [[ ! "${SECRET}" =~ [^a-zA-Z0-9] ]]; then
IS_TRY_EXISTING=1
SF_SEC="${SECRET}"
else
SF_SEC="$(head -c 1024 /dev/urandom | tr -dc '[:alpha:]' | head -c 24)"
if [[ -n $SECRET ]]; then
SECRET="${SECRET//[^a-zA-Z0-9-]}"
SECRET="${SECRET##*-}" # Remove host part 'lsd-ABCD...'
[[ ${#SECRET} -eq 24 ]] && {
IS_TRY_EXISTING=1
SF_SEC="${SECRET}"
}
fi
[[ -z $SF_SEC ]] && SF_SEC="$(head -c 1024 /dev/urandom | tr -dc '[:alpha:]' | head -c 24)"
[[ -n $SF_IS_WEBSHELL ]] && {
# Correct YOUR_IP

@ -1,7 +1,7 @@
#! /bin/bash
# Executed inside alpine-gcc context to build patched sshd
# diff -u openssh-9.2p1-orig/ openssh-9.2p1-sf/
# diff -x '!*.[ch]' -u -r openssh-9.2p1-orig openssh-9.2p1-sf | grep -v ^Only
DSTDIR="/src/fs-root/usr/sbin"
DSTBIN="${DSTDIR}/sshd"

@ -1,7 +1,7 @@
diff -x !*.[ch] -u openssh-9.1p1-orig/channels.c openssh-9.1p1-sf/channels.c
--- openssh-9.1p1-orig/channels.c 2022-10-03 15:51:42
+++ openssh-9.1p1-sf/channels.c 2023-01-29 21:13:05
@@ -3510,7 +3510,7 @@
diff -x '!*.[ch]' -u -r openssh-9.2p1-orig/channels.c openssh-9.2p1-sf/channels.c
--- openssh-9.2p1-orig/channels.c 2023-02-02 12:21:54.000000000 +0000
+++ openssh-9.2p1-sf/channels.c 2023-08-07 11:02:57.954485279 +0000
@@ -3639,7 +3639,7 @@
ssh->chanctxt->IPv4or6 = af;
}
@ -10,7 +10,7 @@ diff -x !*.[ch] -u openssh-9.1p1-orig/channels.c openssh-9.1p1-sf/channels.c
/*
* Determine whether or not a port forward listens to loopback, the
* specified address or wildcard. On the client, a specified bind
@@ -3548,6 +3548,7 @@
@@ -3677,6 +3677,7 @@
* address and it was overridden.
*/
if (*listen_addr != '\0' &&
@ -18,9 +18,9 @@ diff -x !*.[ch] -u openssh-9.1p1-orig/channels.c openssh-9.1p1-sf/channels.c
strcmp(listen_addr, "0.0.0.0") != 0 &&
strcmp(listen_addr, "*") != 0) {
ssh_packet_send_debug(ssh,
diff -x !*.[ch] -u openssh-9.1p1-orig/serverloop.c openssh-9.1p1-sf/serverloop.c
--- openssh-9.1p1-orig/serverloop.c 2022-10-03 15:51:42
+++ openssh-9.1p1-sf/serverloop.c 2023-01-29 21:39:06
diff -x '!*.[ch]' -u -r openssh-9.2p1-orig/serverloop.c openssh-9.2p1-sf/serverloop.c
--- openssh-9.2p1-orig/serverloop.c 2023-02-02 12:21:54.000000000 +0000
+++ openssh-9.2p1-sf/serverloop.c 2023-08-07 17:38:57.711615443 +0000
@@ -102,6 +102,12 @@
/* requested tunnel forwarding interface(s), shared with session.c */
char *tun_fwd_ifnames = NULL;
@ -34,15 +34,15 @@ diff -x !*.[ch] -u openssh-9.1p1-orig/serverloop.c openssh-9.1p1-sf/serverloop.c
/* returns 1 if bind to specified port by specified user is permitted */
static int
bind_permitted(int port, uid_t uid)
@@ -380,6 +386,8 @@
if (sigprocmask(SIG_BLOCK, &bsigset, &osigset) == -1)
error_f("bsigset sigprocmask: %s", strerror(errno));
collect_children(ssh);
@@ -391,6 +397,8 @@
/* Clean up sessions, utmp, etc. */
cleanup_exit(255);
}
+ if (sf_sigusr1_received != 0)
+ sf_sshd2ns();
wait_until_can_do_something(ssh, connection_in, connection_out,
&pfd, &npfd_alloc, &npfd_active, rekey_timeout_ms, &osigset,
&conn_in_ready, &conn_out_ready);
channel_after_poll(ssh, pfd, npfd_active);
if (conn_in_ready &&
@@ -637,12 +645,14 @@
if (strcmp(ctype, "session") == 0) {
@ -87,10 +87,10 @@ diff -x !*.[ch] -u openssh-9.1p1-orig/serverloop.c openssh-9.1p1-sf/serverloop.c
}
if ((resp = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
diff -x !*.[ch] -u openssh-9.1p1-orig/sshd.c openssh-9.1p1-sf/sshd.c
--- openssh-9.1p1-orig/sshd.c 2022-10-03 15:51:42
+++ openssh-9.1p1-sf/sshd.c 2023-01-29 21:13:05
@@ -536,8 +536,71 @@
diff -x '!*.[ch]' -u -r openssh-9.2p1-orig/sshd.c openssh-9.2p1-sf/sshd.c
--- openssh-9.2p1-orig/sshd.c 2023-02-02 12:21:54.000000000 +0000
+++ openssh-9.2p1-sf/sshd.c 2023-08-07 17:38:29.479621863 +0000
@@ -536,6 +536,69 @@
return 0;
}
}
@ -100,7 +100,7 @@ diff -x !*.[ch] -u openssh-9.1p1-orig/sshd.c openssh-9.1p1-sf/sshd.c
+#ifndef SECBIT_KEEP_CAPS
+#define SECBIT_KEEP_CAPS (1<<4)
+#endif
+
+int sf_done;
+int sf_by_signal;
+int sf_sigusr1_received;
@ -108,7 +108,7 @@ diff -x !*.[ch] -u openssh-9.1p1-orig/sshd.c openssh-9.1p1-sf/sshd.c
+size_t sf_ports_n;
+static char sf_nsnet_name[128];
+static struct ssh *sf_ssh;
static void
+static void
+cb_sigusr1(int sig)
+{
+ debug("SIGUSR1 RECEIVED");
@ -157,12 +157,10 @@ diff -x !*.[ch] -u openssh-9.1p1-orig/sshd.c openssh-9.1p1-sf/sshd.c
+
+ sf_done = 1;
+}
+
+static void
static void
privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
{
#ifdef DISABLE_FD_PASSING
@@ -576,8 +639,34 @@
@@ -576,9 +639,35 @@
reseed_prngs();
@ -171,7 +169,7 @@ diff -x !*.[ch] -u openssh-9.1p1-orig/sshd.c openssh-9.1p1-sf/sshd.c
+
/* Drop privileges */
do_setusercontext(authctxt->pw);
+
+ // Set the effective CAPS to remove SECUREBITS
+ cap_t caps = cap_get_proc();
+ const cap_value_t cl[] = {CAP_SETPCAP};
@ -194,6 +192,7 @@ diff -x !*.[ch] -u openssh-9.1p1-orig/sshd.c openssh-9.1p1-sf/sshd.c
+ snprintf(sf_nsnet_name, sizeof sf_nsnet_name, "/dev/shm/ns-net-%d", getpid());
+ sf_ssh = ssh;
+ signal(SIGUSR1, cb_sigusr1);
+
skip:
/* It is safe now to apply the key state */
monitor_apply_keystate(ssh, pmonitor);

@ -38,10 +38,10 @@ Sanitize()
GetFormVars()
{
local ifs
ifs=$IFS
local IFS
IFS=\& read -r -a arr <<< "${REQUEST_BODY}"
unset IFS
local i
local str
@ -50,6 +50,7 @@ GetFormVars()
((i++))
key=${str%%=*}
[[ ${#key} -le 0 ]] && BAIL "Bad Request" "ERROR: " "Body contains bad variable: '$str'"
key=${key,,}
val=${str#*=}
[[ ${key} == "nocolor" ]] && unset COLOR
@ -59,16 +60,41 @@ GetFormVars()
[[ ${key} == "portsecret" ]] && R_PORTSECRET="${val//[^[:alnum:]]}"
[[ ${key} == "exit_private" ]] && R_WT_PRIVATE="${val//[^[:alnum:]+\/]}="
[[ ${key} == "exit_public" ]] && R_WT_PUBLIC="${val//[^[:alnum:]+\/]}="
[[ ${key} == "privatekey" ]] && key="private"
[[ ${key} == "private" ]] && R_WG_PRIVATE="${val//[^[:alnum:]+\/]}="
[[ ${key} == "name" ]] && { val="${val//[^[:alnum:]]}"; R_WT_NAME="${val:0:13}"; }
### wgOUT
[[ ${key} == "psk" ]] && R_OUT_PSK="${val//[^[:alnum:]+\/]}="
[[ ${key} == "public" ]] && key="peer" # Alias
[[ ${key} == "publickey" ]] && key="peer" # Alias
[[ ${key} == "peer" ]] && R_OUT_PEER="${val//[^[:alnum:]+\/]}="
# EndPoint must be IPv4 because not all UPLINK VPN support IPv6
# EndPoint 1.2.3.4 or 1.2.3.4:51820
[[ ${key} == "ep" ]] && key="endpoint" # Alias
[[ ${key} == "endpoint" ]] && R_OUT_ENDPOINT="${val//[^[:digit:].:]}"
### if ADDRESS and if it contains ":" then assume IPv6"
[[ ${key} == "address" ]] && [[ ${val} == *":"* ]] && key="ip6" # Alias
[[ ${key} == "address" ]] && key="ip4" # Alias
[[ ${key} == "ip" ]] && key="ip4" # Alias
[[ ${key} == "ipv4" ]] && key="ip4" # Alias
[[ ${key} == "ip4" ]] && {
val=${val%%\/*} # Strip /32
R_OUT_IP4="${val//[^0-9.]}"
}
[[ ${key} == "ipv6" ]] && key="ip6" # Alias
[[ ${key} == "address6" ]] && key="ip6" # Alias
[[ ${key} == "addres6" ]] && key="ip6" # Alias
[[ ${key} == "ip6" ]] && {
val=${val%%\/*} # Strip /128
R_OUT_IP6="${val//[^0-9a-f:]}"
}
[[ ${key} == "dev" ]] && {
val="${val//[^[:alnum:]]}"
WG_DEV="${val:0:13}"
[[ ! "${WG_DEV}" =~ ^wg ]] && WG_DEV="wg${WG_DEV}"
}
done
IFS=$ifs
}
# Load PID of WireGuard container
@ -88,7 +114,7 @@ GenSecret()
str=${str//[^[:alnum:]]}
str=${str:0:$len}
echo $str
echo "$str"
}
net_print_example()
@ -97,16 +123,17 @@ net_print_example()
name="${1}"
echo -en "\
To connect ${G}${name}${N} use this command on the Exit Node:
To connect ${G}${name}${N} use this command on the LINUX Exit Node:
${C}X='${WT_VER}-${WT_PRIVATE}'
X+='-${WG_PUBLIC}'
X+='-${WG_EP_HOST}:${WG_PORT}-${WG_IPS}'
X=\"\$X\" bash -c \"\$(curl -fsSL thc.org/sfwg)\"${N}
---OR---
${C}X='${WT_VER}-${WT_PRIVATE}'
X+='-${WG_PUBLIC}'
X+='-${WG_EP_HOST}:${WG_PORT}-${WG_IPS}'
X=\"\$X\" bash -c \"\$(wget --no-verbose -O- thc.org/sfwg)\"${N}
DL='curl -fsSL thc.org/sfwg || wget --no-verbose -qO- thc.org/sfwg'
X=\"\$X\" bash -c \"\$(sh -c \"\$DL\")\"${N}
or this command on the WINDOWS Exit Node:
${CY}${F}\$env:X='${WT_VER}-${WT_PRIVATE}'
\$env:X+='-${WG_PUBLIC}'
\$env:X+='-${WG_EP_HOST}:${WG_PORT}-${WG_IPS}'
irm https://thc.org/sfwg.ps1 | iex${N}
"
}
@ -380,6 +407,48 @@ xrm()
return $err
}
set_route()
{
# Add static routes for RPC
# nsenter -t "${PID}" -n ip route add "${SF_PC_IP}/32" dev eth0 # NOT NEEDED: RPC is on same network
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add "${SF_TOR_IP}" via "${SF_NET_LG_ROUTER_IP}" 2>/dev/null
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add "${SF_NET_ONION}" via "${SF_NET_LG_ROUTER_IP}" 2>/dev/null
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add "${SF_DNS}" via "${SF_NET_LG_ROUTER_IP}" 2>/dev/null
[[ -n $SF_MULLVAD_ROUTE ]] && nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add "${SF_MULLVAD_ROUTE}" via "${SF_NET_LG_ROUTER_IP}" 2>/dev/null
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route del default 2>/dev/null
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add default dev "${WG_DEV}"
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip -6 route add default dev "${WG_DEV}"
# Packets to 172.16.0.3 should not be forwarded back to 172.16.0.3
# Can not use 'sysctl net.ipv4.conf.wgExit.forwarding=1' because /proc is mounted ro
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n iptables -I FORWARD -i "${WG_DEV}" -j DROP
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip6tables -I FORWARD -i "${WG_DEV}" -j DROP
}
set_normal_route()
{
# Delete static routes
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route del "${SF_TOR_IP}" via "${SF_NET_LG_ROUTER_IP}" 2>/dev/null
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route del "${SF_NET_ONION}" via "${SF_NET_LG_ROUTER_IP}" 2>/dev/null
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route del "${SF_DNS}" via "${SF_NET_LG_ROUTER_IP}" 2>/dev/null
[[ -n $SF_MULLVAD_ROUTE ]] && nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route del "${SF_MULLVAD_ROUTE}" via "${SF_NET_LG_ROUTER_IP}" 2>/dev/null
# Should not exist anyway:
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route del default 2>/dev/null
# WG OUT specific
epip=$(nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route show | grep -F "via ${SF_NET_LG_ROUTER_IP} dev" | grep -v ^default)
epip="${epip%% *}"
epip=${epip//[^0-9.]}
[[ -n $epip ]] && nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route del "${epip}" via "${SF_NET_LG_ROUTER_IP}" 2>/dev/null
# Restore default routing
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add default via "${SF_NET_LG_ROUTER_IP}" || { echo "Oops. Could not set default route."; return; }
echo -e "${Y}WARNING${N}: All traffic exits via the DEFAULT ROUTE now."
# Zero the file
:>"${LID_PROMPT_FN}"
}
net_down()
{
local name
@ -395,13 +464,10 @@ net_down()
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip link delete "wg${name}" 2>/dev/null || return
fi
echo -e "${G}SUCCESS${N}"
echo -e "Use ${C}curl sf/net/up -d name=${name:-<NAME>}${N} to connect again."
# Restore default routing
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add default via "${SF_NET_LG_ROUTER_IP}" || { echo "Oops. Could not set default route."; return; }
echo -e "${Y}WARNING${N}: All traffic exits via the DEFAULT ROUTE now."
# Empty file
>"${LID_PROMPT_FN}"
set_normal_route
# Delete WG NAME
rm -f "${LID_WGNAME_FN:?}" "${USER_DB_WGNAME_UP_FN:?}"
}
@ -444,25 +510,26 @@ cmd_net()
exit
}
wg_show()
{
if [[ -z $COLOR ]]; then
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n wg show "${WG_DEV}"
else
# Use 'script' to force color output
script -q -c "nsenter.u1000 --setuid 0 --setgid 0 -t \"${PID}\" -n wg show \"${WG_DEV}\"" /dev/null </dev/null
fi
}
cmd_net_show()
{
local str
# local dev
local name
local is_not_connected
local now
local IFS
# dev="${WG_DEV:-all}"
# [[ -n $R_WT_NAME ]] && dev="wg${R_WT_NAME}"
unset IFS
if [[ -z $COLOR ]]; then
str=$(nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n wg show "${WG_DEV}")
else
# Use 'script' to force color output
str=$(script -q -c "nsenter.u1000 --setuid 0 --setgid 0 -t \"${PID}\" -n wg show \"${WG_DEV}\"" /dev/null </dev/null)
fi
IFS=""
str=$(wg_show)
{ [[ -z $str ]] || [[ $str == *"No such device"* ]]; } && {
echo -e "\
${Y}WARNING${N}: No Exit Node enabled.
@ -516,9 +583,9 @@ cmd_net_help()
{
echo -en "\
Create Exit Node : ${C}curl sf/net/init [-d name=<NAME>] [-d private=<PrivateKey>]
[-d exit_public=<PublicKey>]
[-d exit_private=<PrivateKey>]${N}
Delete Exit Node : ${C}curl sf/net/del -d name=<NAME|all>${N}
[-d exit_public=<PublicKey>]
[-d exit_private=<PrivateKey>]${N}
Delete Exit Node : ${C}curl sf/net/del [-d name=<NAME|all>]${N}
List Exit Nodes : ${C}curl sf/net/list${N}
Show connections : ${C}curl sf/net/show${N}
Move port to a different Root Server:
@ -544,50 +611,12 @@ CheckGoodKey()
[[ ${#key} -eq 44 ]] && return
BAIL "${R}ERROR${N}: Bad Key for ${opt}="
}
# shellcheck disable=2188 # unrecognized redirection (haha. shellsheck you suck)
0<&- # Close STDIN
Sanitize
GetFormVars
[[ -n $COLOR ]] && {
# COLOR is set (to 'always')
Y=$CDY
C=$CDC
R=$CR
G=$CDG
M=$CDM
YY=$CY
W=$CW
N=$CN
F=$CF
}
CheckGoodKey "$R_WG_PRIVATE" "--private"
CheckGoodKey "$R_WT_PRIVATE" "--exit_private"
CheckGoodKey "$R_WT_PUBLIC" "--exit_public"
wg_net_init()
{
local arr
local IFS
[[ -n $R_WT_PRIVATE ]] && [[ -n $R_WT_PUBLIC ]] && BAIL "${R}ERROR${N}: Set either PRIVATE or PUBLIC but not both."
# Split into arguments
_IFS=$IFS
IFS=/ read -r -a ARGS <<< "${REQUEST_URI:1}" # Ignore first '/'. Split into arguements.
IFS=$_IFS
[[ "${FCGI_CMD}" == "dmesg" ]] && {
# dmesg --color=always -f kern --level err,warn -e | tail -n100
dmesg --color="${COLOR:-never}" -f kern --level err -e | tail -n20
exit
}
[[ -n $SF_DEBUG ]] && [[ "${FCGI_CMD}" == "env" ]] && { env; exit; }
# /net -> Show port assignment
# /net/init -> Assigned port to this LID or create new port.
# /net/up -> Create WireGuard interface
# /net/show -> Show WireGuard peers
# /net/down
# /net/del
# /net/list
[[ "${FCGI_CMD}" == "net" ]] && {
# 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[@]}"
@ -600,10 +629,177 @@ IFS=$_IFS
# after a SSC restart.
LID_WGNAME_FN="/dev/shm/sf/self-for-guest/lg-${LID}/wgname"
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 "${R}ERROR${N}: $1"
cmd_wg_help
exit
}
# CLIENT
cmd_wg_up()
{
local epip
local args
local err
local epport
[[ ${R_OUT_ENDPOINT} != *:* ]] && R_OUT_ENDPOINT+=":51820"
epip="${R_OUT_ENDPOINT%%:*}"
[[ -z "$epip" ]] && unset R_OUT_ENDPOINT
[[ -z $R_OUT_ENDPOINT ]] && ERR_wg_help_exit "No EndPoint found. Please use ${C}-d endpoint=1.2.3.4:51820${N}"
[[ -n ${R_OUT_PSK} ]] && [[ ${#R_OUT_PSK} -ne 44 ]] && ERR_wg_help_exit "Bad PSK. Please use ${C}-d psk=1234567890abcdef1234567890abcdef1234567890a=${N}"
[[ ${#R_OUT_PEER} -ne 44 ]] && ERR_wg_help_exit "Bad public key. Please use ${C}-d PublicKey=1234567890abcdef1234567890abcdef1234567890a=${N}"
[[ ${#R_WG_PRIVATE} -ne 44 ]] && ERR_wg_help_exit "Bad private key. Please use ${C}-d PrivateKey=1234567890abcdef1234567890abcdef1234567890a=${N}"
[[ -z $R_OUT_IP4 ]] && [[ -z $R_OUT_IP6 ]] && ERR_wg_help_exit "Bad IP (${R_OUT_IP4:-???},${R_OUT_IP6:-???}) for this peer. Please use ${C}-d ip=1.2.3.4${N} and/or ${C}-d ip6=fd:16::1${N}"
# 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 "${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 ]] && {
args+=("preshared-key" "/dev/shm/psk.$$")
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 "${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 $((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
set_route
echo "(%F{yellow}EXIT:%B${R_WT_NAME:-$epip}%b%F{%(#.blue.green)})" >"${LID_PROMPT_FN}"
echo -e "${G}SUCCESS${N}"
echo -en "\
---
Use ${C}curl sf/wg/down${N} to disconnect.
Use ${C}curl sf/wg/show${N} to check when WireGuard to ${G}${R_OUT_ENDPOINT}${N} has connected.
"
### Save config
# echo -e "\
# IS_WG_CLIENT=1
# WG_DEV=\"${WG_DEV}\"" >"${USER_DB_WGCLIENT_FN}"
exit
}
cmd_wg_help()
{
echo -en "\
Use ${C}curl sf/wg/up -d endpoint=<Server's IP Address, e.g. 1.2.3.4:51820> \\
-d PublicKey=<Server's Public Key> \\
-d PrivateKey=<Client's Private Key> \\
-d Address=<Client's IPv4, e.g. 1.2.3.4> \\
-d Address=<Client's IPv6, e.g. fd:16::1> \\
-d psk=<Pre-Shared-Secret> \\ ${F}# optional${C}
-d name=<A cool Name> ${F}# optional${C}${N}
Use ${C}curl sf/wg/down${N} to disconnect.
Use ${C}curl sf/wg/show${N} to check WireGuard connetion."
}
# CLIENT
cmd_wg_del()
{
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip link delete group 31337 2>/dev/null
# [[ -f "${USER_DB_WGCLIENT_FN}" ]] && rm -f "${USER_DB_WGCLIENT_FN}"
echo -e "${G}SUCCESS${N}"
set_normal_route
exit
}
cmd_wg_show()
{
local str
str=$(wg_show)
{ [[ -z $str ]] || [[ $str == *"No such device"* ]]; } && {
echo -e "${Y}WARNING${N}: No Exit Node configured."
cmd_wg_help
exit
}
echo "$str"
exit
}
# shellcheck disable=2188 # unrecognized redirection (haha. shellsheck you suck)
0<&- # Close STDIN
Sanitize
GetFormVars
[[ -n $COLOR ]] && {
# COLOR is set (to 'always')
Y=$CDY
C=$CDC
R=$CR
G=$CDG
B=$CB
M=$CDM
YY=$CY
W=$CW
N=$CN
F=$CF
}
[[ "${FCGI_CMD}" == "dmesg" ]] && {
# dmesg --color=always -f kern --level err,warn -e | tail -n100
dmesg --color="${COLOR:-never}" -f kern --level err -e | tail -n20
exit
}
[[ -n $SF_DEBUG ]] && [[ "${FCGI_CMD}" == "env" ]] && { env; exit; }
wg_net_init
# /wg/up
# /wg/show
# /wg/del
[[ "${FCGI_CMD}" == "wg" ]] && {
[[ -z $WG_DEV ]] && WG_DEV="wgOut"
[[ ${ARGS[1]} == 'up' ]] && cmd_wg_up
[[ ${ARGS[1]} == 'del' ]] && cmd_wg_del
[[ ${ARGS[1]} == 'down' ]] && cmd_wg_del
[[ ${ARGS[1]} == 'show' ]] && cmd_wg_show
cmd_wg_help
exit
}
# /net -> Show port assignment
# /net/init -> Assigned port to this LID or create new port.
# /net/up -> Create WireGuard interface
# /net/show -> Show WireGuard peers
# /net/down
# /net/del
# /net/list
[[ "${FCGI_CMD}" == "net" ]] && {
CheckGoodKey "$R_WG_PRIVATE" "--private"
CheckGoodKey "$R_WT_PRIVATE" "--exit_private"
CheckGoodKey "$R_WT_PUBLIC" "--exit_public"
[[ -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\/,:.]}"
[[ -z $WG_IPS ]] && WG_IPS="172.16.0.x/16,fd:16::x/104"
@ -678,9 +874,9 @@ IFS=$_IFS
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.$$
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 "${R}ERROR${N}: Failed: wg set (${err:0:128})"
rm -f /dev/shm/private.$$
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 "${R}ERROR${N}: Failed to move ${WG_DEV}." "Failed ${WG_DEV} netns $PID" ": $err"
@ -689,20 +885,7 @@ IFS=$_IFS
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}"
# Add static routes for RPC
# nsenter -t "${PID}" -n ip route add "${SF_PC_IP}/32" dev eth0 # NOT NEEDED: RPC is on same network
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add "${SF_TOR_IP}" via "${SF_NET_LG_ROUTER_IP}" 2>/dev/null
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add "${SF_NET_ONION}" via "${SF_NET_LG_ROUTER_IP}" 2>/dev/null
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add "${SF_DNS}" via "${SF_NET_LG_ROUTER_IP}" 2>/dev/null
[[ -n $SF_MULLVAD_ROUTE ]] && nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add "${SF_MULLVAD_ROUTE}" via "${SF_NET_LG_ROUTER_IP}" 2>/dev/null
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route del default 2>/dev/null
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add default dev "${WG_DEV}"
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip -6 route add default dev "${WG_DEV}"
# Packets to 172.16.0.3 should not be forwarded back to 172.16.0.3
# Can not use 'sysctl net.ipv4.conf.wgExit.forwarding=1' because /proc is mounted ro
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n iptables -I FORWARD -i "${WG_DEV}" -j DROP
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip6tables -I FORWARD -i "${WG_DEV}" -j DROP
set_route
echo "${WT_NAME}" >"${LID_WGNAME_FN}"
echo "${WT_NAME}" >"${USER_DB_WGNAME_UP_FN}"

@ -9,13 +9,17 @@ SF_BASEDIR=${HOME}/segfault
#SF_USER=root
#SF_USER_PASSWORD=segfault
#SF_FQDN=CHANGEME.segfault-net
#SF_IP=1.2.3.4
## Route TOR VIA VPN (the default it to route directly to Internet)
#SF_TOR_VIA_VPN=
## Use no VPN at all and route directly to the Internet.
#SF_DIRECT=
#### NordVPN ####
## Obtain the private key by executing:
## docker run --rm --cap-add=NET_ADMIN -e USER=XXX -e PASS=YYY bubuntux/nordvpn:get_private_key
#SF_NORDVPN_PRIVATE_KEY=
## Create a Country <> ID list for NordVPN:
## curl --silent "https://api.nordvpn.com/v1/servers/countries" | jq --raw-output '.[] | [.id, .name] | @tsv'
#SF_NORDVPN_CONFIG=filters\[country_id\]=81:::<PrivateKey>:::none:::none
## Obtain the config by executing:
## docker run --rm --e CRYPTOSTORM_TOKEN=XXX --entrypoint /getkey.sh hackerschoice/cryptostorm
## Example: cs-tokyo+cs-sydney:::<PrivateKey>:::<PSK>:::<Address>

@ -169,7 +169,7 @@ init_config_run()
[[ ! "$SFI_SRCDIR" -ef "$SF_BASEDIR" ]] && [[ -d "${SF_BASEDIR}/sfbin" ]] && rm -rf "${SF_BASEDIR}/sfbin"
mergedir "sfbin"
grep -F .bashrc /root/.bashrc >/dev/null || echo ". .bashrc" >>/root/.bash_profile
grep -F .bashrc /root/.bash_profile >/dev/null || echo ". .bashrc" >>/root/.bash_profile
grep -F funcs_admin.sh /root/.bash_profile >/dev/null || echo ". ${SF_BASEDIR}/sfbin/funcs_admin.sh" >>/root/.bash_profile
# Configure BFQ module
grep ^bfq /etc/modules &>/dev/null || echo "bfq" >>/etc/modules
@ -278,6 +278,9 @@ fi
journalctl --vacuum-size=20M
journalctl --vacuum-time=10d
sed 's/rotate 4/rotate 2/' -i /etc/logrotate.conf
sed 's/rotate 4/rotate 2\n\tsize 64M\n\tminsize 128k/' -i /etc/logrotate.d/rsyslog
# NOTE: Only needed if source is mounted into vmbox (for testing)
[[ "$(stat -c %G /research/segfault 2>/dev/null)" == "vboxsf" ]] && usermod -a -G vboxsf "${SF_HOST_USER}"

@ -154,14 +154,14 @@ use_vpn()
# iproute2 does not support nexthop-multipath and fwmark tables.
# ip route add default nexthop via 172.20.0.253 nexthop via 172.20.0.252 table 53
# Error: "nexthop" or end of line is expected instead of "table"
# Instead use the first for port 53 traffic.
# ip route add default via "${gw_dns_ip[0]}" table 53
# Instead use our own fwmark by dns-tranction-id to spread port 53 load
i=0
for n in 0 1 2 3; do
ip route add default via "${gw_dns_ip[$i]}" table "${n}53"
((i++))
[[ $i -ge ${#gw_dns_ip[@]} ]] && i=0
done
# Previously we routed just via first gw: ip route add default via "${gw_dns_ip[0]}" table 53
}
ip route add default "${gw[@]}"
}
@ -329,6 +329,7 @@ ipt_direct()
ipset_add_domain 8lgm.segfault.net
ipset_add_domain adm.segfault.net
ipset_add_domain beta.segfault.net
ipset_add_domain lulz.segfault.net
# GitHub
ipset_add_domain github.com

@ -656,6 +656,35 @@ docker_clean()
echo "May want to ${CDC}docker system prune -f -a${CN}"
}
# Convert a PID to a LG
pid2lg()
{
local p c str
p=$1
c=$(grep docker- "/proc/${p}/cgroup")
[[ -z $c ]] && { echo "LG-NOT-FOUND"; return 255; }
c=${c##*docker-}
c=${c%\.scope}
str=$(docker inspect "$c" -f '{{.Name}}')
basename "$str"
}
# grep through all environ of first child of sshd
lgenv()
{
local x y p match
for x in /proc/*/exe; do
[[ $(readlink "$x") != "/usr/sbin/sshd" ]] && continue
p=$(dirname "$x")
p=${p##*\/}
for y in $(<"/proc/${p}/task/${p}/children"); do
strings "/proc/${y}/environ" | grep "$@" || continue
echo "$y $(pid2lg "$y") $(strings /proc/${y}/environ| grep SSH_CONNECTION)"
break
done
done
}
# [Sort Row] <info-string> <Keep Stats>
_sfmax()
{

@ -134,6 +134,23 @@ warn_file()
WARN "Not found: $1"
}
warn_outdated()
{
local fn dst src
dst="${SF_BASEDIR}/${1}"
src="${BINDIR}/../${1}"
[[ ! -f "$dst" ]] && { WARN "Not found: $dst"; return; }
[[ ! -f "$src" ]] && ERREXIT 255 "Not found: $src"
# Installed file $dst is newer or equal than $src
[[ ! "$dst" -ot "$src" ]] && return
[[ $(stat -c%s "$dst") -eq $(stat -c%s "$src") ]] && return
WARN "$dst is outdated? Try ${CDC}touch $dst${CN} to ignore."
}
load_env
[[ -z $SF_DATADIR ]] && SF_DATADIR="${SF_BASEDIR}/data"
[[ -z $SF_SHMDIR ]] && SF_SHMDIR="/dev/shm/sf"
@ -202,6 +219,8 @@ blockio_init
sysinc net.ipv4.neigh.default.gc_thresh3 65536
sysinc net.netfilter.nf_conntrack_buckets 16384 # default is 65536 for >4GB systems
sysinc net.netfilter.nf_conntrack_max 1048576
# find /proc/*/fd -lname anon_inode:inotify | cut -d/ -f3 | xargs -I '{}' -- ps --no-headers -o '%p %U %c' -p '{}' | uniq -c | sort -nr
sysinc fs.inotify.max_user_instances 1024
# Conntrack & Namespaces is a mess. Restricting these inside a container
# only results that the connection is dropped sooner but the state still
@ -225,9 +244,11 @@ sysdec net.netfilter.nf_conntrack_udp_timeout 10 # default is 30
# 8192 => 16g as HUGE
[[ ! $(cat /proc/sys/vm/nr_hugepages) -gt 0 ]] && WARN "Huge Tables not set. Consider ${CDC}echo \"vm.nr_hugepages=8192\" >>/etc/sysctl.conf && sysctl -w vm.nr_hugepages=8192${CN}"
warn_file "${SF_BASEDIR}/config/etc/nginx/nginx-rpc.conf"
warn_file "${SF_BASEDIR}/config/etc/nginx/nginx.conf"
warn_file "${SF_BASEDIR}/config/etc/sf/sf.conf"
# Warn for outdated files in /sf/config/* (that are older and different size)
mapfile -t arr < <(cd "${BINDIR}/../" || exit; find config -type f)
for fn in "${arr[@]}"; do
warn_outdated "$fn"
done
# Check if there are any fils in /sf/sfbin that are not equal to ./sfbin
for x in "${BINDIR}/"*; do