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.
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‑userPermission:
rw/rSFTP directory:
/data/project/projectChroot directory:
/projectGroup:
projectRW2. 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
/datavolume; ACL commands become
nfs4_setfacl.
11.2 Keep UID/GID consistent across servers
A Bash script gathers
/etc/passwdand
/etc/groupfrom 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.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.