前言
本文根据本科时的操作系统大作业改编,详细讲解了在Linux下搭建ftp服务器要求、实现以及最终结果。
要求
根据所学内容,使用一种或多种服务(如 ftp、samba、Http)搭建一台服务器,完成下述功能:
- 学生用户能实现学生作业的上传,学生以“姓名+学号”命名作业。 学生能看到作业列表,但是不能下载。
- 在指定的交作业截止时间到时,编写脚本自动统计交作业的学生名 单和人数,生成文档,供教师查看。
- 教师用户能够查看学生提交的作业,在生成的交作业名单中录入成 绩,并发布成绩,供学生查看。
- 对于指定格式的作业,编写脚本自动批改作业并在交作业名单中记录成绩。(注:格式可以自己指定,也可做成模板供学生下载使用)
- 教师可以提供课件和参考资料供学生下载。
- 控制每个学生用户上传文件的个数不得超过 10 个。
- 注:可以根据题目要求,自己设定相关目录和权限
实现
环境
- ubuntu16.04
- vsftpd
FTP相关配置
基本配置
annoymous_enable=No local_enable=YES write_enable=YES
- 不允许匿名登录
- 使在/etc/passwd中的账号以实体用户的方式登录服务器
- 允许写(即上传)
关键配置
local_root=/home/shared/ftp #用来指定服务器所在的目录,否则将在它的默认目录 allow_writeable_chroot=YES #允许有写权限的chroot chroot_local_user=YES #使使用者变为chroot除了下面表中的用户 chroot_list_enable=YES #启用chroot列表,该列表内填写不被chroot的账号列表 chroot_list_file=/etc/vsftpd.chroot_list #chroot列表位置(该列表一行一个用户名) local_umask=037 #设置在服务器上传的文件的默认权限,真实权限为777-umask的权限,即这里我设置的默认权限为740
- chroot可以使系统的目录结构以指定的位置作为
/位置 - 也就是说设置了chroot就禁止了用户切换到服务器目录的上级目录
- umask为037即
- 拥有者有所有权限
- 拥有组有可读权限
- 其他人无任何权限
其它配置
banner_file=/etc/vsftpd_banner_file.txt
dirmessage_enable=YES
- 进服务器后的欢迎语,这里读一个我写的txt文件
- 当用户进入某目录时会显示内容,显示的内容默认为该目录下的.message文件
非chroot与chroot的区别
用户与组情况说明
- 用户
- tux
- bob
- lily
- Alice
- teacher
- 组
- xjtuse 包含
- tux
- bob
- lily
- Alice
- teacher
- teacher 包含
- teacher
- student 包含
- tux
- bob
- lily
- xjtuse 包含
服务器目录的权限逻辑设置
ftp |-- homework //学生作业存放处 | |-- tux_2161601000 | |-- bob_2161601001 | `-- lily_2161601003 |-- textbook //学习资料存放处 | |-- how_to_use_crontab.txt | |-- ppt | `-- ... `-- homework_list.txt //学生交作业情况及分数登记
可以看到homework的权限为777,除此以外group还多了一个s的权限。关于特殊权限(s、t)这里不阐述太多,在这里给group设置s权限的目的就是让该目录下的所有文件的组与该目录的组一致,也就是都是teacher组。这么设置是为了让homework目录下的文件(也就是学生交的作业)的owner为学生自己,组为teacher,为什么要这么设计呢,我们在下面讨论。
homework_list.txt用于存放学生交作业情况统计与学生的分数,它的owner和group都为teacher,other的权限只有r,这就保证了只有teacher能上传,学生们只能读。
textbook目录owner为teacher,group为xjtuse,这样的权限设置使得只有teacher与xjtuse组内用户可以读、执行该目录,也就是只有xjtuse的学生和老师才能进入该目录。除此之外owner还有一个w权限表示只有老师可以在这里面上传资料。
根据上面homework目录的设置,该目录下的文件owner为上传者,而组与homework一致,为teacher。
根据服务器umask037得上传的文件权限均为740,如图所示。这就实现了仅学生自己能上传与下载自己的作业,teacher仅能下载,而其它学生没有任何权限。
脚本设计并自动执行
统计交作业情况
用date命令取得当前时间,以此打印出统计学生数量时的时间
遍历在homework目录下的文件,统计数量,再将文件名以_分割,取前半部分(也就是学生的姓名)写入文件中
最终给出统计得的学生数量
#!/bin/bash count=0 TIME=`date "+%Y-%m-%d %H:%M:%S"` echo "Update time is $TIME" >> homework_list.txt echo "-----------------------------------" >> homework_list.txt echo -e "Name\n" >> homework_list.txt for FILE in `ls homework/` do ((count++)) # # to delete left % to delete right echo ${FILE%_*} >> homework_list.txt done echo "-----------------------------------" >> homework_list.txt echo -e "$count Totally\n" >> homework_list.txt exit 0
在crontab下设置当前用户定时自动执行该脚本
crontab -e
添加
* 18 * * 1-5 ./count_list.sh
表示每礼拜一到礼拜五晚上6点执行一次该脚本,即统计学生交作业情况。
cron格式为
# Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed example: # every mon to fri 18:00 excute count_list.sh 0 18 * * 1-5 ./count_list.sh
自动批改指定格式的作业
我指定的格式为
1.A 2.B 3.C 4.D 5.A 6.B 7.C 8.D 9.A 10.B
还要在与脚本同目录下创建一个正确答案文件correct_answer.txt,在里面按格式写好正确答案。
首先用sed在交作业名单的Name后面加上Score。
然后遍历homework目录下的文件,每遍历到一个文件,再遍历该文件的每一行,然后与正确答案的对应行匹配,以此来计分。
匹配答案运用awk,用NR匹配行号,然后打印出该行第二个参数($2),即作业的答案,用同样的方法在正确答案里取得每一行的答案,然后进行比较来计分。
算出分数后同样运用sed在每个学生姓名后加上分数。
#!/bin/bash sed -i "s/Name/&\tScore/" homework_list.txt for FILE in `ls homework/` do score=0 # compare student\'s answer with correct answer line by line. for ((i=1;i<=10;i++)) do answer=`awk -F. \'NR==\'"$i"\'{print $2}\' homework/$FILE` correct_answer=`awk -F. \'NR==\'"$i"\'{print $2}\' correct_answer.txt` #echo "${FILE%_*}\'s answer is $answer , right answer is $correct_answer." # if the two answers are the same one, score+10. if test "$answer" = "$correct_answer" then ((score+=10)) fi done # add score behind name sed -i "s/${FILE%_*}/&\t$score/g" homework_list.txt done #sed "s/bob/& 100/" homework_list.txt exit 0
磁盘限额的实现
首先用fdisk进行分区,分出一块区并将其格式化为ext3(或其他),然后编辑/etc/fstab,添加一条新纪录来将分出来的区挂载到服务器目录上,属性内要加上usrquota和grpquota,这样才能使用quota。编辑完后运用mount进行挂载(注:此时会格覆盖掉你的原有目录,所以我采用的办法是先挂载到一个空目录上,再将服务器目录mv过来,记得要把设置的权限一同搬过来)。这样就完成了挂载,可以对服务器用quota进行限额了。
然后先初始化限额系统
quotacheck -avug
会生成aquota.user和auota.group文件。
限额时用下面的命令来进行限额,
edquota -u 用户名
然后再用下面的命令来复制限额配置。
edquota -p 待复制用户名 被复制用户名
我们的要求是限制学生上传数量不大于10个,那么就调在最右边的soft和hard,都调成10。
左边的soft和hard是限制文件大小的,而右边的是限制文件个数的。
soft是软限制,若用户超过他设置的值,他们可以在一段固定的时间内通过删除文件或块来释放空间,若用户超过了宽限期,则他不能创建任何新的文件指导他删除了足够的文件回到软限制的范围之内。可以通过edquota -t来设置宽限期。
hard是硬限制,若用户超过了这限制就不能创建新的文件了。
设置完之后重启quota服务来激活设置,这样就完成了限额。
限额报告
结果参考
学生
学生tux登录服务器
tux交作业
tux尝试抄作业下载他人作业
tux查询成绩
lily下载学习资料
尝试上传超过10个文件,在上传第11个时失败
老师
老师下载学生作业老师查看作业并给分
老师运用脚本自动统计学生交作业情况
老师运用脚本自动批改作业
老师上传分数列表
老师上传学习资料
问题
- allow_writeable_chroot=YES
Ubuntu下的vsftpd已经不支持具有写属性的root目录了,如果不添加这一配置用户除非将用户根目录的写属性去掉否则将无法登录进服务器。 - 分区问题
虚拟机下只需再分配一块新的硬盘即可,但由于我是双系统环境,分配硬盘需要自己来分,就回到win10下再分了一块给ubuntu,然后在里面分一块区给服务器使用。
在编辑fstab时也要格外小心,一不小心编辑错了还会导致无法开机亲身经历。