🛡️ Secure SFTP Publishing via Bastion to Synology

This page documents the architecture and implementation of Pattern B: exposing SFTP to the internet through a hardened bastion host in the DMZ, which transparently tunnels all SFTP traffic to Synology on the internal LAN.

Synology remains completely hidden from the internet and never placed in the DMZ. This pattern provides strong isolation, minimal attack surface, and clean firewall boundaries.


🌐 High‑Level Architecture

                     Internet
                         |
                 [ Cloudflare WAF ]
                         |
                 Firewall (WAN → DMZ)
                         |
                    VLAN 30 (DMZ)
                         |
                +-------------------+
                |   Bastion Host    |
                |  Exposes SFTP:22  |
                |  No shell access  |
                +-------------------+
                         |
                 SSH (LAN-only)
                         |
                    VLAN 10 (LAN)
                         |
             +------------------------+
             |     Synology NAS       |
             |  SSH/SFTP internal     |
             |  Never internet-facing |
             +------------------------+

The bastion receives all external SFTP connections and immediately forwards them to Synology using a forced SSH command.
Users never interact with the bastion filesystem.


🎯 Goals of This Pattern


🧱 Bastion Host Responsibilities

The bastion acts as a transparent SFTP relay:


🔧 Implementation Steps

Create a dedicated SFTP user on the bastion

sudo adduser sftpuser --shell /usr/sbin/nologin

This user cannot log in interactively.


Generate SSH keys for the bastion → Synology connection

sudo -u sftpuser ssh-keygen -t ed25519 -f /home/sftpuser/.ssh/id_synology

Copy the public key to Synology:

ssh-copy-id -i /home/sftpuser/.ssh/id_synology.pub synologyuser@<synology-ip>

Harden the bastion’s sshd_config

Add:

Match User sftpuser
    PasswordAuthentication no
    PubkeyAuthentication yes
    X11Forwarding no
    AllowTcpForwarding yes
    PermitTunnel no
    ForceCommand ssh -i /home/sftpuser/.ssh/id_synology synologyuser@192.168.10.50

This forces the bastion to immediately SSH into Synology on behalf of the user.


Configure Synology

Synology only sees a single trusted SSH client: the bastion.


🔥 Firewall Rules

WAN → DMZ

Allow:

Deny everything else.


DMZ → LAN

Allow:

Deny:

This ensures the bastion cannot pivot.


🧩 Connection Flow (ASCII Diagram)

+-------------------------+
|      SFTP Client        |
|  (User on the Internet) |
+-----------+-------------+
            |
            |  SFTP over SSH (port 22)
            v
+-------------------------+
|   Firewall / Cloudflare |
|   Allowlist Enforcement |
+-----------+-------------+
            |
            v
+-------------------------+
|     Bastion Host        |
|  VLAN 30 (DMZ Network)  |
|  - No shell             |
|  - Key-only auth        |
|  - ForcedCommand → SSH  |
+-----------+-------------+
            |
            |  SSH (internal only)
            v
+-------------------------+
|      Synology NAS       |
|   VLAN 10 (LAN Network) |
|   - Never exposed       |
|   - Restricted user     |
+-------------------------+

🧪 Security Properties