SSH
如何在VKUBE中使用shell/ssh远程连接功能
Tool Injection
VKUBE
提供注入工具
的功能,具体可以参考Tool Injection.
使用此功能,用户目前可以选择三个工具:
sshd:sshd(Secure Shell Daemon)是 OpenSSH 提供的 SSH 服务器进程,允许远程用户通过 SSH 协议安全地连接到 Linux 服务器。
ttyd:ttyd 是一个可以将命令行终端(TTY)通过 WebSocket 映射到网页的工具,使得用户可以通过浏览器访问服务器终端。
rsync:rsync(Remote Sync)是一个高效的远程同步工具,可用于本地和远程文件同步,支持增量复制和压缩传输。
VKUBE
将会根据不同的用户选择做出以下的配置:
选择sshd:
VKUBE
将会帮助用户在指定的某一个container中,下载并运行sshd,sshd只能通过public key
/private key
的形式进行验证加密,public key
将会写入container的环境变量当中。此后,用户容器就会启动sshd,而用户可以通过ssh登录用户所指定的容器。选择ttyd:
VKUBE
将会帮助用户在指定的某一个container中,下载并运行ttyd,ttyd将会启动一个web网页形式的程序,可以让用户在网页上连接到对应的container上,用户需要用户填写用户名和密码,并且密码需要满足:至少一个大写字母,至少一个小写字母,至少一个数字,至少一个特殊字符。选择rsync:需要启用
sshd
才可以启用,VKUBE
将会帮助用户在指定的某一个container中,下载并使用rsync。
下载并运行会通过以下脚本的执行得到。注意:VKUBE
会尽力帮助用户下载和运行sshd,但是目前的测试当中比较新版本的ubuntu和apline、Debian为基础的镜像是合适的,其他的linux发行版操作系统有可能会不成功。而在Debian中,ttyd的下载是不行的。
Image customization
用户也可以在创建镜像的时候,自己进行启动sshd,例如以ubuntu基础镜像为主:
RUN /bin/sh -c service ssh start # buildkit
RUN /bin/sh -c echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config # buildkit
RUN /bin/sh -c echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config # buildkit
RUN /bin/sh -c echo "PasswordAuthentication no" >> /etc/ssh/sshd_config # buildkit
RUN apt-get update \
&& apt-get install -y openssh-server \
&& cp /etc/ssh/sshd_config /etc/ssh/sshd_config-original \
&& sed -i 's/^#\s*Port.*/Port 2222/' /etc/ssh/sshd_config \
&& sed -i 's/^#\s*PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config \
&& mkdir -p /root/.ssh \
&& chmod 700 /root/.ssh \
&& mkdir /var/run/sshd \
&& chmod 755 /var/run/sshd \
&& rm -rf /var/lib/apt/lists /var/cache/apt/archives
当然也可以直接使用我们的脚本拷贝到镜像当中,在docker build的时候直接执行并下载。
脚本
#!/bin/sh
# Check for root privileges
if [ "$(id -u)" -ne 0 ]; then
echo "This script must be run as root" >&2
exit 1
fi
# Function to get the correct package name for a tool based on the package manager
get_package_name() {
local tool="$1"
case "$tool" in
openssh)
case "$PACKAGE_MANAGER" in
apt) echo "openssh-server" ;;
dnf|yum) echo "openssh-server" ;;
pacman) echo "openssh" ;;
zypper) echo "openssh" ;;
apk) echo "openssh" ;;
emerge) echo "net-misc/openssh" ;;
*) echo "$tool" ;; # Default to the original name if unrecognized
esac
;;
rsync)
case "$PACKAGE_MANAGER" in
apt) echo "rsync" ;;
dnf|yum) echo "rsync" ;;
pacman) echo "rsync" ;;
zypper) echo "rsync" ;;
apk) echo "rsync" ;;
emerge) echo "net-misc/rsync" ;;
*) echo "$tool" ;;
esac
;;
ttyd)
echo "ttyd"
;;
# Add more tools here if needed
*)
echo "$tool" # Default to the original name
;;
esac
}
# Function to determine the package manager, update repositories, and install the specified package
determine_package_manager() {
# Check if /etc/os-release exists
if [ ! -f /etc/os-release ]; then
echo "Cannot determine the OS. /etc/os-release file not found." >&2
exit 1
fi
# Source the /etc/os-release file to get OS information
. /etc/os-release
# Initialize variables
PACKAGE_MANAGER=""
# Determine package manager based on ID and ID_LIKE
case "$ID" in
ubuntu|debian)
PACKAGE_MANAGER="apt"
;;
fedora)
PACKAGE_MANAGER="dnf"
;;
centos|rhel)
if command -v dnf >/dev/null 2>&1; then
PACKAGE_MANAGER="dnf"
else
PACKAGE_MANAGER="yum"
fi
;;
arch)
PACKAGE_MANAGER="pacman"
;;
opensuse*|suse)
PACKAGE_MANAGER="zypper"
;;
alpine)
PACKAGE_MANAGER="apk"
;;
gentoo)
PACKAGE_MANAGER="emerge"
;;
*)
if [ -n "$ID_LIKE" ]; then
case "$ID_LIKE" in
*debian*)
PACKAGE_MANAGER="apt"
;;
*rhel*|*fedora*)
if command -v dnf >/dev/null 2>&1; then
PACKAGE_MANAGER="dnf"
else
PACKAGE_MANAGER="yum"
fi
;;
*arch*)
PACKAGE_MANAGER="pacman"
;;
*suse*)
PACKAGE_MANAGER="zypper"
;;
*alpine*)
PACKAGE_MANAGER="apk"
;;
*gentoo*)
PACKAGE_MANAGER="emerge"
;;
*)
PACKAGE_MANAGER=""
;;
esac
fi
;;
esac
}
install_package() {
local package_name=$1
PACKAGE_INSTALL_NAME=$(get_package_name "$package_name")
if [ -n "$PACKAGE_MANAGER" ]; then
echo "Installing $PACKAGE_INSTALL_NAME using $PACKAGE_MANAGER"
case "$PACKAGE_MANAGER" in
apt)
apt update && apt install -y "$PACKAGE_INSTALL_NAME"
if [ "$package_name" = "openssh" ]; then
mkdir -p /run/sshd
chmod 755 /run/sshd
fi
;;
dnf)
dnf makecache && dnf install -y "$PACKAGE_INSTALL_NAME"
;;
yum)
yum makecache fast && yum install -y "$PACKAGE_INSTALL_NAME"
;;
pacman)
pacman -Sy --noconfirm "$PACKAGE_INSTALL_NAME"
;;
zypper)
zypper refresh && zypper install -y "$PACKAGE_INSTALL_NAME"
;;
apk)
apk update && apk add "$PACKAGE_INSTALL_NAME"
;;
emerge)
emerge --sync && emerge "$PACKAGE_INSTALL_NAME"
;;
*)
echo "Error: Unsupported package manager." >&2
exit 1
;;
esac
else
echo "Unsupported or unknown Linux distribution: $NAME" >&2
exit 1
fi
}
create_user() {
local username="$1"
local password="$2"
if [ -z "$username" ]; then
echo "Error: VKUBE_TTYD_USER is required." >&2
return 1
fi
if id "$username" >/dev/null 2>&1; then
echo "User $username already exists."
# Check if the existing user has a password (for Alpine, check /etc/shadow)
user_info=$(getent shadow "$username")
if [ -n "$user_info" ] && echo "$user_info" | cut -d: -f2 | grep -q "^\*$\|^!$"; then
if [ -z "$password" ]; then
echo "Error: User $username does not have a password. VKUBE_TTYD_PASSWORD is required." >&2
return 1
fi
fi
# If a password is provided, update it
if [ -n "$password" ]; then
echo "$username:$password" | chpasswd
echo "Password for $username has been updated."
fi
else
# If the user does not exist, a password must be entered
if [ -z "$password" ]; then
echo "Error: User $username does not exist. VKUBE_TTYD_PASSWORD is required to create a new user." >&2
return 1
fi
# Create the user (handling different distributions)
if command -v useradd >/dev/null 2>&1; then
useradd -m -s /bin/bash "$username"
elif command -v adduser >/dev/null 2>&1; then
adduser -D -s /bin/sh "$username"
else
echo "Error: No compatible user creation command found." >&2
return 1
fi
echo "$username:$password" | chpasswd
echo "User $username has been created with a password."
fi
# Special handling for root user in Alpine Linux: Add pts/0 to /etc/securetty
if [ "$username" = "root" ]; then
echo "pts/0" >> /etc/securetty
fi
}
determine_package_manager
# Install packages based on environment variables
[ -n "$VKUBE_SSH_PUB_KEY" ] && install_package openssh
[ -n "$VKUBE_RSYNC" ] && install_package rsync
[ -n "$VKUBE_TTYD_USER" ] && install_package ttyd
# Configure SSH if SSH key is provided
if [ -n "$VKUBE_SSH_PUB_KEY" ]; then
ssh-keygen -A
mkdir -p /root/.ssh
echo "$VKUBE_SSH_PUB_KEY" > /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
echo "PermitRootLogin prohibit-password" >> /etc/ssh/sshd_config
echo "PasswordAuthentication no" >> /etc/ssh/sshd_config
echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config
/usr/sbin/sshd
echo "SSHD service configured for key-based authentication only."
fi
# Configute TTYD if TTYD key is provided
if [ -n "$VKUBE_TTYD_USER" ]; then
create_user "$VKUBE_TTYD_USER" "$VKUBE_TTYD_PASSWORD"
/usr/bin/ttyd -W --port=27681 login > /dev/null 2>&1 < /dev/null &
fi
← 配置文件托管