using ssh inside docker

Introduction

This article shows the following:

  • How to create a custom user in a dockerfile
  • how to setup ssh for easy login
  • how to set up ssh for use with a physical network, even one through a wifi NIC (which has historically been harder)

Folder structure

.
├── build
│   ├── Dockerfile
├── docker-compose.yaml

Dockerfile

FROM ubuntu:latest
WORKDIR /test
ENV MYUSER=danaukes
ENV MYGROUP=danaukes
ENV MYUID=1000
ENV MYGID=1000

RUN apt update && apt install -y openssh-server iputils-ping git sudo net-tools

RUN addgroup --gid ${MYGID} ${MYGROUP} && \
    useradd -p $(perl -e 'print crypt($ARGV[0], "password")' 'test') -u ${MYUID} -g ${MYGID} -G adm,sudo ${MYUSER} && \
    mkdir /home/${MYUSER} && \
    chown ${MYUSER}:${MYGROUP} /home/${MYUSER} && \
    echo "${MYUSER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd

USER ${MYUSER}

Docker compose

version: "3.9"
services:
  web:
    build: ./build
    user: danaukes
    networks:
      ubuntu-network:
        ipv4_address: "192.168.4.99"
    dns:
      - 192.168.4.1
    ports:
      - 22/tcp
    command: bash -c "sudo service ssh start && sleep infinity"
    restart: unless-stopped

networks:
  ubuntu-network:
    driver: ipvlan
    driver_opts:
      parent: wlp1s0
      ipvlan-mode: l2
    ipam:
      driver: default
      config:
        - subnet: 192.168.4.0/24
          gateway: 192.168.4.1
          ip_range: 192.168.4.1/24

Notes and snippets

may need to run this to enable the kind of networking needed above:

sysctl -w net.ipv4.ip_forward=1
sudo iptables -P FORWARD ACCEPT
 
sudo service docker restart
docker system prune
apt update
apt install -y openssh-server iputils-ping
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
#apt install nano
#nano /etc/ssh/sshd_config
service ssh start
#sudo passwd root
sudo /etc/init.d/ssh reload 
docker compose up --force-recreate --build ros -d
docker exec -it --user user1 d64dd7a05bb3 /bin/bash
echo "export PATH=/opt/ros/galactic/bin:\$PATH" >> ~/.bashrc

External Resources

Note: Another important thing to remember (Macvlan and IPvlan): Traffic to and from the master device cannot be sent to and from slave devices. If you need to enable master to slave communication see section “Communication with the host (default-ns)” in the “IPVLAN – The beginning” paper published by one of the IPvlan authors (Mahesh Bandewar). found here