This project integrates MQTT and SSH File Transfer Protocol (SFTP) to facilitate secure file exchanges over MQTT. It utilizes OpenSSH for SFTP functionalities and Mosquitto as the MQTT broker. The architecture also incorporates Public Key Infrastructure (PKI) to ensure secure connections between an IoT device, the MQTT broker, and the SFTP server. This repository includes pre-generated key pairs for testing purposes. However, this setup is not recommended for production environments without further security measures.
- Python 3.11.0-6 (Compatibility with other versions such as 3.10.x or 3.12.x is not tested)
- OpenSSH (Primarily tested on Linux; Windows and macOS versions exist but are not covered here)
- OpenSSL (Primarily tested on Linux; Windows and macOS versions exist but are not covered here)
- Mosquitto (Primarily tested on Linux; Windows and macOS versions exist but are not covered here)
- Install all Python packages using the
requirements.txtfile withsudo pip install -r requirements.txt
-
Install OpenSSH Server and enable the
sshdservice:sudo apt/dnf install openssh-server sudo systemctl enable --now sshd -
Create a dedicated SFTP user (replace "test" with the desired username):
sudo adduser test sudo passwd test
-
Configure SSH for SFTP usage:
Edit the SSHD configuration to enforce SFTP and disable SSH shell access for the user "test":
sudo nano /etc/ssh/sshd_config
Add or modify the following lines:
Match User test ForceCommand internal-sftpRestart the SSH service to apply changes:
sudo systemctl restart sshd
-
Test the SFTP connection from another machine:
sftp test@sftp_ip
-
Install Mosquitto on both the MQTT broker and IoT device:
sudo apt/dnf install mosquitto sudo systemctl enable --now mosquitto -
Edit the Mosquitto configuration file to set up the broker, allowing anonymous connections and binding to all network interfaces:
sudo nano /etc/mosquitto/mosquitto.conf
Add or modify the following lines:
allow_anonymous true bind_address 0.0.0.0 -
Test the MQTT broker by subscribing to a topic on the broker and publishing from the IoT device:
- On the MQTT broker:
mosquitto_sub -h localhost -t "test/topic"- On the IoT device:
mosquitto_pub -h broker_ip -t "test/topic" -m "hi world!"
-
Generate RSA key pairs on the IoT device:
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_iot -
Copy the public key to the SFTP server:
scp ~/.ssh/id_rsa_iot.pub test@sftp_ip:/home/test/ -
On the SFTP server, append the IoT device's public key to the
authorized_keys:ssh test@sftp_ip 'cat >> ~/.ssh/authorized_keys' < ~/.ssh/id_rsa_iot.pub
-
Enable public key authentication and restart the SSH service:
sudo nano /etc/ssh/sshd_config
Uncomment or add:
PubkeyAuthentication yesThen restart the SSH service:
sudo systemctl restart sshd
-
Test the PKI setup by connecting to the SFTP server from the IoT device:
ssh -i ~/.ssh/id_rsa_iot test@sftp_ip
-
On the MQTT Broker, generate the X.509 key for TLS 1.3:
openssl genpkey -algorithm RSA -out mqtt_server.key
-
Create the certificate request:
openssl req -new -key mqtt_server.key -out mqtt_server.csr
-
Generate a self-signed certificate
(for testing purposes):
```bash
openssl x509 -req -days 365 -in mqtt_server.csr -signkey mqtt_server.key -out mqtt_server.crt
```
-
Move the generated files to the Mosquitto certificates directory and adjust permissions:
sudo mv mqtt_server.key mqtt_server.csr mqtt_server.crt /etc/mosquitto/certs/ sudo chown mosquitto:mosquitto /etc/mosquitto/certs/* sudo chmod 400 /etc/mosquitto/certs/mqtt_server.key sudo chmod 444 /etc/mosquitto/certs/mqtt_server.crt -
Transfer the .crt file to the IoT device:
- On the IoT device:
mkdir ~/.mqtt/ scp mqtt_server@mqtt_ip:/etc/mosquitto/certs/mqtt_server.crt ~/.mqtt/
-
Configure Mosquitto to use TLS and restart the service:
sudo nano /etc/mosquitto/mosquitto.conf
Add:
listener 8883 certfile /etc/mosquitto/certs/mqtt_server.crt keyfile /etc/mosquitto/certs/mqtt_server.keyRestart Mosquitto:
sudo systemctl restart mosquitto
-
Test MQTT over TLS by subscribing on the broker and publishing from the IoT device:
- On the broker:
mosquitto_sub -h localhost -p 8883 -t test/topic/pki --cafile /etc/mosquitto/certs/mqtt_server.crt --insecure
- On the IoT device:
mosquitto_pub -h mqtt_ip -p 8883 -t test/topic/pki -m "Hello PKI!" --cafile /path/to/mqtt_server.crt --insecure
-
Install all Python dependencies in the requirements.txt
pip3 install -r requirements.txt
-
Test installation by running the example "SFTP-PKI-TEST.py" in the test folder
python3 ./test/SFTP-PKI-TEST.py
- Note: Use the full path to the private key (usually /etc/user/.ssh/..)
There are two scripts, under /scripts/ broker.py and iot.py.
Before running, make sure to create a file "PKI-Test" on the SFTP server.
touch PKI-TestEdit the contents of "PKI-Test" to include a message. Ideally, this would be the firmware that would be pulled down to the IoT device.
nano/vi PKI-TestRun the broker.py script first. Ensure you have all requirements installed correctly and the paths set correctly. Run the iot.py script next. Ensure you have all requirements installed correctly and that the paths are correctly set.
You can adjust the permissions accordingly if you encounter permission-related issues while transferring or accessing files. For example:
chmod -v 755 ./fileOrDirectoryDouble-check that all the paths of files are correct. I have the following set for this project-- SFTP:
- PKI-Test is located at '/home/test/PKI-Test'
- The username is "test"
Remember that Mosquitto does not read certificates from home directories by default. Place them in /etc/mosquitto/certs/ or a similar directory with proper permissions. As these are self-signed certificates for testing, the --insecure flag is necessary to bypass certificate verification.
