mirror of
https://github.com/hackerschoice/thc-tips-tricks-hacks-cheat-sheet.git
synced 2026-01-08 23:38:07 -05:00
526 lines
17 KiB
Bash
Executable File
526 lines
17 KiB
Bash
Executable File
#! /usr/bin/env bash
|
|
|
|
# Usage:
|
|
# ======
|
|
# source <(curl -fsSL https://github.com/hackerschoice/thc-tips-tricks-hacks-cheat-sheet/raw/master/tools/ghostip.sh)
|
|
#
|
|
# A Linux tool to use a non existing IP address (aka GHOST-IP). It temporarily
|
|
# re-configures the current running shell: Any application started from that shell
|
|
# will use a Ghost-IP.
|
|
#
|
|
# A typical use case is to attack a target with nmap [et al.] from a host
|
|
# but using an IP address that is not assigned to that host.
|
|
# The nmap-scans will originate from the non-existing source IP (untraceable).
|
|
#
|
|
# Using it on a HOST/LAN-Spoofing: It uses an unused IP (aka Ghost-IP) from
|
|
# the LAN's network range. All traffic will originate from that Ghost-IP.
|
|
#
|
|
# Using it on a ROUTER/WAN-Spoofing: It uses 1.0.0.2 to access any workstation
|
|
# within the LAN. The workstation will see the traffic originating from
|
|
# 1.0.0.2, whereas it really originates from the router (e.g. nmap running on
|
|
# the router, not on the spoofed IP of 1.0.0.2).
|
|
#
|
|
# This tool will fail on some VPS providers (like AWS) which don't allow
|
|
# ghost-IPs (IPs not registered to the host).
|
|
#
|
|
# Practical Scenarios:
|
|
# ====================
|
|
# We have access to a workstation. We like to scan the internal
|
|
# network but without the target seeing our workstation's IP address.
|
|
#
|
|
# We have access to a router. We like to scan the internal network
|
|
# (or multiple internal networks) but without the target seeing
|
|
# that the scan comes from within the internal network (we make it appear
|
|
# as if coming from 1.0.0.2 - an external IP address).
|
|
#
|
|
# Notes:
|
|
# ======
|
|
# Ghost-route LAN & WAN traffic by default.
|
|
#
|
|
# GHOST_DEV=
|
|
# Optional. The network interface the Ghost IP will operate on.
|
|
#
|
|
# GHOST_IP=
|
|
# An unused IP address on the LAN. Used for hosts only (don't use on routers)
|
|
#
|
|
# GHOST_IP_WAN=
|
|
# An unused IP address on the WAN facing Interface (the default route).
|
|
# For HOSTS (not routers) this is a unused IP address on the LAN.
|
|
# Find an IP Address automatically if not set [default].
|
|
# -1 to disable WAN ghosting.
|
|
#
|
|
# GHOST_IP_LAN=
|
|
# The Ghost IP to use for traffic towards the LAN [default=1.0.0.2].
|
|
# Only needed when GhostIP is used on a ROUTER (which typically has
|
|
# a WAN interface as well as a LAN interface).
|
|
# If set to a LAN address then ghost a single LAN interface only.
|
|
# -1 to disable LAN ghosting.
|
|
#
|
|
# On a single host (not a router) only the GHOST_IP_WAN= is used.
|
|
#
|
|
# Simple Example for HOSTS:
|
|
# =========================
|
|
# Example 1: Use an unused Ghost-IP from this host:
|
|
# $ source ./ghostip.sh
|
|
#. $ GHOST_DEV=wg0 source ./ghostip.sh # Ghost towards specific interface
|
|
# Identical to:
|
|
# $ GHOST_IP=192.168.0.222 source ./ghostip.sh
|
|
# $ GHOST_IP_LAN=192.168.0.222 source ./ghostip.sh
|
|
# $ GHOST_IP_WAN=192.168.0.222 GHOST_IP_LAN=-1 source ./ghostip.sh
|
|
#
|
|
# Complex Examples for ROUTERS:
|
|
# =============================
|
|
# Example 2: Ghost-route traffic towards _all_ LANs,
|
|
# appearing from 1.0.0.2 [default]
|
|
# $ GHOST_IP_WAN=-1 source ./ghostip.sh
|
|
#
|
|
# Example 3: Ghost-route traffic towards _one_ specific LAN,
|
|
# appearing from 172.17.0.99 (an unused local LAN IP):
|
|
# $ GHOST_IP_WAN=-1 GHOST_IP_LAN=172.17.0.99 source ./ghostip.sh
|
|
#
|
|
# GHOST_NAME=update
|
|
# The name of the cgroup. Must not exist.
|
|
#
|
|
# GHOST_IPT=
|
|
# IPtables match of traffic that should be ghost-routed.
|
|
# This is really only needed if the host is NOT a ROUTER _and_
|
|
# the application is a proxy (like Wiretap, socks, gsnc, ..):
|
|
# It allows the application to connect back to the C2 but all other
|
|
# traffic by the application will be ghost-routed.
|
|
#
|
|
# Do not ghost the C2 traffic:
|
|
# GHOST_IPT="! -d 1.2.3.0/24"
|
|
# Only ghost TCP:
|
|
# GHOST_IPT="-p tcp"
|
|
#
|
|
# How it work:
|
|
# ============
|
|
# It creates a cgroup and iptable SNAT/DNAT rules for the cgroup. It then moves
|
|
# the current shell into the new cgroup. Any new program started from that shell
|
|
# will use the Ghost-IP.
|
|
#
|
|
# This script can be sourced/eval'ed or executed as BASH or ZSH script.
|
|
# Some ninja to make it work on ZSH & BASH:
|
|
# - Bash arrays start at index #0, Zsh at index #1.
|
|
# - Array expansion differs between Bash and Zsh.
|
|
# Try IFS="/" a=(${=HOME}) && echo "${#a[@]}" to understand.
|
|
#
|
|
# Some ideas stolen from novpn:
|
|
# https://gist.github.com/kriswebdev/a8d291936fe4299fb17d3744497b1170
|
|
|
|
if [ -n "$ZSH_EVAL_CONTEXT" ]; then
|
|
[[ "$ZSH_EVAL_CONTEXT" =~ :file$ ]] && sourced=1
|
|
else
|
|
(return 0 2>/dev/null) && sourced=1
|
|
fi
|
|
|
|
err() {
|
|
echo -e >&2 "${CDR}ERROR: ${CN}$*"
|
|
}
|
|
|
|
# Find the GW towards we like to ghost traffic
|
|
# For HOST-ghosting, the first parameter is the Ghost-IP (if known).
|
|
# Example: eth0 or wg0
|
|
ghost_find_gw() {
|
|
local ip="$1"
|
|
local arr
|
|
local IFS
|
|
local l
|
|
|
|
gw_dev="$GHOST_DEV"
|
|
[ -z "$gw_dev" ] && {
|
|
str=$(ip route show match "${ip:-1.1.1.1}")
|
|
str="${str##*dev }"
|
|
gw_dev="${str%% *}"
|
|
}
|
|
|
|
# Get the device IP:
|
|
l="$(ip addr show dev "$gw_dev" | grep -m1 'inet '))"
|
|
l="${l##*inet }"
|
|
l="${l%% *}"
|
|
gw_dev_ip="${l%%/*}"
|
|
}
|
|
|
|
ghost_find_other() {
|
|
local arr
|
|
local IFS
|
|
local d
|
|
local i
|
|
|
|
unset ghost_all_dev
|
|
unset ghost_all_dev_ip
|
|
|
|
[ "$GHOST_IP_LAN" == "-1" ] && return
|
|
|
|
# not not use "mapfile" because job-control is not always available on
|
|
# hacked shells (and thus /dev/fd/63 fails).
|
|
IFS=$'\n' arr=($(ip addr show))
|
|
for l in "${arr[@]}"; do
|
|
[[ "$l" =~ ^[0-9]+: ]] && {
|
|
unset d
|
|
unset i
|
|
[[ "$l" != *"state UP"* ]] && continue
|
|
[[ "$l" == *" master "* ]] && continue # Bridge master / veth
|
|
d="${l#*:}"
|
|
d="${d%%:*}"
|
|
d="${d// /}"
|
|
# Main Internet dev
|
|
[ "$d" == "$gw_dev" ] && unset d
|
|
[ "$d" == "lo" ] && unset d
|
|
continue
|
|
}
|
|
[ -z "$d" ] && continue
|
|
[[ "$l" == *"inet "* ]] && {
|
|
l="${l##*inet }"
|
|
i="${l%% *}"
|
|
i="${i%%/*}"
|
|
[ -z "$i" ] && continue
|
|
ghost_all_dev+=("$d")
|
|
ghost_all_dev_ip+=("$i")
|
|
unset d
|
|
}
|
|
done
|
|
}
|
|
|
|
ghost_find_single() {
|
|
local IFS
|
|
local l
|
|
local arr
|
|
|
|
unset single_dev single_dev_ip
|
|
[ -z "$ghost_ip" ] && return
|
|
IFS=$'\n' arr=($(ip route show match "${ghost_ip:?}"))
|
|
|
|
# Find the DEV for this IP
|
|
for l in "${arr[@]}"; do
|
|
[[ "$l" != *" scope link "* ]] && continue
|
|
single_dev="${l##*dev }"
|
|
single_dev="${single_dev%% *}"
|
|
single_dev_ip="${l##*link src }"
|
|
single_dev_ip="${single_dev_ip%% *}"
|
|
break
|
|
done
|
|
}
|
|
|
|
ghost_init() {
|
|
local IFS=" "
|
|
local classid="0xF0110011"
|
|
local ipt_cgroup="cgroup2"
|
|
|
|
[ -t 1 ] && {
|
|
CDR="\e[0;31m" # red
|
|
CDC="\e[0;36m" # cyan
|
|
CDY="\e[0;33m" # yellow
|
|
CY="\e[1;33m" # yellow
|
|
CDM="\e[0;35m" # magenta
|
|
CDG="\e[0;32m" # green
|
|
CF="\e[2m" # faint
|
|
CN="\e[0m" # none
|
|
}
|
|
|
|
[ -z "$UID" ] && UID=$(id -u)
|
|
[ "$UID" -ne 0 ] && { err "Must be root. Try ${CDC}sudo bash${CN} first."; return 255; }
|
|
|
|
command -v iptables >/dev/null || { err "iptables: command not found. Try ${CDC}apt install iptables${CN}"; return 255; }
|
|
_GHOST_NAME="${GHOST_NAME:-update}"
|
|
|
|
# Some iptables use '-m cgroup' when it should be '-m cgroup2'
|
|
# https://www.spinics.net/lists/netdev/msg352495.html
|
|
iptables -m "$ipt_cgroup" -h &>/dev/null || {
|
|
ipt_cgroup="cgroup"
|
|
iptables -m "$ipt_cgroup" -h &>/dev/null || { err "cgroup not supported by iptables [${CF}iptables -m cgroup -h${CN}]."; return 255; }
|
|
}
|
|
|
|
# Check for cgroup v1
|
|
cg_root="/sys/fs/cgroup/net_cls"
|
|
[ ! -f "${cg_root}/cgroup.procs" ] && cg_root="$(mount -t cgroup | grep net_cls | head -n1 | grep -oP '^cgroup on \K\S+')"
|
|
[ ! -f "${cg_root}/cgroup.procs" ] && unset cg_root
|
|
ipt_args=("-m" "cgroup" "--cgroup" "$classid")
|
|
|
|
# Check for cgroup v2
|
|
# First check if Userland tools support cgroup2
|
|
if iptables -m "$ipt_cgroup" --help 2>&1 | grep -m1 -q -- --path; then
|
|
cg_rootv2="/sys/fs/cgroup"
|
|
[ ! -f "${cg_rootv2}/cgroup.procs" ] && cg_rootv2="/sys/fs/cgroup/unified"
|
|
[ ! -f "${cg_rootv2}/cgroup.procs" ] && cg_rootv2="$(mount -t cgroup2 | head -n1 | grep -oP '^cgroup2 on \K\S+')"
|
|
[ ! -f "${cg_rootv2}/cgroup.procs" ] && unset cg_rootv2
|
|
[ -n "$cg_rootv2" ] && {
|
|
cg_root="${cg_rootv2}"
|
|
ipt_args=("-m" "$ipt_cgroup" "--path" "${_GHOST_NAME:?}")
|
|
}
|
|
else
|
|
[ -z "$cg_root" ] && {
|
|
err "iptables expect cgroup1 but kernel does not support cgroup1"
|
|
return 255
|
|
}
|
|
fi
|
|
|
|
# ZSH/BASH compat (see notes above)
|
|
ipt_args=($(echo "$GHOST_IPT") "${ipt_args[@]}")
|
|
[ -z "$cg_root" ] && { err "No cgroup v1 or v2 found. Not possible to isolate an app to a ghost-IP."; return 255; }
|
|
|
|
|
|
### DISABLED: Better to execute again so that to make ghost_down etc available.
|
|
# [ -d "${cg_root}/${_GHOST_NAME}" ] && {
|
|
# echo -e "\
|
|
# Ghost IP already exists.
|
|
# --> To ghost-route new connections of an already running process:
|
|
# ${CDC}"'echo "<PID>" >"'"${cg_root:?}/${_GHOST_NAME}/cgroup.procs"'"'"${CN}"
|
|
# return 255
|
|
# }
|
|
|
|
mkdir -p "${cg_root}/${_GHOST_NAME}" 2>/dev/null
|
|
[ -z "$cg_rootv2" ] && echo "$classid" >"${cg_root}/${_GHOST_NAME}/net_cls.classid"
|
|
return 0
|
|
}
|
|
|
|
# Add rule if not exist yet
|
|
iptnat() {
|
|
local IFS
|
|
local ins="$1"
|
|
shift 1
|
|
|
|
unset IFS
|
|
GHOST_UNDO_CMD+=("iptables -t nat -D $*")
|
|
iptables -t nat -C "$@" 2>/dev/null && return
|
|
iptables -t nat "$ins" "$@" || return
|
|
}
|
|
|
|
if command -v arp >/dev/null; then
|
|
is_arp_bad() { [[ "$(arp -n "$1")" == *"incomplete"* ]] && return; }
|
|
else
|
|
is_arp_bad() {
|
|
local str="$(ip neig sh "$1")"
|
|
[[ "$str" == *"INCOMPLETE"* ]] && return
|
|
[[ "$str" == *"FAILED"* ]] && return
|
|
}
|
|
fi
|
|
|
|
# Find an unused IP Address on the LAN interface.
|
|
ghost_find_local() {
|
|
local arr
|
|
local IFS
|
|
local str
|
|
local cidr
|
|
local dev="${1:?}"
|
|
local mode="${2}"
|
|
local range ipn ipc i1 i2 i3 i4
|
|
|
|
IFS=" " arr=($(ip addr show dev "${dev:?}" | grep -m1 -F " inet "))
|
|
str="${arr[@]:1:1}" # zsh & bash compat
|
|
cidr=${str##*/}
|
|
|
|
# Ensure it's a number
|
|
cidr=$((cidr + 0))
|
|
[ "$cidr" -lt 8 ] && cidr=8
|
|
# Some hosts use /32 even when /24 are available.
|
|
[ "$cidr" -ge 30 ] && cidr=24
|
|
|
|
range="$((2**(32-cidr)))"
|
|
# Limit range to nearest 256 (if larger)
|
|
# E.g. when 10.0.0.0/8 is used but practically only 10.0.0.1-10.0.0.254 look genuine
|
|
[ "$range" -gt 512 ] && range=512
|
|
|
|
IFS=. read -r i1 i2 i3 i4 <<< "${str%%/*}"
|
|
ipa=$((i1 * 2**24 + i2 * 2**16 + i3*2**8 + i4))
|
|
|
|
# IP Network (start)
|
|
ipn="$(( (ipa / range) * range))"
|
|
|
|
# First and Last IP are not valid _and_ dont try .1 and .254
|
|
((range-=4))
|
|
|
|
for n in {0..10}; do
|
|
ipc=$((ipn + RANDOM % range + 2))
|
|
ghost_ip="$((ipc / 2**24)).$(( (ipc % 2**24) / 2**16)).$(( (ipc % 2**16) / 2**8)).$(( ipc % 2**8 ))"
|
|
ping -c2 -i1 -W2 -w2 -A -q "$ghost_ip" &>/dev/null || {
|
|
# Cannot ping. Check if ARP is bad as well and only then is it an unused IP.
|
|
is_arp_bad "$ghost_ip" && break
|
|
}
|
|
unset ghost_ip
|
|
done
|
|
[ -z "$ghost_ip" ] && return
|
|
echo -e "--> Using unused IP ${CDY}${ghost_ip}${CN}. Set ${CDC}GHOST_IP_${mode}=<IP>${CN} otherwise."
|
|
}
|
|
|
|
# orig-ip new-ip device
|
|
ghost_print() {
|
|
local dev="$3 "
|
|
local ip="$2 "
|
|
echo -e "[${CDG}$4${CN}] ${CDM}Traffic leaving ${CDG}${dev:0:12}${CDM} will now appear as ${CY}${ip:0:16} ${CDY}${CF}[not $1]${CN}"
|
|
}
|
|
|
|
# ghost_single [LAN,WAN]
|
|
ghost_single() {
|
|
local mode="$1"
|
|
[ -z "$single_dev" ] && return 255
|
|
[ -z "$single_dev_ip" ] && return 255
|
|
|
|
[ -n "$ghost_ip" ] && [ -z "$single_dev" ] && { err "${CDC}GHOST_IP_${mode}=${CN} must be a local IP address [not ${ghost_ip}]"; return; }
|
|
[ -z "$ghost_ip" ] && ghost_find_local "$single_dev" "$mode"
|
|
[ -z "$ghost_ip" ] && {
|
|
err "Set ${CDC}export GHOST_IP_${mode}=<IP>${CN} to a local and unused IP Address."
|
|
return 255
|
|
}
|
|
|
|
iptnat -I POSTROUTING -o "${single_dev:?}" -m state --state NEW,ESTABLISHED "${ipt_args[@]}" -j SNAT --to "${ghost_ip:?}" || { is_error=1; return; }
|
|
# NO longer needed because we used -m state for outgoing.
|
|
# iptnat -I PREROUTING -i "${single_dev:?}" -d "${ghost_ip}" -m state --state ESTABLISHED,RELATED -j DNAT --to "${single_dev_ip:?}"
|
|
|
|
# Block anyone connecting to our Ghost-IP:
|
|
# We dont want to show in the INPUT chain. Instead route all invalid to 255.255.255.255 (linux will drop them):
|
|
iptnat -I PREROUTING -i "${single_dev}" -d "${ghost_ip}" -m state --state NEW -j DNAT --to 255.255.255.255
|
|
|
|
# We must respond to ARP request to our Ghost-IP. The simplest is to add
|
|
# the Ghost-IP to the same network interface. An alternative would be to
|
|
# use "arp -i eth0 -Ds ${ghost_ip} eth0"
|
|
ip addr add "${ghost_ip}/32" dev "${single_dev}" 2>/dev/null
|
|
|
|
GHOST_UNDO_CMD+=("ip addr del ${ghost_ip}/32 dev ${single_dev}")
|
|
ghost_print "${single_dev_ip}" "${ghost_ip}" "${single_dev}" "$mode"
|
|
return 0
|
|
}
|
|
|
|
ghost_lan() {
|
|
local n
|
|
local d
|
|
local ghost_ip
|
|
local devip
|
|
|
|
[ -n "$GHOST_IP_LAN" ] && {
|
|
ghost_ip="${GHOST_IP_LAN}"
|
|
ghost_find_single
|
|
ghost_single "LAN"
|
|
return
|
|
}
|
|
|
|
ghost_find_other
|
|
[ ${#ghost_all_dev[@]} -le 0 ] && return
|
|
|
|
# We like to keep the IPT rules to a min. Thus can't use connmark. Instead
|
|
# pick a Ghost-IP that is not essential.
|
|
# ghost_ip_default="104.17.25.14" # cdnjs.cloudflare.com
|
|
ghost_ip="${GHOST_IP_LAN:-1.0.0.2}"
|
|
|
|
iptnat -I POSTROUTING ! -o "${gw_dev:?}" -m state --state NEW,ESTABLISHED "${ipt_args[@]}" -j SNAT --to "${ghost_ip:?}" || { is_error=1; return; }
|
|
n=0
|
|
for d in "${ghost_all_dev[@]}"; do
|
|
devip="${ghost_all_dev_ip[@]:$n:1}"
|
|
ghost_print "${devip}" "${ghost_ip}" "${d}" "LAN"
|
|
iptnat -I PREROUTING -i "${d}" -d "${ghost_ip}" -m state --state ESTABLISHED,RELATED -j DNAT --to "${devip}"
|
|
((n++))
|
|
done
|
|
iptnat -I PREROUTING -d "${ghost_ip}" -m state --state NEW -j DNAT --to 0.0.0.0
|
|
|
|
return 0
|
|
}
|
|
|
|
|
|
ghost_down() {
|
|
local c
|
|
|
|
[ -n "$GHOST_PS_BAK" ] && PS1="$GHOST_PS_BAK"
|
|
unset GHOST_PS_BAK
|
|
|
|
[ "${#GHOST_UNDO_CMD[@]}" -le 0 ] && return
|
|
for c in "${GHOST_UNDO_CMD[@]}"; do
|
|
eval "$c" &>/dev/null
|
|
done
|
|
unset GHOST_UNDO_CMD
|
|
unset -f ghost_down
|
|
}
|
|
|
|
ghost_up2() {
|
|
local ghost_ip
|
|
|
|
ghost_find_gw "${GHOST_IP}" || return
|
|
|
|
[ -n "$GHOST_IP" ] && ghost_ip="$GHOST_IP"
|
|
[ -z "$GHOST_IP" ] && [ -z "$GHOST_IP_LAN" ] && [ -z "$GHOST_IP_WAN" ] && {
|
|
# HERE: No parameters set. HOST only. Find a Ghost-IP automatically.
|
|
[ -z "$ghost_ip" ] && {
|
|
ghost_find_local "$gw_dev" "WAN"
|
|
[ -z "$ghost_ip" ] && { err "No unused IP found. Set ${CDC}GHOST_IP=<IP>${CN}"; is_error=1; return; }
|
|
}
|
|
}
|
|
|
|
### LAN
|
|
[ -z "$ghost_ip" ] && [ "$GHOST_IP_LAN" != "-1" ] && { ghost_lan || return; }
|
|
|
|
[ "${GHOST_IP_WAN}" == "-1" ] && return
|
|
|
|
### WAN + HOST
|
|
ghost_ip="${GHOST_IP_WAN:-$ghost_ip}"
|
|
single_dev="$gw_dev"
|
|
single_dev_ip="$gw_dev_ip"
|
|
|
|
ghost_single "WAN"
|
|
return 0
|
|
}
|
|
|
|
ghost_up() {
|
|
local is_error
|
|
|
|
ghost_down
|
|
ghost_up2
|
|
|
|
[ -n "$is_error" ] && {
|
|
ghost_down
|
|
[ -n "$sourced" ] && unset -f ghost_down
|
|
err "Oops. This did not work..."
|
|
return
|
|
}
|
|
|
|
# We cant exit yet if LAN or WAN was a success.
|
|
if [ "${#GHOST_UNDO_CMD[@]}" -le 0 ]; then
|
|
err "No WAN/LAN found. Check ${CDC}GHOST_IP_WAN=${CN} and ${CDC}GHOST_IP_LAN=${CN}."
|
|
return
|
|
fi
|
|
|
|
[ -n "$GHOST_IPT" ] && echo -e "Traffic matching: ${CDG}${GHOST_IPT}${CN}"
|
|
|
|
if [ -n "$sourced" ]; then
|
|
echo "$$" >"${cg_root:?}/${_GHOST_NAME}/cgroup.procs"
|
|
[[ "$PS1" != *$'\n'* ]] && {
|
|
GHOST_PS_BAK="$PS1"
|
|
PS1="${PS1//\\h/\\h-GHOST}"
|
|
[ "$PS1" == "$GHOST_PS_BAK" ] && unset GHOST_PS_BAK
|
|
}
|
|
# sfwg support
|
|
[ -z "$TYPE" ] && {
|
|
export TYPE="wiretap"
|
|
GHOST_UNDO_CMD+=("unset TYPE")
|
|
}
|
|
echo -e "\
|
|
--> Your current shell (${SHELL##*/}/$$) and any further process started
|
|
from this shell are now ghost-routed.
|
|
--> To ghost-route new connections of an already running process:
|
|
${CDC}"'echo "<PID>" >"'"${cg_root:?}/${_GHOST_NAME}/cgroup.procs"'"'"${CN}
|
|
To UNDO type ${CDC}ghost_down${CN} or:${CF}"
|
|
[ -n "$GHOST_PS_BAK" ] && echo "PS1='$GHOST_PS_BAK'"
|
|
else
|
|
echo -e "\
|
|
--> To ghost-route the current shell and all processes started from
|
|
this shell:
|
|
${CDC}"'echo "$$" >"'"${cg_root:?}/${_GHOST_NAME}/cgroup.procs"'"'"${CN}
|
|
--> To ghost-route new connections of an already running process:
|
|
${CDC}"'echo "<PID>" >"'"${cg_root:?}/${_GHOST_NAME}/cgroup.procs"'"'"${CN}
|
|
To UNDO type:${CF}"
|
|
fi
|
|
|
|
for c in "${GHOST_UNDO_CMD[@]}"; do
|
|
echo "$c";
|
|
done
|
|
[ -n "$sourced" ] && echo "unset GHOST_UNDO_CMD GHOST_PS_BAK TYPE"
|
|
echo -en "${CN}"
|
|
unset _GHOST_NAME
|
|
}
|
|
|
|
|
|
ghost_init && \
|
|
ghost_up
|
|
|
|
[ -n "$sourced" ] && {
|
|
unset -f ghost_init ghost_up ghost_up2 ghost_single ghost_lan ghost_print ghost_find_gw ghost_find_other ghost_find_single ghost_find_local iptnat is_arp_bad
|
|
unset ghost_all_dev ghost_all_dev_ip gw_dev gw_dev_ip single_dev single_dev_ip ipt_args cg_root cg_rootv2 _GHOST_NAME
|
|
} |