Skip to content

FTP Settings Example

This example demonstrates how to configure FTP server settings on a Qumulo cluster using the qumulo_ftp_settings resource. This is a singleton resource that controls global FTP behavior for the cluster.

Features

The qumulo_ftp_settings resource configures:

  • FTP enable/disable for the entire cluster
  • FTPS (FTP over TLS) enforcement for encrypted connections
  • Chroot to restrict users to their home directories
  • Anonymous FTP access with user mapping
  • Custom greeting messages
  • FXP attack prevention via remote host checking
  • Wildcard expansion for directory listings

Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                          FTP SETTINGS SCOPE                                  │
└─────────────────────────────────────────────────────────────────────────────┘

                            QUMULO CLUSTER
┌─────────────────────────────────────────────────────────────────────────────┐
│                                                                             │
│   ┌─────────────────────────────────────────────────────────────────────┐   │
│   │                     FTP SERVER SETTINGS                             │   │
│   │  qumulo_ftp_settings (singleton)                              │   │
│   │                                                                     │   │
│   │  • Enabled: true                                                    │   │
│   │  • FTPS Only: true (allow_unencrypted = false)                      │   │
│   │  • Chroot Users: true                                               │   │
│   │  • Check Remote Host: true (FXP protection)                         │   │
│   │  • Greeting: "Welcome to Qumulo FTP Server"                         │   │
│   └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│   ┌───────────────────────────────────────────────────────────────────┐     │
│   │                        FILESYSTEM                                 │     │
│   │                                                                   │     │
│   │  /home/alice ◄──── alice (chrooted to home)                       │     │
│   │  /home/bob   ◄──── bob (chrooted to home)                         │     │
│   │  /ftp/pub    ◄──── anonymous -> ftp_anonymous (mapped user)       │     │
│   │                                                                   │     │
│   └───────────────────────────────────────────────────────────────────┘     │
│                                                                             │
│   Ports: 21 (control), 989-990 (FTPS), 1024-65535 (passive data)           │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
         │                    │                    │
         │ FTPS (TLS)         │ FTPS (TLS)         │ FTPS (TLS)
         │                    │                    │
         ▼                    ▼                    ▼
   ┌───────────┐        ┌───────────┐        ┌───────────┐
   │ FileZilla │        │ WinSCP    │        │ lftp      │
   │ Client    │        │ Client    │        │ (Linux)   │
   │           │        │           │        │           │
   └───────────┘        └───────────┘        └───────────┘

Prerequisites

  1. Qumulo cluster with REST API access (port 8000)
  2. Admin credentials for the cluster

Usage

  1. Create a terraform.tfvars file:
cluster_endpoint = "https://cluster.example.com:8000"
cluster_username = "admin"
cluster_password = "cluster-admin-password"

# FTP settings
enable_ftp       = true
chroot_users     = true
allow_unencrypted = false  # FTPS only
enable_anonymous = false
ftp_greeting     = "Welcome to Qumulo FTP Server"
  1. Initialize and apply:
terraform init -upgrade
terraform plan
terraform apply

Variables

Name Description Type Default
cluster_endpoint Qumulo cluster REST API endpoint string -
cluster_username Qumulo cluster admin username string "admin"
cluster_password Qumulo cluster admin password string -
enable_ftp Enable FTP connections to the cluster bool true
chroot_users Restrict users to their home directories bool true
allow_unencrypted Allow unencrypted FTP (false = FTPS only) bool false
enable_anonymous Enable anonymous FTP access bool false
anonymous_user Local user to map anonymous logins to string "ftp_anonymous"
ftp_greeting Custom greeting message for FTP clients string "Welcome..."

Outputs

Name Description
ftp_enabled Whether FTP is enabled on the cluster
ftp_encrypted_only Whether unencrypted connections are blocked
ftp_chroot_enabled Whether users are chrooted to home directories
ftp_greeting FTP server greeting message

Configuration Examples

Secure FTPS Only

Maximum security with encrypted connections only:

resource "qumulo_ftp_settings" "secure" {
  connection_profile = "cluster1"

  enabled      = true
  chroot_users = true
  greeting     = "Secure FTP Server - TLS Required"

  # Security settings
  allow_unencrypted_connections = false  # FTPS only
  check_remote_host             = true   # Prevent FXP attacks
  log_operations                = true   # Audit logging

  # No anonymous access
  anonymous_user {
    id_type  = "LOCAL_USER"
    id_value = "nobody"  # Placeholder, not used
  }
}

Anonymous FTP (Read-Only Public)

For public file distribution:

resource "qumulo_ftp_settings" "anonymous" {
  connection_profile = "cluster1"

  enabled      = true
  chroot_users = true
  greeting     = "Public FTP Server - Anonymous Access Allowed"

  # Allow unencrypted for wider compatibility
  allow_unencrypted_connections = true

  # Enable wildcard expansion for directory listings
  expand_wildcards = true

  # Map anonymous logins to a restricted local user
  anonymous_user {
    id_type  = "LOCAL_USER"
    id_value = "ftp_public"  # Create this user with read-only permissions
  }
}

Note: Ensure the mapped user (ftp_public) has appropriate read-only permissions on the public directory.

Legacy Compatibility

For environments requiring plain FTP:

resource "qumulo_ftp_settings" "legacy" {
  connection_profile = "cluster1"

  enabled      = true
  chroot_users = false  # Allow full filesystem access
  greeting     = "FTP Server"

  # Allow unencrypted (not recommended)
  allow_unencrypted_connections = true
  check_remote_host             = false  # Disable FXP check for legacy clients

  log_operations = true

  anonymous_user {
    id_type  = "LOCAL_USER"
    id_value = "nobody"
  }
}

Warning: This configuration has reduced security. Use only when absolutely necessary.

Disabled FTP

To completely disable FTP access:

resource "qumulo_ftp_settings" "disabled" {
  connection_profile = "cluster1"

  enabled = false

  # Other settings are ignored when disabled
  chroot_users                  = true
  allow_unencrypted_connections = false

  anonymous_user {
    id_type  = "LOCAL_USER"
    id_value = "nobody"
  }
}

Security Considerations

FTPS vs Plain FTP

Aspect Plain FTP FTPS (TLS)
Credentials Sent in clear text Encrypted
Data transfer Unencrypted Encrypted
Man-in-the-middle Vulnerable Protected
Recommendation Avoid Recommended

Always set allow_unencrypted_connections = false unless you have specific legacy requirements.

Chroot Security

  • Enabled: Users can only access their home directory and below
  • Disabled: Users can navigate the entire filesystem (subject to permissions)

Recommendation: Always enable chroot_users = true for multi-tenant environments.

FXP Attack Prevention

The check_remote_host setting prevents FXP (File eXchange Protocol) bounce attacks where an attacker uses your server to transfer files to a third party.

Recommendation: Keep check_remote_host = true unless you specifically need FXP functionality.

Anonymous Access Risks

When enabling anonymous FTP:

  1. Create a dedicated local user with minimal permissions
  2. Restrict the user's home directory to a specific public folder
  3. Set permissions to read-only if possible
  4. Monitor for abuse

Full Configuration

# Example: Managing FTP Settings on a Qumulo Cluster
#
# This example demonstrates how to configure FTP server settings
# on a Qumulo cluster using the qumulo_ftp_settings resource.
#
# The resource supports:
# - Enabling/disabling FTP connections
# - Chroot users to their home directories
# - Requiring encrypted connections (FTPS)
# - Anonymous FTP access
# - Custom greeting messages
# - Wildcard expansion in LIST/NLST commands
#
# Note: This is a singleton resource - there is only one FTP
# configuration per cluster.

terraform {
  required_providers {
    qumulo = {
      source  = "qumulo-terraform-registry.s3.us-east-1.amazonaws.com/qumulo/qumulo"
      version = "~> 1.0"
    }
  }
}

variable "cluster_endpoint" {
  description = "Qumulo cluster REST API endpoint (e.g., https://cluster:8000)"
  type        = string
}

variable "cluster_username" {
  description = "Qumulo cluster admin username"
  type        = string
  default     = "admin"
}

variable "cluster_password" {
  description = "Qumulo cluster admin password"
  type        = string
  sensitive   = true
}

# Variables for FTP configuration
variable "enable_ftp" {
  description = "Enable FTP connections to the cluster"
  type        = bool
  default     = true
}

variable "chroot_users" {
  description = "Restrict users to their home directories"
  type        = bool
  default     = true
}

variable "allow_unencrypted" {
  description = "Allow unencrypted FTP connections (set to false for FTPS only)"
  type        = bool
  default     = false
}

variable "enable_anonymous" {
  description = "Enable anonymous FTP access"
  type        = bool
  default     = false
}

variable "anonymous_user" {
  description = "Local user to map anonymous logins to (only used if enable_anonymous is true)"
  type        = string
  default     = "ftp_anonymous"
}

variable "ftp_greeting" {
  description = "Custom greeting message for FTP clients"
  type        = string
  default     = "Welcome to Qumulo FTP Server"
}

# Define connection profile for the cluster
provider "qumulo" {
  connection_profiles = [
    {
      name                 = "cluster1"
      endpoint             = var.cluster_endpoint
      username             = var.cluster_username
      password             = var.cluster_password
      insecure_skip_verify = true # Required for clusters with self-signed certificates
    }
  ]
}

# ------------------------------------------------------------------------------
# FTP Configuration
# ------------------------------------------------------------------------------
# Configure FTP server settings. The variables control:
# - allow_unencrypted: false = FTPS only (secure), true = allow plain FTP
# - enable_anonymous: whether to allow anonymous FTP logins
# - chroot_users: restrict users to their home directories

resource "qumulo_ftp_settings" "this" {
  connection_profile = "cluster1"

  # Core settings
  enabled      = var.enable_ftp
  chroot_users = var.chroot_users
  greeting     = var.ftp_greeting

  # Security settings
  allow_unencrypted_connections = var.allow_unencrypted
  check_remote_host             = true # Prevent FXP attacks

  # Logging
  log_operations = true

  # Enable wildcard expansion for directory listings (useful for anonymous)
  expand_wildcards = var.enable_anonymous

  # Anonymous user mapping (required by schema)
  anonymous_user {
    id_type  = "LOCAL_USER"
    id_value = var.anonymous_user
  }
}

# Outputs
output "ftp_enabled" {
  description = "Whether FTP is enabled on the cluster"
  value       = qumulo_ftp_settings.this.enabled
}

output "ftp_encrypted_only" {
  description = "Whether unencrypted connections are blocked"
  value       = !qumulo_ftp_settings.this.allow_unencrypted_connections
}

output "ftp_chroot_enabled" {
  description = "Whether users are chrooted to their home directories"
  value       = qumulo_ftp_settings.this.chroot_users
}

output "ftp_greeting" {
  description = "FTP server greeting message"
  value       = qumulo_ftp_settings.this.greeting
}