Operations 14 min read

Mastering SFTP: Complete Planning, Configuration, and High‑Availability Guide

This guide walks you through SFTP server planning, user naming conventions, directory structures, SSH configuration, account creation, permission setup, client usage, log auditing, rotation, connection limits, monitoring, and high‑availability deployment across multiple servers, providing ready‑to‑run commands and scripts.

Raymond Ops
Raymond Ops
Raymond Ops
Mastering SFTP: Complete Planning, Configuration, and High‑Availability Guide

SFTP Planning

SFTP Server Port: 30022. Users are named using the pattern region‑project‑user (group or individual) with appropriate permissions and directory paths.

Username: region‑project‑user Permission: rw/r SFTP directory: /data/project/project Chroot directory: /project Group:

projectRW

2. Configure SFTP

2.1 Modify SSH configuration

# vi /etc/ssh/sshd_config
#Subsystem sftp internal-sftp
Match Group sftp
Match LocalPort 20912
ChrootDirectory %h   # chroot to the user's home directory
ForceCommand internal-sftp
# systemctl restart sshd

3. Create SFTP Accounts

3.1 Create directory structure

# mkdir -p /data/projectname/projectname
# chmod 775 /data/projectname/projectname

3.2 Create SFTP users

# useradd -s /bin/false -d /data/projectname CHN-projectname-b
# useradd -s /bin/false -d /data/projectname CHN-projectname-a

3.3 Set user passwords

# echo 'CHN-projectname-b:password1' | chpasswd
# echo 'CHN-projectname-a:password2' | chpasswd

3.4 Create permission group

# groupadd projectnameRW

3.5 Add write‑enabled users to the group

# usermod -aG projectnameRW CHN-projectname-b
# (add CHN-projectname-a to the group if it also needs write permission)

3.6 Set directory ownership

# chown root:projectnameRW /data/projectname/projectname

3.7 Configure ACL permissions

# chmod -R g+s /data/CN-project/CN-project
# setfacl -Rm d:g:groupname:rwx /data/CN-project/CN-project
# (for existing data) chown -R :groupname /data/CN-project/CN-project
# chmod -R 775 /data/CN-project/CN-project

3.8 Restart sshd service

# systemctl restart sshd

4. SFTP Client Usage

4.1 Linux 6

# sftp -oPort=30022 [email protected]
# -oPort=30022: SFTP server port
# CHN-project-user: SFTP username
# 10.0.0.1: SFTP server address

4.2 Linux 7

# sftp -P 30022 [email protected]
# (enter password when prompted)

5. SFTP Log Auditing

5.1 Enable verbose logging in sshd_config

# Subsystem sftp internal-sftp -l VERBOSE -f AUTHPRIV
# Match Group sftp
# Match LocalPort 20912
# ChrootDirectory %h
# ForceCommand internal-sftp -l VERBOSE -f AUTHPRIV

5.2 Configure log path

# cat /etc/rsyslog.conf
# authpriv.*    /var/log/sftp.log

5.3 Restart services to apply

# systemctl restart sshd
# systemctl restart rsyslog

6. SFTP Log Rotation

# cd /etc/logrotate.d/
# vi sftp
# /var/log/sftp.log {
#   monthly
#   missingok
#   rotate 6
#   compress
#   delaycompress
#   dateext
#   create 0600 root root
#   sharedscripts
#   postrotate
#     /bin/kill -HUP `cat /var/run/syslogd.pid`
#   endscript
# }

7. Per‑User Connection Limits

# cat /etc/security/limits.d/95-sftp-limit.conf
# @sftpusername hard nproc 400   # limit connections (400 = 200 users * 2)

8. Authentication Start‑up Limits

# cat /etc/ssh/sshd_config
# MaxStartups 1000:30:1200

9. Per‑User Maximum Open Files

# cat /etc/security/limits.conf
# * soft nofile 100000
# * hard nofile 100000

10. SFTP Monitoring Items

10.1 Monitor connection count

# netstat -an | grep -E '10.*:30022' | wc -l
# or
# ps -ef | grep 'sshd:' | grep 'notty' | wc -l

10.2 Log‑based connection alerts

# cat /var/log/sftp.log
# Mar 27 14:38:28 ... error: do_exec_no_pty: fork: Resource temporarily unavailable [postauth]
# ... subsystem request for sftp by user ... failed, subsystem not found [postauth]
# ... fatal: do_exec: command already set [postauth]

11. SFTP High Availability

11.1 Shared storage with NAS

Use NAS as the /data volume; ACL commands become nfs4_setfacl.

11.2 Keep UID/GID consistent across servers

A Bash script gathers /etc/passwd and /etc/group from each server, determines the next available UID/GID, creates identical groups and users on all servers, and sets passwords.

#!/bin/bash
# env define
sshuser=osadmin
workdir=/tmp
shijian=$(date +%Y_%M_%d_%H_%m)
server1=10.0.0.1
server2=10.0.0.2
server3=10.0.0.3
server4=10.0.0.4
sftpport=30022
sshport=22
new_user=${1}
user_pass=${2}
# ... (functions to fetch passwd/group, find max IDs, create groups/users, set passwords) ...
check_server_alive ${server1}${sftpport}
check_server_alive ${server2}${sftpport}
check_server_alive ${server3}${sftpport}
check_server_alive ${server4}${sftpport}
# ... (rest of the script) ...

11.3 Multi‑server user creation script

#!/bin/bash
# env
homedir='CN-ProjectName'
user1_name='user1'
user1_pass='password'
user1_rights='rw'
user2_name='user2'
user2_pass='password'
user2_rights='r'
sshuser=osadmin
server1=10.0.0.1
server2=10.0.0.2
server3=10.0.0.3
server4=10.0.0.4
# create project directory
mkdir -p /data/${homedir}/${homedir}
chmod 775 /data/${homedir}/${homedir}
chown root:root /data/${homedir}
# function to create sftp user on all servers
create_sftp_user(){
  sftpusername=$1
  sftpuserpassword=$2
  # call external script, set expiration, adjust home directory on each server
  ssh ${sshuser}@${server1} "sudo /sbin/usermod -d /data/${homedir}${sftpusername}"
  ssh ${sshuser}@${server2} "sudo /sbin/usermod -d /data/${homedir}${sftpusername}"
  ssh ${sshuser}@${server3} "sudo /sbin/usermod -d /data/${homedir}${sftpusername}"
  ssh ${sshuser}@${server4} "sudo /sbin/usermod -d /data/${homedir}${sftpusername}"
}
create_sftp_user ${user1_name} ${user1_pass}
create_sftp_user ${user2_name} ${user2_pass}
# configure NAS permissions
chown root:${user1_name} /data/${homedir}/${homedir}
chmod g+s /data/${homedir}/${homedir}
# configure user permissions
config_user_permissions(){
  user_name=$1
  user_rights=$2
  user_id=$(id -u ${user_name})
  if [ "${user_rights}" == 'rw' ]; then
    nfs4_setfacl -a A:df:${user_id}:RWX ${homedir}
  else
    nfs4_setfacl -a A:df:${user_id}:RX ${homedir}
  fi
}
config_user_permissions ${user1_name} ${user1_rights}
config_user_permissions ${user2_name} ${user2_rights}

12. SFTP User Idle Timeout

# Subsystem sftp internal-sftp
# Match Group sftp
# Match LocalPort 20981
# ClientAliveInterval 600
# ClientAliveCountMax 0
# ChrootDirectory %h
# ForceCommand internal-sftp -l VERBOSE -f AUTHPRIV

13. SFTP Server Migration

Reference migration steps can be found in external documentation.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

monitoringhigh availabilityLinuxACLSSHSFTP
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.