diff options
Diffstat (limited to 'features/src/sshd')
-rw-r--r-- | features/src/sshd/NOTES.md | 69 | ||||
-rw-r--r-- | features/src/sshd/README.md | 93 | ||||
-rw-r--r-- | features/src/sshd/devcontainer-feature.json | 21 | ||||
-rwxr-xr-x | features/src/sshd/install.sh | 139 |
4 files changed, 322 insertions, 0 deletions
diff --git a/features/src/sshd/NOTES.md b/features/src/sshd/NOTES.md new file mode 100644 index 0000000..c2ca8c8 --- /dev/null +++ b/features/src/sshd/NOTES.md @@ -0,0 +1,69 @@ +## Usage + +While the some services automates SSH setup (e.g., when using the GitHub CLI for GitHub Codespaces), this may not be the case for other tools and services. Follow these directions to connect to the dev container from these other tools: + +1. Connect to your dev container using a desktop tool or CLI that supports the dev container spec (e.g., VS Code client). + +2. The first time you've started the container, you will want to set a password for your user. If running as a user other than root, and you have `sudo` installed: + + ```bash + sudo passwd $(whoami) + ``` + + Or if you are running as root: + + ```bash + passwd + ``` + +3. Forward the SSH port (`2222` by default) to your local machine using either the `forwardPorts` property in `devcontainer.json` or the user interface in your tool (e.g., you can press <kbd>F1</kbd> or <kbd>Ctrl/Cmd</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd> and select **Ports: Focus on Ports View** in VS Code to bring it into focus). + +4. Use a **local terminal** (or other tool) to connect to it using the command and password from step 2. e.g. + + ```bash + ssh -p 2222 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o GlobalKnownHostsFile=/dev/null vscode@localhost + ``` + + ...where `vscode` above is the user you are running as in the container and `2222` after `-p` is the **local address port** from step 2. + + The “-o” arguments are optional, but will prevent you from getting warnings or errors about known hosts when you do this from multiple containers/codespaces. + +5. Next time you connect to your container, just repeat steps 3 and 4 and use the same password you set in step 2. + +### Using SSHFS + +[SSHFS](https://en.wikipedia.org/wiki/SSHFS) allows you to mount a remote filesystem to your local machine with nothing but a SSH connection. Here's how to use it with a dev container. + +1. Follow the steps in the previous section to ensure you can connect to the dev container using the normal `ssh` client. + +2. Install a SSHFS client. + + - **Windows:** Install [WinFsp](https://github.com/billziss-gh/winfsp/releases) and [SSHFS-Win](https://github.com/billziss-gh/sshfs-win/releases). + - **macOS**: Use [Homebrew](https://brew.sh/) to install: `brew install macfuse gromgit/fuse/sshfs-mac` + - **Linux:** Use your native package manager to install your distribution's copy of the sshfs package. e.g. `sudo apt-get update && sudo apt-get install sshfs` + +3. Mount the remote filesystem. + + - **macOS / Linux:** Use the `sshfs` command to mount the remote filesystem. The arguments are similar to the normal `ssh` command but with a few additions. For example: + + ``` + mkdir -p ~/sshfs/devcontainer + sshfs "vscode@localhost:/workspaces" "$HOME/sshfs/devcontainer" -p 2222 -o follow_symlinks -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o GlobalKnownHostsFile=/dev/null -C + ``` + ...where `vscode` above is the user you are running as in the container (e.g. `codespace`, `vscode`, `node`, or `root`) and `2222` after the `-p` is the same local port you used in the `ssh` command in step 1. + + - **Windows:** Press Window+R and enter the following in the "Open" field in the Run dialog: + + ``` + \\sshfs.r\vscode@localhost!2222\workspaces + ``` + ...where `vscode` above is the user you are running as in the container and `2222` after the `!` is the same local port you used in the `ssh` command in the previous section. + +4. Your dev container's filesystem should now be available in the `~/sshfs/devcontainer` folder on macOS or Linux or in a new explorer window on Windows. + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/features/src/sshd/README.md b/features/src/sshd/README.md new file mode 100644 index 0000000..7314e16 --- /dev/null +++ b/features/src/sshd/README.md @@ -0,0 +1,93 @@ + +# SSH server (sshd) + +Adds a SSH server into a container so that you can use an external terminal, sftp, or SSHFS to interact with it. + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers/features/sshd:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| version | Currently unused. | string | latest | + +## Usage + +While the some services automates SSH setup (e.g., when using the GitHub CLI for GitHub Codespaces), this may not be the case for other tools and services. Follow these directions to connect to the dev container from these other tools: + +1. Connect to your dev container using a desktop tool or CLI that supports the dev container spec (e.g., VS Code client). + +2. The first time you've started the container, you will want to set a password for your user. If running as a user other than root, and you have `sudo` installed: + + ```bash + sudo passwd $(whoami) + ``` + + Or if you are running as root: + + ```bash + passwd + ``` + +3. Forward the SSH port (`2222` by default) to your local machine using either the `forwardPorts` property in `devcontainer.json` or the user interface in your tool (e.g., you can press <kbd>F1</kbd> or <kbd>Ctrl/Cmd</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd> and select **Ports: Focus on Ports View** in VS Code to bring it into focus). + +4. Use a **local terminal** (or other tool) to connect to it using the command and password from step 2. e.g. + + ```bash + ssh -p 2222 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o GlobalKnownHostsFile=/dev/null vscode@localhost + ``` + + ...where `vscode` above is the user you are running as in the container and `2222` after `-p` is the **local address port** from step 2. + + The “-o” arguments are optional, but will prevent you from getting warnings or errors about known hosts when you do this from multiple containers/codespaces. + +5. Next time you connect to your container, just repeat steps 3 and 4 and use the same password you set in step 2. + +### Using SSHFS + +[SSHFS](https://en.wikipedia.org/wiki/SSHFS) allows you to mount a remote filesystem to your local machine with nothing but a SSH connection. Here's how to use it with a dev container. + +1. Follow the steps in the previous section to ensure you can connect to the dev container using the normal `ssh` client. + +2. Install a SSHFS client. + + - **Windows:** Install [WinFsp](https://github.com/billziss-gh/winfsp/releases) and [SSHFS-Win](https://github.com/billziss-gh/sshfs-win/releases). + - **macOS**: Use [Homebrew](https://brew.sh/) to install: `brew install macfuse gromgit/fuse/sshfs-mac` + - **Linux:** Use your native package manager to install your distribution's copy of the sshfs package. e.g. `sudo apt-get update && sudo apt-get install sshfs` + +3. Mount the remote filesystem. + + - **macOS / Linux:** Use the `sshfs` command to mount the remote filesystem. The arguments are similar to the normal `ssh` command but with a few additions. For example: + + ``` + mkdir -p ~/sshfs/devcontainer + sshfs "vscode@localhost:/workspaces" "$HOME/sshfs/devcontainer" -p 2222 -o follow_symlinks -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o GlobalKnownHostsFile=/dev/null -C + ``` + ...where `vscode` above is the user you are running as in the container (e.g. `codespace`, `vscode`, `node`, or `root`) and `2222` after the `-p` is the same local port you used in the `ssh` command in step 1. + + - **Windows:** Press Window+R and enter the following in the "Open" field in the Run dialog: + + ``` + \\sshfs.r\vscode@localhost!2222\workspaces + ``` + ...where `vscode` above is the user you are running as in the container and `2222` after the `!` is the same local port you used in the `ssh` command in the previous section. + +4. Your dev container's filesystem should now be available in the `~/sshfs/devcontainer` folder on macOS or Linux or in a new explorer window on Windows. + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/sshd/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/features/src/sshd/devcontainer-feature.json b/features/src/sshd/devcontainer-feature.json new file mode 100644 index 0000000..8c36557 --- /dev/null +++ b/features/src/sshd/devcontainer-feature.json @@ -0,0 +1,21 @@ +{ + "id": "sshd", + "version": "1.0.9", + "name": "SSH server", + "documentationURL": "https://github.com/devcontainers/features/tree/main/src/sshd", + "description": "Adds a SSH server into a container so that you can use an external terminal, sftp, or SSHFS to interact with it.", + "options": { + "version": { + "type": "string", + "proposals": [ + "latest" + ], + "default": "latest", + "description": "Currently unused." + } + }, + "entrypoint": "/usr/local/share/ssh-init.sh", + "installsAfter": [ + "https://gitrepo.ru/api/packages/NeonXP/generic/features/latest/devcontainer-feature-common-utils.tgz" + ] +} diff --git a/features/src/sshd/install.sh b/features/src/sshd/install.sh new file mode 100755 index 0000000..1460408 --- /dev/null +++ b/features/src/sshd/install.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env bash +#------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. +#------------------------------------------------------------------------------------------------------------- +# +# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/sshd.md +# Maintainer: The VS Code and Codespaces Teams +# +# Note: You can change your user's password with "sudo passwd $(whoami)" (or just "passwd" if running as root). + +SSHD_PORT="${SSHD_PORT:-"2222"}" +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +START_SSHD="${START_SSHD:-"false"}" +NEW_PASSWORD="${NEW_PASSWORD:-"skip"}" + +set -e + +# Clean up +rm -rf /var/lib/apt/lists/* + +if [ "$(id -u)" -ne 0 ]; then + echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi + +# Determine the appropriate non-root user +if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then + USERNAME="" + POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") + for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do + if id -u ${CURRENT_USER} > /dev/null 2>&1; then + USERNAME=${CURRENT_USER} + break + fi + done + if [ "${USERNAME}" = "" ]; then + USERNAME=root + fi +elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then + USERNAME=root +fi + +apt_get_update() +{ + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + apt-get update -y + fi +} + +# Checks if packages are installed and installs them if not +check_packages() { + if ! dpkg -s "$@" > /dev/null 2>&1; then + apt_get_update + apt-get -y install --no-install-recommends "$@" + fi +} + +# Ensure apt is in non-interactive to avoid prompts +export DEBIAN_FRONTEND=noninteractive + +# Install openssh-server openssh-client +check_packages openssh-server openssh-client lsof + +# Generate password if new password set to the word "random" +if [ "${NEW_PASSWORD}" = "random" ]; then + NEW_PASSWORD="$(openssl rand -hex 16)" + EMIT_PASSWORD="true" +elif [ "${NEW_PASSWORD}" != "skip" ]; then + # If new password not set to skip, set it for the specified user + echo "${USERNAME}:${NEW_PASSWORD}" | chpasswd +fi + +if [ $(getent group ssh) ]; then + echo "'ssh' group already exists." +else + echo "adding 'ssh' group, as it does not already exist." + groupadd ssh +fi + +# Add user to ssh group +if [ "${USERNAME}" != "root" ]; then + usermod -aG ssh ${USERNAME} +fi + +# Setup sshd +mkdir -p /var/run/sshd +sed -i 's/session\s*required\s*pam_loginuid\.so/session optional pam_loginuid.so/g' /etc/pam.d/sshd +sed -i 's/#*PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config +sed -i -E "s/#*\s*Port\s+.+/Port ${SSHD_PORT}/g" /etc/ssh/sshd_config +# Need to UsePAM so /etc/environment is processed +sed -i -E "s/#?\s*UsePAM\s+.+/UsePAM yes/g" /etc/ssh/sshd_config + +# Write out a scripts that can be referenced as an ENTRYPOINT to auto-start sshd and fix login environments +tee /usr/local/share/ssh-init.sh > /dev/null \ +<< 'EOF' +#!/usr/bin/env bash +# This script is intended to be run as root with a container that runs as root (even if you connect with a different user) +# However, it supports running as a user other than root if passwordless sudo is configured for that same user. + +set -e + +sudoIf() +{ + if [ "$(id -u)" -ne 0 ]; then + sudo "$@" + else + "$@" + fi +} + +EOF +tee -a /usr/local/share/ssh-init.sh > /dev/null \ +<< 'EOF' + +# ** Start SSH server ** +sudoIf /etc/init.d/ssh start 2>&1 | sudoIf tee /tmp/sshd.log > /dev/null + +set +e +exec "$@" +EOF +chmod +x /usr/local/share/ssh-init.sh + +# If we should start sshd now, do so +if [ "${START_SSHD}" = "true" ]; then + /usr/local/share/ssh-init.sh +fi + +# Output success details +echo -e "Done!\n\n- Port: ${SSHD_PORT}\n- User: ${USERNAME}" +if [ "${EMIT_PASSWORD}" = "true" ]; then + echo "- Password: ${NEW_PASSWORD}" +fi + +# Clean up +rm -rf /var/lib/apt/lists/* + +echo -e "\nForward port ${SSHD_PORT} to your local machine and run:\n\n ssh -p ${SSHD_PORT} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o GlobalKnownHostsFile=/dev/null ${USERNAME}@localhost\n" |