Setting up an SSH Lab using Docker

Setting up an SSH Lab using Docker

In organizations as Software Professionals we generally come across machines that we can access through remote ssh. In general in K8s environment it is advisable to ssh login to machines. We will try to set up a small SSH Lab using docker as container technology. The purpose is to know

  1. What is SSH?
  2. How to set up an ssh server?

What is SSH?

SSH stands for Secure Shell. It's a cryptographic network protocol used for secure communication over an unsecured network. SSH provides a secure way to access and manage remote devices, servers, and computers. It establishes an encrypted connection between a client and a server, allowing users to remotely log in to a system or execute commands securely over the internet.

SSH encrypts data, including passwords, login credentials, and other sensitive information, making it highly secure against eavesdropping, interception, or tampering by malicious entities. It uses public-key cryptography to authenticate the remote computer and allow secure communication, offering a higher level of security compared to traditional methods like Telnet or FTP, which transmit data in plain text.

SSH is widely used by system administrators, developers, and users who need to securely access and manage remote systems, transfer files securely, and execute commands on remote machines.

Now it is important to worth knowing about encryption that SSH uses - Public key cryptography! It is an asymmetric cryptography in which we have a key pair one is public and the other is private. Public key is shared using which senders can send data encrypted with this key. Then a user with access to private key can only decrypt the data and read the content. It is safer than symmetric cryptography in which both the keys are same. It is obvious that one would intend that a user with access to private key should only be able to read data which is a major drawback in Symmetric Cryptography.

Here's a brief explanation of how it works for asymmetric cryptography:

  1. Key Pairs: Asymmetric cryptography involves the use of key pairs - a public key and a private key. These keys are mathematically related but are different from each other.
  2. Public Key: The public key is shared openly and is used to encrypt data or messages. It's distributed widely and is accessible to anyone who wants to send encrypted information to the owner of the key.
  3. Private Key: The private key is kept secret and should never be shared. It is used for decrypting data that has been encrypted using the corresponding public key. Only the owner of the private key has access to it.
  4. Encryption and Decryption: When someone wants to establish a secure connection using SSH, the client and server engage in a process that involves the exchange of keys. The client sends its public key to the server. The server, upon receiving the public key, encrypts a session key (used for encrypting the actual data transmission during the SSH session) with the client's public key and sends it back to the client.
  5. Authentication: The client then decrypts the session key using its private key and sends a message to the server saying, "I have decrypted the session key, let's use this key for secure communication." The server acknowledges this, and both sides now have a shared session key that can be used for encrypting the data transmitted during the session.
  6. Secure Communication: From this point on, the client and server use this shared session key to encrypt and decrypt the data exchanged during the SSH session. Even if someone intercepts the data being sent, they cannot read or decipher it without the session key.

The use of asymmetric cryptography in SSH ensures secure key exchange and authentication between the client and server without transmitting sensitive information like passwords in plain text over the network. It provides a robust method for secure communication and remote access.

How to set up an SSH server?

Install Docker on macOS(if you are using something else you can check for instructions on website for Windows and Linux):

  • Download and install Docker Desktop for macOS from the?Docker website.
  • Once installed, start Docker Desktop and ensure that it's running.

Create and Run an Ubuntu Container:

  • Open a terminal on your macOS.
  • Pull the official Ubuntu image from Docker Hub using the following command:

docker pull ubuntu        

  • Create a new Docker container from the Ubuntu image and start an interactive shell session within the container:

docker run -it --name ubuntu-ssh-lab ubuntu /bin/bash        

  • -it?specifies an interactive session with a terminal.
  • --name ubuntu-ssh-lab?assigns the name "ubuntu-ssh-lab" to the container.
  • ubuntu?is the image to use.
  • /bin/bash?starts a Bash shell inside the container.
  • You are now inside the Ubuntu container. You can install packages, configure SSH, and perform various lab exercises.

Installing SSH server on Ubuntu container:

We will use OpenSSH which is an open-source project and is widely used in commercial projects and organizations.

  • In the container's shell, run the following Linux commands to update the package list and install OpenSSH Server:

apt-get update
apt-get install -y openssh-server        

  • Start the SSH service within the container:

service ssh start        

Tweaking the SSH installation and important tools to deal with it:

  • SSH service by default gets installed on port 22. Linux services are basically programs that run in the background.
  • We can use service command to deal with ssh service.

service ssh status # to check status
service ssh stop # to stop service
service ssh start # to start service
service ssh restart # to restart service        

Now to check on which port ssh service is running we can use net-stat which comes with net-tools. Use below command to get an insight and confirm once:

netstat -anp | grep ssh        

It would show Program name sshd running on :22 port.

Checking the installation directory for SSH configuration

  1. Go to /etc/ssh and list directory contents.
  2. Directory contains various files ending with '_keys' in filenames. Also these files include the crypto algorithm used to generate keys e.g ecdsa, rsa, ed25519 etc
  3. Two config files ssh_config and sshd_config
  4. ssh_config is system-wide ssh client configuration using which you would login to remote ssh servers
  5. sshd_config is system-wide ssh server configuration with some default configuration set
  6. You can check the content file using cat command 'cat /etc/ssh/sshd_config'
  7. Now Ubuntu container does not come up with any default editor such vim or nano. Install nano

apt-get install -y nano        

Accessing the docker container from external system

  1. There are two mechanisms to make ssh lab accessible from external sources. First is port-forwarding and another is creating a custom bridge network.
  2. In later approach we create a custom network and while starting a container we attach the custom network to that container.
  3. In the former approach which is easier and generally more preferred for simple use cases such as ours, we run our container using option -p option and then give value to it as <host_port>:<container_port>.
  4. In our case container_port would be 22 as on this port our ssh service is running. For host_port we would be using 2222
  5. Here is the command -it is for interactive --name is for the name of the resultant container

docker run -it --name ubuntu-ssh-lab -p 2222:22 ubuntu /bin/bash        

But in our case we already ran a container without port mapping. So we would need to stop the container, remove it, create another container and repeat the same steps. Another approach is you can commit the existing container to a new image. Remove the existing container and then create a container using docker run command with the newer image name and this time ensure the port mapping. You can also rename the container first to append -old.

docker rename ubuntu-ssh-lab ubuntu-ssh-lab-old
docker commit ubuntu-ssh-lab-old ubuntu-ssh-lab-preinstalled
docker images # output list contains ubuntu-ssh-lab-preinstalled        

Now execute the docker run command again this time with port mapping using the new image.

docker run -it --name ubuntu-ssh-lab -p 2222:22 ubuntu-ssh-lab-preinstalled /bin/bash        

In the interactive terminal perform below commands:

service ssh start # should start the ssh server
service ssh status # to check the status is running
netstat -anp # to check ssh server is running on 22 port        

Login through the ssh client on your host

If you are using windows then you may need to install OpenSSH on windows. In general go to .ssh folder on your host machine list the directory contents. You should be able to see the filer known_hosts.

Initially there should be nothing in the file which corresponds to your ssh server i.e something starting with [localhost:2222] algorithm <public key>. Remember we talked about the SSH using public keys with a particular algo. This is what known_hosts file stores in it.

Now ubuntu-ssh-lab is having the root user having ssh server running at port 22 forwarded to host port 2222 so we should try to login using below command:

ssh root@localhost -p 2222        

For the first time login since there is no entry in .ssh/known_hosts you should get the below message

The authenticity of host '[localhost]:2222 ([::1]:2222)' can't be established.
ED25519 key fingerprint is SHA256:a+RG2MM2pvyjSFkXLUfvz5+wK7AsT6caNVwF3ri1t+s.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?        

Hit enter with yes. You should be prompted with password!

Warning: Permanently added '[localhost]:2222' (ED25519) to the list of known hosts.
root@localhost's password:        

Now hitting enter without any password would not be allowed. It would say Permission denied, please try again. Three attempts are provided by default. In the end you get a message

 root@localhost: Permission denied (publickey,password).        

Now the host has been added to known_hosts file but further authentication cannot be completed. This is where we need to tweak with our sshd_config file or may be configure a user on container with some password.

We will aim to be able to login as root user and would configure accordingly for learning purpose.

Tweaking the sshd_config file

  • Using nano you can open the file by logging in to the container with an interactive terminal
  • Now remove # to uncomment the config PasswordAuthentication, - means removed lines and + means added lines. check below changes

-#PasswordAuthentication yes
-#PermitEmptyPasswords no
+PasswordAuthentication no
+PermitEmptyPasswords yes        

  • Press ctrl-o to write out to the sshd_config and then exit.
  • Restart the ssh service and try to login again.
  • This time you should see below message. It is not asking for password and it says that permission denied because of public key. We tried to login using using very verbose option so that we know what is going under the hood to debug where it might have failed.

ssh root@localhost -p 2222 -vvv2 
//// ........   some text omitted ....... ////
debug1: Authentications that can continue: publickey
debug1: Trying private key: /Users/sourabhdhingra/.ssh/id_ed25519_sk
debug3: no such identity: /Users/sourabhdhingra/.ssh/id_ed25519_sk: No such file or directory
debug1: Trying private key: /Users/sourabhdhingra/.ssh/id_xmss
debug3: no such identity: /Users/sourabhdhingra/.ssh/id_xmss: No such file or directory
debug1: Trying private key: /Users/sourabhdhingra/.ssh/id_dsa
debug3: no such identity: /Users/sourabhdhingra/.ssh/id_dsa: No such file or directory
debug2: we did not send a packet, disable method
debug1: No more authentication methods to try.
root@localhost: Permission denied (publickey).        

In nutshell it identifies the hosts in known_hosts and when a key is found it tries to authenticate using the corresponding public keys found. This is basically Public Key Authentication. The client generates a key pair (public key and private key), and the public key is uploaded to the server's authorized_keys file. During authentication, the server verifies the client's identity by validating the digital signature with the stored public key.

We are getting the error permission denied because of the public key.

  1. There should be a root folder in our Ubuntu container. If there is not one then create it.
  2. We should have .ssh folder as well in our root. If not then either create or move it to root folder.
  3. Within the .ssh folder there should be a file called authorized_keys in which will go public keys of the clients who can connect to the ssh server. In this case public key of your host machine.
  4. There should be right ownership and privileges to the folder and the file.
  5. Now to resolve the permission error lets copy content of our public key from host machine to ssh lab machine's authorized_keys file.

# on your localhost machine, make sure you have public-private key   # pair, public keys end with .pub extension
cat ~/.ssh/id_rsa.pub # copy the content of public key file

# then login to the ssh lab using
docker exec -it ubuntu-ssh-lab /bin/bash 

# you should see root@<container_id> e.g root@142f8c5e578d

# once logged in paste the copied content to authorized_keys
echo <copied_content> > authorized_keys

# Now try to ssh login from another terminal
ssh root@localhost -p 2222 -vvv2 # use verbose to know better        

You should be able to do ssh login to your ssh lab now. You may check this stackoverflow thread to resolve if any similar issues occur!

要查看或添加评论,请登录

社区洞察

其他会员也浏览了