Motivation
During my work in Geniox mobile, I face responsibility to maintain Golang service that connects to the SFTP server. The existing code is pretty advanced, therefore I decided to learn from basic, main source of Golang package (https://pkg.go.dev/). Moreover, It’s better for us to understand the fundamentals of File Transfer Protocol before jumping to the code.
FTP Concept
Fundamental FTP is very important to understand. If somehow you should use other programming languages or face other problems that force you to interact with SFTP, this information will help you since the concept remains the same.
What is SFTP
SFTP is stand for SSH File Transfer Protocol (or sometimes called ‘Secure’ File Tranfer Protocol). In ordinary FTP, file tranfered without encryption, making data readable for anyone who intercepts it. While this is fine if you’re just sending unimportant files, this could lead to major data compromises if you’re sending crucial data (ftptoday).
Advantages of using (s)FTP
- It allows you to transfer multiple files and folders
- When the connection is lost then it has the ability to resume the transfer
- There is no limitation on the size of the file to be transferred. The browsers allow a transfer of only up to 2GB.
- Many FTP clients like FileZilla have the ability to schedule the transfers.
- The data transfer is faster than HTTP.
- The items that are to be uploaded or downloaded are added to the ‘queue’. The FTP client can add items to the ‘queue’.
source: afteracademy
Glossary
SSH Key
An SSH key is a secure access credential used in Secure Shell (SSH) protocol. SSH keys use key pairs based on public key infrastructure (PKI) technology, the gold standard for digital identity authentication and encryption, to provide a secure and scalable method of authentication. (source: sectigo)
Public Key and Private Key
An SSH key relies upon the use of two related keys, a public key and a private key, that together create a key pair that is used as the secure access credential. The private key is secret, known only to the user, and should be encrypted and stored safely. The public key can be shared freely with any SSH server to which the user wishes to connect. (source: sectigo)
Uploading
Transferring files from a client computer to a server computer (source: deskshare)
Downloading
Transferring files from a server to a client (source: deskshare)
Control Connection
The FTP client, for example, FileZilla sends a connection request usually to server port number 21. Typically a user needs to log on to the FTP server for estabilishing the connection but there are some servers that make all their content available without login. These servers are known as anonymous FTP
Data Connection
For transferring the files and folder we use a separate connection called data connection (source: afteracademy)
known_hosts
a client file containing all remotely connected hosts, and the ssh client uses this file. This file authenticates for the client to the server they are connecting to. The known_hosts file contains the host public key for all known hosts. Usually this file created automatically when client try to connect server at the first time ssh user@host
or ssh user@host -p custom_port
(note: you’re only be able to connect after creating ssh key e.g. ssh-keygen -t rsa
). To remove host public key, we can use ssh-keygen -R "hostname"
. (source: linuxhint, howtouselinux, serverfault).
authorized_keys
a server file that houses are all SSH authentication keys that were copied to the server, from remote clients. Usually this file is located in ~/home/username/.ssh/
. The ssh id can be copied by running ssh-copy-id user@host
if ssh id located in the default folder, usually $HOME/.ssh/id_rsa.pub
. If not, you can use ssh-copy-id path/to/id_rsa.pub user@host
Steps to generate SSH key
- Client generate the key using command
ssh-keygen -t rsa
- Enter location in which to save the keys. Typically, the keys stored in
~/home/username/.ssh/
in Linux or~/Users/username/.ssh/
in Mac. - Enter in an optional passphrase or leave empty for no passphrase.
- Once the pair is generated, the next step is to put the public one on the remote server using command
ssh-copy-id
command.
(source: sectigo)
Golang Snippet
I combine example code in the sftp here and ssh here and also a little help from stackoverflow here
SFTP Example
This example is written as package sftp. The code I copied directly from here
|
|
On the line number #3, a SSH connection is estabilished. Then the connection is used in the next code ln #6. The code for generating this SSH connection will be explained on the next session.
SSH Example
To get SSH connection, we should take a look at other examples from pkg.go.dev. There are two ways of example how to make SSH connection, password (example-dial) and public key (example-PublicKeys). I combine both auth method and get the following code:
|
|
The auth method using PublicKey doesn’t require password but the server should have public key of client on server’s authorized_keys.
Getting Host PublicKey
From stackoverflow, I get this lines
|
|
Entire Code
Mixing up the code together, finally I get this code running and hit the SFTP server.
Next Question
Still, I have some of question in my mind regarding SFTP and SSH.
Firstly, How if someone steal the known_hosts file and put it onto his/her laptop and try to access the server. Could he/she impersonante the origin client and access the server?. Second, Is there anyway to make our the known_hosts safer? by adding salt or hash perhaps, so the thief couldn’t see what hostname server connecting to the client.
References: