TailScale On Containers (All CAPS & PRIVS)

TailScale On Containers (All CAPS & PRIVS)

Using TailScale on anything & everything (with/without Systemd/Init), no matter the privileges (Root | No Root | UserSpace) or capabilities (CAP_*)

·

3 min read

🔰 Always UpDated Article: https://ajam.notion.site/TailScale-b5ce8cf95446468784c7ac8a274be2d2 ⬅️

Q. Will TailScale run?

!# Check & Enum Privs
❯ caps
# Reference: https://man7.org/linux/man-pages/man7/capabilities.7.html
# Explainer: https://blog.container-solutions.com/linux-capabilities-in-practice
# Additional Reads: https://tbhaxor.com/understanding-linux-capabilities/
#                 : https://madhuakula.com/content/attacking-and-auditing-docker-containers-and-kubernetes-clusters/attacking-docker-containers/capabilities.html
#    Effective capabilities (e): capabilities that are currently usable in the current process.
#    Permitted capabilities (p): capabilities that may be "activated" in the current process.
#    Inheritable capabilities (i): file capabilities that may be inherited.
ROOT: CAP_SYS_ADMIN
GOOD TO HAVES: CAP_NET_ADMIN
Required: CAP_NET_RAW # Without this, you probably can't initiate connections & tailscale likely won't work
Error: socket: Operation not permitted # Can test this with ping, if have setcap/setuid perms, this shouldn't be an issue
# CAP_SYS_ADMIN --> If this is set, you don't need to worry about anything (Basically root at this poinnt)
# CAP_NET_ADMIN  --> Basically do anything in terms of networking at least
# CAP_NET_RAW --> •  Use RAW and PACKET sockets || •  bind to any address for transparent proxying.
# CAP_NET_BIND_SERVICE (May exist without CAP_NET_RAW) --> Allows to bind a socket to a port (example: python server on localhost:80)
#---------------------------------------------------------------------------#
#-------#
!# capsh: This should be installed on most systems (ideally a part of libcap: https://command-not-found.com/capsh)
# if it's not and you can't install it (No Root | Limited Privs) proceed to the next method
# Note: If you have root, running this from a root shell will output different results
# Ref: https://unix.stackexchange.com/questions/571028/what-does-capsh-print-actually-do
capsh --print
# Anything with `!` means it's not allowed/excluded/not-set
# Current: shows the current capabilities held by the process
# Bounding set : bounding capabilities of a process, Defines Upper Limits (Basically how much privs the current sessio/user can have)
# Ambient set: ambient capabilities (inherited capabilities) that a process can pass on to its child processes
# Current IAB : Usually lists all the caps you don't have & thing's you can't do
#---------#
!# setpriv: If capsh isn' installed and you can't install it (You don't have root access or are very restricted)
setpriv --dump
# Capability bounding set: Look here for all the caps you can have
#---------------------------------------------------------------------------#

❯ Privileges
#---------------------------------------------------------------------------#
!# This command checks the process with PID 1 (the first process started by the kernel, which is typically the init process) and retrieves its command name.
# If it says systemd etc, you don't need to use --tun="userspace-networking" , else if it shows docker-init , you have to use it
ps -p 1 -o comm=
!# Another alternative way would be to:
cat "/proc/1/cmdline"
# If it shows: /sbin/init , you don't need to use --tun="userspace-networking", else if it shows /sbin/docker-init , you have to use it
#---------------------------------------------------------------------------#

#---------------------------------------------------------------------------#
❯ Root Checks
# If you have don't have root access then,You will need to use a temp socket
if [ "$(id -u)" = 0 ]; then
  echo -e "\n[+] Root Access : ✓"
  echo -e "[+] Current SHELL Session is already Elevated\n"
# Check if 'sudo' is available and executable
elif command -v sudo &>/dev/null; then
  # Check if 'sudo' is passwordless for the current user
  if sudo -n true 2>/dev/null; then
    echo -e "\n[+] Sudo Available : ✓"
    echo -e "[+] Current User has Passwordless Sudo\n"
  else
    echo -e "\n[+] Sudo Available : ✓"
    echo -e "[+] Current User must Enter Sudo Password\n"
  fi
# Check if 'doas' is available and executable
elif command -v  doas &>/dev/null && doas -v; then
     echo -e "\n[+] doas Available : ✓"
fi
#---------------------------------------------------------------------------#