Home

Awesome

Azure Scanned SFTP

What is sSFTP

Azure Scanned SFTP or simply sSFTP is a Go app deployed on Azure Container Instance to provide SFTP server and client services with integrated ClamAV virus scan and Azure File shares as file storage.

Features

How Things Work - Directories & Conventions

<img src="./doc/ssftp-modules-directories.png" width="850" height="600" />

Chaining sSFTP & Abusing It!

<img src="./doc/ssftp-chain.png" width="750" height="600" />

Apart from being a Sftp server and clients, its quite possible to chain up numerious sSFTP like laying connected jet bridges for the files to trave to their ultimate destination. Network channels between each sSFTP is secured with SSH and authentication, in addition each file is ClamAV scanned upon passing through each sSFTP instance.

How Things Work - Probable Deployment Model

<img src="./doc/ssftp-azure-architecture.png" width="900" height="700" />

Configuring sSFTP

Configurable is all done through a single Yaml file.
*ssftp.yaml must be located in mounted fileshare path as /mnt/ssftp/system/ssftp.yaml.
Update ssftp.yaml by uploading and overwriting Yaml file in ssftp-system fileshare, without restarting containers sSFTP monitors and load file changes from path: /mnt/ssftp/system/ssftp.yaml

<img src="./doc/ssftp-config-update.png" width="500" height="300" />
sftpClientDownloaders:              #Downloaders are Sftp clients runs concurrently to download files from remote Sftp servers
  - name: "test.rebex.net-1"        #mandatory unique name
    host: "test.rebex.net"
    port: 22
    username: "demo"
    password: "password"
    privateKeyPath: "/mnt/ssftp/system/downloaders/rsa-putty-privatekey-authn.ppk"
    privatekeyPassphrase: "password-for-privatekey" #empty if no privatekey path is empty
    localStagingDirectory: "staging-rebex-1"  #files downloaded to "staging" directory /mnt/ssftp/staging/{localStagingDirectory}
    remoteDirectory: ""             #optional
    deleteRemoteFileAfterDownload: false
    overrideExistingFile: true
sftpClientUploaders:              #Uploaders are Sftp clients runs concurrently to upload local files to remote Sftp servers
  - name: "sftpclient-uploader-1" #mandatory unique name
    host: "100.0.10.100"
    port: 22
    username: "sftpclient-uploader-1"
    password: "password"
    privatekeyPath: null              #example: /mnt/ssftp/system/sftpclient/uploader/privatekey.ppk
    privatekeyPassphrase: null
    localDirectoryToUpload: "test.rebex.net-1" # files in this "clean" directory to be uploaded to remote Sftp
    remoteDirectory: null           #leave it empty if no remote sub dir
    overrideRemoteExistingFile: true
users:
  cleanDir:                         
    - directory: "clean-dir-1"
      auth:
        username: "username-of-clean-dir-1"
        password: "verycomplexpassword"
        publicKey: "ssh-rsa AAAAB3NzaC...Akgdv/+1a45V1b...jfl5..BvQ=="
stagingDir:
  - directory: "stage-dir-1" # * not supporetd, sub directory name of Staging directory /mnt/ssftp/staging/{stage-dir-1}
    auth:
      username: "stage-dir-1"
      password: "supersecure"
      publicKey: "ssh-rsa AAAAB3NzaC...Akgdv/+1a45V1b...jfl5..BvQ=="

Deploy sSFTP

  1. Prerequisites
    Install Azure CLI

  2. Create Network Profile for Azure Container Instance

    2.1 Login to Azure
    <code> az login </code>

    2.2 To deploy ACI into a VNet Subnet ACI needs a network profile, this network profile can then be reuse to deploy 1 or more future ACI Container Groups into the same Subnet.
    The following command creates a temporary container instance in order to create a reusable network profile.
    <code> az container create --resource-group <resource group> --name aci-temp-test-np --image alpine --vnet $vnetName --subnet $subnetName --restart-policy never </code> <br /> <br /> Wait a moment for "aci-temp-test-np" container to complete creation, then <b>copy network profile id</b>

    <img src="./doc/azcli-networkprofile.png" width="750" height="400" /> <br /> <br /> 2.3 Delete container "aci-temp-test-np" (we only need this container to get the network profile ID) <code> az container delete -g <resource group> -n aci-temp-test-np -y </code>
  3. You can manually create the mandatory Azure File shares in Azure Portal or Azure Storage Explorer, or use this powershell script to do the same azfile-createfileshare-ssftp.ps1

  4. Deploy sSFTP using Container Instance Yaml

    4.1 Save a copy of sSFTP ACI Yaml file as "deploy-aci.yaml".
    Replace all < values > with comment "input", also note to <b>replace network profile id from Step 2.2</b>.

    4.2 Deploy yaml file by running the following command
    <code> az container create -g <resource group> --file .\deploy-aci.yaml </code>

An example of a successful deployment
<img src="./doc/ssftp-deploy-result.png" width="1100" height="600" />

Webhook

sSFTP supports webhook when a virus is found, HTTP POST schema below:

  {
    "username": "user1",
    "scanMessage": "Win.Test.EICAR_HDB-1 FOUND",
    "filePath": "/mnt/ssftp/quarantine/v.exe",
    "timeGenerated": "Tue Mar  9 05:50:06 2021"
  }

Networking

As ACI is deployed in a Subnet, you can choose to assign a Route Table/UDR on ACI Subnet to route all outbound traffic from sSFTP to an Azure Firewall or any NextGen Firewall.
An example of Azure Firewall Application Rule with domains whitelisted for sSFTP to work.
Also refer to How Things Work - Proposed Deployment Architecture. <br /> <img src="./doc/azfw-app-rules.png" width="850" height="150" />
<br /> <br />