---
order: 31
navTitle: 系统安全
---
# 系统安全性设置

本文从用户、网络、应用、数据库等多层面介绍让系统更安全、数据不泄漏的具体措施。

## 密码安全

密码安全的范围包括web用户密码，数据库用户密码，操作系统用户密码，其中影响安全的因素有以下三点:

1. 密码复杂度： 密码复杂度也可以说是密码强度，需要密码的组成包含大小写字母，数字，特殊字符中的最少三种，且密码长度不低于8位。
2. 密码生存期： 密码有效期限一般可设置为不超过180天或者90天，到期后有7天的宽限期更新密码，不能重复设置为上次的密码。
3. 密码锁定： 密码多次错误应该有锁定策略，比如5次错误后锁定180秒，防止暴力破解行为。

开启操作系统密码安全策略的以及修改密码操作，以Centos为例：

```sh
#修改文件/etc/login.defs来配置密码生存期
PASS_MAX_DAYS 90    #修改密码最长过期时间为90天
PASS_MIN_LEN 8      #修改密码最短长度为8位
PASS_WARN_AGE 7     #密码过期后宽限期
#修改/etc/pam.d/system-auth来配合密码复杂度，最短8位，大小写、数字、特殊字符最少一位，不能与上次密码相同
password    requisite     pam_cracklib.so try_first_pass retry=3 type= minlen=8 ucredit=-1 lcredit=-1 ocredit=-1 dcredit=-1 remember=1
#修改/etc/pam.d/sshd配置远程登录密码错误锁定
auth      required  pam_tally2.so   deny=5  lock_time=180 even_deny_root root_unlock_time=90
#修改用户密码，以test用户为例执行以下命令：
passwd test #当两次输入密码后回车，出现 "passwd: all authentication tokens updated successfully" 设置成功
```

数据库密码复杂度配置，mysql8默认已设置，这里以oracle为例：

```sh
#使用oracle本地用户登录sqlplus，执行以下命令
@?/rdbms/admin/utlpwdmg.sql
#修改数据库用户密码，以test用户为例
alter user test identified by 'Password#123';
```

## 系统防火墙

配置良好的防火墙规则，可以减少许多来自互联网、局域网的网络层扫描和攻击。在整个服务器网络环境中，各个机器应该只允许开放其必要的端口给其他服务器，比如web服务器，通常情况下只允许代理服务器访问其8080端口，允许其他web服务器访问7800集群端口。假设有以下服务器组成的环境。
| 服务器角色 | ip                        |
| ------ | :------------------------------ |
| 代理服务器  | 192.168.1.5 |
| web1  | 192.168.1.10 |
| web2  | 192.168.1.11 |
| DB  | 192.168.1.20 |\
那么可以设置的防火墙规则为：

```sh
代理服务器
#允许任意客户端访问80，443端口
iptables -I INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
```

```sh
web1，web2同理
#允许代理服务器访问8080端口，允许对方访问7800端口
iptables -I INPUT -s 192.168.1.5 -p tcp --dport 8080 -j ACCEPT
iptables -I INPUT -s 192.168.1.11 -p tcp --dport 7800 -j ACCEPT
```

```sh
DB服务器
#允许web服务器访问数据库端口，以3306为例
iptables -I INPUT -s 192.168.1.10,192.168.1.11 -p tcp --dport 3306 -j ACCEPT
```

```sh
#列出防火墙规则，确定上面的规则是否配置成功
iptables -L -n
```

## 系统权限控制

权限的分配应该遵循最小化原则，包括web权限、数据库权限以及操作系统权限，这里只对后两种进行说明:

1. 数据库权限：
   1. 在创建数据库用户时，应该只赋予其有限的操作权限，比如oracle，可以授权`grant connect，resource，create view`，mysql可授权`grant all on DBNAME.* to`，这样用户所做的操作无法对其他用户以及数据库全局造成影响
   2. 应该坚决避免在web直接使用具有dba权限的用户。
2. 操作系统权限：
   1. 各个应用程序，例如web应用，代理应用，数据库应用应该尽可能使用普通用户启动运行，防止应用在受到攻击时对操作系统造成更大范围的破坏，如果有些服务必须使用超级用户启动，那么仍需要确保它的工作进程使用普通用户运行。
   2. 列出系统中所有管理员用户名 `cat /etc/passwd | awk -F":" '{ if($3==0) print $1}'` 对于未知的以及不需要的用户及时清理。
   3. 建议使用单独的运维账号登录服务器做维护操作，且仅允许此账号切换到管理员。
      ```sh
      #新增test用户为例，作为运维账号
      useradd test
      #增加test的附加组为wheel
      usermod -G wheel test
      #修改/etc/pam.d/su取消注释以下行
      auth            required        pam_wheel.so use_uid
      #使用test用户登录操作系统后，使用su - root切换至root
      ```

## 通过代理访问Tomcat

在正式环境中，直接把web服务器暴露出去是比较危险的，客户端可以不受限制的对服务端发送任何请求，比如dos攻击，webshell攻击，SQL注入等，这些攻击请求不仅会极大增加web运行的负担，并且一旦攻击成功，甚至会使服务器崩溃，影响正常用户使用。为了尽可能减少这样的安全风险，我们可以在web服务器的前面增加一层代理服务器，代理服务器仅转发客户端请求，能够承载几万甚至几十万的并发访问，对于一些可能的或者明显攻击的请求可以先在代理服务器中选择过滤、限速、限制ip等，缓解web真实服务器的处理压力，同时也可以对一些正常的web管理页面进行限制访问，参考[负载平衡反向代理配置部分](../cluster/reverse-proxy.md)，以提升环境的安全性和可用性。

## 使用https协议

https所具有的三个特性分别为，保密性、完整性、可靠性，这些特性能够保证客户端与服务端建立链接时对方是可信的，展示和传输的数据是真实可靠的，传输过程中数据是不易被破解和修改的。如果条件允许，我们总是推荐环境中使用https协议，并且能够在 [ssl安全评估站点](https://myssl.com/) 内达到A+级别，需要注意一下几个参数。

| 参数| 值                     | 说明 |\
| ------ | :----------------- | :-------------------------- |\
| ssl\_protocols   | TLSv1.2,TLSv1.3 | 不使用不安全的TLSv1.1,SSLv3等协议 |\
| ssl\_ciphers  | EECDH+AESGCM:EDH+AESGCM | 使用强度高的加密算法，更多算法可以参考ssl安全评估站点 |\
| 增加响应头 | Strict-Transport-Security | 浏览器与该站点建立过https链接后应该总是使用https |
| 使用服务端优先的加密算法 | ssl\_prefer\_server\_ciphers on |   |
