Running OpenSSH in an Alpine Docker Container
Solution 1
A container is not a full installed environment. The official document is for that installed alpine on some machine. With power on, boot up services, etc. that a container does not have.
So, anything in /etc/init.d/
can not be used directly in a container which is used by boot up service (like systemd, or alpine's rc*). That's why you got error messages cause the rc*
isn't installed in the container.
What you need to do is start sshd manuanlly. You can take look on below example:
https://hub.docker.com/r/danielguerra/alpine-sshd/~/dockerfile/
Solution 2
Despite there are some details still not clear to me, let me take a voice in the discussion. The solution specified by the below configuration works for me. It's the result of arduous experiments.
First, the dockerfile
FROM alpine
RUN apk update && \
apk add --no-cache sudo bash openrc openssh
RUN mkdir -p /run/openrc && \
touch /run/openrc/softlevel && \
rc-update add sshd default
RUN adduser --disabled-password regusr && \
sh -c 'echo "regusr:<encoded_passwd>"' | chpasswd -e > /dev/null 2>&1 && \
sh -c 'echo "regusr ALL=NOPASSWD: ALL"' >> /etc/sudoers
VOLUME ["/home/reguser/solution/entrypoint-init.d","/sys/fs/cgroup"]
USER reguser
WORKDIR /home/reguser
RUN mkdir -p $HOME/solution && sudo chown reguser:reguser $HOME/solution
ADD ./entrypoint.sh /home/reguser/solution/
EXPOSE 22
ENTRYPOINT ["./solution/entrypoint.sh"]
CMD ["/bin/bash"]
Next, /home/reguser/solution/entrypoint.sh
#!/bin/bash
for f in ./solution/entrypoint-init.d/*; do
case "$f" in
*.sh) echo "$0: running $f"; . "$f" ;;
*) echo "$0: ignoring $f" ;;
esac
echo
done
exec "$@"
Next, /home/reguser/solution/entrypoint-init.d/10-ssh-up.sh
#!/bin/bash
sudo sed --in-place --expression='/^#[[:space:]]*Port[[:space:]]\+22$/ s/^#//i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^#[[:space:]]*AddressFamily[[:space:]]\+any$/ s/^#//i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^#[[:space:]]*HostKey[[:space:]]\+\/etc\/ssh\/ssh_host_rsa_key$/ s/^#//i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^#[[:space:]]*HostbasedAuthentication[[:space:]].*/ s/^#//i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^[[:space:]]*HostbasedAuthentication[[:space:]].*/ s/^[[:space:]]*\(HostbasedAuthentication\)[[:space:]]\(.*\)/\1 no/i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^[[:space:]]*HostbasedAuthentication[[:space:]]\+yes.*/ s/^/#/i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^#[[:space:]]*IgnoreRhosts[[:space:]].*/ s/^#//i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^[[:space:]]*IgnoreRhosts[[:space:]].*/ s/^[[:space:]]*\(IgnoreRhosts\)[[:space:]]\(.*\)/\1 yes/i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^[[:space:]]*IgnoreRhosts[[:space:]]\+no.*/ s/^/#/i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^#[[:space:]]*PasswordAuthentication[[:space:]].*/ s/^#//i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^[[:space:]]*PasswordAuthentication[[:space:]].*/ s/^[[:space:]]*\(PasswordAuthentication\)[[:space:]]\(.*\)/\1 yes/i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^[[:space:]]*PasswordAuthentication[[:space:]]\+no.*/ s/^/#/i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^#[[:space:]]*PubkeyAuthentication[[:space:]].*/ s/^#//i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^[[:space:]]*PubkeyAuthentication[[:space:]].*/ s/^[[:space:]]*\(PubkeyAuthentication\)[[:space:]]\(.*\)/\1 yes/i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^[[:space:]]*PubkeyAuthentication[[:space:]]\+no.*/ s/^/#/i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^#[[:space:]]*PrintMotd[[:space:]].*/ s/^#//i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^[[:space:]]*PrintMotd[[:space:]].*/ s/^[[:space:]]*\(PrintMOTD\)[[:space:]]\(.*\)/\1 no/i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='/^[[:space:]]*PrintMotd[[:space:]]\+yes.*/ s/^/#/i' -- /etc/ssh/sshd_config
sudo sed --in-place --expression='$ a\' --expression='\nAcceptEnv LANG LC_\*' -- /etc/ssh/sshd_config
sudo /etc/init.d/sshd --dry-run start
sudo /etc/init.d/sshd start
The last two lines are in the heart of the trick. In particular, the sudo /etc/init.d/sshd --dry-run start
makes the solution working.
Finally, command-line controls
docker build --tag='dockerRegUser/sshdImg:0.0.1' --file='./dockerfile' .
docker container create --tty \
--volume $(pwd)/dock/entrypoint-init.d:/home/reguser/solution/entrypoint-init.d:ro \
--name sshdCnt 'dockerRegUser/sshdImg:0.0.1' tail -f /dev/null
docker start sshdCnt && \
ssh-keygen -f "/home/user/.ssh/known_hosts" -R "$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' sshdCnt)" && \
sleep 5 && \
ssh-copy-id -i ~/.ssh/sshkey reguser@$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' sshdCnt)
I know, I know, there is a lot of unnecessary constructs. The example is also against the single service docker container principle. But there are phases and situations in solution development and delivery lifecycle that justify (or at least tempt) considering extending the container with the sshd or other openrc-controlled services.
Solution 3
/etc/init.d/sshd: not found
Try to run these commands:
apk add --no-cache openrc
rc-update add sshd
Ole
Updated on December 31, 2021Comments
-
Ole over 2 years
I've installed OpenSSH and now I wish to run it as described in the documentation by running
/etc/init.d/sshd start
. However it does not start:/ # /etc/init.d/sshd start /bin/ash: /etc/init.d/sshd: not found
Thoughts?
P.S.
/ # ls -la /etc/init.d/sshd -rwxr-xr-x 1 root root 2622 Jan 14 20:48 /etc/init.d/sshd
Contents of /etc/init.d/sshd:
#!/sbin/openrc-run # Copyright 1999-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: /var/cvsroot/gentoo-x86/net-misc/openssh/files/sshd.rc6.4,v 1.5 2015/05/04 02:56:25 vapier Exp $ description="OpenBSD Secure Shell server" description_checkconfig="Verify configuration file" description_reload="Reload configuration" extra_commands="checkconfig" extra_started_commands="reload" : ${SSHD_CONFDIR:=/etc/ssh} : ${SSHD_CONFIG:=${SSHD_CONFDIR}/sshd_config} : ${SSHD_PIDFILE:=/var/run/${SVCNAME}.pid} : ${SSHD_BINARY:=/usr/sbin/sshd} depend() { use logger dns if [ "${rc_need+set}" = "set" ] ; then : # Do nothing, the user has explicitly set rc_need else local x warn_addr for x in $(awk '/^ListenAddress/{ print $2 }' "$SSHD_CONFIG" 2>/dev/null) ; do case "${x}" in 0.0.0.0|0.0.0.0:*) ;; ::|\[::\]*) ;; *) warn_addr="${warn_addr} ${x}" ;; esac done if [ -n "${warn_addr}" ] ; then need net ewarn "You are binding an interface in ListenAddress statement in your sshd_config!" ewarn "You must add rc_need=\"net.FOO\" to your /etc/conf.d/sshd" ewarn "where FOO is the interface(s) providing the following address(es):" ewarn "${warn_addr}" fi fi } checkconfig() { if [ ! -d /var/empty ] ; then mkdir -p /var/empty || return 1 fi if [ ! -e "${SSHD_CONFIG}" ] ; then eerror "You need an ${SSHD_CONFIG} file to run sshd" eerror "There is a sample file in /usr/share/doc/openssh" return 1 fi if ! yesno "${SSHD_DISABLE_KEYGEN}"; then ssh-keygen -A || return 1 fi [ "${SSHD_PIDFILE}" != "/var/run/sshd.pid" ] \ && SSHD_OPTS="${SSHD_OPTS} -o PidFile=${SSHD_PIDFILE}" [ "${SSHD_CONFIG}" != "/etc/ssh/sshd_config" ] \ && SSHD_OPTS="${SSHD_OPTS} -f ${SSHD_CONFIG}" "${SSHD_BINARY}" -t ${SSHD_OPTS} || return 1 } start() { checkconfig || return 1 ebegin "Starting ${SVCNAME}" start-stop-daemon --start --exec "${SSHD_BINARY}" \ --pidfile "${SSHD_PIDFILE}" \ -- ${SSHD_OPTS} eend $? } stop() { if [ "${RC_CMD}" = "restart" ] ; then checkconfig || return 1 fi ebegin "Stopping ${SVCNAME}" start-stop-daemon --stop --exec "${SSHD_BINARY}" \ --pidfile "${SSHD_PIDFILE}" --quiet eend $? if [ "$RC_RUNLEVEL" = "shutdown" ]; then _sshd_pids=$(pgrep "${SSHD_BINARY##*/}") if [ -n "$_sshd_pids" ]; then ebegin "Shutting down ssh connections" kill -TERM $_sshd_pids >/dev/null 2>&1 eend 0 fi fi } reload() { checkconfig || return 1 ebegin "Reloading ${SVCNAME}" start-stop-daemon --signal HUP \ --exec "${SSHD_BINARY}" --pidfile "${SSHD_PIDFILE}" eend $? }
-
Ole about 8 yearsIt is present is
usr/sbin
. Also runningrc-update
results in/bin/ash: rc-update: not found
-
Ole about 8 yearswhen running that I get the same result >>> / # /usr/bin/sshd start /bin/ash: /usr/bin/sshd: not found
-
VonC about 8 yearsI see the size of sshd is relatively small. Is it a script? Can you open it and see if it refers in it to non-existent paths?
-
Ole about 8 yearsI pasted the contents of
/etc/init.d/sshd in the question. The contents of
/bin/sbin/sshd` are binary. -
VonC about 8 years@Ole does
/sbin/openrc-run
exists? -
Ole about 8 yearsNo - BTW - @VonC you could just start a container and have a look like this: docker run -it --rm alpine /bin/ash
-
timetofly over 7 yearsIt's my understanding that example script ONLY can run sshd, and not any other command. How would you make it turn sshd + another application, whatever you specify as the command?
-
FreeSoftwareServers about 4 yearsLink Only Answer :(
-
CSJ about 4 years@FreeSoftwareServers maybe click link is too hard for you :)
-
FreeSoftwareServers about 4 years@CSJ I would think you would know better as a higher rep user but it's bad to avoid Link_Rot among other things --> en.wikipedia.org/wiki/Link_rot