工作需要,用户上传文件到目录下,用ftp不太安全,选择sftp。让用户在自己的home目录下活动,不能ssh到机器进行操作。
下面开始干活。 查看ssh版本 ssh -V,我的系统是CentOS6.4 ssh版本是5.3(大于4.8)的没有问题。
0, 创建用户目录root权限下创建用户和属组都是root
mkdir -p /opt/sftp/dir1/{upload,public}
1,创建 groupadd sftp
2. 创建 user -s /sbin/nologin -G sftp davis
user -s /sbin/nologin -G sftp davis1
3, 创建 davis 密码
passwd davis or echo davis:123456|chpasswd
passwd davis1
4, 修改sshd_config文件
#Subsystem sftp /usr/libexec/openssh/sftp-server(注释掉)
添加下面行
Subsystem sftp internal-sftp
Match Group sftp (Match User $username)
ChrootDirectory /opt/sftp/dir1 ($homedir)or %h
ForceCommand internal-sftp
X11Forwarding no
AllowTcpForwarding no
重启sshd /etc/init.d/sshd restart
5, 给目录附属权限
chown davis:sftp /opt/sftp/dir1/upload
chown davis1:sftp /opt/sftp/dir1/public
chmod 700 /opt/sftp/dir1/upload
chmod 700 /opt/sftp/dir1/public
6, 将upload 给davis用户
usermod -d /upload davis
usermod -d /public davis1
7, 测试 ssh davis@localhost 和 sftp davis@localhost or sftp -oPort=2000 davis@localhost(ssh端口更换为2000)
sftp登陆davis帐号,对应的是/upload,而davis1 登陆后则对应的是/public
注意:
要实现Chroot功能,目录权限的设置非常重要。否则无法登录,给出的错误提示让人无从下手。
目录权限设置
ChrootDirectory设置的目录权限及其所有的上级文件夹权限,属主和属组必须是root;
ChrootDirectory设置的目录权限及其所有的上级文件夹权限,只有属主能拥有写权限,也就是说权限最大设置只能是755
ChrootDirectory %h 如果选择了这种模式,用户的home目录必须是root:root 权限,否则就会报错。
记录一下,以备以后使用,同时也提供给有需要的朋友。
Sftp 密钥登录
mkdir -p $homedir/.ssh
chmod 700 $homedir/.ssh
chmod 600 $homedir/.ssh/authorized_keys
chown -R $username.sftp $homedir/.ssh
把用户生成的公钥改名为authorized_key即可
写了个脚本,内容如下
#!/bin/bash
#
#create sftp user
# Author: davis.qi
# Last Modified: 2013/11/14 by davis.qi
userfile=/etc/passwd
groupfile=/etc/group
homedir=/opt/sftp
loginshell=/sbin/nologin
groupname=sftp
username=$2
ssh_conf=/etc/ssh/sshd_config
fftp="Subsystem sftp internal-sftp"
gftp=`grep "internal-sftp" $ssh_conf`
pa=123456
function add_sshconf()
{
if [ "w$gftp" == "w" ]
then
echo "no sftp-config."
sed -i '/Subsystem/ s/^/#/' $ssh_conf
cat >> $ssh_conf <<EOF
Subsystem sftp internal-sftp
#Match user $username
Match group sftp
ChrootDirectory %h
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
EOF
else
echo "you have add sftp-config ok"
fi
}
function check_root()
{
if [ $EUID -ne 0 ]; then
echo "This script must be run as root"
exit 1
fi
}
function print_help(){
#Print help messages then exit
echo "Usage: $0 {create|add_sshdir|delete} {username}"
exit 1
}
function check_usergroup(){
#cut -d : -f 1 $groupfile | grep -wq $groupname
awk -F":" '{print $1}' $groupfile|grep -wq $groupname
if [ $? -ne 0 ];then
groupadd $groupname
else
echo " group $groupname is exist"
fi
}
function check_homedir(){
#Create homedir if NOT exist
if [ ! -d "$homedir" ];then
mkdir -p $homedir
fi
}
function check_username_exist(){
#Check if user already exist
#cut -d : -f 1 $userfile | grep -wq $username
awk -F":" '{print $1}' $userfile|grep -wq $username
if [ $? -eq 0 ];then
echo "User $username ALREADY exist."
else
useradd -d "$homedir/$username" -g $groupname -s $loginshell $username
fi
}
function mk_passwd(){
echo "create $username passwd"
echo $username:$pa|chpasswd
}
function mk_sshdir(){
# mkdir sshkey dir
mkdir $homedir/$username/.ssh
chmod 700 $homedir/$username/.ssh
#chmod 600 $homedir/$username/.ssh/authorized_keys
chown -R $username:$groupname $homedir/$username/.ssh
}
function mk_dir(){
# mkdir upload dir
chmod 755 -R $homedir
chown root.root $homedir/$username
mkdir $homedir/$username/$upload && echo "create upload dir success."
chown $username.$groupname $homedir/$username/$upload
}
if [ $# -lt 2 -o $# -gt 3 ];then
print_help
fi
if [ "w$3" == "w" ]
then
upload=upload
else
upload=$3
fi
case "$1" in
'create')
check_root
check_usergroup
check_homedir
add_sshconf && echo "add sshconfig on sshd_config ok"
check_username_exist && echo "User $username was created."
mk_dir && echo "$upload dir was created."
mk_passwd && echo "username $username passwd $pa"
mk_sshdir && echo "create .ssh dir ok"
;;
'delete')
check_root
userdel -rf $username && echo "User $username was deleted"
rm -rf $homedir$username && [ ! -d $homedir$username ] && echo "User dir was deleted"
;;
'add_sshdir')
mk_sshdir && echo "create .ssh dir ok"
;;
*)
print_help
;;
esac