linux系统安全加固--账号相关
linux系统安全加固
一、账号相关
1、禁用或删除无用账号
减少系统无用账号,降低安全风险。
当我们的系统安装完毕后,系统默认自带了一些虚拟账户,比如bin、adm、lp、games、postfix等,这些账号理论上是可以删除的。但是因为它们的登录shell都是/sbin/nologin,所以它们本身也是无法登录的,不用删也可以。我们要注意的是系统安装完成后,自己手动创建的一些账户,比如这些登录shell是/bin/bash,一定要控制好。
1.1、使用cat /etc/passwd 命令查看所有账号
如下图所示:
注:/etc/passwd是存放用户的地方,简单学习一下。各个字段描述如下:
用户名: 密码 : uid : gid :用户描述:主目录:登陆shell
把系统一些自带的账号注释掉:
注意:不建议直接删除,当你需要某个用户时,自己重新添加会很麻烦。
删除用户主要包括:adm,lp,sync,shutdown,halt,news,uucp,operator,games,ftp,postfix,dovecot
[root@localhost ~]# cp /etc/passwd /etc/passwdbak [root@localhost ~]# vim /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin #adm:x:3:4:adm:/var/adm:/sbin/nologin #lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin #sync:x:5:0:sync:/sbin:/bin/sync #shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown #halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin #operator:x:11:0:operator:/root:/sbin/nologin #games:x:12:100:games:/usr/games:/sbin/nologin #ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:998:996:User for polkitd:/:/sbin/nologin tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin #postfix:x:89:89::/var/spool/postfix:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin lulu:x:1000:1000::/home/lulu:/bin/bash #dovecot:x:97:97:Dovecot IMAP server:/usr/libexec/dovecot:/sbin/nologin #dovenull:x:997:995:Dovecot's unauthorized user:/usr/libexec/dovecot:/sbin/nologin mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin dockerroot:x:996:993:Docker User:/var/lib/docker:/sbin/nologin dd:x:1001:1001::/home/dd:/bin/bash doubles:x:1002:1002::/home/doubles:/bin/bash apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin d1:x:1003:1004::/home/d1:/bin/bash d3:x:1004:1007::/home/d3:/bin/bash [root@localhost ~]# id adm id: adm: no such user [root@localhost ~]# id lp id: lp: no such user [root@localhost ~]#
注释用户组
删除的用户组包括:adm,lp,mail,games,ftp,audio
[root@localhost ~]# cp /etc/group /etc/groupbak [root@localhost ~]# vim /etc/group root:x:0: bin:x:1: daemon:x:2: sys:x:3: #adm:x:4: tty:x:5: disk:x:6: #lp:x:7: mem:x:8: kmem:x:9: wheel:x:10:doubles cdrom:x:11: mail:x:12:postfix man:x:15: dialout:x:18: floppy:x:19: #games:x:20: tape:x:30: video:x:39: #ftp:x:50: lock:x:54: #audio:x:63: .....
1.2、userdel -r删除不必要的账号
如果是一些自己添加的账户,不用的话,建议直接删除。
加上参数-r,将账号相应的home目录与mail目录都一起删掉。
[root@localhost ~]# userdel -r d2 userdel: d2 mail spool (/var/spool/mail/d2) not found userdel: d2 home directory (/home/d2) not found [root@localhost ~]#
1.3、passwd -l禁用账户
使用passwd -l禁用账户dd,禁用后,root用户仍然可以su,但是其他用户无法su到dd,也无法通过xshell去ssh到dd了。
[root@localhost ~]# passwd -l dd Locking password for user dd. passwd: Success [root@localhost ~]# su dd [dd@localhost root]$ exit exit [root@localhost ~]# su - doubles Last login: Sat Sep 8 20:24:52 HKT 2018 on pts/2 [doubles@localhost ~]$ su dd Password: su: Authentication failure [doubles@localhost ~]$
1.4、passwd -u解锁账户
使用passwd -u解锁后,账户可以正常登陆。
[doubles@localhost ~]$ exit logout [root@localhost ~]# passwd -u dd Unlocking password for user dd. passwd: Success [root@localhost ~]# su doubles [doubles@localhost root]$ su dd Password: [dd@localhost root]$
2、检查特殊账号
检查是否存在空口令和root权限的账号。
2.1、检测空口令账户
[root@localhost ~]# awk -F: '$2=="!!" {print $1}' /etc/shadow systemd-bus-proxy systemd-network dbus polkitd tss postfix sshd lulu dovecot dovenull mysql dockerroot apache d3
再去/etc/passwd查看哪些账户是可登录的,如下:
2.2、加固空口令账号
对无口令并且可登录的账户,进行密码设置:(注意密码不能包含用户名,也不能少于7位)
[root@localhost ~]# passwd lulu Changing password for user lulu. New password: Retype new password: passwd: all authentication tokens updated successfully. [root@localhost ~]# passwd d3 Changing password for user d3. New password: BAD PASSWORD: The password is shorter than 7 characters Retype new password: passwd: all authentication tokens updated successfully. [root@localhost ~]# [root@localhost ~]# passwd d3 Changing password for user d3. New password: Retype new password: passwd: all authentication tokens updated successfully.
2.3、检测root权限账号
使用命令 awk -F: '($3==0)' /etc/passwd 查看UID为零的账号。
[root@localhost ~]# awk -F: '($3==0)' /etc/passwd root:x:0:0:root:/root:/bin/bash [root@localhost ~]#
确保uid为0的账号只能是root账号。
3、添加口令策略
3.1、密码复杂度设置
加强口令的复杂度等,降低被猜解的可能性。
a、用户密码不能包含用户名
b、用户密码不能少于10位
c、用户密码需要是特殊字符、数字、字母的组合
Linux对应的密码策略模块有:pam_passwdqc 和 pam_pwquality 。
pam_passwdqc模块对应的是/etc/login.defs
pam_pwquality模块对应的是/etc/security/pwquality.conf
(旧版是pam_cracklib.so)
3.1.1、修改/etc/login.defs
[root@localhost ~]# vim /etc/login.defs
PASS_MIN_LEN 10 #密码最小长度,使用pam_cracklib module,该参数不再有效
3.1.2、修改/etc/pam.d/system-auth
修改前,我们先备份一下:
[root@localhost ~]# cp /etc/pam.d/system-auth /etc/pam.d/system-auth-backup
3.1.2.1、禁止使用旧密码
找到同时有 “password” 和 “pam_unix.so” 字段并且附加有 “remember=5” 的那行,它表示禁止使用最近用过的5个密码(己使用过的密码会被保存在 /etc/security/opasswd 下面)。
配置如下:
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok remember=5
3.1.2.2、设置密码最小长度
找到同时有 “password” 和 “pam_cracklib.so” 字段并且附加有 “minlen=10” 的那行,它表示最小密码长度为(10 - 类型数量)。这里的 “类型数量” 表示不同的字符类型数量。PAM 提供4种类型符号作为密码(大写字母、小写字母、数字和标点符号)。如果你的密码同时用上了这4种类型的符号,并且你的 minlen 设为10,那么最短的密码长度允许是6个字符。
配置如下:
password requisite pam_cracklib.so retry=3 difok=3 minlen=10
3.1.2.3、其他复杂度设置
pam_cracklib.so比较重要和难于理解的是它的一些参数和计数方法,其常用参数包括:
debug:将调试信息写入日志;
type=xxx:当添加/修改密码时,系统给出的缺省提示符是“New UNIX password:”以及“Retype UNIX
password:”,而使用该参数可以自定义输入密码的提示符,比如指定type=your own word;
retry=N:定义登录/修改密码失败时,可以重试的次数;
difok=N:定义新密码中必须有几个字符要与旧密码不同。但是如果新密码中有1/2以上的字符与旧密码不同时,该新密码将被接受;
minlen=N:定义用户密码的最小长度;
dcredit=N:定义用户密码中必须包含多少个数字;
ucredit=N:定义用户密码中必须包含多少个大写字母;
lcredit=N:定义用户密码中必须包含多少个小些字母;
ocredit=N:定义用户密码中必须包含多少个特殊字符(除数字、字母之外);
我的配置如下:
主要是两行:
[root@localhost ~]# vim /etc/pam.d/system-auth password requisite pam_pwquality.so try_first_pass local_users_only retry=3 dcredit=-1 ucredit=-1 lcredit=-1 ocredit=-1 difok=1 minlen=8 authtok_type="doubles type" password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok remember=5
(注)
a、*credit=-1表示至少有一个的意思。
b、旧版的系统用的pam_cracklib.so,只要把上面的pam_pwquality.so替换成pam_cracklib.so就可以了。
c、Centos7以后都用pam_pwquality了,pam_pwquality完全向下兼容pam_cracklib,并且还提供了/etc/security/pwquality.conf进行参数配置。
3.1.2.4、测试
以上设置对root用户完全不起作用的。root是个bug般的存在
[root@localhost ~]# passwd doubles Changing password for user doubles. New "doubles password: (输入的是dd) BAD PASSWORD: The password is a palindrome Retype new "doubles password: (输入的是dd123) Sorry, passwords do not match. New "doubles password: (输入的是dd123) BAD PASSWORD: The password contains less than 1 uppercase letters Retype new "doubles password: (再次输入dd123) passwd: all authentication tokens updated successfully. [root@localhost ~]#
以上root给doubles最终设置密码为dd123,虽然不符合规则,但还是设置成功了,这就是root。
切换成普通用户去更改自己的密码:
[root@localhost ~]# su doubles [doubles@localhost root]$ passwd doubles passwd: Only root can specify a user name. [doubles@localhost root]$ passwd Changing password for user doubles. Changing password for doubles. (current) UNIX password: (输入的是dd) passwd: Authentication token manipulation error [doubles@localhost root]$ passwd Changing password for user doubles. Changing password for doubles. (current) UNIX password: New "doubles password: (输入的是dd123,跟老密码一样了,remember起作用了。) BAD PASSWORD: The password is the same as the old one New "doubles password: (输入的是doubles,没有数字) BAD PASSWORD: The password contains less than 1 digits New "doubles password: (输入的是doubles123,没有大写) BAD PASSWORD: The password contains less than 1 uppercase letters passwd: Have exhausted maximum number of retries for service [doubles@localhost root]$ # 尝试了最大次数,再试: [doubles@localhost root]$ passwd Changing password for user doubles. Changing password for doubles. (current) UNIX password: (当前密码dd123) New "doubles password: (Doubles123,没有特殊字符) BAD PASSWORD: The password contains less than 1 non-alphanumeric characters New "doubles password: (doubles123!!,包含用户名) BAD PASSWORD: The password contains the user name in some form New "doubles password: (dd123456!!!,没有大写) BAD PASSWORD: The password contains less than 1 uppercase letters passwd: Have exhausted maximum number of retries for service [doubles@localhost root]$ passwd Changing password for user doubles. Changing password for doubles. (current) UNIX password: (当前密码dd123) New "doubles password: (Dou12313456,没有特殊字符) BAD PASSWORD: The password contains less than 1 non-alphanumeric characters New "doubles password: (dd123!!,少于8位了) BAD PASSWORD: The password is shorter than 8 characters New "doubles password: (Ddou123!!!) Retype new "doubles password: (Ddou123!!!) passwd: all authentication tokens updated successfully. [doubles@localhost root]$
3.2、设置用户密码过期时间
3.2.1、修改 /etc/login.defs
通过修改配置文件 vi /etc/login.defs ,设置全体用户的密码过期时间等。
[root@localhost ~]# vim /etc/login.defs PASS_MAX_DAYS 90 #新建用户的密码最长使用天数 PASS_MIN_DAYS 0 #新建用户的密码最短使用天数 PASS_WARN_AGE 7 #新建用户的密码到期提前提醒天数
3.2.2、使用命令chage
使用chage 命令单独修改单用户配置
chage -m (最短时间) -M (最长时间) -E (过期时间) -W (过期前X天提示) 用户名
[root@localhost ~]# chage -m 0 -M 30 -E 2020-01-01 -W 7 doubles [root@localhost ~]#
表示将此用户doubles的密码最短使用天数设为0,最长使用天数设为30,密码2020年1月1日过期,过期前七天警告用户。
注意:当出现如下图错误的时候,基本就是密码过期了,可以使用上面的命令修改过期时间,即可重新登录。
WARNING: Your password has expired.
You must change your password now and login again!
[root@localhost ~]# chage -m 0 -M 99999 -E 2020-01-01 -W 7 doubles
再重新连接即可不用修改密码就能登录了。
这里一般不建议把过期时间设为99999,之前30天,你设个60天就好了,延长30天。
3.3、密码输错三次,锁定用户5分钟
使用cat /etc/pam.d/sshd命令查看密码策略:
设置连续输错三次密码,账号锁定五分钟,只能由root用户解锁。
3.3.1、修改配置:
一定要写在#%PAM-1.0下面,否则即使输错三次,只要继续输对了密码,还是可以登录,导致无法锁定。
auth required pam_tally2.so onerr=fail deny=3 unlock_time=300
参数解释:
pam_tally2.so:位于/usr/lib64/security/下。(注意:如果用pam_tally.so,是没有自动解锁的功能。只能进单用户模式解锁。)
deny:设置普通用户和root用户连续错误登陆的最大次数,超过最大次数,则锁定该用户;
unlock_time 设定普通用户锁定后,多少时间后解锁,单位是秒;
no_magic_root 连root用户也在限制范围,不给root特殊权限。
even_deny_root 也限制root用户;
root_unlock_time 设定root用户锁定后,多少时间后解锁,单位是秒;
3.3.2、上面配置完毕后,我们在另一台机器用ssh试一下:
这里故意输错三次密码,
[doubles@localhost root]$ ssh dd1@192.168.188.129 dd1@192.168.188.129's password: Permission denied, please try again. dd1@192.168.188.129's password: Permission denied, please try again. dd1@192.168.188.129's password: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password). [doubles@localhost root]$ [doubles@localhost root]$
输错三次后,再输入正确密码,发现也没办法登录了。
[doubles@localhost root]$ ssh dd1@192.168.188.129 dd1@192.168.188.129's password: Permission denied, please try again. dd1@192.168.188.129's password: [doubles@localhost root]$
3.3.3、我们在192.168.188.129上面查看/var/log/secure日志发现:
[root@localhost ~]# vim /var/log/secure Sep 9 17:47:40 localhost unix_chkpwd[72389]: password check failed for user (dd1) Sep 9 17:47:40 localhost sshd[72387]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.188.128 user=dd1 Sep 9 17:47:42 localhost sshd[72387]: Failed password for dd1 from 192.168.188.128 port 46584 ssh2 Sep 9 17:47:43 localhost unix_chkpwd[72390]: password check failed for user (dd1) Sep 9 17:47:45 localhost sshd[72387]: Failed password for dd1 from 192.168.188.128 port 46584 ssh2 Sep 9 17:47:46 localhost sshd[72387]: pam_tally2(sshd:auth): user dd1 (1001) tally 3, deny 2 Sep 9 17:47:46 localhost unix_chkpwd[72391]: password check failed for user (dd1) Sep 9 17:47:48 localhost sshd[72387]: Failed password for dd1 from 192.168.188.128 port 46584 ssh2 Sep 9 17:47:48 localhost sshd[72387]: Connection closed by 192.168.188.128 [preauth] Sep 9 17:47:48 localhost sshd[72387]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.188.128 user=dd1 Sep 9 17:47:59 localhost sshd[72393]: pam_tally2(sshd:auth): user dd1 (1001) tally 4, deny 2 Sep 9 17:48:01 localhost sshd[72393]: Failed password for dd1 from 192.168.188.128 port 46586 ssh2 Sep 9 17:48:07 localhost sshd[72393]: Connection closed by 192.168.188.128 [preauth]
查看错误登录次数:
[root@localhost ~]# pam_tally2 --user dd1 Login Failures Latest failure From dd1 4 09/09/18 17:47:59 192.168.188.128 [root@localhost ~]#
清空错误登录次数:(解锁)
[root@localhost ~]# pam_tally2 --user dd1 --reset Login Failures Latest failure From dd1 4 09/09/18 17:47:59 192.168.188.128 [root@localhost ~]# pam_tally2 --user dd1 Login Failures Latest failure From dd1 0 [root@localhost ~]#
3.3.4、其他设置
以上是针对远程登录的sshd,针对不同服务来限制不同登陆方式:
#只在本地文本终端tty上做限制,可以编辑如下文件,添加的内容和上方一样。
vim /etc/pam.d/login
#只在远程telnet、ssh登陆上做限制,可以编辑如下文件,添加的内容和上方也一样。
vim /etc/pam.d/remote
vim /etc/pam.d/sshd
3.3.5、汇总更改
参考文档:https://www.jb51.net/article/116935.htm
如果想要各个终端都限制,那么更改/etc/pam.d/password-auth。
加入下面两行:
auth required pam_tally2.so deny=3 unlock_time=600 account required pam_tally2.so
注意:
很多教程里都说更改/etc/pam.d/system-auth文件,这是错误的,要看/etc/pam.d/sshd各终端调用的是哪个文件,像我这里就没有调用这个文件,调用的是password-auth,如下图:
这是/etc/pam.d/sshd:
再看/etc/pam.d/login:
通过上述两个文件,你会发现sshd用了password-auth,而login用了system-auth,所以要看清楚再去设置相应的文件。
小编曾经就在这里折腾了好久,引以为鉴......
4、限制用户su
禁止普通用户su到root用户,只允许指定的用户su到root用户。(需要root权限)
为禁止普通用户su至root,需要分别修改/etc/pam.d/su和/etc/login.defs两个配置文件。
4.1、只有wheel组用户能够su
4.1.1、配置
首先:将用户加入到wheel组(后面会设置只有wheel组的用户才能su到root)
[root@localhost ~]# usermod -G wheel doubles [root@localhost ~]# id doubles uid=1002(doubles) gid=1002(doubles) groups=1002(doubles),10(wheel)
去除/etc/pam.d/su文件中如下行的注释:(表示要求用户在wheel组下才能root)
[root@localhost ~]# vim /etc/pam.d/su auth required pam_wheel.so use_uid
在/etc/login.defs文件中加入如下配置项:(表示只有wheel组能够su到root)
[root@localhost ~]# vim /etc/login.defs SU_WHEEL_ONLY yes
4.1.2、测试
下面我们切换到普通用户su试一下
[root@localhost shellscript]# su dd [dd@localhost shellscript]$ id uid=1001(dd) gid=1001(dd) groups=1001(dd) [dd@localhost shellscript]$ su Password: su: Permission denied [dd@localhost shellscript]$
上面用户dd没有在wheel组下,所以即使输入了正确的密码也不能su,权限限制。而doubles是在wheel组下的,所以下面我们用doubles试一下
[root@localhost shellscript]# su doubles [doubles@localhost shellscript]$ su Password: [root@localhost shellscript]#
doubles在wheel组下,成功su到root。
4.2、自定义用户组能够su
除了wheel组,也可以配置只有指定的组的用户能够su到root。
参考:https://access.redhat.com/solutions/64860
https://www.cnblogs.com/kevingrace/p/8671964.html
A、创建用户组groupa
[root@localhost ~]# groupadd groupa
B、创建/etc/security/su-groupa-access文件,里面指定允许su到的用户
[root@localhost ~]# vim /etc/security/su-groupa-access doubles root
这就表示groupa的用户可以su到root和doubles
保证文件权限不是所有人都可以修改的。
[root@localhost ~]# ll /etc/security/su-groupa-access -rw-r--r-- 1 root root 13 Sep 8 19:46 /etc/security/su-groupa-access
C、在/etc/pam.d/su下加入下面三行
[root@localhost ~]# vim /etc/pam.d/su auth [success=2 default=ignore] pam_succeed_if.so use_uid user notingroup groupa auth required pam_wheel.so use_uid group=groupa auth required pam_listfile.so item=user sense=allow onerr=fail file=/etc/security/su-groupa-access
配置如下图:
D、将用户dd加入到groupa组中测试
[root@localhost ~]# gpasswd -a dd groupa Adding user dd to group groupa [root@localhost ~]# id dd uid=1001(dd) gid=1001(dd) groups=1001(dd),1005(ddd),1006(groupa) [root@localhost ~]# su dd [dd@localhost root]$ su doubles Password: [doubles@localhost root]$ [doubles@localhost root]$ exit exit [dd@localhost root]$ su Password: [root@localhost ~]#
发现此时dd已经可以su到doubles和root了。
(注意)这里自定义用户组的话,按照网上很多教程说的这样加:
[root@localhost ~]# vim /etc/pam.d/su auth required pam_wheel.so group=test
是不起作用的,最后从redhat文档里看到用创建 /etc/security/su-groupa-access的方式才真正成功。这里也是折腾了小编一下午呢,大家引以为鉴......
5、配置sudo权限
5.1、su与sudo简介
5.1.1、su
su:就是switch user的意思,表示切换用户。
普通用户su到其他用户需要输入目标用户的密码。Root切换到其他用户不需输入密码。
命令su后面什么都不接的时候表示切换到root用户。
[doubles@localhost shellscript]$ su Password: [root@localhost shellscript]#
输入su root(或者其他用户名),表示不切换环境变量到当前用户下。
[doubles@localhost root]$ su root Password: [root@localhost ~]#
输入:su - root(或者其他用户名)这里加了"-"后表示添加切换的当前的环境变量到新用户的环境变量。
[doubles@localhost shellscript]$ su - root Password: Last login: Sat Sep 8 01:22:45 HKT 2018 on pts/2 [root@localhost ~]#
5.1.2、sudo
sudo命令:superuser do,表示以root的身份来执行后面的命令。
想要使用sudo,必须在/etc/sudoers里面给自己添加root权限。
Visudo命令:就是vi /etc/sudoers。
[doubles@localhost ~]$ visudo visudo: /etc/sudoers: Permission denied visudo: /etc/sudoers: Permission denied [doubles@localhost ~]$ sudo visudo [sudo] password for doubles: visudo: /etc/sudoers.tmp unchanged [doubles@localhost ~]$
5.2、指定用户能够sudo
配置普通用户通过sudo继承了root权限
在root用户下,修改/etc/sudoers
[root@localhost ~]# ll /etc/sudoers -r--r-----. 1 root root 3941 Sep 6 18:32 /etc/sudoers
/etc/sudoers默认是只读的,需要给/etc/sudoers添加可写权限:
[root@localhost ~]# chmod u+w /etc/sudoers [root@localhost ~]# vim /etc/sudoers ## Allow root to run any commands anywhere root ALL=(ALL) ALL doubles ALL=(root) NOPASSWD: ALL
这几项意思分别为:
第一列:doubles为要添加sudo权限的用户
第二列:ALL表示从哪里登录,ALL表示不限制本地远程,可以填写ip段
第三列:(root)表示以root身份执行
第四列:NOPASSWD:表示执行sudo的时候不需要密码,默认不填就表示要输入密码。
第五列:ALL表示允许以root身份执行所有命令,以,隔开。
[root@localhost ~]# chmod g-w /etc/sudoers
现在doubles就可以通过sudo来以root身份执行命令了。
[doubles@localhost ~]$ sudo chmod u-w /etc/sudoers [doubles@localhost ~]$ ls [doubles@localhost ~]$ sudo vim /etc/sudoers [sudo] password for doubles: Sorry, try again. [sudo] password for doubles:
这个操作比较严格,所以可能会需要输入密码确认。
dd不在sudoers里,我们尝试用dd进行sudo操作报错。
[dd@localhost shellscript]$ sudo vim /etc/shadow dd is not in the sudoers file. This incident will be reported.
5.3、wheel组用户能够sudo
/etc/sudoers里面还有一项:
[doubles@localhost ~]$ ## Allows people in group wheel to run all commands %wheel ALL=(ALL) ALL ## Same thing without a password # %wheel ALL=(ALL) NOPASSWD: ALL
这项表示允许wheel组的用户执行所有用户的所有命令,相当于wheel组的用户都继承了root权限。
比如,我们将dd加入到wheel组:
[root@localhost ~]# usermod -G wheel dd # (用命令gpasswd -a dd wheel也行)
/doubles/shellscript目录只有root用户可写,理论上dd是不能在shellscript里创建文件的。
[root@localhost ~]# ll /doubles/shellscript/ -d drwxr-xr-x. 5 root root 4096 Sep 7 21:09 /doubles/shellscript/ [root@localhost ~]# cd /doubles/shellscript/ [root@localhost shellscript]# su dd [dd@localhost shellscript]$ mkdir aa mkdir: cannot create directory ‘aa’: Permission denied
普通用户dd尝试在root的目录shellscript里创建目录失败,权限拒绝。
但是我们已经将dd加入到wheel组下了,所以用sudo试下
[dd@localhost shellscript]$ id dd uid=1001(dd) gid=1001(dd) groups=1001(dd),10(wheel) [dd@localhost shellscript]$ sudo mkdir aa [sudo] password for dd: [dd@localhost shellscript]$ ll aa -d drwxr-xr-x 2 root root 4096 Sep 7 21:09 aa
用sudo去创建目录aa成功。所以wheel组下的dd也跟doubles用户一样可以通过sudo来以root身份执行所有的命令。
我们把dd从wheel组删除:
[dd@localhost shellscript]$ sudo gpasswd -d dd wheel Removing user dd from group wheel [dd@localhost shellscript]$ id dd uid=1001(dd) gid=1001(dd) groups=1001(dd) 也可以去/etc/group里删除: [dd@localhost shellscript]$ sudo vim /etc/group # wheel:x:10:doubles,dd wheel:x:10:doubles
5.4、自定义用户组能够sudo
编辑配置文件/etc/sudoers
[root@localhost ~]# vim /etc/sudoers ## Allows members of the users group to mount and unmount the ## cdrom as root # %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom ## Allows members of the users group to shutdown this system # %users localhost=/sbin/shutdown -h now # customize group's user to sudo %d1 ALL=(root) NOPASSWD: ALL
前面两个注释是教程实例,我们依样自定义用户组d1能够通过sudo以root身份执行所有命令,而且不会询问密码。
测试如下:
[root@localhost ~]# su d1 [d1@localhost root]$ id d1 uid=1003(d1) gid=1004(d1) groups=1004(d1) [d1@localhost root]$ sudo vim /etc/shadow [d1@localhost root]$ sudo crontab -l #0 0 * * * /bin/bash /doubles/shellscript/cut_log.sh >>cutlog.log 2>&1 [d1@localhost root]$
如上所示,d1已经可以通过sudo去做只有root能做的事了,比如查看/etc/shadow
5.5、sudo密码过期处理
5.5.1、背景:
按照上面的设置之后,我们就可以用sudo以root身份执行命令了。但是我们发现每次用sudo的时候都会提示我们输入用户密码,所以我们一般会配置NOPASSWD:,如下:
doubles ALL=(root) NOPASSWD: ALL
但是我们发现,即使配置了NOPASSWD:,后面仍然还是有时候会提示我们输入密码,这是因为sudo的NOPASSWD:是有时间限制的,默认为5分钟。
5.5.2、配置
如果想以后每次使用sudo的时候不再验证密码,可以在刚刚的sudoers文件做如下操作:
参数解释:
其中timestamp_timeout=-1只需验证一次密码,以后系统自动记忆,runaspw需要root密码,如果不加默认是要输入普通账户的密码.
timestamp_timeout=2:表示将密码的超时时间设置为2分钟。
timestamp_timeout=0:为0表示永远提示输入密码。
timestamp_timeout=-1:
设置为负数的话(译注,原文是”-1“,但是手册中写明只要是负数就可以)只需要证明一次你知道密码就可以(译注:就是密码永不过期)。
如果你指向给某个特定用户应用默认值的话,这样做:
Defaults:doubles timestamp_timeout=-1
多个用户已逗号隔开。
小技巧:如果软件升级, /etc/sudoers 可能会被覆盖掉,所以好的习惯是在 /etc/sudoers.d 中添加
在 /etc/sudoers.d 目录中增加一个文件,添加相同的内容
6、ssh登录配置
对SSH服务进行安全加固,防止暴力破解成功。
6.1、配置密钥登录
所有服务器管理人员,与需要登录服务器的人员,都要配置密钥登录,避免使用密码登录。
关于在windows上,怎么配置与服务器登录的密钥,请查看文档:
https://www.cnblogs.com/doublexi/p/9564493.html
(注):配置密钥登录的时候,一定要对自己的密钥进行口令设置,否则别人拿到了你的私钥,你的服务器就是别人的了。
6.2、禁止用密码登录
前面,我们已经配置了使用密钥登录,每个用户只要记住自己密钥的口令就可以了,他们登录服务器已经不需要密码了,所以我们为了安全,禁止用密码登录。
[root@localhost ~]# cp /etc/ssh/sshd_config /etc/ssh/sshd_config_backup [root@localhost ~]# vim /etc/ssh/sshd_config # To disable tunneled clear text passwords, change to no here! #PasswordAuthentication yes #PermitEmptyPasswords no PasswordAuthentication no
把PasswordAuthentication yes改为no。
改配置之前一定要记得,先备份一下,方便以后回滚。
改完配置之后,接下来就是重启服务了,在重启之前一定要确保:
确保已经按照6.1配置了密钥登录。
确保已经按照6.1配置了密钥登录。
确保已经按照6.1配置了密钥登录。
重要事情说三遍,确保自己配置了密钥登录,并且能够通过这个密钥登录到服务器,特别是root。不然就是把自己锁在了门外。。。
重启ssh服务
[root@localhost ~]# systemctl restart sshd
重启服务后,再次登录的用户就只能通过密钥登录了,通过密码登录会提示错误。
[root@localhost ~]# ssh -p 2202 root@192.168.188.128 Permission denied (publickey,gssapi-keyex,gssapi-with-mic). [root@localhost ~]# ssh -p 2202 doubles@192.168.188.128 Permission denied (publickey,gssapi-keyex,gssapi-with-mic). [root@localhost ~]#
通过xshell尝试:
如图所示,即使我们输入了正确的用户名和密码,连接的时候会直接拒绝用密码登录。
拒绝密码的,直接跳到密钥登录:
6.3、禁止root用户直接登录
为了加强服务器安全,我们应该
A、避免使用root账户直接登录。
B、每个需要登录服务器的操作人员都应该用自己的账户
C、管理员为这些账户分配不同的权限
D、部分人员(如管理员)需要执行特权操作时,通过su或者sudo去操作。
所以在上述4、5点的时候,我们必须要严格控制好各个用户的su与sudo的权限。
接下来修改/etc/ssh/sshd_config来禁止root用户直接登录。
[root@localhost ~]# cp /etc/ssh/sshd_config /etc/ssh/sshd_config_backup [root@localhost ~]# vim /etc/ssh/sshd_config PermitRootLogin no
将PermitRootLogin的yes改为no。
改完配置,接下来自然是重启服务了。重启服务前,请确认:
A、确保自己已经配置了其他用户可以登录服务器
B、确保自己已经配置用户可以su或者sudo(防止以后自己要改回来)
重启服务:
[root@localhost ~]# systemctl restart sshd
重启后,再用xshell登录如图所示:
在另一台服务器登录也是一样:
[root@localhost ~]# ssh -p 2202 root@192.168.188.128 Permission denied (publickey,gssapi-keyex,gssapi-with-mic). [root@localhost ~]#
6.4、SSH其他配置
我们登录系统后,一般还会更改ssh的默认端口号,一般改为1024以上的。
[doubles@localhost ~]$ sudo vim /etc/ssh/sshd_config Port 2202
修改允许密码错误次数(默认6次)。
设置 MaxAuthTries 的值为 3。
最终ssh配置修改总结为:
[doubles@localhost ~]$ sudo vim /etc/ssh/sshd_config Port 2202 PermitRootLogin no MaxAuthTries 3 RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys # To disable tunneled clear text passwords, change to no here! #PasswordAuthentication yes #PermitEmptyPasswords no PasswordAuthentication no
重启服务:
[root@localhost ~]# systemctl restart sshd
6.5、登录超时设置
让用户在登录后,一段时间内不活动,自动登出。
6.5.1、修改环境变量TMOUT
$TMOUT = 30
参数说明:
# 用以下命令判断是否是否设置了该参数
echo $TMOUT
# 如果输出空或0表示不超时,大于0的数字n表示n秒没有收入则超时
6.5.1.1、/etc/profile全局设置
查看/etc/profile之前是否有配置,有则修改,没有则增加
[doubles@localhost ~]$ cat /etc/profile|grep TMOUT -n [doubles@localhost ~]$ [doubles@localhost ~]$ echo $TMOUT [doubles@localhost ~]$
上面$TMOUT变量为空,没有设置
修改前先备份一下
[doubles@localhost ~]$ cp /etc/profile /etc/profile-backup
在/etc/profile最下面增加一行如下
[doubles@localhost ~]$ sudo vim /etc/profile # ---------------------------- export TMOUT=900 # ---------------------------- # 900就是15分钟,将以上900修改为0就是设置不超时
接下来,source一下,让配置立即生效
[doubles@localhost ~]$ source /etc/profile [doubles@localhost ~]$
测试:
配置完之后,不动终端,过了15分钟之后自动退出如下:
[doubles@localhost ~]$ echo $TMOUT [doubles@localhost ~]$ sudo vim /etc/profile [doubles@localhost ~]$ source /etc/profile [doubles@localhost ~]$ timed out waiting for input: auto-logout Connection closing...Socket close. Connection closed by foreign host. Disconnected from remote host(192.168.188.128:2202) at 12:45:21. Type `help' to learn how to use Xshell prompt. [c:\~]$
6.5.1.2、个人超时配置
上面/etc/profile是对所有用户都生效的,如果要只针对个别用户配置登录超时,可以通过修改个人home目录下的.bashrc或.bash_profile文件来实现。
这两个文件选择其中一个在末尾加入如下一行,具体操作如下:
[doubles@localhost ~]$ pwd /home/doubles [doubles@localhost ~]$ vim .bash_profile export TMOUT=900 [doubles@localhost ~]$ source .bash_profile
测试结果如下:
[doubles@localhost ~]$ timed out waiting for input: auto-logout Connection closing...Socket close. Connection closed by foreign host. Disconnected from remote host(192.168.188.128:2202) at 14:59:19. Type `help' to learn how to use Xshell prompt. [c:\~]$
6.5.2、修改sshd_config
6.5.2.1、全局超时配置
通过修改ssh的配置文件 /etc/ssh/sshd_config我们同样也可以实现超时自动登出功能,具体如下:
[doubles@localhost ~]$ sudo vim /etc/ssh/sshd_config
找到这两行:
#ClientAliveInterval 0 #ClientAliveCountMax 3
修改如下:
ClientAliveInterval 300 ClientAliveCountMax 2
第一行表示每300秒检测一次,默认为0表示不发送alive检测
第二行表示检测到2次(即2*300=600秒,即10分钟)不活动就断开连接。
上述配置,对除了root之外的用户都生效。
保存退出,重启服务:
[doubles@localhost ~]$ sudo systemctl restart sshd
关于这个配置,小编这里测试一直没有生效,不知道为什么,用户一直没有被踢下线。。。。。。
从坑里爬出来的总结:
(启发文:https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/296920)
引用原文的一句话:To make it work ClientAliveCountMax should to be 0
所以,以上配置全部忘掉,接下来我们重新弄:
[doubles@localhost ~]$ sudo vim /etc/ssh/sshd_config ClientAliveInterval 300 ClientAliveCountMax 0 # 这里必须是0
保存退出,重启服务:
[doubles@localhost ~]$ sudo systemctl restart sshd
接下来,我们要退出登录,让整个shell连接都断开,下次再重新进行ssh连接的时候,新的配置才会生效,否则你应用的还是上一次的配置。
一定要断开连接
一定要断开连接
一定要断开连接
重要事情说三遍,
重点1:ClientAliveCountMax 0(必须是0)
重点2:必须退出整个ssh连接,重新登录,配置才会生效。
6.5.2.2、个人不超时配置
在进行ssh连接的时候,加上参数:
法一:
[dd@localhost doubles]$ ssh -o ConnectTimeout=3 dd1@192.168.188.129 Enter passphrase for key '/home/dd/.ssh/id_rsa': Last login: Tue Sep 11 20:41:43 2018 from 192.168.188.128 [dd1@localhost ~]$ Connection to 192.168.188.129 closed by remote host. Connection to 192.168.188.129 closed. [dd@localhost doubles]$
法二:
[dd@localhost doubles]$ ssh -o ServerAliveInterval=5 -o ServerAliveCountMax=0 dd1@192.168.188.129 Enter passphrase for key '/home/dd/.ssh/id_rsa': Last login: Tue Sep 11 22:22:15 2018 from 192.168.188.128 [dd1@localhost ~]$ Timeout, server 192.168.188.129 not responding. [dd@localhost doubles]$
这样子只会在需要的连接中保持持久连接, 毕竟不是所有连接都要保持持久的
6.6、登录日志配置
通过脚本代码实现记录所有用户的登录操作日志,防止出现安全事件后无据可查。
操作如下:(这里最好切换成root用户来操作)
在profile最后一行追加:
[root@localhost ~]# vim /etc/profile history USER=`whoami` USER_IP=`who -u am i 2>/dev/null| awk '{print $NF}'|sed -e 's/[()]//g'` if [ "$USER_IP" = "" ]; then USER_IP=`hostname` fi if [ ! -d /var/log/history ]; then mkdir /var/log/history chmod 777 /var/log/history fi if [ ! -d /var/log/history/${LOGNAME} ]; then mkdir /var/log/history/${LOGNAME} chmod 300 /var/log/history/${LOGNAME} fi export HISTSIZE=4096 DT=`date +"%Y%m%d_%H:%M:%S"` export HISTFILE=/var/log/history/${LOGNAME}/${USER}@${USER_IP}_$DT chmod 600 /var/log/history/${LOGNAME}/*history* 2>/dev/null [root@localhost ~]#
Source让配置生效
[root@localhost ~]# source /etc/profile
注意: /var/log/history 是记录日志的存放位置,可以自定义。
通过上述步骤,可以在 /var/log/history 目录下以每个用户为名新建一个文件夹,每次用户退出后都会产生以用户名、登录IP、时间的日志文件,包含此用户本次的所有操作(root用户除外)。
同时,建议您使用OSS服务收集存储日志。
6.7、屏蔽ssh的Banner信息
banner的作用:你用ssh登陆的时候,会自动显示系统版本信息之类的敏感信息
有些版本会存在一些固有的安全问题,很容易被黑客利用。所以我们需要屏蔽这些信息。
这一点看需要,很多系统默认是没有显示Banner的。
6.7.1、检查
查看/etc/ssh/sshd_config文件中是否存在Banner字段
[root@localhost ~]# cat /etc/ssh/sshd_config |grep -i banner # no default banner path #Banner none
发现Banner是none,没有设置Banner,ssh连接是没有信息显示的,
查看/etc/motd 文件内容,该处内容将作为banner信息显示给登录用户
[root@localhost ~]# cat /etc/motd [root@localhost ~]#
发现设置都是空的,那么ssh连接信息将如下:
通过xshell连接也是这样:
没有显示什么有用的信息,所以可以不用屏蔽,下面直接略过。
6.7.2、屏蔽
如果有设置,那么屏蔽只需要Banner改为none即可。
操作前先备份
[root@localhost ~]# cp /etc/ssh/sshd_config /etc/ssh/sshd_config_backup [root@localhost ~]# cp -p /etc/motd /etc/motd_bak [root@localhost ~]# vim /etc/ssh/sshd_config Banner none [root@localhost ~]# vim /etc/motd
6.7.3、自定义Banner信息
参考:https://blog.csdn.net/sdb5858874/article/details/80525992
新建Banner文件ssh_banner
[root@localhost doubles]# vim /etc/ssh_banner Authorized only. All activity will be monitored and reported
将该文件归为bin用户和属组
[root@localhost doubles]# chown bin:bin /etc/ssh_banner
设置权限为600
[root@localhost doubles]# chmod 644 /etc/ssh_banner
编辑登陆后的欢迎信息
[root@localhost doubles]# vim /etc/motd login success. All activity will be monitored and reported
修改ssh配置
[root@localhost doubles]# vim /etc/ssh/sshd_config Banner /etc/ssh_banner
重启服务
[root@localhost doubles]# systemctl restart sshd
测试:
在另一台机发起ssh登录请求:
终端登录也是一样:
Banner信息设置完毕。
7、为grub设置密码
可以为linux引导器grub设置密码,防止别人通过grub引导进入单用户模式进行非法操作。(当然此项不是必须,因为当别人能接触到你的grub的时候,也就说明你的机器已经被别人掌握了,此刻服务器已经没有安全性可言了。)
方法一:命令设置(推荐)
查看系统默认密码:
[root@localhost doubles]# cat /etc/grub2.cfg | grep password password_pbkdf2 root ${GRUB2_PASSWORD}
首先查看grub登录用户名:
[root@localhost doubles]# cat /etc/grub.d/01_users #!/bin/sh -e cat << EOF if [ -f \${prefix}/user.cfg ]; then source \${prefix}/user.cfg if [ -n "\${GRUB2_PASSWORD}" ]; then set superusers="root" export superusers password_pbkdf2 root \${GRUB2_PASSWORD} fi fi EOF [root@localhost doubles]#
通过上面发现用户名是root,接下来通过grub2-setpassword命令修改密码:
[root@localhost doubles]# grub2-setpassword Enter password: Confirm password: [root@localhost doubles]#
改完密码重启:
[root@localhost doubles]# init 6
在选择内核的时候,按e,如下图:
此时它会提示你输入用户名和密码:
输入完用户名和密码之后,就进入了
在这里你就可以修改root密码的,慎重。。。
注意:以上环境是centos7,7以下的系统环境略有所不同。这里不建议按照网上说的,通过修改/etc/grub2.cfg或者/etc/grub.d/00_header文件来明文指定密码。
方法二:明文密码
操作前,先备份一下文件
[root@localhost ~]# cp /etc/grub2.cfg /etc/grub2.cfg_backup
先查看之前是否有设置密码:
[root@localhost ~]# cat /etc/grub2.cfg | grep password
在/etc/grub.d/01_users文件中指定超级用户,其中root为超级用户的用户名,PassRoot+123为超级用户root的密码,清空该文件并添加以下几行。(用户名和密码按实际情况设置)
[root@localhost ~]# cp /etc/grub.d/01_users /etc/grub.d/01_users_backup [root@localhost ~]# vim /etc/grub.d/01_users cat << EOF set superusers="root" password root DoublesRoot!!123 EOF
我把之前的注释了,重新添加的,如下:
重新编译配置文件:
[root@localhost ~]# grub2-mkconfig -o /boot/grub2/grub.cfg Generating grub configuration file ... Found linux image: /boot/vmlinuz-3.10.0-514.el7.x86_64 Found initrd image: /boot/initramfs-3.10.0-514.el7.x86_64.img Found linux image: /boot/vmlinuz-0-rescue-ea399cee8fa94b1d9901ffd9d37bf7c6 Found initrd image: /boot/initramfs-0-rescue-ea399cee8fa94b1d9901ffd9d37bf7c6.img done [root@localhost ~]#
此时重新查看配置文件,发现多了密码,而且这个密码是明文的,不安全。
[root@localhost ~]# cat /etc/grub2.cfg |grep password password root DoublesRoot!!123 [root@localhost ~]#
此时,grub密码设置成功,重启即可生效。
方法三:密文密码
方法二是明文密码,在/etc/grub2.cfg就可以看到,很不安全,接下来我们设置密文密码。
使用grub2-mkpasswd-pbkdf2命令创建密文
[root@localhost ~]# grub2-mkpasswd-pbkdf2 Enter password: Reenter password: PBKDF2 hash of your password is grub.pbkdf2.sha512.10000.94A2F8EEA383CA6DDC6B432E9878FD12A02BF114A9B13FEAE0D2E834ADFF4B0A791DD1FDFF7A21E9CA3E277D567CDC12E2E99AEE7EF83E0D52B534B740B2117A.729B52B7BA281FF693EA3EA02FC7C22275A17DEEDF994BFAEC4B8ECC5046FC86FCDAB7B68D33DAC3A7419AA8C32B6F9AFE901BEBB4F4DFABC6213BE03FC1D711 [root@localhost ~]#
上面会输出一段密文,我们把它复制到/etc/grub.d/01_user里面,如下:
[root@localhost ~]# vim /etc/grub.d/01_users cat << EOF set superusers="root" password_pbkdf2 root PBKDF2 hash of your password is grub.pbkdf2.sha512.10000.94A2F8EEA383CA6DDC6B432E9878FD12A02BF114A9B13FEAE0D2E834ADFF4B0A791DD1FDFF7A21E9CA3E277D567CDC12E2E99AEE7EF83E0D52B534B740B2117A.729B52B7BA281FF693EA3EA02FC7C22275A17DEEDF994BFAEC4B8ECC5046FC86FCDAB7B68D33DAC3A7419AA8C32B6F9AFE901BEBB4F4DFABC6213BE03FC1D711 EOF
最后:重新编译生成grub2.cfg文件
[root@localhost ~]# grub2-mkconfig -o /boot/grub2/grub.cfg Generating grub configuration file ... Found linux image: /boot/vmlinuz-3.10.0-514.el7.x86_64 Found initrd image: /boot/initramfs-3.10.0-514.el7.x86_64.img Found linux image: /boot/vmlinuz-0-rescue-ea399cee8fa94b1d9901ffd9d37bf7c6 Found initrd image: /boot/initramfs-0-rescue-ea399cee8fa94b1d9901ffd9d37bf7c6.img done [root@localhost ~]#
检查/etc/grub2.cfg,发现多了一段密文
[root@localhost ~]# cat /etc/grub2.cfg | grep password password_pbkdf2 root PBKDF2 hash of your password is grub.pbkdf2.sha512.10000.94A2F8EEA383CA6DDC6B432E9878FD12A02BF114A9B13FEAE0D2E834ADFF4B0A791DD1FDFF7A21E9CA3E277D567CDC12E2E99AEE7EF83E0D52B534B740B2117A.729B52B7BA281FF693EA3EA02FC7C22275A17DEEDF994BFAEC4B8ECC5046FC86FCDAB7B68D33DAC3A7419AA8C32B6F9AFE901BEBB4F4DFABC6213BE03FC1D711 [root@localhost ~]#
密钥设置成功,重启即生效。