[TOC]
0x00 快速入门
重要知识点:用户和用户组的概念?
- 用户 user:使用操作系统的人
- 用户组 user group:操作系统中具有相同系统权限的一组用户
Linux 用户管理查看的主要文件目录和用途
/etc/passwd 存储当前系统中所有用户的信息
代码语言:javascript复制$cat /etc/passwd
getent passwd
#基本格式a:b:c:d:e:f:g:
a是用户名:b是密码占位符:c是用户编号:d是用户组编号:e是用户注释信息:f是用户主目录:g是shell类型
root:x:0:0:root:/root:/bin/bash
/etc/shadow 存储当前系统中所有用户的密码信息
代码语言:javascript复制$cat /etc/shadow
getent shadow
#基本格式a:b:c:d:e:f:g:
Srcweb:$6$uamdgp/v$Uv.mmE42Dka/sHqj3eZTdmZndIqTtzOVyLeYzeMlpVtsVntMeafXnJgTaD4G/XM4zM37lNCTKau5q6x7RMDWn.:17098:0:99999:7:::
root:$6$C88LCVx5ZjfBU7xv$cKcdyNeTFmOYTs9NbRZDTA4hGcbMXc/5hQEWZKCtNyLqlBagrjct.pMfs39iEaF1UbEvcOzWZHMDf9Q5KojXM1::0:99999:7:::
:a 是用户名
:b 是用户登录密码单向加密分为三个部分,第一部分是表示使用哪种哈希算法(`$1表示MD5 ; $6 表示SHA-512 ; $5 SHA-256`);第二部分是用于加密哈希的salt;第三部分是已加密的哈希;
:c 上次更改密码的日期(从1970-1-1开始)
:d 最短密码期限(按天计算,0 = 无最短期限)
:e 最长密码期限(按天计算)
:f 密码警告期限(按天计算,0 = 未指定警告)
:g 密码非活动期限(按天计算)
:h 账号到期时间(从1970-1-1开始)
:i 保留域
/etc/group 存储当前系统中所有用户组信息
代码语言:javascript复制cat /etc/group
getent group
#基本格式a:b:c:d
root:x:0:root,roottest
a是组名称;b是组密码占位符;c是组编号;d是组中用户名列表,为空不代表没有用户,当这个组内只要一个用户,且用户名和组名相同时是可以省略的
#需要注意以下几点:
root用户组的组号一定为0,如'root:x:0:'
组号1-499是预留给系统软件和服务的,如安装了MySQL,会自动创建一个MySQL用户组,越早安装的软件和服务,组号越小
用户手动创建的用户组编号是从500开始的
主密码占位符无一例外全都是用x来表示的,这与系统安全演变有关,后面课程会提
/etc/gshadow 存储当前系统中用户组的密码信息 Tips:原先只有group和passwd两个文件,但后来考虑到安全性问题就又演变出shadow和gshadow两个文件
代码语言:javascript复制cat /etc/gshadow
getent gshadow
#基本格式a:b:c:d:
Srcweb:!::
a是组名称:b是组密码:c是组管理者:d是组中用户名列表
0x01 用户信息查看
getent 命令 - 从名称服务开关库获取条目
描述:用来察看系统的数据库中的相关记录,比如passwd 、 shadow、 group
代码语言:javascript复制# 用法:
getent [选项...] 数据库 [键 ...]
# 参数:
-s, --service=CONFIG # 要使用的服务配置
-s database:service, --service database:service
-i, --no-idn # Disables IDN encoding in lookups
# 支持的数据库:
ahosts ahostsv4 ahostsv6 aliases ethers hosts networks netgroup protocols rpc services
passwd shadow group gshadow
使用示例:
代码语言:javascript复制# 查看所有账户与指定账户
getent passwd root #等同于执行 cat /etc/passwd
getent group # 查看所有用户组
root:x:0:0:root:/root:/bin/bash
root:x:0:
#示例2.同理也可查询密码文件
getent shadow
getent gshadow
#示例3. 同理也可查询用户别名
getent aliases
mailer-daemon: postmaster
postmaster: root
bin: root
#示例4.查询端口与服务
getent services | more # 等同于 cat /etc/services | more
getent services ftp
ftp 21/tcp
#示例5.查看协议数据库
getent protocols tcp
tcp 6 TCP
whoami 命令
描述:显示当前shell中运行的用户,Linux上WINDOWS上都支持该命令; 使用案例:
代码语言:javascript复制whoami #显示当前登录用户名
#whoami /all #显示当前计算机所有的用户 - windows 下 echo %username% #采用系统变量也能看见
$whoami
root
$echo $USER
root
id 命令
描述:显示指定用户信息,包括用户编号和用户名;主要组编号及名称,附属组列表
代码语言:javascript复制id【用户名】
# id
uid=0(root) gid=0(root) groups=0(root)
w 命令
描述:用于显示已经登陆系统的用户列表,并显示用户正在执行的指令,读取的是wtmp 执行这个命令可得知目前登入系统的用户有那些人,以及他们正在执行的程序。单独执行w命令会显示所有的用户,您也可指定用户名称,仅显示某位用户的相关信息。
代码语言:javascript复制-h:不打印头信息
-u:当显示当前进程和cpu实际式忽略用户名
-s:使用断输出格式
-d:输出用户从哪里登陆
实际案例:
代码语言:javascript复制#示例1.w用户解释
$w 用户名 (不加用户名也可以)
11:45:28 up 23 days, 12:31, 2 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 102.17.8.29 09:26 1:54m 0.27s 0.27s -bash
#命令输出:
USER:登录的用户名
TTY: 登录终端
FROM:从哪个IP地址登录
LOGIN@:登录时间
IDLE:用户闲置时间
JCPU:指的是该终端连接的所有进程占用的时间。这个时间里并不包括过去的后台作业时间,但却包括当前正在运行的后台作业所占用的时间
PCPU:是指当前进程所占用的时间
WHAT:当前正在运行的命令
WeiyiGeek.w命令
who 命令
描述:是显示目前登录系统的用户信息,who 用户名和w一样,只不过更简单(不加用户名也可以) 执行who命令可得知目前有那些用户登入系统,单独执行who命令会列出登入帐号,使用的终端机,登入时间以及从何处登入或正在使用哪个X显示器
WeiyiGeek.
实际案例:
代码语言:javascript复制#示例1.基础示例
$who
root pts/0 2019-06-06 09:26 (22.17.8.229)
-用户名
-登录终端
-登录时间(登录来源IP地址)
#示例2.参数数据
$who -q #统计用户登录个数
root root
# users=2
$who -w
root pts/0 2019-06-06 09:26 (192.168.1.120) #显示 pid 的pts/1(终端线路)
root pts/1 2019-06-06 10:51 (192.168.1.120)
$who -H
NAME LINE TIME COMMENT
root pts/0 2019-06-06 09:26 (192.168.1.120)
root pts/1 2019-06-06 10:51 (192.168.1.120)
$who -u #显示当前 ssh 连接的 PID
root pts/0 2019-06-06 09:26 02:02 11496 (192.168.1.120)
root pts/1 2019-06-06 10:51 . 16408 (192.168.1.120)
$who -r #显示 pid 的pts/1(终端线路)
run-level 3 2019-05-13 23:14
$who -H
NAME LINE TIME COMMENT
root pts/0 2018-10-08 18:56 (218.201.8.36)
#当前终端信息
$who -u am i
root pts/1 Aug 1 16:55 . 9974 (192.168.1.88)
last 命令
描述:查看过去所有用户的开关机重启信息,默认是读取cat /var/log/wtmp文件数据,这是一个二进制文件防止人为修改
代码语言:javascript复制# 语法:
last(选项)(参数)
# 命令输出:
-用户名
-登录终端
-登录IP
-登录时间
-退出时间(在线时间)
WeiyiGeek.参数
实际案例:
代码语言:javascript复制#示例1.常用示例使用查看
last -10(-n) 查看最近10条记录
#示例2.查看指定记录
last -x reboot 查看重启的记录
last -x shutdown 查看关机的记录
$last -d #查看登陆的记录
root pts/0 192.168.1.120 Thu Jun 6 12:34 still logged in
#示例3.last打开wtmp文件
last -f wtmp #用last命令查看wtmp文件(直接打开无法查看)
WeiyiGeek.示例
lastb 命令
描述:lastb命令用于显示用户错误的登录列表,此指令可以发现系统的登录异常,本质就是将/var/log/btmp文件格式化输出。 Tips: 使用ssh的登录失败不会记录在btmp文件中
案例示例:
代码语言:javascript复制#示例1.查看root用户登陆失败记录
lastb name(root) 查看root用户登陆失败记录
$lastb admin
admin ssh:notty 113.172.26.33 Thu Jun 6 04:06 - 04:06 (00:00)
admin ssh:notty 197.55.205.215 Wed Jun 5 14:28 - 14:28 (00:00)
admin ssh:notty 14.46.201.194 Wed Jun 5 00:50 - 00:50 (00:00)
admin ssh:notty 212.108.136.97 Tue Jun 4 11:10 - 11:10 (00:00)
lastb -10(-n) 查看最近10条登陆失败记录
$lastb -10 #常常是被爆破了
admin ssh:notty 113.172.26.33 Thu Jun 6 04:06 - 04:06 (00:00)
admin ssh:notty 197.55.205.215 Wed Jun 5 14:28 - 14:28 (00:00)
root ssh:notty 139.224.31.106 Wed Jun 5 11:00 - 11:00 (00:00)
admin ssh:notty 14.46.201.194 Wed Jun 5 00:50 - 00:50 (00:00)
admin ssh:notty 212.108.136.97 Tue Jun 4 11:10 - 11:10 (00:00)
lastlog 命令
描述:查看所有用户的最后一次登录信息,lastlog默认读取” /var/log/lastlog “文件数据(Bin)
代码语言:javascript复制#查看用户的的登录情况
$lastlog -u root
root pts/0 192.168.1.120 Thu Jun 6 12:34:07 0800 2019
$lastlog -u admin
Username Port From Latest
admin pts/0 120.78.45.59 Sun May 19 22:10:15 0800 2019
lslogins 命令
描述:列出当前已经登录的用户信息
代码语言:javascript复制$lslogins
UID USER PROC PWD-LOCK PWD-DENY LAST-LOGIN GECOS
0 root 126 0 0 14:30:25 root
1 bin 0 0 1 bin
2 daemon 0 0 1 daemon
3 adm 0 0 1 adm
4 lp 0 0 1 lp
5 sync 0 0 1 sync
6 shutdown 0 0 1 5月27/16:02 shutdown
7 halt 0 0 1 halt
8 mail 0 0 1 mail
11 operator 0 0 1 operator
12 games 0 0 1 games
14 ftp 0 0 1 FTP User
74 sshd 0 0 1 Privilege-separated SSH
81 dbus 0 0 1 System message bus
89 postfix 0 0 1
99 nobody 1 0 1 Nobody
192 systemd-network 0 0 1 systemd Network Management
998 chrony 0 0 1
999 polkitd 0 0 1 User for polkitd
1000 ctcss 0 0 1
1001 nginx 0 0 1
1011 www 0 0 1
1012 mysql 0 0 1
0x02 用户操作配置
useradd 命令
描述:增加用户修改用户属性
代码语言:javascript复制用法: useradd [选项] 登录
useradd -D
useradd -D [选项]
选项:
-b, --base-dir BASE_DIR 新账户的主目录的基目录
-c, --comment COMMENT 新账户的 GECOS 字段
-d, --home-dir HOME_DIR 新账户的主目录
-D, --defaults 显示或更改默认的 useradd 配置
-e, --expiredate EXPIRE_DATE 新账户的过期日期
-f, --inactive INACTIVE 新账户的密码不活动期
-g, --gid GROUP 新账户主组的名称或 ID
-G, --groups GROUPS 新账户的附加组列表
-h, --help 显示此帮助信息并推出
-k, --skel SKEL_DIR 使用此目录作为骨架目录
-K, --key KEY=VALUE 不使用 /etc/login.defs 中的默认值
-l, --no-log-init 不要将此用户添加到最近登录和登录失败数据库
-m, --create-home 创建用户的主目录
-M, --no-create-home 不创建用户的主目录
-N, --no-user-group 不创建同名的组
-o, --non-unique 允许使用重复的 UID 创建用户
-p, --password PASSWORD 加密后的新账户密码
-r, --system 创建一个系统账户
-R, --root CHROOT_DIR chroot 到的目录
-s, --shell SHELL 新账户的登录 shell
-u, --uid UID 新账户的用户 ID
-U, --user-group 创建与用户同名的组
-Z, --selinux-user SEUSER 为 SELinux 用户映射使用指定 SEUSER
实际案例:
代码语言:javascript复制#示例1.跟用户有关的命令
useradd jeff # 添加一个jeff用户
useradd -u 1024 jacker # 为新添加的用户指定一个uid
useradd -g hadoop Jeff # 将用户添加到hadoop组里
useradd -d /home/Jeff Jeff # -d代表创建指定用户的目录,默认会在/home下创建一个和用户名同名的目录
useradd -g group1 -G group2,group3 Jeff # 直接设置用户的主组-g 合设置 用户附属用户组
#示例2.创建相应用户,及指定(修改)执行shell
useradd nobody -s /sbin/nologin
#示例3.创建用户及其家目录
sudo useradd -m -g sonarqube sonarqube
userdel 命令
描述:字面意思删除用户; 实际案例:
代码语言:javascript复制#示例1.删除用户
userdel Jeff # 删除用户,但不会删除/home/Jeff内的文件
userdel -r Jeff # 完全删除,包含用户的家目录
#补充:
$touch /etc/nologin # 只要创建这个空文件就能禁止root用户外的用户删除用户信息
usermod 命令
描述:修改用户的信息和配置
实际案例:
代码语言:javascript复制usermod -c helloworld Jeff # -c代表为用户添加hello注释信息
usermod -l WeiyiGeek Jeff # -l代表修改用户名
usermod -d /home/WeiyiGeek WeiyiGeek # 修改用户的目录
usermod -g Master -G slave Jeff # -g代表更改用户所在的用户组/附属组
usermod -aG root $USER
passwd 命令
描述:改使用者的密码passwd文件是普通的文本文件,可以手工修改文件中的用户信息(usermod),或者用(useradd)
代码语言:javascript复制#参数
-l 关闭账号密码。效果相当于usermod -L,只有root才有权使用此项
-u 恢复账号密码。效果相当于usermod -U,同样只有root才有权使用
-g 修改组密码。gpasswd的等效命令
-f 更改由finger命令访问的用户信息
-d 关闭使用者的密码认证功能, 使用者在登入时将可以不用输入密码, 只有具备 root 权限的使用者方可使用
-S 显示指定使用者的密码认证种类, 只有具备 root 权限的使用者方可使用
--stdin 接受来自标准输入的字符床
实际案例:
代码语言:javascript复制#示例1.常规参数使用
passwd root #修改root用户密码
passwd -l WeiyiGeek # 锁定用户
passwd -u WeiyiGeek # 解锁用户
passwd -d WeiyiGeek # 无密码登录(清除密码)
#示例2.显示密码认证种类
passwd -S root
root PS 2019-02-24 0 99999 7 -1 (Password set, SHA512 crypt.)
#示例3.非交互式改密码
echo 123456 | passwd --stdin Weiyegeek
echo "$( echo ${RANDOM}`date %s%S`|md5sum|cut -c 2-9 )" passwd --stdin 用户名
# Changing password for user Weiyegeek.
# passwd: all authentication tokens updated successfully.
#示例4.要强制用户更改用户的密码,首先必须是密码已过期,你可以使用 passwd command,用于通过指定-e或--expire开关以及用户名来更改用户的密码
passwd --expire WeiyiGeek
groupadd 命令
描述:跟用户组有关的命令添加新的用户组
实际案例:
代码语言:javascript复制#示例1.用户组的添加与修改
groupadd cloudedge # 创建用户组 cat /etc/group # 看最后一行是否已添加
groupadd -g 888 Master # -g代表在创建用户组时也指定组编号
groupmod 命令
描述:更改用户组信息与配置
实际案例:
代码语言:javascript复制#示例1.修改用户组以及组编号
groupmod -n hadoop cloudedge # -n代表修改组名
groupmod -g 668 hadoop # -g代表修改组编号
groupdel 命令
描述:字面意思删除用户组
实际案例:
代码语言:javascript复制groupdel hadoop # 删除用户组
gpasswd 命令
描述:主要组和附属组:用户可以同时属于多个用户组,但必须要有一个主要组,加上多个附属组,当然使用usermod也能达到
WeiyiGeek.主要组和附属组
代码语言:javascript复制# -a 代表将用户添加到一个附属组,如果有多个附属组,可以相互之间用逗号隔开
# -d 表示将用户从组里删除
# -r, --remove-password 表示移除组的密码
-Q, --root CHROOT_DIR directory to chroot into
-R, --restrict restrict access to GROUP to its members
-M, --members USER,... set the list of members of GROUP
-A, --administrators ADMIN,...
实际案例:
代码语言:javascript复制# 示例1.为用户添加到多个组里面
gpasswd -a WeiyiGeek Master,groupMaster #但用户创建文件等操作都默认属于他的主用户组,
#如果要在附属组下进行,就要将身份临时切换到附属组 master:x:1005:jeff
$gpasswd -a admin jacker
Adding user admin to group jacker
#gpasswd -a user1 usergroup #将用户加到组里
# 示例2.从master用户组中删掉用户,即将用户的某个附属组去掉.
gpasswd -d WeiyiGeek Master
sudo gpasswd -d $USER root
# Removing user weiyigeek from group root
# 示例3.为某组设置用户组密码
gpasswd master
WeiyiGeek.gpasswd
groups 命令
描述:显示用户所在的主要组和附属组,需要添加一个用户到多个主和从组中.
代码语言:javascript复制groups【用户】
# 示例1.显示主组和附属组
$ groups app
app : app adm cdrom sudo dip plugdev docker
$groups admin
admin : admin jacker
newgrp 命令 - 用于登入另一个群组
描述: newgrp 指令类似 login 指令,当它是以相同的帐号,另一个群组名称,再次登入系统 注意: 切换用户组注意这个命令的前提是你现在登录在WeiyiGeek下!需要用户自己执行!
代码语言:javascript复制# 1.切换master组
$ newgrp Master # 此时可能需要你输入Master的组密码(如果存在的话)
# 2.将当前用户加入到docker组之后切换当前会话到新 group 或者重启 X 会话
# 则因为 groups 命令获取到的是缓存的组信息,刚添加的组信息未能生效,所以 docker images 执行时同样有错。
$ newgrp - docker
chpasswd 命令
chpasswd命令是批量更新用户口令的工具,是把一个文件内容重新定向添加到/etc/shadow中。
代码语言:javascript复制chpasswd (选项)
-e:输入的密码是加密后的密文;
-h:显示帮助信息并退出;
-m:当被支持的密码未被加密时,使用MD5加密代替DES加密。
实际案例:
代码语言:javascript复制#1. 先创建用户密码对应文件,格式为username:password,如abc:abc123,
# 必须以这种格式来书写,并且不能有空行,保存成文本文件user.txt,然后执行chpasswd命令:
chpasswd < user.txt
echo "weiyi:test" | chpasswd
# 以上是运用chpasswd命令来批量修改密码。是linux系统管理中的捷径。
echo "root:wgr1TDs2Mnx0XuAv" | chpasswd
WeiyiGeek.
chage 命令
描述:chage命令是用来修改帐号和密码的有效期限,密码失效是通过此命令来管理的。
代码语言:javascript复制chage [选项] 用户名
-m:密码可更改的最小天数。为零时代表任何时候都可以更改密码。
-M:密码保持有效的最大天数。
-w:用户密码到期前,提前收到警告信息的天数。
-E:帐号到期的日期。过了这天,此帐号将不可用。
-d:上一次更改的日期。
-i:停滞时期。如果一个密码已过期这些天,那么此帐号将不可用。
-l:例出当前的设置。由非特权用户来确定他们的密码或帐号何时过期。 root|用户
-I, --inactive INACTIVE : 密码到期后不能登陆
实际案例:
代码语言:javascript复制#示例2.我的服务器root帐户密码策略信息如下:
$ chage -l root #列出指定用户设置
$ chage -M 60 root #修改我的密码过期时间为60天
$ chage -I 5 root #命令设置密码失效时间5天 #在密码过期后5天,密码自动失效,这个用户将无法登陆系统了。
------------------------------------------------------
近一次密码修改时间 : 3月 12, 2013
密码过期时间 :从不
密码失效时间 :从不
帐户过期时间 :从不
两次改变密码之间相距的最小天数 :0
两次改变密码之间相距的最大天数 :99999
在密码过期之前警告的天数 :7
------------------------------------------------------
#示例2.强制用户登陆时修改口令
$ chage -d 0 username(linux)
$ passwd -f username(solaris)
#示例3.现在要设置用户的密码过期时间,通过将日期指定为零 (0) 来运行以下命令,表示自上述日期以来密码未更改(即 January 1st, 1970),因此密码实际上已经过期,需要在用户再次访问系统之前立即更改。
chage --lastday 0 rumenz
chage --lastday 1970-01-01 rumenz
#示例4.强制用户下次登陆时修改密码,并且设置密码最低有效期0和最高有限期90,提前15天发警报提示
$ chage -d 0 -m 0 -M 90 -W 15 root(linux)
$ passwd -f -n 0 -x 90 -w 15 root(solaris)
Tips : Linux下对于新添加的用户,用户密码过期时间是从 /etc/login.defs 中 PASS_MAX_DAYS 提取的,普通系统默认就是99999,而有些安全操作系统是90(等保要求三个月更换一次密码)
代码语言:javascript复制#采用正则表达式进行匹配
$ sed -i.bak -e 's/^(PASS_MAX_DAYS).*/1 90/' /etc/login.defs #以PASS开头 -i 备份
$ cat /etc/login.defs |grep "PASS_M";
#可以编辑/etc/login.defs来设定几个参数,以后设置口令默认就按照参数设定为准:
PASS_MAX_DAYS 99999
PASS_MIN_DAYS 0
PASS_MIN_LEN 5
PASS_WARN_AGE 7
#当然在/etc/default/useradd可以找到如下2个参数进行设置
#通过修改配置文件,能对之后新建用户起作用,而目前系统已经存在的用户,则直接用chage来配置。:
# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
# 对于已存在的用户进行设置失效时期。
chage -d 0 -m 0 -M 90 -W 15 root && passwd --expire root
chage
pwconv 命令
描述:/etc/shadow 由 pwconv 命令根据/etc/passwd中的数据自动产生
代码语言:javascript复制#实际案例
$getent passwd | wc -l
29
$getent shadow | wc -l
29
$pwunconv #在执行pwconv后才将jacker用户配置信息吸入到shadow中
$useradd jacker
$getent shadow | wc -l
0 #区别点
$getent passwd | wc -l
30
$pwconv #关键点
$getent shadow | wc -l
30
chfn 命令
chfn【用户】 #设置用户资料,依次输入用户资料
finger 命令
finger【用户】 ## 显示用户的详细资料
代码语言:javascript复制[root@localhost ~]# yum install finger #没安装得执行
faillog|pam_tally2 命令
描述:使用该命来解锁通过PAM模块设置的策略被锁定的用户,主要正对于使用了PAM_tally.so的登陆配置文件; 而从上面可以看出如果使用了pam_tally2动态链接库就需要采用pam_tally2命令进行解锁;
基础使用:
代码语言:javascript复制pam_tally2: [-f rooted-filename] [--file rooted-filename]
[-u username] [--user username]
[-r] [--reset[=n]] [--quiet]
基础示例:
代码语言:javascript复制# 示例1.
# faillog –a # 查看用户登录错误次数
# 如果超过三次的话,用户不能登录并且此后登录用户错误登录次数还是会增加。
# 在登录错误次数不满三次时,登录成功后,则这个用户登录错误值将清零,退出后重新 ssh 登录将采用新的计数。
# faillog -u user –r # 清空指定用户 user 的错误登录次数
# faillog –r # 清空所有用户错误登录次数
# 示例2.
pam_tally2 -u test # 查看被锁定的用户
pam_tally2 -r -u test # 解锁被锁定的用户
faillock 命令
描述:pam_faillock 模块用来管理员锁定制定次数内登陆失败用户,防止针对获取用户密码暴力破解。
通过 pam_faillock 模块,将登录尝试失败的数据储存在 /var/run/faillock
目录下每位用户的独立文件中
#在以下两个配置文件 /etc/pam.d/system-aut h或 /etc/pam.d/password-auth 中加入字段
auth required pam_faillock.so preauth silent audit deny=3 unlock_time=600 even_deny_root #须在文件最前
基础语法:
代码语言:javascript复制$ faillock -h
Usage: faillock [--dir /path/to/tally-directory] [--user username] [--reset]
基础使用:
代码语言:javascript复制# 示例1.查看每个用户的尝试失败次数
$ faillock
test:
When Type Source Valid
2017-06-20 14:29:05 RHOST 192.168.56.1
# 示例2.解锁一个用户的账户
faillock --user <username> --reset
adduser 命令 - alpine 操作系统
描述: adduser来自英语“add user”该命令用于新增使用者帐号或更新预设的使用者资料, 实际上 adduser
与 useradd
指令为同一指令(经由符号连结 symbolic link)。
语法参数:
代码语言:javascript复制$ adduser -help
BusyBox v1.32.1 () multi-call binary.
Usage: adduser [OPTIONS] USER [GROUP]
Create new user, or add USER to GROUP
-h DIR Home directory
-g GECOS GECOS field
-s SHELL Login shell
-G GRP Group
-S Create a system user
-D Don't assign a password
-H Don't create home directory
-u UID User id
-k SKEL Skeleton directory (/etc/skel)
常用参数:
代码语言:javascript复制-c 加上备注文件,备注文字会存储在 passwd 的备注参数中
-d 指定用户登录时的起始目录
-D 变更默认值
-e 设定此帐号的使用期限(格式为 YYYY-MM-DD),预设值为永久有效
-f <缓冲天数> 指定在密码过期后多少天即关闭该帐号
-g <群组> 指定用户所属的群组
-G <群组> 指定用户所属的附加群组
-m 自动建立用户的登入目录
-M 不要自动建立用户的登入目录
-n 取消建立以用户名称为名的群组
-r 建立系统帐号
-s <shell> 指定用户登入后所使用的shell
-u <uid> 指定用户ID
简单示例:
代码语言:javascript复制# (1) 常用用户组与用户添加
USERNAME=weiyigeek
addgroup -g 1000 -S ${USERNAME}
&& adduser ${USERNAME} -D -g ${USERNAME} -G ${USERNAME} -u 1000 -s /bin/sh
# (2) 建立名为linuxcool的用户账号并指定有效期为2014年1月2日, 以及指定相应的用户组和家目录
adduser -e 1/2/14 -g root -d /home/weiyigeek weiyigeek
0x03 用户权限
su 命令
面对:su(Switch User),切换到超级管理员权限需要Root老大亲自出马的,如su root,当前用户身份完全切换到root账户,但必须使用root用户密码进行验证,除非执行exit退出登陆,否则超级管理权限一直有效
代码语言:javascript复制[root@localhost ~]$ su Srcweb #切换用户 切换后不能采用logout退出用户 (相当于是root当前shell的子线程)
[root@localhost ~]$ su - Srcweb #切换用户 切换后可以采用logout退出用户
#指定用户执行某一个程序
[root@localhost ~]$ su - weiyigeek -c nohup -c "$CASSANDRA_DIR/bin/cassandra" >> $CASSANDRA_DIR/logs/system.log 2>&1 &
WeiyiGeek.su命令
sudo 命令 - 使用另一个用户来执行命令
描述:sudo(Switch User and Do) 以超级管理员身份执行,当前用户身份没有改变,使用自身密码获取授权,超级权限是临时的,root把本来只能超级用户执行的命令赋予普通用户执行,sudo的操作对象是系统命令。 比如,有时低用户需要管理员的权限时执行某些命令的时候就需要用sudo权限命令配置;
语法参数:
代码语言:javascript复制# sudo, sudoedit — execute a command as another user
# SYNOPSIS
sudo -h | -K | -k | -V
sudo -v [-ABknS] [-g group] [-h host] [-p prompt] [-u user]
sudo -l [-ABknS] [-g group] [-h host] [-p prompt] [-U user] [-u user] [command]
sudo [-ABbEHnPS] [-C num] [-g group] [-h host] [-p prompt] [-r role] [-t type] [-T timeout] [-u user] [VAR=value]
[-i | -s] [command]
sudoedit [-ABknS] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u user] file ...
# Paramater
-A, --askpass 使用助手程序进行密码提示
-b, --background 在后台运行命令
-C, --close-from=num 关闭所有 >= num 的文件描述符
-E, --preserve-env 在执行命令时保留用户环境
-e, --edit 编辑文件而非执行命令
-g, --group=group 以指定的用户组或 ID 执行命令
-H, --set-home 将 HOME 变量设为目标用户的主目录。
-h, --help 显示帮助消息并退出
-h, --host=host 在主机上运行命令(如果插件支持)
-i, --login 以目标用户身份运行一个登录 shell;可同时指定一条命令
-K, --remove-timestamp 完全移除时间戳文件
-k, --reset-timestamp 无效的时间戳文件
-l, --list 列出用户权限或检查某个特定命令;对于长格式,使用两次
-n, --non-interactive 非交互模式,不提示
-P, --preserve-groups 保留组向量,而非设置为目标的组向量
-p, --prompt=prompt 使用指定的密码提示
-r, --role=role 以指定的角色创建 SELinux 安全环境
-S, --stdin 从标准输入读取密码
-s, --shell 以目标用户运行 shell;可同时指定一条命令
-t, --type=type 以指定的类型创建 SELinux 安全环境
-U, --other-user=user 在列表模式中显示用户的权限
-u, --user=user 以指定用户或 ID 运行命令(或编辑文件)
-V, --version 显示版本信息并退出
-v, --validate 更新用户的时间戳而不执行命令
# 常用命令
sudo -i :Linux终端命令下改变用户对命令使用权限的命令,(将目标用户的密码数据库条目指定的shell作为登录shell运行)
sudo -s :执行环境变数中的 SHELL 所指定的 shell ,或是 /etc/passwd 里所指定的 shell 。
温馨提示: sudo 配置文件来修改权限, 除了使用vim /etc/sudoers 我们也可也使用 visudo 命令打开sudo编辑文件, 可通过 man 5 sudoers
命令查看帮助。
$ visudo # 实际修改的是/etc/sudoers文件
/etc/sudoers # 特殊权限配置
#
#Allow root to run any commands anywhere Allows people in group wheel to run all commands
root ALL=(ALL) ALL
#用户名 被管理主机的地址=(可使用的身份)授权命令(绝对路径)
admin ALL=(ALL) ALL #设置了后admin用户才能执行sudo -l进行查看自己的权限
#%组名 被管理主机的地址=(可使用的身份)授权命令(绝对路径)
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS
# %users localhost=/sbin/shutdown -h now
# %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom #命令以,分割
%wheel ALL=(ALL) ALL # 注释后低权限用户不能使用sudo(值得注意)
# - 可能会有不安全的配置,建议设置为PASSWD而不是NOPASSWD,在sudo时会输入该用户的Pass密码才能登陆.
# includedir /etc/sudoers.d
lighthouse ALL=(ALL) PASSWD: ALL
ubuntu ALL=(ALL:ALL) NOPASSWD: ALL
WeiyiGeek.实际配置
实际案例:
代码语言:javascript复制# 示例1.sudo权限打开root权限才能读取的
$ sudo cat /etc/shadow
[sudo] password for Srcweb:
Srcweb 不在 sudoers 文件中,此事将被报告
# 示例2.查看当前用户的user的sudo权限
$ sudo -l
# 匹配 %2$s 上 %1$s 的默认条目:!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset,
env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep ="MAIL PS1 PS2 QTDIR USERNAME
LANG LC_ADDRESS LC_CTYPE", env_keep ="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES",
env_keep ="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep ="LC_TIME LC_ALL LANGUAGE
LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin:/bin:/usr/sbin:/usr/bin
用户 root 可以在 master 上运行以下命令:(ALL) ALL
# 示例3.修改sudoer配置文件来指定用户可使用的sudo权限
user1 ALL=/usr/bin/passwd #收于用户设定密码的权限(普通用户执行sudo命令),但这会有很大问题 普通用户会修改其他用户密码
user1 All=/usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd "", !/usr/bin/passwd root #让不能修改root密码,注意中间必须有空格,顺序不能颠倒
# 最好不要给user ALL=vi (这时是Rootquan权限)
mynote ALL=/usr/bin/cat
# 约定普通用户的用户名是 www-data,其用户组只有 www-data
www-data ALL=(www-data:www-data) /bin/*,/usr/bin/*,/sbin/*, /usr/sbin/*,!/usr/bin/sudo,!/bin/su,!/usr/bin/passwd,!/usr/bin/chattr -* /etc/sudoers
# 示例4.sudo两种方式切换到root用户终端
sudo -i # 快速切换到root, 是Linux终端命令下改变用户对命令使用权限的命令
sudo -i -u root
sudo su - root # 不加-i的话是以非登录模式切换,不会拿到root的环境变量。
温馨提示: sudo -i
与 su -
的不同点是前者获取到一个全新的shell,而后者只是允许具有权限的用户以超级用户或另一个用户的身份执行命令,但是环境变量是保持不变的。
注意事项:
1.root上编辑 /etc/sudoers
写得越简单,普通用户的权限就越大.
2.Ubuntu系统提示用户不在 sudoers 文件中错误解决方法,以admin用户以及用户组为例.
代码语言:javascript复制# 切换到root账号
su -
# 解除sudoers的写入限制
chmod u w /etc/sudoers
# 为用户admin添加sudo权限
admin ALL=(ALL:ALL) ALL
# 为用户组admin添加sudo权限
�min ALL=(ALL) ALL
# 将test用户添加到admin组并拥有一定sudo权限
usermod -G admin test
# 切换用户
su - test
# 在test用户下执行sudo命令
sudo apt update
# 用户 test 可以在 master 上运行以下命令:(ALL) ALL
$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
3.禁止普通用户通过 sudo -i
或 sudo -s
命令进入root模式。
4.禁止普通用户通过 sudo su -
或 su - root
切换到root用户
# 1.在Ubuntu 系统下设置
# 步骤01 #
# /etc/pam.d/su
# 打开这个配置文件,找到如下行,并将行首”#”去掉,保存文件
auth required pam_wheel.so
# /etc/login.defs
# 文件末尾添加, 如下指令
SU_WHEEL_ONLY yes
# 步骤02 #
# /etc/sudoers
$ visudo
weiyigeek ALL=(ALL) ALL,!/bin/su
# 步骤03 #
sudo addgroup wheel
sudo usermod -a -G wheel weiyigeek
温馨提示: 前面两个步骤做完,则可以实现上述所说目的,如果只做了第一步或者第二步,那情况将如下
- 如果只做了第一步,则还是可以通过
sudo su -
或sudo su
切换到root - 如果只做了第二步,则还是可以通过
su - root
切换到root
5.如何定制sudoer规则,定制功能需要用到以下选项。
代码语言:javascript复制# 配置Host_Alias:就是主机的列表(可以填本机ip地址)
Host_Alias HOST_FLAG = hostname1, hostname2, hostname3
# 配置Cmnd_Alias:就是允许执行的命令的列表
Cmnd_Alias COMMAND_FLAG = command1, command2, command3
# 配置User_Alias:就是具有sudo权限的用户的列表
User_Alias USER_FLAG = user1, user2, user3
# 配置Runas_Alias:就是用户以什么身份执行(例如root,或者oracle)的列表
Runas_Alias RUNAS_FLAG = operator1, operator2, operator3
# * 配置权限的格式如下:
USER_FLAG HOST_FLAG=(RUNAS_FLAG) COMMAND_FLAG
# * 如果不需要密码验证的话,则按照这样的格式来配置
USER_FLAG HOST_FLAG=(RUNAS_FLAG) NOPASSWD: COMMAND_FLAG
实践案例:
代码语言:javascript复制$ visudo
....
Host_Alias HOST_FLAG = 172.17.0.2
User_Alias USER_FLAG = weiyigeek
Runas_Alias RUNAS_FLAG = root
Cmnd_Alias COMMAND_FLAG = /bin/mount,/bin/umount
USER_FLAG HOST_FLAG=(RUNAS_FLAG) COMMAND_FLAG
gosu 命令
描述:该命令工具主要用来提升指定账号的权限作用与sudo命令类似; 由su和sudo具有非常奇怪且经常令人讨厌的TTY和信号转发行为这一简单事实发展而来。它们的设置和使用也有些复杂(特别是在sudo的情况下)它允许大量的表达,但如果您需要的只是”作为特定用户运行这个特定的应用程序,然后离开管道” 那么它就会失败(退出即生效)。
gosu的核心工作方式直接借鉴了Docker/libcontainer在容器内启动应用程序的方式(实际上是直接使用来自libcontainer代码库的/etc/passwd处理代码)
应用环境:
- 1.由于安全相关问题在Docker容器中建议使用gosu而不是sudo;
- 2.对于脚本执行有严格权限要求的场景;
项目地址:https://github.com/tianon/gosu
安装说明:
代码语言:javascript复制#CentOS
GOSU_VERSION=1.14
wget https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-amd64 -O /usr/local/bin/gosu
wget https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-amd64.asc -O /tmp/gosu.asc
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4
gpg --batch --verify /tmp/gosu.asc /usr/local/bin/gosu
chmod x /usr/local/bin/gosu
# debian
# gosu-$(dpkg --print-architecture | awk -F- '{ print $NF }') as gosu
# gosu-$(dpkg --print-architecture | awk -F- '{ print $NF }').asc as gosu.asc
基础语法:
代码语言:javascript复制$ gosu
Usage: ./gosu user-spec command [args]
eg: ./gosu tianon bash
./gosu nobody:root bash -c 'whoami && id'
./gosu 1000:1 id
./gosu version: 1.14 (go1.3.1 on linux/amd64; gc)
基础示例:
代码语言:javascript复制#(1)当前用户是root执行以web用户执行命令创建目录文件目录文件的所属者和所属组都是
gosu web mkdir -p /tmp/web
drwxr-xr-x. 2 web web 6 6月 19 09:42 web
#(2)设置所属者与不同的组
gosu nobody:root bash -c 'whoami && id'
#(3)从下面这个示例我们知道为何在docker建议使用gosu而不是sudo
#由于gosu使用Docker自己的代码来处理这些user:group,所以它与Docker自己的——user标志是1:1的。
#如果你对gosu处理的边界情况感到好奇,请参阅Dockerfile。
$ docker run -it --rm ubuntu:trusty su -c 'exec ps aux'
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 46636 2688 ? Ss 02:22 0:00 su -c exec ps a
root 6 0.0 0.0 15576 2220 ? Rs 02:22 0:00 ps aux
$ docker run -it --rm ubuntu:trusty sudo ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 3.0 0.0 46020 3144 ? Ss 02:22 0:00 sudo ps aux
root 7 0.0 0.0 15576 2172 ? R 02:22 0:00 ps aux
$ docker run -it --rm -v $PWD/gosu-amd64:/usr/local/bin/gosu:ro ubuntu:trusty gosu root ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 7140 768 ? Rs 02:22 0:00 ps aux
补充其他类似命令工具:
su-exec: 是用C语言对gosu进行的最小的重写,使得二进制文件更小,可以在主要的Alpine软件包存储库中使用。
chroot: 使用--userspec标志
chroot可以提供类似的好处/行为;
$ docker run -it --rm ubuntu:trusty chroot --userspec=nobody / ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
nobody 1 5.0 0.0 7136 756 ? Rs 17:04 0:00 ps aux
setpriv: Available in newer util-linux (>= 2.32.1-0.2, in Debian; https://manpages.debian.org/buster/util-linux/setpriv.1.en.html)
代码语言:javascript复制$ docker run -it --rm buildpack-deps:buster-scm setpriv --reuid=nobody --regid=nogroup --init-groups ps faux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
nobody 1 5.0 0.0 9592 1252 pts/0 RNs 23:21 0:00 ps faux
setpriv 命令
描述:setpriv命令作用是使用不同的Linux特权设置运行程序 (PS:该命令在百度上找了一圈都没找到相关还是man setpriv
好使且完整),设置或查询跨execve(2)继承的各种Linux特权设置。
Tips:
- 如果应用任何指定的选项失败程序将不运行setpriv将返回退出代码为
127
。 - Dangers: 使用时候需要非常小心,它会带来意想不到的后果;例如设置
no_new_privs
然后执行一个SELinux限制的程序(就像这个工具会做的那样)可能会阻止SELinux限制生效。
基础语法:
代码语言:javascript复制#Usage:
setpriv [options] <program> [args...]
#OPTION
-d, --dump:转储当前特权状态。多次指定以显示额外的、大部分是无用的信息。与所有其他选项不兼容。
--ruid uid, --euid uid, --reuid uid: 设置uid或gid不会更改功能,尽管最后的exec调用可能会更改功能,例如 --reuid=1000 --regid=1000 --caps=-all
--rgid gid, --egid gid, --regid gid: 设置真实的、有效的,或同时设置两个gid。为了安全起见必须指定 --keep-groups, --clear-groups, or --groups 如果您设置了任何主要gid。
--no-new-privs: 设置该位后execve(2)将不会授予新的特权如, `setuid和setgid位`以及文件功能将被禁用(用这些位执行二进制文件set仍然可以工作但它们不会获得特权),从Linux 3.5开始就支持no_new_privs位。
--inh-caps ( |-)cap: 可继承的功能
--bounding-set ( |-)cap: 设置可继承能力或能力边界集,参数是一个逗号分隔的 cap和-cap条目列表,它们分别添加或删除条目。
--list-caps: 列出所有已知的能力必须单独指定。
--clear-groups: 清除补充组。
--keep-groups: 保留补充组, Only useful in conjunction with --rgid, --egid, or --regid.
--groups group: 集补充组。
--securebits ( |-)securebit: 设置或清除securebits。有效的securebits是noroot、noroot_locked、no_setuid_fixup、no_setuid_fixup_locked和keep_caps_locked。execve(2)清除keep_caps,因此不允许。
--selinux-label label: 请求一个特定的SELinux转换(使用exec上的转换,而不是dyntrans)不能与`--no-new-privs`连用。如果SELinux不在使用中这将失败并导致setpriv(1)中止,转换可能被忽略或导致execve(2)。
--apparmor-profile profile: 请求特定的AppArmor配置文件(使用exec上的转换)。这将失败,并导致setpriv(1)中止,如果设备不在使用中,过渡可能被忽略或导致execve(2)在AppAr‐mor的兴致下失败。
基础用法:
代码语言:javascript复制#(1) 列出所有已知可操作的权限
$ setpriv --list-caps
chown
dac_override
dac_read_search
fowner
fsetid
kill
setgid
setuid
setpcap
linux_immutable
net_bind_service
net_broadcast
net_admin
net_raw
ipc_lock
ipc_owner
sys_module
sys_rawio
sys_chroot
sys_ptrace
sys_pacct
sys_admin
sys_boot
sys_nice
sys_resource
sys_time
sys_tty_config
mknod
lease
audit_write
audit_control
setfcap
mac_override
mac_admin
syslog
wake_alarm
block_suspend
#(2) 以额外用户执行命令ps
setpriv --reuid=nobody --regid=nogroup --init-groups ps