多用户态是 GNU/Linux 的一个创举,引入了多用户、多任务的概念,任何操作都需要建立在用户的基础上。
用户系统一方面可以帮助系统管理员对使用系统的用户进行跟踪,并控制用户对系统资源的访问;另一方面也可以帮助用户组织文件,并为用户提供安全性保护。
用户的管理
Linux 下的用户系统引入了用户与用户组的概念,用户组可以提高此系统的灵活度,可将部分用户划分为组,使得组内资源可以共享。
用户及组添加
使用 useradd
命令即可添加系统用户。
# useradd [options] LOGIN
常用参数 | 长参数 | 作用及描述 | 注意事项 |
---|---|---|---|
-c | --comment | 指定用户的描述 | 非必要 |
-d | --home-dir | 指定用户的家目录 | / |
-D | --default | 修改默认参数 | / |
-e | --expiredate | 指定用户的过期时间 | 时间格式必须为 YYYY-MM-DD |
-f | --inactive | 指定用户密码过期后的禁用时间 | / |
-g | --gid | 指定用户的所属用户组 | / |
-G | --groups | 指定用户的所属用户组群 | 使用此参数可将用户添加至多个用户组 |
-m | --create-home | 自动为用户创建用户家目录 | 默认为 /home/用户名 |
-M | --no-create-home | 不创建用户家目录 | / |
-u | --uid | 指定用户的UID | / |
-s | --shell | 指定用户登陆的命令解释器 | / |
-r | --system | 指定用户为系统账户 | 可使用 UID 1000 以内 |
-p | --password | 指定用户密码 | / |
使用 groupadd
命令即可添加用户组
# groupadd [options] group
常用参数 | 长参数 | 作用及描述 | 注意事项 |
---|---|---|---|
-f | --force | 强制添加用户组 | 若用户组已经存在,则会随机分配另一个 GID |
-g | --gid | 指定用户的 GID | / |
-r | --system | 指定用户组系统用户组 | / |
举个例子:
例一:建立一个不允许登陆,且不创建家目录的用户 www-data(常用来给服务使用)
# useradd -s /sbin/nologin -M www-data
例二:建立一个 UID 为 666,且 GID 为 666 的用户 www-data
# groupadd -g 666 www-data
# useradd -u 666 -g www-data www-data
用户及组删除
使用 userdel
命令即可删除用户
# userdel [options] LOGIN
常用参数 | 长参数 | 作用及描述 | 注意事项 |
---|---|---|---|
-f | --force | 强制删除用户 | 用户登陆中也可删除 |
-r | --remove | 同时删除用户的家目录 | / |
使用 groupdel
命令即可删除用户组
# groupdel [options] GROUP
用户信息修改
使用 usermod
命令即可删除用户
# usermod [options] LOGIN
常用参数 | 长参数 | 作用及描述 | 注意事项 |
---|---|---|---|
-c | --comment | 修改用户的描述 | 非必要 |
-d | --home-dir | 修改用户的家目录 | / |
-g | --gid | 修改用户的所属用户组 | / |
-G | --groups | 修改用户的所属用户组群 | / |
-u | --uid | 修改用户的UID | / |
-s | --shell | 修改用户登陆的命令解释器 | / |
例三:将用户 kane 的命令解释器修改为 ksh ,家目录改为 /var/lib ,用户组改为 root
# usermod -s /bin/ksh -d /var/lib -g root kane
例四:将一个已有用户 nginx 增加到一个已有用户组 www-data 中
将一个已有用户增加到一个已有用户组中,使此用户组成为该用户的附加用户组,可以使用带 -a 参数的 usermod 指令。-a 代表 append,也就是将用户添加到新用户组中而不必离开原有的其他用户组。不过需要与 -G 选项配合使用。
# usermod -a -G www-data nginx
如果要同时将 nginx 的主要用户组改为 www-data,则直接使用 -g 选项。
# usermod -g www-data nginx
将一个用户从某个组中移除。
# gpasswd -d user group
注意:使用此命令需要保证 group 不是 user 的主组。
用户密码设置
使用 passwd
命令即可修改用户密码
# passwd [options] LOGIN
常用参数 | 长参数 | 作用及描述 | 注意事项 |
---|---|---|---|
-k | --keep | 用户密码只能在过期后才能重置 | |
-l | --lock | 锁定用户 | / |
-u | --unlock | 解锁用户 | / |
-d | --delete | 删除用户密码 | / |
-f | --force | 强制指定的操作 | / |
--stdin | / | 从标准输入内获取密码 | / |
例五:无交互式地修改用户 kane 的密码
# echo "centos" | passwd --stdin kane
登陆用户查询及清理
Linux 为多用户系统,可以多人同时登陆,因此需要得知系统有多少用户登陆。及清理掉未知的登陆用户,保护系统安全。
使用 w
命令即可查询用户登陆状态
# w
10:19:12 up 19 days, 27 min, 1 user, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.1.215 09:40 0.00s 0.01s 0.00s w
项目名 | 说明 |
---|---|
USER | 登陆用户 |
TTY | 终端 |
FROM | 来源 |
LOGIN@ | 登陆时间 |
IDLE | 用户空闲时间(从上一任务结束后开始计算) |
JCPU | 此终端的相关的进程所耗费的CPU时间 |
PCPU | 指WHAT域的任务执行后耗费的CPU时间 |
WHAT | 表示当前执行的任务 |
小贴士:使用 w
命令可以仅仅查看某个用户的状态,使用 w 后加用户名即可。
使用 who
命令也可查询系统登陆的用户
# who
踢掉某个用户可以使用 pkill
# pkill -kill -t pts
注意:后面接 TTY 字段的名称。
示例脚本
需求:批量添加用户并设置密码
Shell 实现
#!/bin/bash
# 批量添加指定数量的用户
# 创建用户默认名
# 配置默认密码
# 输入用户名,输入信息存入name变量中,限制30s的输入时间
read -p "Please input user name:" -t 30 name
# 输入需要创建的用户数量,存入num中,限制30s输入时间
read -p "Please input the number of users:" -t 30 num
# 输入需要创建的默认密码,存入pass中,限制30s输入时间
read -p "Please input the password of users:" -t 30 pass
# 用户名、用户数量、默认密码都输入成功之后
if [ ! -z "$name" -a ! -z "$num" -a ! -z "$pass" ]
then
# 输入的num变量为数值类型
y=$(echo $num | sed 's/[0-9]//g')
if [ -z "$y"]
then
# 创建用户
for (( i=1;i<=$num;i=i+1))
do
# 用户名以输入用户名+序号组成
/usr/sbin/useradd $name$i &> /dev/null
# 创建默认密码
echo $pass | /usr/bin/passwd --stdin $name$i &> /dev/null
done
fi
fi
改进可以引用随机密码的方式优化脚本,并记录到文件中。
Linux 的生成随机字符串的方式有很多,比如要产生一个 16 位的字母和数字混合的随机密码,可以这样:
方式1:
$ cat /dev/urandom | head -1 | md5sum | head -c 16
在 Linux 中有一个特殊的虚拟设备 /dev/urandom
是用来产生随机数序列的。利用该设备可以根据需要生成随机字符串。
方式2:
$ date +%s | sha256sum | base64 | head -c 16
可以先获取当前时间戳,然后对其进行加密(校验)用 md5sum 也行,然后取前 16 位。
方式3:
$ openssl rand 100 | base64 | head -c 16
使用 openssl 套件生成随机字符串,然后进行加密,再取前 16 位。
方式4:
#!/bin/bash
a=(a b c d e A B C D E F @ $ % ^ 0 1 2 3 4 5 6 7 8 9)
for ((i=0;i<10;i++)); do
echo -n ${a[$RANDOM % ${#a[@]}]}
done
echo
Python 实现
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import random
import time
import io
def deluser(nums):
'''删除用户测试用户'''
for i in range(nums):
username = 'stu' + str(i)
linux_cmd = 'userdel -r {username}'.format(username=username)
cmd_stat = os.system(linux_cmd)
if cmd_stat == 0:
print(username + " userdel: OK")
else:
print(username + " userdel: FAIL")
def create_user(nums, record_adduser):
'''添加用户测试用户'''
if isinstance(nums, str):
nums = int(nums)
symbol = '1234567890'
if not os.path.exists(os.path.dirname(record_adduser)):
# 没有这个目录创建
os.mkdir(os.path.dirname(record_adduser))
# 这个文件直接打开,没有就创建
f = io.open(record_adduser, 'a+', encoding='utf-8')
for i in range(nums):
passwd = ''.join(random.sample(symbol, 6))
username = 'stu' + str(i)
linux_cmd = 'useradd {username} && echo "{passwd}" | passwd {username} --stdin{linesep}'.format(username=username,
passwd=passwd, linesep=os.linesep)
current_user = os.popen('whoami').read().strip()
cmd_stat = os.system(linux_cmd)
tmp = str(time.strftime('%Y-%m-%d %H:%M ', time.localtime()) + \
' ' + current_user + ' ' + linux_cmd + ' {stat}')
if cmd_stat == 0:
print(username + " useradd: OK")
tmp = tmp.format(stat='OK').decode('utf-8')
# 创建成功写一句
f.write(tmp)
else:
print(username + " useradd: FAIL")
tmp = tmp.format(stat='FAIL').decode('utf-8')
f.write(tmp)
# f.flush()
f.close()
if __name__ == '__main__':
record_adduser = '/root/adduser{sep}useradd.log'.format(sep=os.path.sep)
create_user(10, record_adduser)
# deluser(10)
# python 2 下,str 是 bytes类型,文件通过 io模块打开
附录
参考链接
本文由 柒 创作,采用 知识共享署名4.0
国际许可协议进行许可。
转载本站文章前请注明出处,文章作者保留所有权限。
最后编辑时间: 2018-12-28 16:51 PM