How To Install SFTPGo on Ubuntu 26.04 LTS

Install SFTPGo on Ubuntu 26.04

Managing secure file transfers on Linux servers often feels like wrestling with duct tape. You install OpenSSH, enable the SFTP subsystem, and suddenly you are dealing with no user isolation, no web interface, and permission nightmares that take hours to debug. In my 10 years managing production Linux infrastructure, I have seen this pattern repeat across dozens of servers until teams finally discover SFTPGo.

SFTPGo is a fully featured, open-source SFTP server that delivers HTTP/S Web UI, FTP/S, and WebDAV support from a single daemon. You can Install SFTPGo on Ubuntu 26.04 using the official PPA, and within 20 minutes you will have enterprise-grade file transfer capabilities with granular permissions, virtual folders, and support for S3, Google Cloud Storage, and Azure Blob backends.

This guide walks you through every command you need to configure SFTPGo on Ubuntu 26.04 securely, from firewall setup to SSL encryption and user management. I will explain not just what to type, but why each step matters based on real production experience.

Prerequisites

Before you type a single command, verify your environment meets these requirements. Skipping prerequisites is how production servers get compromised or misconfigured from day one.

  • Ubuntu 26.04 LTS fresh server installation (64-bit)
  • Non-root sudo user with administrative privileges — never run SFTPGo as root
  • Root or sudo access confirmed via sudo -v before starting
  • Minimum hardware: 1 vCPU and 512MB RAM (SFTPGo is compiled in Go and runs efficiently on small VMs)
  • Outbound internet access enabled on the server to download packages from the PPA
  • Optional: Registered domain name pointing to your server IP if you plan to enable Let’s Encrypt TLS certificates

Why the non-root user requirement? If SFTPGo or any service gets compromised, running as a dedicated non-root user limits the blast radius. Attackers cannot access /root, modify /etc, or affect other services on your system.

Step 1: Update Your System Packages

sudo apt update && sudo apt upgrade -y

What this command does: apt update refreshes your local package index against the current Ubuntu 26.04 repositories. apt upgrade -y installs all available security patches and bug fixes for currently installed packages.

Why this step is critical: Ubuntu 26.04 LTS ships with a known package list from its release date. Installing SFTPGo on top of unpatched system libraries is like building a house on a cracked foundation. Dependency conflicts and known CVEs come pre-installed if you skip this step.

Expected behavior:

Get:1 http://id.archive.ubuntu.com/ubuntu noble InRelease [256 kB]
Get:2 http://id.archive.ubuntu.com/ubuntu noble-updates InRelease [126 kB]
...
The following packages will be upgraded: 12
0 upgraded, 0 newly installed, 12 to remove and 0 not upgraded.

After the upgrade completes, check if a kernel update was applied:

uname -r

If the kernel version changed, reboot the server:

sudo reboot

Wait 2 minutes after reboot, then reconnect via SSH before proceeding.

Step 2: Configure UFW Firewall Before Installation

sudo apt install ufw -y
sudo ufw allow OpenSSH
sudo ufw allow 2022/tcp
sudo ufw allow 8080/tcp
sudo ufw enable
sudo ufw status

What these commands do:

  • apt install ufw -y installs the Uncomplicated Firewall package
  • ufw allow OpenSSH permits SSH traffic on port 22 so you do not lock yourself out
  • ufw allow 2022/tcp opens SFTPGo’s default SFTP port (not standard SSH port 22)
  • ufw allow 8080/tcp opens the Web Admin UI port
  • ufw enable activates the firewall rules immediately
  • ufw status displays the active firewall configuration

Why configure the firewall BEFORE installing SFTPGo: Many online tutorials skip this ordering and configure the firewall after installation. This is dangerous. If SFTPGo starts during installation and UFW is not yet configured, the service is briefly exposed on an open port to the entire internet. Always lock the perimeter first.

Why port 2022 and not 22? SFTPGo deliberately uses port 2022 to avoid conflicting with your existing OpenSSH server. This also reduces automated SSH brute-force attacks hitting your SFTP service since most bots target port 22.

Expected output after ufw status:

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
2022/tcp                   ALLOW       Anywhere
8080/tcp                   ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
2022/tcp (v6)              ALLOW       Anywhere (v6)
8080/tcp (v6)              ALLOW       Anywhere (v6)

Pro tip for production: Restrict Web Admin UI access to your IP only:

sudo ufw deny 8080/tcp
sudo ufw allow from YOUR.IP.ADDRESS.HERE to any port 8080

Step 3: Add the Official SFTPGo PPA Repository

sudo add-apt-repository ppa:sftpgo/sftpgo
sudo apt update

What these commands do: add-apt-repository adds the official SFTPGo PPA (Personal Package Archive) to your APT sources list and automatically imports the GPG signing key. apt update refreshes the package index so APT knows SFTPGo is now available for installation.

Why use the official PPA instead of Ubuntu’s default repository: SFTPGo is not included in Ubuntu’s default main or universe repositories. Installing from the official PPA maintained by SFTPGo’s authors guarantees you receive the latest stable release with security patches, not an outdated community snapshot that could be months old.

Why GPG key verification matters: The GPG signing key cryptographically verifies that packages originate from SFTPGo’s official maintainers and have not been tampered with during transit. Without this verification, you could accidentally install a malicious package that replaces the legitimate binary with malware.

Verify the PPA was added correctly:

cat /etc/apt/sources.list.d/sftpgo-ubuntu-sftpgo-*.list

Expected output:

deb [arch=amd64 signed-by=/usr/share/keyrings/sftpgo-archive-keyring.gpg] https://ppa.launchpadcontent.net/sftpgo/sftpgo/ubuntu noble main

If you see this output, the PPA is correctly configured and signed.

Step 4: Install SFTPGo Package

sudo apt install sftpgo -y

What this command does: Downloads and installs the SFTPGo package version 2.6 or later from the PPA, including all dependencies and systemd service configuration.

Why the -y flag: In automated or headless server environments, the -y flag confirms installation prompts non-interactively. In interactive sessions it saves a keystroke. If you want to review exactly what will be installed before proceeding, omit the -y flag and read the package list.

What the APT postinstall script automatically does:

  • Creates a dedicated sftpgo system user with non-login shell (/usr/sbin/nologin)
  • Registers and starts the sftpgo.service systemd unit
  • Places the default configuration at /etc/sftpgo/sftpgo.json
  • Creates /var/lib/sftpgo as the default data directory for SQLite database

Why a dedicated system user matters: Running SFTPGo as a dedicated, privilege-stripped user means that even if the process is exploited through a vulnerability, the attacker cannot read /root, write to /etc, or affect other services. This is the principle of least privilege in action.

Installation progress output:

Reading package lists... Done
Building dependency tree... Done
The following NEW packages will be installed:
  sftpgo
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 35.4 MB of archives.
Get:1 https://ppa.launchpadcontent.net/sftpgo/sftpgo/ubuntu noble/main amd64 sftpgo amd64 2.6.1 [35.4 MB]
Fetched 35.4 MB in 3s (10.5 MB/s)
Selecting previously unselected package sftpgo.
(Reading database ... 123456 files and directories currently installed.)
Preparing to unpack .../sftpgo_2.6.1_amd64.deb ...
Unpacking sftpgo (2.6.1) ...
Setting up sftpgo (2.6.1) ...
Processing triggers for systemd (255.4-1ubuntu8) ...

Wait for the installation to complete fully before proceeding to the next step.

Step 5: Start, Enable, and Verify SFTPGo Service

sudo systemctl start sftpgo
sudo systemctl enable sftpgo
sudo systemctl status sftpgo

What these commands do:

  • systemctl start sftpgo activates the SFTPGo service immediately without rebooting
  • systemctl enable sftpgo creates a symlink in the systemd target so SFTPGo starts automatically on every server reboot
  • systemctl status sftpgo displays the current service state, including whether it is running, enabled, and any recent log entries

Why systemctl enable is not optional: The start command only activates the service for the current boot session. Without enable, a server reboot leaves your SFTP service offline until someone manually intervenes. In production environments, this means downtime and angry users.

Healthy status output:

● sftpgo.service - SFTPGo
     Loaded: loaded (/lib/systemd/system/sftpgo.service; enabled; preset: enabled)
     Active: active (running) since Tue 2026-06-02 09:15:23 WIB; 5s ago
   Main PID: 12345 (sftpgo)
      Tasks: 12 (limit: 9234)
     Memory: 45.2M
     CPU: 1.234s

If status shows failed:

sudo journalctl -u sftpgo -n 50 --no-pager

This command shows the last 50 log lines from the SFTPGo service. Common failure causes include:

  • Port 2022 already in use by another process
  • Invalid JSON syntax in /etc/sftpgo/sftpgo.json
  • Permission issues on /var/lib/sftpgo

Check for port conflicts:

ss -tlnp | grep 2022

If you see output showing another process listening on port 2022, either stop that process or change SFTPGo’s port in the configuration file.

Step 6: Complete Initial Setup via Web Admin UI

Open your web browser and navigate to:

http://YOUR_SERVER_IP:8080

Replace YOUR_SERVER_IP with your server’s public IP address. Do not use localhost unless you are testing from the server itself.

Why the first-run wizard exists: SFTPGo ships with NO default admin credentials to prevent unauthorized access on first boot. The web wizard forces you to create an admin account with a password you control before any configuration is possible. This is a critical security measure.

Install SFTPGo on Ubuntu 26.04

Steps in the wizard:

  1. Enter a strong admin username — avoid admin, root, or administrator since these are dictionary-attacked immediately
  2. Set a strong password with minimum 12 characters including mixed case, numbers, and symbols
  3. Click “Create Admin” — you will be logged in automatically after creation

Post-login actions to complete immediately:

Navigate to Users in the left sidebar and click the “+” button to create your first SFTP user.

Why create users through the Web UI instead of command line: SFTPGo’s user system includes advanced features like virtual folders, per-user bandwidth limits, and SSH public key authentication that are difficult to configure manually via JSON editing. The Web UI provides a guided interface that prevents syntax errors.

User configuration checklist:

  • Set Home Directory to /srv/sftpgo/data/%username% — the %username% placeholder automatically creates separate directories for each user
  • Set Status to Enabled
  • Assign Max upload size per file (e.g., 1073741824 bytes = 1GB)
  • Choose Password auth or Public key auth or both
  • Set Allowed IPs if you want IP-based access restrictions

Create the parent directory before users exist:

sudo mkdir -p /srv/sftpgo/data
sudo chown -R sftpgo:sftpgo /srv/sftpgo/data
sudo chmod 750 /srv/sftpgo/data

Why set ownership to sftpgo:sftpgo: The SFTPGo service runs as the sftpgo user. If the data directory is owned by root, the service cannot write files to it. Proper ownership prevents permission errors that look like SFTPGo bugs but are actually filesystem configuration issues.

Test the connection immediately:

sftp -P 2022 yourusername@YOUR_SERVER_IP

Why -P 2022 and not -p 2022: The sftp command uses uppercase -P for port specification (unlike ssh which uses lowercase -p). This is a common mistake that results in confusing connection errors.

Successful connection output:

Connected to YOUR_SERVER_IP.
sftp> ls

Step 7: Configure SSL/TLS with Let’s Encrypt (ACME)

For any production server, running the Web Admin UI over plain HTTP is unacceptable. Credentials and session tokens transmit in cleartext and can be intercepted by anyone on the same network. SFTPGo has built-in ACME support for automatic Let’s Encrypt certificate issuance and renewal.

Prerequisites for SSL configuration:

  • A registered domain name pointed at your server’s public IP via A record
  • Port 80 accessible from the internet (required for HTTP-01 ACME challenge)
  • Valid email address for certificate expiration notifications

Edit the configuration file:

sudo nano /etc/sftpgo/sftpgo.json

Locate and update the acme section:

"acme": {
  "domains": ["yourdomain.com"],
  "email": "admin@yourdomain.com",
  "key_type": "4096",
  "certs_path": "/var/lib/sftpgo/certs",
  "ca_endpoint": "https://acme-v02.api.letsencrypt.org/directory",
  "renew_days": 30,
  "http01_challenge": {
    "port": 80,
    "webroot": ""
  }
}

Why key_type: 4096 instead of the default 2048: A 4096-bit RSA key offers stronger encryption than the 2048-bit default, making brute-force attacks on the private key computationally infeasible with current hardware. The performance difference is negligible for typical SFTP workloads.

Run certificate issuance manually:

sudo -E su - sftpgo -m -s /bin/bash -c 'sftpgo acme run -c /etc/sftpgo'

What this command does: Switches to the sftpgo user and runs the ACME certificate issuance process. The -E flag preserves your environment variables, and -m ensures the shell is invoked properly.

Expected successful output:

Certificate successfully obtained for domains: yourdomain.com
Certificate stored in: /var/lib/sftpgo/certs/fullchain.pem
Private key stored in: /var/lib/sftpgo/certs/privkey.pem

Update HTTP binding to enable HTTPS:

In the same sftpgo.json file, locate the httpd.bindings section and update it:

"httpd": {
  "bindings": [
    {
      "address": "0.0.0.0",
      "port": 9443,
      "protocol": "https",
      "tls_config": {
        "certificate_file": "/var/lib/sftpgo/certs/fullchain.pem",
        "key_file": "/var/lib/sftpgo/certs/privkey.pem"
      }
    }
  ]
}

Why port 9443 instead of 443: Port 443 requires root privileges to bind. Running SFTPGo as root violates the principle of least privilege. Port 9443 provides HTTPS without elevated privileges.

Validate JSON syntax before restarting:

python3 -m json.tool /etc/sftpgo/sftpgo.json > /dev/null && echo "JSON is valid"

Why validate JSON first: A single misplaced comma in sftpgo.json causes the service to fail to start. Validating takes 2 seconds and avoids a service outage that could take 15 minutes to debug.

Apply changes:

sudo systemctl restart sftpgo
sudo systemctl status sftpgo

Access your Web Admin UI at https://yourdomain.com:9443 with a padlock icon in the browser address bar.

Certificates auto-renew 30 days before expiry via a systemd timer. Verify the timer is active:

sudo systemctl list-timers | grep sftpgo

Troubleshooting Common Issues

Even with perfect instructions, real-world installations encounter problems. Here are the most common issues I have debugged across production deployments.

Issue 1: Service Fails to Start After Installation

Symptoms: systemctl status sftpgo shows Active: failed

Most likely cause: Port 2022 already in use by another process

Solution:

ss -tlnp | grep 2022

If you see output showing another process, identify it and either stop it or change SFTPGo’s port in /etc/sftpgo/sftpgo.json:

"sftpd": {
  "bindings": [
    {
      "port": 2023,
      "address": "0.0.0.0"
    }
  ]
}

Then update your firewall rules:

sudo ufw allow 2023/tcp
sudo ufw delete allow 2022/tcp

Issue 2: Cannot Reach Port 8080 or 9443 from Browser

Symptoms: Browser shows “Connection timed out” or “Unable to connect”

Most likely cause: UFW firewall blocking the port or wrong IP address

Solution:

sudo ufw status

Verify you see 8080/tcp ALLOW Anywhere or 9443/tcp ALLOW Anywhere in the output. If not:

sudo ufw allow 8080/tcp
sudo ufw allow 9443/tcp

Also verify you are using the correct server IP. If you are behind a NAT router, you need the public IP, not the private LAN IP. Check with:

curl -s https://api.ipify.org

Issue 3: SFTP Connection Refused

Symptoms: sftp -P 2022 user@IP returns Connection refused

Most likely cause: SFTPGo service not running

Solution:

sudo systemctl status sftpgo
sudo systemctl start sftpgo

If the service fails to start, check logs:

sudo journalctl -u sftpgo -n 50 --no-pager

Issue 4: JSON Configuration Syntax Error

Symptoms: Service fails after editing sftpgo.json with error “invalid character”

Most likely cause: Misplaced comma, missing bracket, or unquoted string in JSON

Solution:

python3 -m json.tool /etc/sftpgo/sftpgo.json

This command highlights the exact line with the syntax error. Fix the issue and revalidate before restarting the service.

Issue 5: Certificate Not Issued via ACME

Symptoms: ACME command returns “DNS problem” or “Timeout during challenge”

Most likely cause: Domain not pointing to your server or port 80 blocked

Solution:

dig yourdomain.com

Verify the A record returns your server’s public IP. If not, update your DNS configuration at your domain registrar.

Also verify port 80 is accessible:

sudo ufw allow 80/tcp
curl -I http://yourdomain.com

[su_box title=”VPS Manage Service Offer” style=”bubbles” box_color=”#000000″ radius=”10″]If you don’t have time to do all of this stuff, or if this is not your area of expertise, we offer a service to do “VPS Manage Service Offer”, starting from $10 (Paypal payment). Please contact us to get the best deal![/su_box]

r00t is a Linux Systems Administrator and open-source advocate with over ten years of hands-on experience in server infrastructure, system hardening, and performance tuning. Having worked across distributions such as Debian, Arch, RHEL, and Ubuntu, he brings real-world depth to every article published on this blog. r00t writes to bridge the gap between complex sysadmin concepts and practical, everyday application — whether you are configuring your first server or optimizing a production environment. Based in New York, US, he is a firm believer that knowledge, like open-source software, is best when shared freely.

Related Posts