0

I want to be able to start a Docker container as a user other than root and be able to ssh into it. When I start sshd as root I am able to log into it. When I switch it to start the container as another user and then try to ssh in as that user I get errors "Cannot bind any address." and "Bind to port 22 on :: failed: Permission denied.".

I have set up the other user to have root permissions and it still does not work.

Note that I am trying to get this to work in Alpine Linux and use it as a Fargate task - when fargate initially connects to the container is immediately passes in a public key which gets put in the authorized key file behind the scenes. I also make sure to have Fargate ssh as the other user when it fails. In the instance below I have it set to ernie. When I set the user to root in the files below and change the Fargate code to use root as the user I can get in to the container just fine. It is onky with setting ernie as the user I get the error.

My Dockerfile :

FROM alpine:latest

# Set the name of the user we want to use
ENV LOGINUSER="ernie"

# --------------------------------------------------------------------------------#
# Install and configure sshd.3                                                                    #
# https://www.cyberciti.biz/faq/how-to-install-openssh-server-on-alpine-linux-including-docker/   # 
# https://docs.docker.com/engine/examples/running_ssh_service for reference.                      #
# --------------------------------------------------------------------------------#
RUN apk add --no-cache openssh-server bash shadow sudo\
    && mkdir -p /var/run/sshd

RUN adduser --disabled-password --gecos "" $LOGINUSER
# https://ostechnix.com/add-delete-and-grant-sudo-privileges-to-users-in-alpine-linux/
RUN echo '%wheel ALL=(ALL) ALL' > /etc/sudoers.d/wheel
RUN adduser $LOGINUSER wheel

RUN cat /etc/ssh/sshd_config && echo "AllowUsers $LOGINUSER" >> /etc/ssh/sshd_config
RUN echo "$LOGINUSER ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/$LOGINUSER
RUN chmod 0440 /etc/sudoers.d
#RUN echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config

RUN echo 'root:dummy_passwd'|chpasswd

EXPOSE 22

# change ownership of /etc/ssh to the user we want to use
RUN sudo chown -R $LOGINUSER /etc/ssh
RUN sudo chown -R $LOGINUSER /run

####################CREATE CUSTOM SSHD CONFIG ###########################
RUN mkdir /opt/custom_ssh
RUN chmod -R 777 /opt/custom_ssh/

# Need to chown to allow ernie access - remove for root to work again
RUN chown -R $LOGINUSER:$LOGINUSER /opt/custom_ssh

USER $LOGINUSER
RUN ssh-keygen -f /opt/custom_ssh/ssh_host_rsa_key -N '' -t rsa
RUN ssh-keygen -f /opt/custom_ssh/ssh_host_dsa_key -N '' -t dsa

# This creates the keys in 
RUN ssh-keygen -A

RUN echo 'Port 22' >> opt/custom_ssh/sshd_config
RUN echo 'AuthorizedKeysFile  /opt/custom_ssh/authorized_keys' >> /opt/custom_ssh/sshd_config
RUN echo 'Subsystem       sftp    /usr/lib/ssh/sftp-server' >> /opt/custom_ssh/sshd_config
RUN echo 'X11Forwarding no' >> /opt/custom_ssh/sshd_config
RUN echo 'GatewayPorts no' >> /opt/custom_ssh/sshd_config
RUN echo 'AllowTcpForwarding no' >> /opt/custom_ssh/sshd_config
RUN echo 'StrictModes no'  >> /opt/custom_ssh/sshd_config
RUN echo 'PubkeyAcceptedKeyTypes +ssh-rsa'  >> /opt/custom_ssh/sshd_config
RUN echo 'PubkeyAuthentication yes'  >> /opt/custom_ssh/sshd_config

RUN chmod 644 /opt/custom_ssh/sshd_config

USER $LOGINUSER

ENTRYPOINT ["/docker-entrypoint.sh"]

My docker-entrypoint.sh file

#!/bin/sh

# Needed for Fargate connection
setUpSSH() {
    echo "DEBUG - I am in the setUpSSh function"
    echo "DEBUG - the public key passed in is $$SSH_PUBLIC_KEY"
    # Block the container to start without an SSH public key.
    if [ -z "$SSH_PUBLIC_KEY" ]; then
        echo 'Need your SSH public key as the SSH_PUBLIC_KEY environment variable.'
        exit 1
    fi

    # Create a folder to store user's SSH keys if it does not exist.
    USER_SSH_KEYS_FOLDER=/opt/custom_ssh
    [ ! -d ${USER_SSH_KEYS_FOLDER} ] && mkdir -p ${USER_SSH_KEYS_FOLDER}

    # Copy contents from the `SSH_PUBLIC_KEY` environment variable
    # to the `$USER_SSH_KEYS_FOLDER/authorized_keys` file.
    # The environment variable must be set when the container starts.
    echo ${SSH_PUBLIC_KEY} > ${USER_SSH_KEYS_FOLDER}/authorized_keys
    echo " DEBUG - cat ${USER_SSH_KEYS_FOLDER}/authorized_key"
    # Clear the `SSH_PUBLIC_KEY` environment variable.
    unset SSH_PUBLIC_KEY
}

setUpSSH


/usr/sbin/sshd -D -e -f /opt/custom_ssh/sshd_config
# Start the SSH daemon

#exec "$@"

1 Answer 1

1

Only root can bind to ports less than 1024. But there's no reason your ssh daemon must listen to port 22. You can configure it to listen to any other port > 1024 (2222 is common for SSH in this use case).

If your clients really must connect to port 22 then you can simply map the external port 22 to the internal port 2222 in your ECS Task definition. See "Port mappings" here: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html

1
  • Thanks! That solved my issue!! Commented Dec 16, 2021 at 15:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .