SSH Review
A review of the SSH protocol and its use cases on Ubuntu
A learning objective of this post is to review the SSH protocol and related commands on Ubuntu. We will be simulating a remote linux server (Ubuntu 22.04 on a docker container) and a client from a local machine. Note that Docker provides commands like docker exec for direct container interaction, often eliminating the need for SSH. However, for the sake of this post, we will be using SSH to connect to the running container to practice SSH commands, key management, port forwarding, and other SSH-related tasks.
- Create a Dockerfile for a custom image with SSH enabled and vim installed.
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y openssh-server vim
RUN mkdir /var/run/sshd
# Set root password
RUN echo 'root:password' | chpasswd
# Permit root login via SSH
RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
# Expose SSH port
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
- The last line of the Dockerfile ensures that the ssh daemon is running automatically on boot.
- Build the Docker image
docker build -t ssh-practice-server .
- Run the container
docker run -d --name ssh-server -p 2222:22 ssh-practice-server
<CONTAINER_ID>
- Connect to your container using SSH.
└─> ssh -p 2222 root@localhost
The authenticity of host '[localhost]:2222 ([::1]:2222)' can't be established.
ED25519 key fingerprint is SHA256:9XlzUUNoU5ikZr2cEIGw0NYzlnz6zJDsZ0eaiNBAty0.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[localhost]:2222' (ED25519) to the list of known hosts.
root@localhost's password:
root@localhost's password: password
- In case there is an error related to man-in-the-middle attack, you can remove the lines containing [localhost]:2222 in the known_hosts file in ~/.ssh/known_hosts.
- Check the status of the SSH service
root@<CONTAINER_ID>:~# service ssh status
* sshd is running
- Create a new user with admin privileges
root@<CONTAINER_ID>:~# adduser admin
root@<CONTAINER_ID>:~# usermod -aG sudo admin
-
Answer the questions, including the password, for the new user.
-
To check all the users on the system, you can use the following command on the /etc/passwd file. The last line should contain the newly created user.
cut -d: -f1 /etc/passwd
- Switch to the new user
root@<CONTAINER_ID>:~# su - admin
- Set up SSH keys for the new user from your local machine
ssh-keygen -t ed25519 -f ~/.ssh/ssh-practice -C "admin@ssh-server"
- Copy the public key to the server
- Prompt for the password of the new user will appear. Enter the password.
ssh-copy-id -i ~/.ssh/ssh-practice -p 2222 admin@localhost
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "$HOME/.ssh/ssh-practice.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
admin@localhost's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -p 2222 'admin@localhost'"
and check to make sure that only the key(s) you wanted were added.
(base)
- Connect to the server using the new user
ssh -i ~/.ssh/ssh-practice -p 2222 admin@localhost
- Check the newly created authorized_keys file
admin@<CONTAINER_ID>:~$ cat ~/.ssh/authorized_keys
ssh-ed25519 <CONTENT> admin@ssh-server
- Configure SSH settings in /etc/ssh/sshd_config
-
Login as root user first.
-
Disable Password Authentication for the root user by setting PasswordAuthentication to no
root@<CONTAINER_ID>:~# vim /etc/ssh/sshd_config
# Edit this line
PasswordAuthentication no
- Restart the SSH service
root@<CONTAINER_ID>:~# service ssh restart
└─> docker start ssh-server
ssh-server
- Now when you try logging as root user, it should fail.
└─> ssh -p 2222 root@localhost
root@localhost: Permission denied (publickey).
(base)
- Try again with an admin user.
ssh -i ~/.ssh/ssh-practice -p 2222 admin@localhost
- As admin user has root privileges, you can switch to root user using su
admin@<CONTAINER_ID>:~$ su -
Password: password
- Practice SSH tunneling and port forwarding
admin@<CONTAINER_ID>:~$ apt-get update
admin@<CONTAINER_ID>:~$ apt-get install -y apache2
- Check files created
admin@<CONTAINER_ID>:~$ ls /var/www/html
index.html
- Start the apache2 service by configuring the default site
root@<CONTAINER_ID>:~# cd /etc/apache2/sites-available/
root@<CONTAINER_ID>:/etc/apache2/sites-available# vim 000-default.conf
- Edit the line containing ServerName www.example.com as follows and save it.
ServerName localhost
- Activate the virtual hosts configuration file to enable it by running the following command:
a2ensite 000-default.conf
service apache2 reload
service apache2 status
* apache2 is running
- Test your port forwarding by accessing http://localhost:8080 in your local machine's web browser.
└─> ssh -i ~/.ssh/ssh-practice -L 8080:localhost:80 -p 2222 admin@localhost
- Visit localhost:8080 in your web browser to see the apache2 default page.
- Practice SCP (Secure Copy Protocol) to transfer files between the server and your local machine.
- Create a file on the server
admin@<CONTAINER_ID>:~$ echo "Hello from the server" > server.txt
- Copy the file to your local machine
└─> scp -i ~/.ssh/ssh-practice -P 2222 admin@localhost:~/server.txt "$(pwd)/server.txt"
server.txt 100% 22 13.2KB/s 00:00
(base)
- The same can be achieved by running docker cp command:
└─> docker cp ssh-server:/home/admin/server.txt .
Successfully copied 2.05kB to <CURRENT_DIR>/.
(base)
- Lastly, edit the SSH config file in your local machine to avoid typing the SSH key path and port number every time.
vim ~/.ssh/config
Host ubuntu
HostName localhost
User admin
Port 2222
PreferredAuthentications publickey
IdentityFile ~/.ssh/ssh-practice
IdentitiesOnly yes