linux系统安全加固--账号相关

linux系统安全加固

一、账号相关

1、禁用或删除无用账号

减少系统无用账号,降低安全风险。

当我们的系统安装完毕后,系统默认自带了一些虚拟账户,比如bin、adm、lp、games、postfix等,这些账号理论上是可以删除的。但是因为它们的登录shell都是/sbin/nologin,所以它们本身也是无法登录的,不用删也可以。我们要注意的是系统安装完成后,自己手动创建的一些账户,比如这些登录shell是/bin/bash,一定要控制好。

1.1、使用cat /etc/passwd 命令查看所有账号

如下图所示:

注:/etc/passwd是存放用户的地方,简单学习一下。各个字段描述如下:

用户名: 密码 : uid : gid :用户描述:主目录:登陆shell

image

把系统一些自带的账号注释掉:

注意:不建议直接删除,当你需要某个用户时,自己重新添加会很麻烦。

删除用户主要包括: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查看哪些账户是可登录的,如下:

image

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:定义用户密码中必须包含多少个特殊字符(除数字、字母之外);

我的配置如下:

image

主要是两行:

[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!

image

[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用户锁定后,多少时间后解锁,单位是秒;

image

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

image

注意:

很多教程里都说更改/etc/pam.d/system-auth文件,这是错误的,要看/etc/pam.d/sshd各终端调用的是哪个文件,像我这里就没有调用这个文件,调用的是password-auth,如下图:

这是/etc/pam.d/sshd:

image

再看/etc/pam.d/login:

image

通过上述两个文件,你会发现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

配置如下图:

image

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文件做如下操作:

image

参数解释:

其中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 ~]# 

image

通过xshell尝试:

如图所示,即使我们输入了正确的用户名和密码,连接的时候会直接拒绝用密码登录。

image

拒绝密码的,直接跳到密钥登录:

image

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登录如图所示:

image

在另一台服务器登录也是一样:

[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连接信息将如下:

wps1CD3.tmp

通过xshell连接也是这样:

wps1CD4.tmp

没有显示什么有用的信息,所以可以不用屏蔽,下面直接略过。

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

wps1CD5.tmp

重启服务

[root@localhost doubles]# systemctl restart sshd

测试:

在另一台机发起ssh登录请求:

wps1CE6.tmp

终端登录也是一样:

wps1CE7.tmp

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,如下图:

image

此时它会提示你输入用户名和密码:

image

输入完用户名和密码之后,就进入了

image

在这里你就可以修改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

我把之前的注释了,重新添加的,如下:

image

重新编译配置文件:

[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 ~]# 

image

此时,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 ~]# 

密钥设置成功,重启即生效。

原文地址:https://www.cnblogs.com/doublexi/p/9636506.html