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

<code># 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</code>

3. Create SFTP Accounts

3.1 Create directory structure

<code># mkdir -p /data/projectname/projectname
# chmod 775 /data/projectname/projectname</code>

3.2 Create SFTP users

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

3.3 Set user passwords

<code># echo 'CHN-projectname-b:password1' | chpasswd
# echo 'CHN-projectname-a:password2' | chpasswd</code>

3.4 Create permission group

<code># groupadd projectnameRW</code>

3.5 Add write‑enabled users to the group

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

3.6 Set directory ownership

<code># chown root:projectnameRW /data/projectname/projectname</code>

3.7 Configure ACL permissions

<code># 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</code>

3.8 Restart sshd service

<code># systemctl restart sshd</code>

4. SFTP Client Usage

4.1 Linux 6

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

4.2 Linux 7

<code># sftp -P 30022 [email protected]
# (enter password when prompted)</code>

5. SFTP Log Auditing

5.1 Enable verbose logging in sshd_config

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

5.2 Configure log path

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

5.3 Restart services to apply

<code># systemctl restart sshd
# systemctl restart rsyslog</code>

6. SFTP Log Rotation

<code># 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
# }</code>

7. Per‑User Connection Limits

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

8. Authentication Start‑up Limits

<code># cat /etc/ssh/sshd_config
# MaxStartups 1000:30:1200</code>

9. Per‑User Maximum Open Files

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

10. SFTP Monitoring Items

10.1 Monitor connection count

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

10.2 Log‑based connection alerts

<code># 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]</code>

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.

<code>#!/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) ...</code>

11.3 Multi‑server user creation script

<code>#!/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}</code>

12. SFTP User Idle Timeout

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

13. SFTP Server Migration

Reference migration steps can be found in external documentation.

monitoringoperationsHigh 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

login 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.