5、DNS,防火墙,mysql总结

DNS,防火墙,mysql总结

安全相关总结

总结openssh服务安全加固

#ssh服务
修改配置文件: vim /etc/ssh/sshd_config 

#修改默认端口号22
Port 2222
#禁用root登陆
PermitRootLogin no
#禁用密码登陆使用密钥登陆
PasswordAuthentication no
#禁止使用空密码连接
PermitEmptyPasswords no
#基于key验证
PubkeyAuthentication yes

#利用黑白名单来限制登陆
#用户白名单
AllowUsers user1 user2 
#用户组白名单
AllowGroups group1  group2
#用户黑名单
DenyUsers  user1 user2 
#DenyGroups用户组黑名单
DenyGroups  group1  group2
#设置ssh session超时
ClientAliveInterval 60 
ClientAliveCountMax 30

#设置防火墙
方法1:firewalld服务:永久开放2222端口,加载配置文件生效,查看添加的端口是否成功
# firewall-cmd --permanent --add-port=2222/tcp  
#firewall-cmd --reload
#firewall-cmd --list-ports
#firewall-cmd --list-all

方法2:iptables服务:
注意:在centos7系统中默认是没有安装iptables服务的,如果使用iptables,必须要先关闭firewalld服务,否则会有冲突
#默认没有安装iptables,使用命令安装
#yum -y install iptables
[root@localhost ~]# iptables -Ln 注意参数n和L有先后顺序,写反了报错
iptables: No chain/target/match by that name.
[root@localhost ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
#清除所有的iptables规则,但不会清除默认规则
iptables -F
iptables -D INPUT 1    #删除,指定是INPUT链,第一个规则
iptables -nL --line-numbers  #查看规则是第几个,删除可以用到
#指定源IP为10.255.18.15通过2222端口访问服务器,其他的拒绝所有
iptables -A INPUT -s 10.255.18.15 -p tcp -m state --state NEW -m tcp --dport 2222 -j ACCEPT

iptables -A INPUT -p tcp --dport 2222 -j REJECT --reject-with icmp-host-prohibite

或者直接禁用
iptables  -A INPUT -p tcp --dport 2222 -j DROP
iptables  -t filter -A INPUT -p tcp --dport 2222 -j DROP
或者
禁止指定ip,访问本服务器指定端口
iptables -I INPUT -s 10.255.18.14 -p tcp --dport 22222 -j DROP 
禁止指定网段访问本服务器的指定端口
iptables -I INPUT -s 10.255.0.0/24 -p tcp --dport 2222 -j DROP
禁止用户访问本服务器指定范围(使用冒号:)或者指定多个的端口(使用逗号,)
iptables -I INPUT -p tcp --dport 1024:65535 -j DROP
iptables -I INPUT -p tcp -m multiport --dport 81,444 -j DROP
使用iptables实现禁止ping功能:
#实际上icmp协议的类型有很多,影响我们ping的类型是8,只需禁止8就行
iptables -I INPUT -p icmp --icmp-type 8 -j DROP 
iptables -I INPUT -p icmp --icmp-type any -j DROP
#清除好环境
iptables -F
iptables -X
iptables -Z
iptables -nL
#默认配置
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
#保存配置
iptables-save 

#内网服务器通过iptables转发实现访问外网(共享上网)
单个ip实现源地址转换
iptables -t nat -A POSTROUTING -s 10.255.0.13 -j SNAT --to-source 10.0.0.11
echo 1 >/proc/sys/net/ipv4/ip_forward
echo 'net.ipv4.ip_forward=1' >>/etc/sysctl.conf
sysctl -p

指定网段的地址实现源地址转换
iptables -t nat -A POSTROUTING -s 10.255.0.0/24 -j SNAT --to-source 10.0.0.11

当公网ip不固定时:更换使用用如下命令
iptables -t nat -A POSTROUTING -s 10.255.0.0/24 -j MASQUERADE

#DNAT端口转发(内网服务器不暴露在公网上,但是它上面的服务可以通过某台服务器的端口转发提供给外网)
iptables -t nat -A PREROUTING -d 10.0.0.11 -p tcp --dport 9000 -j DNAT --to-destination 10.255.0.13:22

有点像Nginx的端口转发
当外网需要访问内网某个主机的某个服务时,服务无法提供。我们可以使用端口转发,ens192有外网ip,当外网访问ens192的外网时,我们可以根据端口来将请求转发给内网某个服务器如ens192,ens192上是没有外网ip的。
#开启ipv4转发
#tail -1 /etc/sysctl.conf 
net.ipv4.ip_forward=1

总结sudo配置文件格式,总结相关示例。

#定义:Sudo是Unix/Linux平台上的一个非常有用的工具,它允许系统管理员分配给普通用户一些合理的“权限”,让他们执行一些只有超级用户或其他特许用户才能完成的任务,比如:运行一些像mount,halt,su之类的命令

#sudo执行命令的流程:
当用户执行sudo时,系统会主动寻找/etc/sudoers文件,判断该用户是否有执行sudo的权限
-->确认用户具有可执行sudo的权限后,让用户输入用户自己的密码确认
-->若密码输入成功,则开始执行sudo后续的命令

#sudo设计者的宗旨是:给用户尽可能少的权限但仍允许完成他们的工作
设置下EDITOR=vim来替换默认的vi
# export EDITOR=vim
#sudo条目语法
 who host=(runas)  TAG:command
    who :运行者用户名
    host:主机
    runad:以那个身份运行
    TAG:标签
    command:命令

#实例1: oracle用户可以在任何地点以root的身份执行命令useradd(无需密码)和userdel(需要密码)
oracle ALL=(root) NOPASSWD:/usr/sbin/useradd, PASSWD:/usr/sbin/userdel
#实例2:让普通用户user1具有所有超级用户的权限而又不用输入密码
user1 ALL=(ALL)NOPASSWD:ALL
#实例3:让普通用户user2具有/etc/init.d/nginx 脚本重启的权限
user2 ALL=NOPASSWD:/etc/init.d/nginx restart

#sudo的日志审计
为了能够明确的追究责任,sudo还提供了人性化的日志功能,在/var/log/secure日志文件中可以查看到,用于记录所有sudo类用户的所有动作。

总结PAM架构及工作原理

PAM架构
在这里插入图片描述

PAM工作原理

PAM认证一般遵循这样的顺序:Service(服务)→PAM(配置文件)→pam_*.so
PAM认证首先要确定那一项服务,然后加载相应的PAM的配置文件(位于/etc/pam.d下),最后调用认证
文件(位于/lib64/security下)进行安全认证 

PAM认证过程示例:

1.使用者执行/usr/bin/passwd 程序,并输入密码
2.passwd开始调用PAM模块,PAM模块会搜寻passwd程序的PAM相关设置文件,这个设置文件一般是在/etc/pam.d/里边的与程序同名的文件,即PAM会搜寻/etc/pam.d/passwd此设置文件
3.经由/etc/pam.d/passwd设定文件的数据,取用PAM所提供的相关模块来进行验证
4.将验证结果回传给passwd这个程序,而passwd这个程序会根据PAM回传的结果决定下一个动作(重新输入
密码或者通过验证)

常用的PAM模块介绍

pam_unix.soauth提示用户输入密码,并与/etc/shadow文件相比对.匹配返回0
account检查用户的账号信息(包括是否过期等).帐号可用时,返回0.
password修改用户的密码. 将用户输入的密码,作为用户的新密码更新shadow文件
pam_shells.soauth account如果用户想登录系统,那么它的shell必须是在/etc/shells文件中之一的shell
pam_deny.soaccount auth password session该模块可用于拒绝访问
pam_permit.soauth account password session模块任何时候都返回成功.
pam_securetty.soauth如果用户要以root登录时,则登录的tty必须在/etc/securetty之中.
pam_listfile.soauth account password session访问应用程的控制开关
pam_cracklib.sopassword这个模块可以插入到一个程序的密码栈中,用于检查密码的强度.
pam_limits.sosession定义使用系统资源的上限,root用户也会受此限制,可以通过/etc/security/limits.conf或/etc/security/limits.d/*.conf来设定

总结PAM配置文件格式,总结相关示例, nologin.so, limits,等模块的使用。

pam_nologin.so 模块

功能:如果/etc/nologin文件存在,将导致非root用户不能登陆,当该用户登陆时,会显示/etc/nologin文件内容,并拒绝登陆,它一般与 auth 和 account 验证类型一同使用。

pam_limits.so模块

功能:在用户级别实现对其可使用的资源的限制,例如:可打开的文件数量,可运行的进程数量,可用内存空间

修改限制的实现方式:
(1) ulimit命令,立即生效,但无法保存

-n 每个进程最多的打开的文件描述符个数
-u 最大用户进程数
-S 使用 soft(软)资源限制
-H 使用 hard(硬)资源限制

(2) 配置文件:

/etc/security/limits.conf
/etc/security/limits.d/*.conf

配置文件格式:

#每行一个定义
## <domain>        <type>  <item>  <value>
- <domain> : 可以是用户名、采用@group 语法的组名,还可以用通配符 * 来表示任何用户, 以及使用 “%” 通配符来只限制 maxlogins ,并可以采用 %group 的语法格式。

- <type> : 
  - soft : 用来设置对系统资源的软限制,它允许用户所使用的系统资源可以在设定的硬限制值的规定范围来上下浮动
  - hard : 用来设置对系统资源的硬限制,这些硬限制由超级用户设置,并由系统内核来执行。(`普通用户对系统资源的使用率不能超过设置的硬限制设定值`)
  - "-" : 表示无限制系统资源;

- <item> <value> : 两者总是成对使用的,"Item"表示某类具体的系统资源,而"Value"就是"Item"的值;
  * as  # 地址空间限制( KB )
  * core  # 核心文件的大小  (KB)
  * data  # 最大的数据包大小 (KB)
  * fsize  # 最大的文件大小 (KB)
  * memlock  # 最大可用的内存空间 (KB)
  * rss  # 最大的可驻留空间 (KB)
  * stack  # 最大的堆栈空间 (KB)
  * cpu  # 最大的 CPU 占用时间( minutes )
  * nproc  # 所能够同时运行的进程的最大数量,默认为1024
  * maxlogins  # 用户可以登录到系统的最多次数, UID=0 的用户除外
  * priority  # 优先运行的用户进程(负值越高的进程优先)
  * sigpending  # 最大数量的等待信号( Linux2.6 及以上内核)
  * msqqueue   # POSIX 信息队列的最大可使用的内存( bytes )( Linux2.6 及以上内核)
  * nofile  # 所能够同时打开的最大文件数量,默认为1024
  * locks  # 最大可锁定文件的数目( Linux2.4 及以上内核的系统)

格式说明:

应用于哪些对象

Username 单个用户
@group 组内所有用户
* 所有用户
% 仅用于限制 maxlogins limit , 可以使用 %group 语法. 只用 % 相当于 * 对所有用户
maxsyslogins limit限制. %group 表示限制此组中的所有用户总的最大登录数

限制的类型

Soft 软限制,普通用户自己可以修改
Hard 硬限制,由root用户设定,且通过kernel强制生效
- 二者同时限定

案例1:ulimit命令修改用户打开的文件个数

临时修改
#ulimit -n 65535
#ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 7092
max locked memory       (kbytes, -l) 16384
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 7092
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
永久修改,写入配置文件
#vim /etc/security/limits.conf

* soft nofile 65535
* hard nofile 65535	

案例2:ulimit命令修改用户同时运行的进程的最大数量

vim /etc/security/limits.conf
# 添加如下的行
* soft nproc 11000
* hard nproc 11000

实现私有时间服务器

配置时间同步服务

查看系统时区
#timedatectl
修改系统时区
#timedatectl set-timezone Asia/Shanghai
更新硬件时钟(rtc)
#hwclock -w
查看时区状态
timedatectl status

配置chronyd时钟同步

#服务端编辑chrony配置文件,配置如下
vim /etc/chrony.conf
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
server 10.255.18.11 iburst

allow 10.255.18.0/24
local stratum 10
#客户端编辑chrony配置文件,配置如下
vim /etc/chrony.conf
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
server 10.255.18.11  iburst

#重新启动chronyd服务并设置开机自启动
systemctl restart chronyd.service
systemctl enable chronyd.service

#开始ntp时间同步
timedatectl set-ntp true

#执行chronyc sources命令,结果中存在以^*开头的行,则同步成功
#chronyc sources
210 Number of sources = 1
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* 127.127.1.0                  14   6   177    32   -153ns[-4191ns] +/-  153us

#查看本机时间同步状态,用于验证服务是否已启动
chronyc tracking

#查看时间同步服务器列表
chronyc -n sources -v

#进入Chrony工具,使用chrony手动同步时钟
chronyc
#在Chrony工具内,运行以下命令同步时钟
makestep

DNS相关总结

总结DNS域名三级结构

BIND:Bekerley Internet Name Domain

由于因特网的用户数量较多,所以因特网在命名时采用的是层次树状结构的命名方法。任何一个连接在因特网上的主机或路由器,都有一个唯一的层次结构的名字,即域名(domain name)。这里,“域”(domain)是名字空间中一个可被管理的划分。从语法上讲,每一个域名都是有标号(label)序列组成,而各标号之间用点(小数点)隔开。域名可以划分为各个子域,子域还可以继续划分为子域的子域,这样就形成了顶级域、主域名、子域名等。关于域名层次结构如下图:

image-20221115163521691

  • .com是顶级域名
  • aliyun.com是主域名(也可称托管一级域名),主要指企页名;
  • example.aliyun.com是子域名(也可称为托管二级域名);
  • www.example.aliyun.com是子域名的子域(也可称为托管三级域名)

总结DNS服务工作原理,涉及递归和迭代查询原理

image-20221115155435059

DNS 查询有两种方式:递归迭代

  • 一般来说,DNS 客户端设置使用的 DNS 服务器一般都是 递归服务器 ,它负责全权处理客户端的 DNS 查询请求,直到返回最终结果
  • 而 DNS 根域名服务器之间一般采用 迭代查询 方式,以免根域名服务器的压力过大

在这里插入图片描述

image-20221116135535802

实现私有DNS, 供本地网络主机作DNS递归查询。

DNS正向解析配置过程

安装服务

#(1)使用命令安装bind包
#yum -y install bind  bind-utils

(2)修改全局配置文件 
#vim /etc/named.conf

options {
        listen-on port 53 { 10.255.18.14; };#修改为自己本地的服务器IP地址
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        recursing-file  "/var/named/data/named.recursing";
        secroots-file   "/var/named/data/named.secroots";
        allow-query     { any; };#修改为any,允许查询所有
        
(3)修改区域配置文件  
#vim /etc/named.rfc1912.zones     
复制该文件模板进行修改为如下内容:
zone "fq.com" IN {
        type master;
        file "fq.com.zone";
        allow-update { none; };
};

(4)复制区域数据文件模板到配置文件目录下进行修改
[root@localhost ~]# cd /var/named/
[root@localhost named]# ls
data     fq.com.zone  named.empty      named.loopback
dynamic  named.ca     named.localhost  slaves
[root@localhost named]# cp -p  named.localhost fq.com.zone 

(5)修改区域数据文件
#vim /etc/named/fq.com.zone
修改模板文件为如下内容:
$TTL 1D
@       IN SOA  fq.com.  fq.com. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
        IN      NS      fq.com.
        IN      A       10.255.18.14
dns     IN      A       10.255.18.14
www     IN      A       10.255.18.15
ftp     IN      A       10.255.18.16
mail     IN      A       10.255.18.17


(6)确认关闭防火墙或放行服务端口,且开启服务
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# systemctl  disable firewalld
[root@localhost ~]# sestatus

[root@localhost ~]# systemctl start named
[root@localhost ~]# systemctl status named

(7)修改dns配置文件本地解析
#echo  "nameserver 10.255.18.14" > /etc/resolv.conf

(8)用host进行域名解析验证,测试正向解析是否成功
[root@localhost named]# host dns.fq.com
dns.fq.com has address 10.255.18.14
[root@localhost named]# host www.fq.com
www.fq.com has address 10.255.18.15
[root@localhost named]# host ftp.fq.com
ftp.fq.com has address 10.255.18.16
[root@localhost named]# host mail.fq.com
mail.fq.com has address 10.255.18.17

[root@localhost named]# dig -t A www.fq.com

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.10 <<>> -t A www.fq.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42207
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.fq.com.                    IN      A

;; ANSWER SECTION:
www.fq.com.             86400   IN      A       10.255.18.15

;; AUTHORITY SECTION:
fq.com.                 86400   IN      NS      fq.com.

;; ADDITIONAL SECTION:
fq.com.                 86400   IN      A       10.255.18.14

;; Query time: 0 msec
;; SERVER: 10.255.18.14#53(10.255.18.14)
;; WHEN: Sun Nov 20 20:39:24 EST 2022
;; MSG SIZE  rcvd: 85

DNS反向解析配置过程

(1)修改区域配置文件
#vim /etc/named.rfc1912.zones
复制模板修改为如下内容:
zone "18.255.10.in-addr.arpa" IN {
        type master;
        file "fq.com.local";
        allow-update { none; };
};

(2)复制区域数据文件模板 
[root@localhost ~]# cp -p /var/named/fq.com.zone /var/named/fq.com.local
[root@localhost ~]# vim /etc/named/fq.com.local
修改为如下内容:
$TTL 1D
@       IN SOA  fq.com.  fq.com. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
        IN      NS      fq.com.
        IN      A       10.255.18.14
14      IN      PTR     dns.fq.com
15      IN      PTR     www.fq.com
16      IN      PTR     ftp.fq.com
17      IN      PTR     mail.fq.com

(3)重启服务
[root@localhost ~]# systemctl restart named
[root@localhost ~]# systemctl status  named

(4)使用host命令进行反向解析测试验证是否成功
[root@localhost named]# host 10.255.18.14
14.18.255.10.in-addr.arpa domain name pointer dns.fq.com.18.255.10.in-addr.arpa.
[root@localhost named]# host 10.255.18.15
15.18.255.10.in-addr.arpa domain name pointer www.fq.com.18.255.10.in-addr.arpa.
[root@localhost named]# host 10.255.18.16
16.18.255.10.in-addr.arpa domain name pointer ftp.fq.com.18.255.10.in-addr.arpa.
[root@localhost named]# host 10.255.18.17
17.18.255.10.in-addr.arpa domain name pointer mail.fq.com.18.255.10.in-addr.arpa.

[root@localhost named]# dig -x 10.255.18.15

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.10 <<>> -x 10.255.18.15
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24380
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;15.18.255.10.in-addr.arpa.     IN      PTR

;; ANSWER SECTION:
15.18.255.10.in-addr.arpa. 86400 IN     PTR     www.fq.com.18.255.10.in-addr.arpa.

;; AUTHORITY SECTION:
18.255.10.in-addr.arpa. 86400   IN      NS      fq.com.

;; ADDITIONAL SECTION:
fq.com.                 86400   IN      A       10.255.18.14

;; Query time: 0 msec
;; SERVER: 10.255.18.14#53(10.255.18.14)
;; WHEN: Sun Nov 20 20:40:06 EST 2022
;; MSG SIZE  rcvd: 115

总结DNS服务器类型,解析答案,正反解析域,资源记录定义。

DNS服务器的类型

  • 主DNS服务器:

    • 管理和维护所负责解析的域内解析库的服务器
  • 从DNS服务器:从服务器"复制"(区域传输)解析库副本

    • 序列号:解析库版本号,主服务器解析库变化时,其序列递增

    • 刷新时间间隔:从服务器从主服务器请求同步解析的时间间隔

    • 重试时间间隔:从服务器请求同步失败时,再次尝试时间间隔

    • 过期时长:从服务器联系不到主服务器时,多久后停止服务

    • 通知机制:主服务器解析库发生变化时,会主动通知从服务器

  • 缓存DNS服务器(转发器)

区域传输:

  • 完全传输:传送整个解析库
  • 增量传输:传递解析库变化的那部分内容

解析形式:

  • 正向解析:FQDN( Fully Qualified Domain Name) --> IP
  • 反向解析: IP --> FQDN

负责本地域名的正向和反向解析库

  • 正向区域
  • 反向区域

解析答案:

  • 肯定答案:存在对应的查询结果
  • 否定答案:请求的条目不存在等原因导致无法返回结果
  • 权威答案:直接由存有此查询结果的DNS服务器(权威服务器)返回的答案
  • 非权威答案:由其它非权威服务器返回的查询答案

各种资源记录

区域解析库:由众多资源记录RR(Resource Record)组成

记录类型:A, AAAA, PTR, SOA, NS, CNAME, MX

  • SOA:Start Of Authority,起始授权记录;一个区域解析库有且仅能有一个SOA记录,必须位于解析库的第一条记录
  • A:internet Address,作用,FQDN --> IPAAAA:FQDN --> IPv6
  • PTR:PoinTeR,IP --> FQDN
  • NS:Name Server,专用于标明当前区域的DNS服务器
  • CNAME : Canonical Name,别名记录
  • MX:Mail eXchanger,邮件交换器
  • TXT:对域名进行标识和说明的一种方式,一般做验证记录时会使用此项,如:SPF(反垃圾邮件)记录,https验证等,如下示例:
_dnsauth TXT 2012011200000051qgs69bwoh4h6nht4n1h0lr038x

各资源记录的定义

name [TTL] IN rr_type value

注意:

  • TTL可从全局继承
  • 使用 “@” 符号可用于引用当前区域的域名
  • 同一个名字可以通过多条记录定义多个不同的值;此时DNS服务器会以轮询方式响应
  • 同一个值也可能有多个不同的定义名字;通过多个不同的名字指向同一个值进行定义;此仅表示通过多个不同的名字可以找到同一个主机

实现DNS主从同步

DNS服务器主从同步

#(1)准备工作:再开启一台虚拟机作为辅助服务器,并关闭防火墙,安装bind
# yum -y install bind bind-utils
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# systemctl disable  firewalld
[root@localhost ~]# sestatus
SELinux status:                 disabled

(2)修改全局配置文件
# vim /etc/named.conf
修改如下两行内容:
options {
        listen-on port 53 { 10.255.18.15; }; #修改地址为DNS从服务器IP地址
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        recursing-file  "/var/named/data/named.recursing";
        secroots-file   "/var/named/data/named.secroots";
        allow-query     { any; }; #修改为any 允许查询所有
        
# vim /etc/named.rfc1912.zones
修改文件的模板为如下内容:正向解析和反向解析
zone "fq.com" IN {
        type slave;
        file "slaves/fq.com.zone";
        masters { 10.255.18.14; };
};

zone "18.255.10.in-addr.arpa" IN {
        type slave;
        file "slaves/fq.com.local";
        masters { 10.255.18.14; };
};

(3)切换到DNS主服务器上修改区域配置文件
#vim /etc/named.rfc1912.zones
修改文件的模板为如下内容:正向解析和反向解析
zone "fq.com" IN {
        type master;
        file "fq.com.zone";
        allow-transfer { 10.255.18.15; };
};

zone "18.255.10.in-addr.arpa" IN {
        type master;
        file "fq.com.local";
        allow-transfer { 10.255.18.15; };
};

(4)重启主DNS上的服务
# systemctl restart named

(5)启动从DNS上的服务并配置解析
# echo "nameserver 10.255.18.15" > /etc/resolv.conf
# systemctl  restart named  

(6)在从DNS服务上进行验证,是否正向和反向解析成功
[root@localhost ~]# host www.fq.com
www.fq.com has address 10.255.18.14
[root@localhost ~]# host ftp.fq.com
ftp.fq.com has address 10.255.18.14
[root@localhost ~]# host 10.255.18.14
14.18.255.10.in-addr.arpa domain name pointer www.fq.com.
[root@localhost ~]# host 10.255.18.15
15.18.255.10.in-addr.arpa domain name pointer ftp.fq.com.

`此时可以看到`:从服务器拥有了与主服务器相当的解析功能

DNS完全转发

#主:vim fq.com.zone 
$TTL 1D
@       IN SOA  fq.com.  fq.com. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
                IN      NS      fq.com.
                IN      A       10.255.18.14
dns             IN      A       10.255.18.14
www             IN      A       10.255.18.14
bbs             IN      A       10.255.18.16
games           IN      A       10.255.18.17
data            IN      A       10.255.18.18
bbs.fq.com      IN      NS      www.bbs.fq.com. vim fq.com.zone 
www.bbs         IN      A       10.255.18.16
games.fq.com    IN      NS      www.games.fq.com.
www.games       IN      A       10.255.18.17
data.fq.com     IN      NS      www.data.fq.com.
www.data        IN      A       10.255.18.18


#(1)准备工作:再开启一台虚拟机作为辅助服务器,并关闭防火墙,安装bind
# yum -y install bind bind-utils
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# systemctl disable  firewalld
[root@localhost ~]# sestatus
SELinux status:                 disabled

(2)修改全局配置文件
# vim /etc/named.conf
修改如下两行内容:
options {
        listen-on port 53 { 10.255.18.16; };
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        recursing-file  "/var/named/data/named.recursing";
        secroots-file   "/var/named/data/named.secroots";
        allow-query     { any; };
       //添加实现全局转发 
        forward         only;
        forwarders      { 10.255.18.14;10.255.18.15; };
        
  (3)切换到DNS主服务器上修改区域配置文件
#vim /etc/named.rfc1912.zones      
#添加只转发到父域服务器
 zone "fq.com" IN {
        type forward;
        forward only;
        forwarders  { 10.255.18.14;10.255.18.15; };
};

(4)重新加载配置文件和重启服务
# rndc  reload
server reload successful
[root@localhost ~]# systemctl restart  named
[root@localhost ~]# systemctl status  named

(5)最后测试验证转发的DNS服务器上的解析就可以了

forward指令用于设置DNS转发的工作方式:

  • forward first设置优先使用forwarders DNS服务器做域名解析,如果查询不到再使用本地DNS服务器做域名解析。
  • forward only设置只使用forwarders DNS服务器做域名解析,如果查询不到则返回DNS客户端查询失败。
forward {only|first};    #指定为only时若解析不了,转发给指定的服务器;
              #first则表示先转发给指定的服务器,若无结果,自己找根

实现DNS子域授权

什么是子域授权?

每一个大的域里面都会有若干个小域。
比如fq.com就是一个大域,里面会有www域,即www.fq.com,会有bbs域,即bbs.fq.com和www.bbs.fq.com,会有games域games.fq.com和www.games.fq.com,会有data域,即data.fq.com和www.data.fq.com

#(1)在父域fq.com中声明子域bbs.fq .com
#在主DNS上添加正向配置文件添加如下记录:
[root@localhost named]# vim fq.com.zone 
$TTL 1D
@       IN SOA  fq.com.  root.fq.com. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
                IN      NS      www.bbs.fq.com.
                IN      NS      www.games.fq.com.
                IN      NS      www.data.fq.com.
www.bbs         IN      A       10.255.18.14
www.games       IN      A       10.255.18.15
www.data        IN      A       10.255.18.16
dns             IN      A       10.255.18.14
www             IN      A       10.255.18.15
ftp             IN      A       10.255.18.16

反向解析区域文件配置
[root@localhost named]# vim fq.com.local
$TTL 1D
@       IN SOA  fq.com.  fq.com. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
                IN      NS      www.bbs.fq.com.
                IN      NS      www.games.fq.com.
                IN      NS      www.data.fq.com.
14              IN      PTR     www.bbs.fq.com.
15              IN      PTR     www.games.fq.com.
16              IN      PTR     www.data.fq.com.
14              IN      PTR     dns.fq.com.
15              IN      PTR     www.fq.com.
16              IN      PTR     ftp.fq.com.



(2)在要授权的子域服务器上创建子域的主配置文件
#vim /etc/named.rfc1912.zones
添加如下内容:正向解析
zone "bbs.fq.com" IN {
        type master;
        file "bbs.fq.com.zone";
        allow-update { none; };
};

#vim /etc/named.rfc1912.zones
添加如下内容:反向解析
zone "18.255.10.in-addr.arpa" IN {
        type master;
        file "bbs.fq.com.local";
        allow-update { none; };
};


(3)创建子域的正向区域文件(正向解析和反向解析基本相同)
#创建正向区域文件bbs.fq.com.zone
[root@localhost ~]# cd /var/named/
[root@localhost named]# vim bbs.fq.com.zone
$TTL 1D
@       IN SOA  bbs.fq.com.  root.bbs.fq.com. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
                IN      NS      www.bbs.fq.com.
dns             IN      A       10.255.18.16
www             IN      A       10.255.18.16
ns1             IN      A       10.255.18.14
ns2             IN      A       10.255.18.15

(3)创建子域的正向区域文件(正向解析和反向解析基本相同)
#创建正向区域文件bbs.fq.com.local
[root@localhost ~]# cd /var/named/
[root@localhost named]# cp -p bbs.fq.com.zone bbs.fq.com.local
[root@localhost named]# vim bbs.fq.com.local
$TTL 1D
@       IN SOA  bbs.fq.com.  root.bbs.fq.com. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
                IN      NS      www.bbs.fq.com.
16              IN      PTR     dns.bbs.fq.com.
16              IN      PTR     www.bbs.fq.com.
14              IN      PTR     ns1.bbs.fq.com.
15              IN      PTR     ns2.bbs.fq.com.




(4)重启服务
# systemctl restart named
# systemctl status  named


(5)在子域上进行解析测试
#反向解析测试
在父域
[root@localhost named]# host 10.255.18.14
14.18.255.10.in-addr.arpa domain name pointer dns.fq.com.
14.18.255.10.in-addr.arpa domain name pointer www.bbs.fq.com.
[root@localhost named]# host 10.255.18.15
15.18.255.10.in-addr.arpa domain name pointer www.games.fq.com.
15.18.255.10.in-addr.arpa domain name pointer www.fq.com.
[root@localhost named]# host 10.255.18.16
16.18.255.10.in-addr.arpa domain name pointer ftp.fq.com.
16.18.255.10.in-addr.arpa domain name pointer www.data.fq.com.
在子域
[root@localhost named]# host 10.255.18.14
14.18.255.10.in-addr.arpa domain name pointer ns1.bbs.fq.com.
[root@localhost named]# host 10.255.18.15
15.18.255.10.in-addr.arpa domain name pointer ns2.bbs.fq.com.
# host 10.255.18.16
16.18.255.10.in-addr.arpa domain name pointer dns.bbs.fq.com.
16.18.255.10.in-addr.arpa domain name pointer www.bbs.fq.com.
#正向解析测试
[root@localhost ~]# dig -t A  www.bbs.fq.com      

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.10 <<>> -t A www.bbs.fq.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43752
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.bbs.fq.com.                        IN      A

;; ANSWER SECTION:
www.bbs.fq.com.         86400   IN      A       10.255.18.16

;; AUTHORITY SECTION:
bbs.fq.com.             86400   IN      NS      www.bbs.fq.com.

;; Query time: 0 msec
;; SERVER: 10.255.18.16#53(10.255.18.16)
;; WHEN: Mon Nov 21 22:26:56 EST 2022
;; MSG SIZE  rcvd: 73



当子域无法解析时,会转发到父域进行解析,前提是子域配置了全局转发到父域
# dig -t A www.fq.com

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.10 <<>> -t A www.fq.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62107
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.fq.com.                    IN      A

;; ANSWER SECTION:
www.fq.com.             86377   IN      A       10.255.18.15

;; Query time: 0 msec
;; SERVER: 10.255.18.16#53(10.255.18.16)
;; WHEN: Mon Nov 21 22:15:14 EST 2022
;; MSG SIZE  rcvd: 55


重新加载配置文件,不用重启服务,注意:前提是服务重启要正常
#rndc reload
清楚bind服务器上的cache缓存
#rndc flush
注意:如果重启服务失败,请检查配置文件:
#检查主配置文件语法错误:# named-checkconf 
# named-checkzone "bbs.fq.com"  /var/named/bbs.fq.com.zone 
zone bbs.fq.com/IN: loaded serial 0
OK

注意

  • 子域授权:就是从父域fq.com进行指定子域bbs.fq.com分支,进而实现分而治之的道理
  • 子域授权最好是配合全局转发功能一起实现
父域DNS IP:10.255.18.14
子域DNS IP:10.255.18.16

# 在父DNS上可以解析父A记录(DNS)
# nslookup www.fq.com 10.255.18.14
Server:         10.255.18.14
Address:        10.255.18.14#53

Name:   www.fq.com
Address: 10.255.18.15
# 在父DNS上可以解析子A记录(子域委派)
# nslookup www.bbs.fq.com  10.255.18.16
Server:         10.255.18.16
Address:        10.255.18.16#53

Name:   www.bbs.fq.com
Address: 10.255.18.16
# nslookup www.bbs.fq.com
Server:         10.255.18.14
Address:        10.255.18.14#53

Name:   www.bbs.fq.com
Address: 10.255.18.14

# 在子DNS上可以解析子A记录(DNS)
# nslookup www.bbs.fq.com 10.255.18.16
Server:         10.255.18.16
Address:        10.255.18.16#53

Name:   www.bbs.fq.com
Address: 10.255.18.16
# 在子DNS上可以解析父A记录(解析转发)# 非权威应答
# nslookup www.fq.com 10.255.18.16
Server:         10.255.18.16
Address:        10.255.18.16#53

Non-authoritative answer:
Name:   www.fq.com
Address: 10.255.18.15 

疑问总结:

子域授权设置了全局转发:

  • 当正向解析在子域解析时,如果有A记录则直接解析,否则会转发到指定的父域进行解析,测试成功;
  • 当反向解析在子域解析时,如果有A记录则直接解析,否则直接失败,不会转发到指定的父域进行解析,测试成功;

基于acl实现智能DNS

线路选择:

  • 10.255.18.0/24
  • 192.168.0.0/16
  • other
(1)首先定义访问控制
注意:访问控制列表只有定义后才能使用,通常acl要定义在named.conf的最上方
#针对不同的IP范围定义DNS视图
#vim /etc/named.conf
添加如下内容:
acl test1 { 10.255.18.0/24; }; //定义test1网段的用户
acl test2 { 192.168.0.0/16; }; //定义test2网段的用户
options {
        listen-on port 53 { 10.255.18.16; };
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        recursing-file  "/var/named/data/named.recursing";
        secroots-file   "/var/named/data/named.secroots";
        allow-query     { any; };
        forward         first;
        forwarders      { 10.255.18.14;10.255.18.15; };

view test1 {
        match-clients { test1; };//声明只允许test1用户查询
        recursion yes;//允许递归查询
        include "/etc/named.rfc1912.zones.sh1";//调用的区域文件zone
};
view test2 {
        match-clients { test2; };//声明只允许test2用户查询
        recursion yes;//允许递归查询
        include "/etc/named.rfc1912.zones.sh2";//调用的区域文件zone
};
view default {
        match-clients { any; };//默认允许其他网段的用户查询
        recursion yes;//允许递归查询
        include "/etc/named.rfc1912.zones.sh3";//调用的区域文件zone
};      

(2)配置区域文件
[root@localhost ~]# cp -p /etc/named.rfc1912.zones /etc/named.rfc1912.zones.sh1
[root@localhost ~]# cp -p /etc/named.rfc1912.zones /etc/named.rfc1912.zones.sh2
[root@localhost ~]# cp -p /etc/named.rfc1912.zones /etc/named.rfc1912.zones.sh3

#vim /etc/named.rfc1912.zones.sh1
zone "." IN {
   type hint;
   file "named.ca";
};
zone "fq.com" IN {
        type master;
        file "fq.com.zone.test1";
        allow-update { none; };
};


#vim /etc/named.rfc1912.zones.sh2
zone "." IN {
   type hint;
   file "named.ca";
};
zone "fq.com" IN {
        type master;
        file "fq.com.zone.test2";
        allow-update { none; };
};
#vim /etc/named.rfc1912.zones.sh3
zone "." IN {
   type hint;
   file "named.ca";
};
zone "fq.com" IN {
        type master;
        file "fq.com.zone.other";
        allow-update { none; };
};

(3)创建区域数据库文件
[root@localhost ~]# cd /var/named/
[root@localhost named]# vim fq.com.zone.test1
$TTL 1D
@       IN SOA  master  root.fq.com. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
                IN      NS      master
master          IN      A       10.255.18.16
web             IN      A       10.255.18.17
www				CNMAE	web

[root@localhost named]# vim fq.com.zone.test2
$TTL 1D
@       IN SOA  master  root.fq.com. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
                IN      NS      master
master          IN      A       10.255.18.16
web             IN      A       192.168.0.10
www				CNMAE	web

[root@localhost named]# vim fq.com.zone.other
$TTL 1D
@       IN SOA  master  root.fq.com. (
                                        0       ; serial
                                        1D      ; refresh
                                        1H      ; retry
                                        1W      ; expire
                                        3H )    ; minimum
                IN      NS      master
master          IN      A       10.255.18.16
web             IN      A       127.0.0.1
www				CNMAE	web

(4)重启服务
#systemctl start named
#systemctl status named

(5)测试
#分别测试三个不同网段上安装的http服务
yum install httpd                        
echo www.fq.com in Other > /var/www/html/index.html
systemctl start httpd  

#10.255.18.0/24
curl www.fq.com
www.fq.com in test1
#192.168.0.0/16
curl www.fq.com
www.fq.com in test2
#127.0.0.1
curl www.fq.com
www.fq.com in test3

防火墙总结

总结防火墙分类

按保护范围划分:

  • 主机防火墙:服务范围为当前一台主机
  • 网络防火墙:服务范围为防火墙一侧的局域网

按实现方式划分:

  • 硬件防火墙:在专用硬件级别实现部分功能的防火墙;另一个部分功能基于软件实现,如:华为,山石hillstone,天融信,启明星辰,绿盟,深信服, PaloAlto , fortinet飞塔, Cisco, Checkpoint,NetScreen(2004年被 Juniper 用40亿美元收购)等
  • 软件防火墙:运行于通用硬件平台之上的防火墙的应用软件,Windows 防火墙 ISA --> Forefront TMG

按网络协议划分:

  • 网络层防火墙:OSI模型下四层,又称为包过滤防火墙
  • 应用层防火墙/代理服务器:proxy 代理网关,OSI模型七层

总结iptable 5表5链, 基本使用,扩展模块。

iptables由五个表table和五个链chain以及一些规则组成

五个内置链chain:

INPUT,OUTPUT,FORWARD,PREROUTING,POSTROUTING

chain:

  • 内置链:每个内置链对应于一个钩子函数
  • 自定义链:用于对内置链进行扩展或补充,可实现更灵活的规则组织管理机制;只有Hook钩子调用自定义链时,才生效

五个表table:

filter、nat、mangle、raw、security
  • filter:过滤规则表,根据预定义的规则过滤符合条件的数据包,默认表
  • nat:network address translation 地址转换规则表
  • mangle:修改数据标记位规则表
  • raw:关闭启用的连接跟踪机制,加快封包穿越防火墙速度
  • security:用于强制访问控制(MAC)网络规则,由Linux安全模块(如SELinux)实现

优先级由高到低的顺序为:

security -->raw-->mangle-->nat-->filter

image-20221122161721118

总结iptables规则优化实践,规则保存和恢复。

iptables 规则组成

  • 规则rule:根据规则的匹配条件尝试匹配报文,对匹配成功的报文根据规则定义的处理动作作出处理,规则在链接上的次序即为其检查时的生效次序
  • 匹配条件:默认为与条件,同时满足
  • 基本匹配:IP,端口,TCP的Flags(SYN,ACK等)
  • 扩展匹配:通过复杂高级功能匹配
  • 处理动作:称为target,跳转目标
    • 内建处理动作:ACCEPT,DROP,REJECT,SNAT,DNAT,MASQUERADE,MARK,LOG…
    • 自定义处理动作:自定义chain,利用分类管理复杂情形

规则要添加在链上,才生效;添加在自定义链上不会自动生效

  • 白名单:只有指定的特定主机可以访问,其它全拒绝
  • 黑名单:只有指定的特定主机拒绝访问,其它全允许,默认方式

规则优化最佳实践

  1. 安全放行所有入站和出站的状态为ESTABLISHED状态连接,建议放在第一条,效率更高

  2. 谨慎放行入站的新请求

  3. 有特殊目的限制访问功能,要在放行规则之前加以拒绝

  4. 同类规则(访问同一应用,比如:http ),匹配范围小的放在前面,用于特殊处理

  5. 不同类的规则(访问不同应用,一个是http,另一个是mysql ),匹配范围大的放在前面,效率更高

  6. 应该将那些可由一条规则能够描述的多个规则合并为一条,减少规则数量,提高检查效率

  7. 设置默认策略,建议白名单(只放行特定连接)

    • iptables -P,不建议,容易出现“自杀现象”

    • 规则的最后定义规则做为默认策略,推荐使用,放在最后一条

-s 10.0.0.6 -p tcp --dport 3306 -j REJECT
-s 172.16.0.0/16 -p tcp --dport 80 -j REJECT

iptables规则保存

使用iptables命令定义的规则,手动删除之前,其生效期限为kernel存活期限

持久保存规则:

iptables-save > /PATH/TO/SOME_RULES_FILE

加载规则:重新载入预存规则文件中规则

iptables-restore < /PATH/FROM/SOME_RULES_FILE

iptables-restore选项

  • -n, --noflush:不清除原有规则
  • -t, --test:仅分析生成规则集,但不提交

开机自动重载规则

  • 用脚本保存各个iptables命令;让此脚本开机后自动运行/etc/rc.d/rc.local文件中添加脚本路径 /PATH/TO/SOME_SCRIPT_FILE
  • 用规则文件保存各个规则,开机时自动载入此规则文件中的规则,在/etc/rc.d/rc.local文件添加
  • 定义Unit File, CentOS 7,8 可以安装 iptables-services 实现iptables.service

实例:

# yum -y install iptables
# cp  /etc/sysconfig/iptables-config{,.bak}

#保存
#iptables-save > /etc/sysconfig/iptables

恢复
#iptables-restore > /etc/sysconfig/iptables

#systemctl enable iptables.service
#systemctl start iptables.service
#systemctl status iptables.service

总结NAT转换原理, DNAT/SDNAT原理,并自行设计架构实现DNAT/SNAT。

NAT的实现分为下面类型:

  • SNAT:source NAT ,支持POSTROUTING, INPUT,让本地网络中的主机通过某一特定地址访问外部网络,实现地址伪装,请求报文:修改源IP
  • DNAT:destination NAT 支持PREROUTING , OUTPUT,把本地网络中的主机上的某服务开放给外部网络访问(发布服务和端口映射),但隐藏真实IP,请求报文:修改目标IP
  • PNAT: port nat,端口和IP都进行修改

范例:

#启用路由转发
[root@firewall ~]#vim /etc/sysctl.conf 
net.ipv4.ip_forward=1
[root@firewall ~]#sysctl -p
#针对专线静态公共IP
[root@firewall ~]#iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j SNAT --tosource 192.168.0.8
#针对拨号网络和专线静态公共IP
[root@firewall ~]#iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j MASQUERADE
#
iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -j SNAT--to-source 10.0.0.8
#
iptables -t nat -A PREROUTING -s 0/0 -d 172.18.100.6 -p tcp --dport 22 -j DNAT --to-destination 10.0.1.22
iptables -t nat -A PREROUTING -s 0/0 -d 172.18.100.6 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.22:8080

实例

#内网服务器通过iptables转发实现访问外网(共享上网)
单个ip实现源地址转换
iptables -t nat -A POSTROUTING -s 10.255.18.13 -j SNAT --to-source 10.0.0.11
echo 1 >/proc/sys/net/ipv4/ip_forward
echo 'net.ipv4.ip_forward=1' >>/etc/sysctl.conf
sysctl -p

指定网段的地址实现源地址转换
iptables -t nat -A POSTROUTING -s 10.255.18.0/24 -j SNAT --to-source 10.0.0.11

当公网ip不固定时:更换使用用如下命令
iptables -t nat -A POSTROUTING -s 10.255.18.0/24 -j MASQUERADE

#DNAT端口转发(内网服务器不暴露在公网上,但是它上面的服务可以通过某台服务器的端口转发提供给外网)
iptables -t nat -A PREROUTING -d 10.0.0.11 -p tcp --dport 9000 -j DNAT --to-destination 10.255.18.13:22

有点像Nginx的端口转发
当外网需要访问内网某个主机的某个服务时,服务无法提供。我们可以使用端口转发,ens192有外网ip,当外网访问ens192的外网时,我们可以根据端口来将请求转发给内网某个服务器如ens192,ens192上是没有外网ip的。
#开启ipv4转发
#tail -1 /etc/sysctl.conf 
net.ipv4.ip_forward=1

使用REDIRECT将90端口重定向80,并可以访问到80端口的服务

REDIRECT,是NAT表的 target,通过改变目标IP和端口,将接受的包转发至同一个主机的不同端口,可

用于PREROUTING OUTPUT链

REDIRECT选项:注意无需开启ip_forward

  • –to-ports port[-port]
iptables -t nat -A PREROUTING -d 172.16.100.10 -p tcp --dport 80 -j REDIRECT --to-ports 8080

实例:

iptables -t nat -A PREROUTING -d 10.255.18.15 -p tcp --dport 90 -j REDIRECT --to-ports 80

firewalld常见区域总结。

区域说明
public(公共区域)在公共区域内使用,不能相信网络内的其他计算机不会对您的计篝机造成危害,只能接收经过选取的连接
trusted(信任区域)允许所有的传入流量。
drop(丢弃区域)任何接收的网络数据包都被丟弃,没有任何回复.仅能有发送出去的网络连接
block (限制区域)任何接收的网络连接都被IPv4的icmp-host-prohibited信息和IPv6的icmp6-adm- prohibited 信息所拒绝
external (外部区域特别是为路由器启用了伪装功能的外部网.您不能信任来自网络的其他计算,不能相信它们不会对您的计算机造成危害,只能接收经过选择的连接
work (工作区域)用于工作区.您可以基本相信网络内的其他电脑不会危害您的电脑.仅仅接收经过选择的连接
dmz(隔离区域也称为非军事区域)允许与 ssh 预定义服务匹配的传入流量,其余均拒绝。
internal (内部区域)用于内部网络.您可以基本上信任网络内的其他计算机不会威胁您的计算机仅仅接受经过选择的连接
home(家庭区域)用于家庭网络.您可以基本信任网络内的其他计算机不会危害您的计算机仅仅接收经过选择 的连接

注意:

  • 一个区域的安全程度取决于管理员在此区域中设置的规则
  • 每个区域规则是不同的,只会允许符合规则的流量传入
  • 可以根据网络规模,使用一个或多个区域,但是任何一个 活跃区域 至少需要关联 源地址或接口。
  • 默认情况下,public区域是默认区域,包含所有接口(网卡)

常用参数:

参数作用
-P设置默认策略:iptables -P INPUT (DROP|ACCEPT)
-F清空规则链
-L查看规则链
-A在规则链的末尾加入新规则
-I num在规则链的头部加入新规则
-D num删除某一条规则
-s匹配来源地址IP/MASK,加叹号"!"表示除这个IP外。
-d匹配目标地址
-i 网卡名称匹配从这块网卡流入的数据
-o 网卡名称匹配从这块网卡流出的数据
-p匹配协议,如tcp,udp,icmp
–dport num匹配目标端口号
–sport num匹配来源端口号

其他常用命令:

命令说明
systemctl start firewalld.service启动防火墙
systemctl satus firewalld.service查看防火墙状态
systemctl disable firewalld.service禁止开机启动防火墙
systemctl enable firewalld.service开机启动防火墙
systemctl stop firewalld.service关闭防火墙
systemctl is-enbale firewalld.service查看防火墙是否开机启动
systemctl list-unit-files|grep enabled查看已启动的服务列表
systemctl --failed查看启动失败的服务列表
firewall-cmd --version查看防火墙版本
firewall-cmd --state显示防火墙状态
firewall-cmd --get-service获取防火墙所支持的服务
firewall-cmd --zone=public --list-service查看防火墙public区域,允许访问的服务有那些
firewall-cmd --zone=public --list-ports查看防火墙public区域,允许访问的端口有那些
firewall-cmd --reload更新防火墙规则,使得永久生效策略不用重启当前立即生效,覆盖当前的
firewall-cmd --get-active-zones查看防火墙当前活跃的区域
firewall-cmd --get-default-zone查看防火墙当前工作的默认的区域是那个
firewall-cmd --get-zone-of-interface=eth100查看防火墙指定接口eth100所属的区域
firewall-cmd --panic -on拒绝所有包,需要远程连接服务器ssh的慎用
firewall-cmd --panic-off取消拒绝所有包
firewall-cmd --query-panic查看是否拒绝所有包
firewall-cmd --zone=public --add-service=https --permanent firewall-cmd --reload在防火墙public区域配置永久允许https请求流量,并应用不用重启当前立即生效
firewall-cmd --zone=public --remove-service=https --permanent firewall-cmd --reload在防火墙public区域配置永久拒绝https请求流量,并应用不用重启当前立即生效
firewall-cmd --zone=public --query-service=http --permanent查看防火墙public区域是否永久允许http请求流量
firewall-cmd --zone=public --add-port=80/tcp --permanent firewall-cmd --reload在防火墙public区域配置永久允许80端口tcp请求流量,并应用不用重启当前立即生效
firewall-cmd --zone=public --add-port=8080-8085/tcp --permanent firewall-cmd --reload在防火墙public区域配置永久允许8080-8085端口tcp请求流量,并应用不用重启当前立即生效
firewall-cmd --zone=public --query-port=80/tcp --permanent查看80端口是否开启
firewall-cmd --zone=public --remove-port=80/tcp --permanent firewall-cmd --reload防火墙public区域永久关闭80端口,并应用不用重启当前立即生效

通过ntftable来实现暴露本机80/443/22服务端口给指定网络访问

RHEL 8 用 ntftable 替换 iptables,

参考1

参考2

安装服务
#sudo yum install nftables

#sudo systemctl enable nftables
#sudo systemctl start nftables

ntftables从/etc/sysconfig/nftables.conf加载其配置。我们可以用以下命令显示配置文件的内容:

sudo cat /etc/sysconfig/nftables.conf

默认的nftables配置在nftables.conf 中没有活动条目,除了一些注释:

默认的 nftables 配置文件

正如评论所建议的,要更改nftables配置,我们有几个选择:

  • 直接编辑nftables.conf文件。
  • 手动编辑 /etc/nftables/main.nft配置文件,然后在nftables.conf 中取消注释相关行。
  • 使用nft命令行实用程序编辑规则,然后将当前配置转储到nftables.conf 中。

无论采用哪种方法,我们都需要通过重新启动nftables服务来重新加载更新的配置。在本节中,我们将使用nft命令行示例来更改nftables配置。高级用户通常编写NFT配置脚本,但最好先学习基本步骤。

以下命令显示当前配置中的所有规则:# sudo nft list tables

实例:

使用 nftables 的简单防火墙配置输出建议输入链 (packt_chain) 的以下设置:

  • 允许目标端口22、80 和443 上的 TCP 流量(TCP dport { 22, 80, 443 } 接受)
  • 允许ping请求(IP 协议 icmp 接受)
  • 拒绝其他一切(meta nfproto ipv4 reject)
接受 SSH、HTTP 和 HTTPS 流量分别为22,80,443
(1)首先,我们需要创建一个表和一个链。以下命令创建一个名为packt_table 的表:
sudo nft add table inet packt_table
(2)接下来,我们将在packt_table中创建一个名为packt_chain的链:
sudo nft add chain inet packt_table packt_chain { type filter hook input priority 0 \; }
(3)现在,我们可以开始向packt_chain添加规则了。允许 SSH、HTTP 和 HTTPS 访问:
sudo nft add rule inet packt_table packt_chain tcp dport {ssh, http, https} accept
(4)让我们也启用ICMP (ping):
sudo nft add rule inet packt_table packt_chain ip protocol icmp accept
(5)最后,我们将拒绝其他一切:
sudo nft add rule inet packt_table packt_chain reject with icmp type port-unreachable
#查看配置
#sudo nft list ruleset
table inet packt_table {
        chain packt_chain {
                type filter hook input priority filter; policy accept;
                ip protocol icmp accept
                tcp dport { 22, 80, 443 } accept
                meta nfproto ipv4 reject
        }
}


接下来,我们将当前配置保存到/etc/nftables/packt.nft:
#sudo nft list ruleset | sudo tee /etc/nftables/packt.nft
最后,我们将通过添加以下行将当前的nftables配置指向 /etc/sysconfig/nftables.conf 文件中的 /etc/nftables/packt.nft
#sudo vim /etc/sysconfig/nftables.conf
添加内容:
include "/etc/nftables/packt.nft"

新的nftables.conf现在包含对我们packt.nft配置的引用:

以下命令重新加载新的nftables配置:
#sudo systemctl restart nftables

数据库之mysql相关总结

总结关系型数据库相关概念,关系,行,列,主键,惟一键,域。

什么是数据?什么是信息?

数据(data):

定义:

  • 对客观事物的符号表示(文字,数字,图片…),数据是数据库的基本存储对象

信息:

信息:指的是数据经过加工处理后所获取的有用知识。

信息的三种分类(信息的三种世界):

  • 现实世界:指的是存在于人脑之外的客观世界中
  • 信息世界:指的是现实世界在人们头脑中的反应,观念世界
  • 数据世界:指的是信息世界中数据产出物,存储在计算机系统中

什么是数据库?

数据库(database或db):

定义:

  • 长期存储在计算机内,有组织,可共享的数据集合
  • 数据库就是存储数据的仓库
    • 其本质是一个文件系统,数据按照特定的格式将数据存储起来,用户可以对数据库中的数据进行增加,修改,删除及查询(CURD)操作

数据库中对于存储数据的要求:

  • 具有较小的数据冗余度(重复性),较高的数据独立性和易扩展性(可以修改的),并为各个用户所共享。

  • 数据库<-------表<--------数据

数据库系统(DBS)

  • DBS=DATA+DBMS+应用系统+数据库管理员(DBA)+用户

DBS发展经历的三个阶段:

  • 网状数据库—>数据组织方式:网状模型(图形结构)
  • 层次数据库—>数据组织方式:层次模型(树形结构)
  • 关系数据库—>数据组织方式:关系模型(表)

关系型数据库管理系统(relational database management system 简称RDBMS)

  • 是管理、操作和维护关系型数据库的一种软件程序
    • 分为本地(local)和服务器(server)数据库管理系统两种类型。
  • 指一种操作和管理数据库的大型软件
    • 用于建立、使用和维护数据库,对数据库进行统一管理和控制,以保证数据库的安全性和完整性

常见数据库管理系统

  • MYSQL:开源免费的数据库,小型的数据库.已经被Oracle收购了.MySQL6.x版本也开始收费。
  • Oracle:收费的大型数据库,Oracle公司的产品。Oracle收购SUN公司,收购MYSQL。
  • DB2:IBM公司的数据库产品,收费的。常应用在银行系统中.
  • SQLServer:MicroSoft 公司收费的中型的数据库。C#、.net等语言常使用。
  • SyBase:已经淡出历史舞台。提供了一个非常专业数据建模的工具PowerDesigner。
  • SQLite: 嵌入式的小型数据库,应用在手机端

文件系统管理的缺点

  • 编写应用程序不方便
  • 数据冗余不可避免
  • 应用程序依赖性
  • 不支持对文件的并发访问
  • 数据间联系弱
  • 难以按用户视图表示数据
  • 无安全控制功能

数据库管理系统的优点

  • 相互关联的数据的集合
  • 较少的数据冗余
  • 程序与数据相互独立
  • 保证数据的安全、可靠
  • 最大限度地保证数据的正确性
  • 数据可以并发使用并能同时保证一致性

什么是关系型数据库,如何理解关系型?

关系型数据库(relationnal database):用关系模型创建的数据库成为关系型数据库

关系模型:把世界看做是由实体和联系组成的。

数据库的第一个模型:E-R模型

模型(Model)

  • 定义:是现实世界特征的模拟和抽象表达。

数据模型:

  • 是对现实世界数据特征的抽象,描述的是数据的共性内容。

实体-联系——>E-R图

  • 实体(E):指的是客观事物在信息世界中的描述
  • 属性:描述实体的特征项
  • 联系®:指的是实体与实体之间的关联

作用:为了体现表结构(比如:表名,表中包含的列…)

  • 实体的定义:是指客观存在并相互区别的事物,实体具有的特性称为属性,实体可以通过属性来描述。

一、那么什么是E-R模型?

E-R模型即实体-联系模型,E-R模型的提出基于这样一种认识,数据库总是存储现实世界中有意义的数据,而现实世界是由一组实体和实体的联系组,E-R模型可以成功描述数据库所存储的数据。

二、为什么要设计E-R模型?

设计E-R模型能够更有效和更好的模拟现实世界。

三、E-R模型的基本要素

  • 实体 :实体是E-R模型的基本对象,是现实世界中各种事物的抽象,凡是可以相互区别,并可以被识别的事、物概念等均可认为是实体。
    • 在一个单位中,具有共性的一类实体可以划分为一个实体集,例如,学生李明,黄颖等都是实体,为了便于描述,可以定义学生这样的一个实体集,所有学生都是这个集合的成员。
  • 属性:每个实体都具有各种特征,称其为实体的属性,如学生有学号,姓名,年龄等属性。
    • 实体的属性值是数据库存储的主要数据。能唯一标识实体的属性或属性组称为实体键,如一个实体有多个键存在。则可从中选取一个作为主键。
  • 联系:实体间会存在各种关系,如人与人之间可能存在领导与雇员关系等,实体间的关系被抽象为联系。

数据库发展史上出现的数据模型:

  • 层次模型
  • 网状模型
  • 关系模型:用组成数据的表的行和列结构,即二维结构
  • 对象模型

数据库管理技术的发展

  • 萌芽阶段-----文件系统 使用磁盘文件来存储数据
  • 初级阶段-----第一代数据库 出现了网状模型、层次模型的数据库
  • 中级阶段-----第二代数据库 关系型数据库和结构化查询语言
  • 高级阶段------新一代数据库 “关系-对象”型数据库

关系的基本特征:

  • 关系必须规范化,属性不可再分。
  • 在同一个关系中,属性名不能重复。
  • 在同一个关系中,元组和属性的顺序可以是任意的。

关系的规范化形式:

  • 指的是关系模式要满足的条件被称为规范化形式,简称范式(NF)
总结mysql设计范式

一个表中引入范式的目的:

  • 消除数据存储异常,减少数据冗余,保证数据的完整性和提高数据的存储效率,一般的表都达到了3NF要求。

范式的分类:

  • 第一范式(1NF):如果关系R中所有的属性均为简单属性,属性不可再分割,则称R满足第一范式。简单来说:表中的列是不能再分割了。
  • 第二范式(2NF):如果关系R满足第一范式,非主键字段完全依赖于主键,则称关系R满足第二范式。
  • 第三范式(3NF):如果关系R满足第二范式,且非主键字段之间不能存在任何依赖关系,则称R满足第三范式。
  • 补充:
    • 一个基本的关系型数据库,只需要满足第一范式;
    • 一个完整的关系型数据库,要满足第三范式。

什么是表?

  • 关系型数据库表:

    • 是对应于一个关系模型的所有的关系的集合。
      • 它是一种以关系模式DAO为基础存储数据以及用数字方法处理数据库组织的方法,是目前最为流行的一种数据组织形式。
  • 表:是指同一类记录的集合

  • 字段:对应实体的属性,也称做数据项

  • 元组:元组是关系数据库中的基本概念,关系是一张表,表中的每行(即数据库中的每条记录)就是一个元组,在二维表里,元组也称为记录

  • 相互关系:

    • 一个数据库可以包含若干张表
    • 一张表有若干个字段
    • 每张表又有若干条记录(元组)
    • 每条记录(元组)对应每个字段都有一个值
总结关联类型,1对1,1对多,多对多关系。可以自行设计表进行解释
  • **一对一关系示例:**一个学生对应一个学生档案材料,或者每个人都有唯一的身份证编号。

  • **一对多关系示例:**一个班级拥有多个学生,一个学生只能够属于某个班级。

  • **多对多关系示例:**多对多就是双向一对多,一个学生可以选择多门课,一门课也有多名学生选择。

一对一关系:一个人有且唯一的学生号

IDNameSid
1zhangsan20220518
2lisi20221622

一对多关系:一个学生有多门课程

学生表

IDName
1zhangsan

课程表

IDCourseScoreSid
1chinese951
2math981
3english991

多对多关系:就是双向一对多(多个学生和多个课程)

  • 学生表
  • 课程表
  • 中间关系表

注意:所以对于多对多表,通过关系表就建立起了两张表的联系!多对多表时建立主外键后,要先删除约束表内容再删除主表内容

学生表

IDNameAgeSex
1zhangsan22
2lisi25
3wangwu26

课程表

IDCourse
1chinese
2math
3english

中间关系表:

IDStudentIdCourseId
132
212
323
421
531

什么是视图?

  • 视图是一张虚拟表
    • 表示一张表的部分数据或多张表的综合数据
    • 其结构和数据是建立在对表的查询基础上
    • 视图中不存放数据
    • 数据存放在视图所引用的原始表中
    • 一个原始表根据不同用户的不同需求可以创建不同的视图

视图的优点:

  • 筛选表中的行
  • 防止未经许可的用户访问敏感数据
  • 降低数据库的复杂程度
  • 将多个物理数据库抽象为一个逻辑数据库

什么是索引

索引是一种有效组合数据的方式,为快速查找到指定记录。索引技术就是为了让数据库更快的定位一条数据所采用的一种查询性能优化技术。

MySQL索引分类:

索引说明
普通索引基本索引类型,允许在定义索引的列中插入重复值和空值
唯一索引索引列数据不重复,允许有空值
主键索引主键列中的每个值都是非空、唯一的,一个主键将自动创建主键索引
复合索引将多个列组合作为索引
全文索引支持值的全文查找,允许重复值和空值
空间索引对空间数据类型的列建立的索引

什么是事务

事务指的是逻辑上的一组操作,组成这组操作的各个单元要么全都成功,要么全都失败。

MySQL事务操作

sql语句描述
start transaction;开启事务
commit;提交事务
rollback;回滚事务

事务特性:ACID

  • 原子性(Atomicity):原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
  • 一致性(Consistency):事务前后数据的完整性必须保持一致。
  • 隔离性(Isolation):事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。
  • 持久性(Durability):持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

事务的并发访问问题:如果不考虑隔离性,事务存在三种并发访问问题。

  • 脏读:一个事务读到了另一个事务未提交的数据
  • 不可重复读:一个事务读到了另一个事务已经提交(update)的数据。引发另一个事务,在事务中的多次查询结果不一致
  • 虚读 /幻读:一个事务读到了另一个事务已经提交(insert)的数据。导致另一个事务,在事务中多次查询的结果不一致

事务并发问题的解决方案:隔离级别

  1. read uncommitted:读未提交,一个事务读到另一个事务没有提交的数据。
    a)存在:3个问题(脏读、不可重复读、虚读)。
    b)解决:0个问题
  2. read committed:读已提交,一个事务读到另一个事务已经提交的数据。
    a)存在:2个问题(不可重复读、虚读)。
    b)解决:1个问题(脏读)
  3. repeatable read:可重复读,在一个事务中读到的数据始终保持一致,无论另一个事务是否提交。
    a)存在:1个问题(虚读)。
    b)解决:2个问题(脏读、不可重复读)
  4. serializable:串行化,同时只能执行一个事务,相当于事务中的单线程。
    a)存在:0个问题。
    b)解决:3个问题(脏读、不可重复读、虚读)
  • 安全和性能对比
    安全性:serializable > repeatable read > read committed > read uncommitted
    性能: serializable < repeatable read < read committed < read uncommitted
  • 常见数据库的默认隔离级别:
    MySql:repeatable read 可重复读
    Oracle:read committed 读已提交

什么是行,什么是列?什么是主键?什么是唯一键?什么是域?

基本概念:

  • 关系:指的是表(没有重复行和重复列)

  • 关系名:指的是表名

  • 表中的行:元组,记录

  • 表中的列:属性,字段

    • 表中的列名:属性名,字段名
  • 域:指的是每一列的取值范围

  • 键(Key):针对的是表中的列来进行设置的,要求该列的值至少是唯一的

    • 属性(或属性组)的值都能用来唯一标识该关系的元组,则称这些属性(或属性组)为该关系的键。
  • 主关键字(主键Primary key):<====>唯一,不重复,不为空,用于惟一确定一个记录的字段

    • 一旦发现表中的某个列的值,它是唯一,不重复,不为空,就可以把该列看成是一个主关键字(主键)
  • 外关键字(外键Foreign Key):针对两个表来说的,加强表与表之间的关联。设定两个表中共有的列,来实现两个表之间的关联

    • 某个属性(或属性组)不是这个关系的主键,而是另一个关系的主键

什么是SQL?

定义

结构化查询语言(Structured Query Language)简称SQL

  • 定义:是关系型数据库管理系统都需要遵循的规范。
    • 注意:不同的数据库生产厂商都支持SQL语句,但都有特有内容

SQL语句分类

  • 数据定义语言:简称DDL(Data Definition Language),用来定义数据库对象(结构):数据库,表,列等。关键字:create,alter,drop等
  • 数据控制语言:简称DCL(Data Control Language),用来定义数据库的访问权限和安全级别,及创建用户。
  • 数据操作语言:简称DML(Data Manipulation Language),用来对数据库中表的记录进行更新。关键字:insert,delete,update等。
  • 数据查询语言:简称DQL(Data Query Language),用来查询数据库中表的记录。关键字:select,from,where等。

SQL通用语法

  • SQL语句可以单行或多行书写,以分号结尾
  • 可使用空格和缩进来增强语句的可读性
  • MySQL数据库的SQL语句不区分大小写,关键字建议使用大写
  • 同样可以使用/**/的方式完成注释,也可以用 – 的形式完成注释

MySQL的数据类型

分类类型名称说明
整数类型tinyInt很小的整数
smallint小的整数
mediumint中等大小的整数
int(integer)普通大小的整数
小数类型float单精度浮点数
double双精度浮点数
decimal(m,d)压缩严格的定点数
日期类型yearYYYY1901~2155
timeHH:MM:SS-838:59:59~838:59:59
dateYYYY-MM-DD 1000-01-01~9999-12-3
datetimeYYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00~ 9999-12-31 23:59:59
timestampYYYY-MM-DD HH:MM:SS 19700101 00:00:01 UTC~2038-01-19 03:14:07UTC
文本、二进制类型CHAR(M)M为0~255之间的整数
VARCHAR(M)M为0~65535之间的整数
TINYBLOB允许长度0~255字节
BLOB允许长度0~65535字节
MEDIUMBLOB允许长度0~167772150字节
LONGBLOB允许长度0~4294967295字节
TINYTEXT允许长度0~255字节
TEXT允许长度0~65535字节
MEDIUMTEXT允许长度0~167772150字节
LONGTEXT允许长度0~4294967295字节
VARBINARY(M)允许长度0~M个字节的变长字节字符串
BINARY(M)允许长度0~M个字节的定长字节字符串

MySQL常用约束

目的:

  • 约束就是对表或字段的限制,用来确保数据的完整性、唯一性。

常用约束:

  • 主键约束(primary key)
    • 主键约束列不允许重复,也不允许空值,相当于非空约束+唯一约束。每个表最多只能有一个主键
-- 创建表时添加主键约束
create table person(
pid int primary key,
pname varchar(20)
);

-- 创建表时添加联合主键(多个字段组合)
create table grade(
pid int, /* 学生id */
cid int, /* 课程id */
score double,
primary key(pid, cid); /* 联合作为主键 */
)

-- 删除主键约束
alter table person drop primary key;

-- 创建表后添加主键
alter table grade add primary key(id, name);

-- 修改主键约束
alter table person modify pname varchar(20) primary key
  • 外键约束(foreign key)

    • 外键约束是保证表与表之间的参照完整性,外键是构建于主表和从表的两个字段之间的参照关系

    • 格式:alter table 从表名 add [constraint 外键名] foreign key(字段名1[,字段名N]) reference 主表名(字段1[,字段N])

-- 基本外键
-- 主表
create table worker(
wid int primary key,
name varchar(20)
);

-- 从表
create table salary(
sid int primary key,
smoney double,
foreign key(sid) references worker(wid)
);

-- 多列外键组合
-- 主表
create table student(
sid int,
sname varchar(32),
primary key(sid, sname)
);
-- 从表
create table grade(
sid int,
cid int,
score double,
foreign key(sid,cid) references student(sid,sname)
);

-- 删除外键约束
alter table student drop foreign key fk_student_score;

-- 增加外键约束
alter table grade add foreign key(sid, cid) reference student(sid, sname)
  • 唯一约束(unique)
    • 唯一约束是指定表的列或列组合不能重复,保证数据的唯一性。
    • 唯一约束不允许出现重复的值,但是可以为多个null。
    • 同一个表可以有多个唯一约束,多个列组合的约束。
    • 在创建唯一约束时,如果不给唯一约束名称,就默认和列名相同。
-- 创建表时添加唯一约束
create table uuser(
uid int not null,
uname varchar(20),
upassword varchar(20),
unique(pname,ppassword)
);

-- 创建表后添加唯一约束
alter table uuser add unique(uname,upassword)

-- 修改唯一约束
alter table uuser modify uname varchar(32) unique;

-- 删除唯一约束
alter table uuser drop index uname;
  • 非空约束(not null)
    • 非空约束用于确保当前列的值不为空值,强制列不接受null值,如果不向字段添加值,就无法插入新记录或者更新记录。
-- 创建表时添加为空约束
create table person(
pid int not null,
pname varchar(20)
);

-- 增加非空约束
alter table person modify pname varchar(20) not null;

-- 取消非空约束
alter table person modify pname varchar(20) null;
  • 自增约束(auto_increment)
    • 在每次插入新记录时,数据库自动生成字段的值。自增约束只能是整型值。
-- 创建表时添加自增约束
create table person(
pid int auto_increment,
pname varchar(32)
);

-- 取消自增约束
alter table person modify pid int;

-- 添加自增约束
alter table person modify pid int auto_crement;

-- 默认auto_incremnt的开始值是1,修改初始值
alter table person auto_increment=100
  • 默认值约束(default)
    • 添加一条记录前设置默认值,再添加时可以不用填写该值
-- 创建表时添加默认约束
create table person(
pid int primary key,
pname varchar(32) default '默认值'
);

-- 取消默认约束
alter table person alter column pname drop default; // 默认值独有方法,更快
alter table person modify pname varchar(32);

-- 添加默认约束
alter table person alter column pname set default '默认值';
alter table person modify pname varchar(32) default '默认值';

总结Mysql多种安装方式,及安全加固,并总结mysql配置文件。

mysql安装方式

  • 在线安装:
    • yum 安装
    • rpm安装
    • 二进制安装
  • 离线安装:

mysql安全加固

判断Mysql数据库版本
 nmap的指纹识别可以精确的判断数据库的版本号,通过telnet来判断是否支持远程连接(telnet 192.168.0.88 3306)。当连接成功后会显示Mysql版本号。
 然后可以利用hydra来探测是否存在弱口令:
 #hydra -L user.txt -P pass.txt -o savessh.log -f -vV -e ns 192.168.0.88 mysql
InnoDB并发调优
解决InnoDB高并发条件性能下降快,就是限制并发。SHOW INNODB STATUS输出中的SEMAPHORES部分来确认是否发生了并发问题,
并发 = CPU的数量 x 磁盘的数量 x 2
帐号安全
(1)正确设置目录权限:
设置目录权限的原则是软件和数据分开,具体如下:
(1)将 mysql 安装在单独的用户下
(2)安装时,以 root 用户进行安装,mysql 的软件默认都为 root 权限
(3)安装完毕后,将数据目录权限设置为实际运行 mysql 的用户权限,比如:Chown –R mysql:mysql /home/mysql/data

(2)禁止 Mysql 以管理员帐号权限运行
以普通帐户安全运行 mysqld,禁止以管理员帐号权限运行 MySQL 服务。在 /etc/my.cnf 配置文件中进行以下设置
[mysql.server]
user=mysql

(3)避免不同用户间共享帐号
参考以下步骤。
a、创建用户。
mysql> insert into mysql.user(Host,User,Password,ssl_cipher,x509_issuer,x509_subject) values("localhost","pppadmin",password("passwd"),'','','');

执行以上命令可以创建一个 phplamp 用户。
b、使用该用户登录 MySQL 服务。
mysql>exit; 
@>mysql -u phplamp -p 
@>输入密码 
mysql>登录成功

(4)删除无关帐号
    DROP USER 语句可用于删除一个或多个 MySQL 账户。使用 DROP USER 命令时,必须确保当前账号拥有 MySQL 数据库的全局 CREATE USER 权限或 DELETE 权限。账户名称的用户和主机部分分别与用户表记录的 User 和 Host 列值相对应。

执行DROP USER user;语句,您可以取消一个账户和其权限,并删除来自所有授权表的帐户权限记录。
口令
检查账户默认密码和弱密码。口令长度需要至少八位,并包括数字、小写字母、大写字母和特殊符号四类中的至少两种类型,且五次以内不得设置相同的口令。密码应至少每 90 天进行一次更换。
修改root用户口令,删除空口令
您可以通过执行以下命令修改密码
mysql> update user set password=password('test!p3') where user='root';
mysql> flush privileges;
授权
在数据库权限配置能力范围内,根据用户的业务需要,配置其所需的最小权限。
查看数据库授权情况。

mysql> use mysql;
mysql> select * from user;
mysql>select * from db;
mysql>select * from host;
mysql>select * from tables_priv;
mysql>select * from columns_priv;

通过 revoke 命令回收不必要的或危险的授权。
mysql> help revoke
Name: 'REVOKE'
Description:
Syntax:
REVOKE
priv_type [(column_list)]
   [, priv_type [(column_list)]] ...
 ON [object_type]
     {
         *
       | *.*
       | db_name.*
       | db_name.tbl_name
       | tbl_name
       | db_name.routine_name
     }
 FROM user [, user] ...
开启日志审计功能

数据库应配置日志功能,便于记录运行状况和操作行为。

MySQL服务有以下几种日志类型:

  • 错误日志: -log-err
  • 查询日志: -log (可选)
  • 慢查询日志: -log-slow-queries (可选)
  • 更新日志: -log-update
  • 二进制日志: -log-bin
    找到 MySQL 的安装目录,在 my.ini 配置文件中增加上述所需的日志类型参数,保存配置文件后,重启 MySQL 服务即可启用日志功能。例如,
#Enter a name for the binary log. Otherwise a default name will be used. 
#log-bin= 
#Enter a name for the query log file. Otherwise a default name will be used. 
#log= 
#Enter a name for the error log file. Otherwise a default name will be used. 
log-error= 
#Enter a name for the update log file. Otherwise a default name will be used. 
#log-update=

该参数中启用错误日志。如果您需要启用其他的日志,只需把对应参数前面的 “#” 删除即可。

日志查询操作说明
执行show variables like 'log_%';命令可查看所有的 log。
执行show variables like 'log_bin';命令可查看具体的 log。
安装最新补丁
确保系统安装了最新的安全补丁。

注意: 在保证业务及网络安全的前提下,并经过兼容性测试后,安装更新补丁
禁止不必要的远程访问
禁止网络连接,防止猜解密码攻击、溢出攻击、和嗅探攻击。

注意: 仅限于应用和数据库在同一台主机的情况。

如果数据库不需要远程访问,可以禁止远程 TCP/IP 连接,通过在 MySQL 服务器的启动参数中添加–skip-networking参数使 MySQL 服务不监听任何 TCP/IP 连接,增加安全性。

您可以使用 安全组 进行内外网访问控制,建议不要将数据库高危服务对互联网开放。
设置可信IP访问控制
通过数据库所在操作系统的防火墙限制,实现只有信任的 IP 才能通过监听器访问数据库。
 mysql> GRANT ALL PRIVILEGES ON db.*
 ·-> -> TO 用户名@'IP子网/掩码';
连接数设置
根据您的机器性能和业务需求,设置最大、最小连接数。

在 MySQL 配置文件(my.conf 或 my.ini)的 [mysqld] 配置段中添加max_connections = 1000,保存配置文件,重启 MySQL 服务后即可生效
删除匿名账户
安装完毕 mysql 后,会自动安装一个空帐号,普通用户只需要执行 mysql 命令即可
登陆 mysql,给系统造成隐患,建议删除此空帐号:
drop user ''@'localhost';
drop user ''@' localhost.localdomain’;
给root账户设置口令
Mysql 安装完毕后,root 默认口令为空,需要马上修改 root 口令:
$ mysql  –uroot
mysql> set password=password('123');
Query OK, 0 rows affected (0.00 sec)
设置安全密码并定期修改
尽量使用安全密码,建议使用 6 位以上字母、数字、下画线和一些特殊字符组合而
成的字符串
只授予账号必须的权限
只需要赋予普通用户必须的权限,比如:Grant select,insert,update,delete on tablename to ‘username’@’hostname’;
除 root 外 , 任何用户不应有l mysql 库 user 表的存取权限:
如果拥有 mysql 库中 user 表的存取权限(select 、 update 、 insert 、 delete ), 就可以轻易的增加、修改、删除其他的用户权限,造成系统的安全隐患。
不要把 FILE 、S PROCESS 或 或 SUPER 权限授予管理员以外的帐号
FILE 权限可以被滥用于将服务器主机上 MySQL能读取的任何文件读入到数据库表中 。
包括任何人可读的文件和服务器数据目录中的文件。可以使用 SELECT 访问数据库表 ,
然后将其内容传输到客户端上。不要向非管理用户授予 FILE 权限。有这权限的任何用户能在拥有 d mysqld 守护进程权
限的文件系统那里写一个文件!为了更加安全,由SELECT … INTO OUTFILE 生成的所有文件对每个人是可写的,并且你不能覆盖已经存在的文件。 file 权限也可以被用来读取任何作为运行服务器的 Unix 用户可读取或访问的文件。使用该权限,你可以将任何文件读入数据库表。这可能被滥用,例如,通过使用 LOAD DATA 装载“/etc/passwd”进一个数据库表,然后能用 SELECT 显示它。PROCESS 权限能被用来察看当前执行的查询的明文文本,包括设定或改变密码的查
询。
SUPER 权限能用来终止其它用户或更改服务器的操作方式。比如 kill 进程不要将 PROCESS 或 SUPER 权限授给非管理用户。n mysqladmin t processlist 的输出显示出当前执行的查询正文,如果另外的用户发出一个 UPDATE user SET password=PASSWORD(‘not_secure’)查询,被允许执行那个命令的任何用户可能看得到
15、 尽量避免通过 symlinks 访问表:
不要允许使用表的符号链接。(可以用–skip-symbolic-links 选项禁用)。如果你用 root 运行 mysqld则特别重要,因为任何对服务器的数据目录有写访问权限的人则能够删除系统中的任何文件!
16、 使用 merge 存储引擎潜藏的安全漏洞:
Merge 表在某些版本中可能存在以下安全漏洞:
 用户 A 赋予表 T 的权限给用户 B
 用户 B 创建一个包含 T 的 merge 表,做各种操作
 用户 A 收回对 T 的权限
 安全隐患:用户 B 通过 merge 表仍然可以访问表 A 中的数据
17、 drop table 命令并不收回以前的相关访问授权:
drop 表的时候,其他用户对此表的权限并没有被收回,这样导致重新创建同名的
 表时,以前其他用户对此表的权限会自动赋予,导致权限外流。
 因此,要在删除表时,同时取消其他用户在此表上的相应权限。
18、 如果可能,给所有用户加上访问 IP 限制:
给所有用户加上 ip 限制将拒绝所有未知的主机进行的连接,保证只有受信任的主 机才可以进行连接。
例如:Grant select on dbname.* to ‘username’@’ip’ identified by ‘passwd’;
19、MySQL日志安全分析技巧

常见的数据库攻击包括弱口令、SQL注入、提升权限、窃取备份等。对数据库日志进行分析,可以发现攻击行为,进一步还原攻击场景及追溯攻击源。

0x01 Mysql日志分析

general query log能记录成功连接和每次执行的查询,我们可以将它用作安全布防的一部分,为故障分析或黑客事件后的调查提供依据。

1、查看log配置信息

show variables like '%general%';

2、开启日志

SET GLOBAL general_log = 'On';

3、指定日志文件路径

SET GLOBAL general_log_file = '/var/lib/mysql/mysql.log';

比如,当我访问 /test.php?id=1,此时我们得到这样的日志:

190604 14:46:14       14 Connect    root@localhost on
                      14 Init DB    test
                      14 Query    SELECT * FROM admin WHERE id = 1
                      14 Quit

按列来解析一下:

第一列:Time,时间列,前面一个是日期,后面一个是小时和分钟,有一些不显示的原因是因为这些sql语句几乎是同时执行的,所以就不另外记录时间了。
第二列:Id,就是show processlist出来的第一列的线程ID,对于长连接和一些比较耗时的sql语句,你可以精确找出究竟是那一条那一个线程在运行。
第三列:Command,操作类型,比如Connect就是连接数据库,Query就是查询数据库(增删查改都显示为查询),可以特定过虑一些操作。
第四列:Argument,详细信息,例如 Connect    root@localhost on 意思就是连接数据库,如此类推,接下面的连上数据库之后,做了什么查询的操作。

mysql安全防护

数据库版本mysql 5.7

配置密码复杂度检查
1,需要安装插件validate_password
mysql>>INSTALL PLUGIN validate_password SONAME 'validate_password.so';
(2)修改配置文件
#vim /etc/my.cnf
[mysqld]
plugin-load=validate_password.so
validate_password_policy=2 
validate-password=FORCE_PLUS_PERMANENT
(3)重启mysql服务
#systemctl restart mysqld.service
配置密码定期更换
定期更换口令策略:由于定期修改密码,会涉及到应用一块更改,涉及到应用重启,不建议定期修改密码
(1)在/etc/my.cnf配置文件中增加
[mysqld]
default_password_lifetime=90  # 90天过期
(2)重启服务
#systemctl restart mysqld.service
1.禁用local-infile选项

禁用local_infile选项会降低攻击者通过SQL注入漏洞器读取敏感文件的能力

编辑Mysql配置文件/etc/my.cnf,在[mysqld](https://yundun.console.aliyun.com/?p=sasnext) 段落中配置local-infile参数为0,并重启mysql服务:
local-infile=0
2.确保配置了log-error选项

启用错误日志可以提高检测针对mysql和其他关键消息的恶意尝试的能力,例如,如果错误日志未启用,则连接错误可能会被忽略

编辑Mysql配置文件/etc/my.cnf,在[mysqld_safe](https://yundun.console.aliyun.com/?p=sasnext) 段落中配置log-error参数,<log_path>代表存放日志文件路径,如:/var/log/mysqld.log,并重启mysql服务:
log-error=<log_path>
3.禁用symbolic-links选项
编辑Mysql配置文件/etc/my.cnf,在[mysqld](https://yundun.console.aliyun.com/?p=sasnext) 段落中配置`symbolic-links=0`,5.6及以上版本应该配置为`skip_symbolic_links=yes`,并重启mysql服务。
4.为Mysql服务使用专用的最低特权帐户

使用最低权限帐户运行服务可减小MySQL天生漏洞的影响。受限帐户将无法访问与MySQL无关的资源,例如操作系统配置。

使用非root和非sudo权限用户启动Mysql服务
5.禁止使用–skip-grant-tables选项启动Mysql服务

使用此选项,会导致所有客户端都对所有数据库具有不受限制的访问权限。

编辑Mysql配置文件/etc/my.cnf,删除skip-grant-tables参数,并重启mysql服务
6.删除’test’数据库

测试数据库可供所有用户访问,并可用于消耗系统资源。删除测试数据库将减少mysql服务器的攻击面

登陆数据库执行以下SQL语句删除test数据库:

DROP DATABASE test;
flush privileges;
7.确保log-raw选项没有配置为ON

当log-raw记录启用时,有权访问日志文件的人可能会看到纯文本密码。

编辑Mysql配置文件/etc/my.cnf,删除log-raw参数,并重启mysql服务
8.确保没有用户配置了通配符主机名

避免在主机名中只使用通配符,有助于限定可以连接数据库的客户端,否则服务就开放到了公网

执行SQL更新语句,为每个用户指定允许连接的host范围。 
1. 登录数据库,执行use mysql;2. 执行语句select user,Host from user where Host='%';查看HOST为通配符的用户; 
3. 删除用户或者修改用户host字段,删除语句:DROP USER 'user_name'@'%'; 。更新语句:update user set host = <new_host> where host = '%';4. 执行SQL语句:

OPTIMIZE TABLE user;
flush privileges;
9.匿名登陆检查

检查Mysql服务是否允许匿名登陆

登陆Mysql数据库,执行以下命令删除匿名帐户:
delete from user where user='';
flush privileges;
10.数据库登陆弱密码

若系统使用弱口令,存在极大的被恶意猜解入侵风险,需立即修复

可使用 SET PASSWORD 命令把弱密码修改为强密码

1、登陆数据库 
2、查看数据库用户密码信息   
    mysql> SELECT user, host, authentication_string FROM user;   
    部分版本查询命令为: 
    mysql> SELECT user, host, password FROM user;  
3、根据查询结果及弱密码告警信息修改具体用户的密码 
    mysql> SET PASSWORD FOR '用户名'@'主机' = PASSWORD('新密码');
限制多次登录失败重试时间
如果连续5次输入密码错误,限制登录数据库30分钟 --次数和限制时间可以根据实际变更
通过MySQL插件控制:登录数据库,安装插件(CONNECTION_CONTROL和CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS)
(1)安装插件
#mysql -uroot -p
mysql>>install plugin CONNECTION_CONTROL soname 'connection_control.so';
mysql>>install plugin CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS soname 'connection_control.so';
(2)查看所有已安装的插件
mysql>>show plugins;
(3)按需修改配置文件(/etc/my.cnf)
vim /etc/my.cnf
添加如下两行配置:
connection-control-failed-connections-threshold=5   #登陆失败次数限制
connection-control-min-connection-delay=1800000    #限制重试时间,此处为毫秒,注意按需求换算
(4)重启服务
#systemctl restart mysqld.service
(5)重新登录数据库,查看配置是否生效
#mysql -uroot -p
mysql>>show variables like '%connection_control%';
(6)验证
输错5次密码后,会发现第6次登录会卡住,限制登录,时间为设定的限制时间30分钟

mysql配置文件

[mysqld]
# 设置3306端口
port=3306
# 设置mysql的安装目录   ----------是你的文件路径-------------
basedir=D:\mysql-8.0.26-winx64\mysql-8.0.26-winx64
# 设置mysql数据库的数据的存放目录  ---------是你的文件路径data文件夹自行创建
#datadir=E:\mysql\mysql\data
# 允许最大连接数
max_connections=200
# 允许连接失败的次数。
max_connect_errors=10
# 服务端使用的字符集默认为utf8mb4
character-set-server=utf8mb4
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# 默认使用“mysql_native_password”插件认证
#mysql_native_password
default_authentication_plugin=mysql_native_password
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8mb4
[client]
# 设置mysql客户端连接服务端时默认使用的端口
port=3306
default-character-set=utf8mb4

基线安全问题

从MongoDB和Elasticsearch,以及现在的MySQL, Redis, PostgreSQL,Oracle数据库勒索案例中,可以发现受害数据库都是因为基线安全问题,才被黑客劫持而勒索。

这些被勒索的自建数据库服务都开放在公网上,并且存在空密码或者弱口令,使得攻击者可以轻易暴力破解出密码,连接数据库,下载并清空数据。再加上不正确的安全组配置,甚至没有配置任何网络访问控制策略,导致问题被放大。

基线安全问题已经成了Web漏洞之外入侵服务器的主要途径,特别是无网络访问控制、默认账号和空口令、默认账号弱口令、后台暴露、后台无口令、未授权访问等情况。错误的配置可以导致相关服务暴露在公网上,成为黑客攻击的目标;加上采用空密码和弱口令,更方便了黑客以极低的攻击成本入侵这些服务。

有用户配置了通配符主机名

避免在主机名中只使用通配符,有助于限定可以连接数据库的客户端,否则服务就开放到了公网

执行SQL更新语句,为每个用户指定允许连接的host范围。 
1. 登录数据库,执行use mysql;2. 执行语句select user,Host from user where Host='%';查看HOST为通配符的用户; 
3. 删除用户或者修改用户host字段,删除语句:DROP USER 'user_name'@'%'; 。更新语句:update user set host = <new_host> where host = '%';4. 执行SQL语句:

OPTIMIZE TABLE user;
flush privileges;
9.匿名登陆检查

检查Mysql服务是否允许匿名登陆

登陆Mysql数据库,执行以下命令删除匿名帐户:
delete from user where user='';
flush privileges;
10.数据库登陆弱密码

若系统使用弱口令,存在极大的被恶意猜解入侵风险,需立即修复

可使用 SET PASSWORD 命令把弱密码修改为强密码

1、登陆数据库 
2、查看数据库用户密码信息   
    mysql> SELECT user, host, authentication_string FROM user;   
    部分版本查询命令为: 
    mysql> SELECT user, host, password FROM user;  
3、根据查询结果及弱密码告警信息修改具体用户的密码 
    mysql> SET PASSWORD FOR '用户名'@'主机' = PASSWORD('新密码');
限制多次登录失败重试时间
如果连续5次输入密码错误,限制登录数据库30分钟 --次数和限制时间可以根据实际变更
通过MySQL插件控制:登录数据库,安装插件(CONNECTION_CONTROL和CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS)
(1)安装插件
#mysql -uroot -p
mysql>>install plugin CONNECTION_CONTROL soname 'connection_control.so';
mysql>>install plugin CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS soname 'connection_control.so';
(2)查看所有已安装的插件
mysql>>show plugins;
(3)按需修改配置文件(/etc/my.cnf)
vim /etc/my.cnf
添加如下两行配置:
connection-control-failed-connections-threshold=5   #登陆失败次数限制
connection-control-min-connection-delay=1800000    #限制重试时间,此处为毫秒,注意按需求换算
(4)重启服务
#systemctl restart mysqld.service
(5)重新登录数据库,查看配置是否生效
#mysql -uroot -p
mysql>>show variables like '%connection_control%';
(6)验证
输错5次密码后,会发现第6次登录会卡住,限制登录,时间为设定的限制时间30分钟

mysql配置文件

[mysqld]
# 设置3306端口
port=3306
# 设置mysql的安装目录   ----------是你的文件路径-------------
basedir=D:\mysql-8.0.26-winx64\mysql-8.0.26-winx64
# 设置mysql数据库的数据的存放目录  ---------是你的文件路径data文件夹自行创建
#datadir=E:\mysql\mysql\data
# 允许最大连接数
max_connections=200
# 允许连接失败的次数。
max_connect_errors=10
# 服务端使用的字符集默认为utf8mb4
character-set-server=utf8mb4
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# 默认使用“mysql_native_password”插件认证
#mysql_native_password
default_authentication_plugin=mysql_native_password
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8mb4
[client]
# 设置mysql客户端连接服务端时默认使用的端口
port=3306
default-character-set=utf8mb4

基线安全问题

从MongoDB和Elasticsearch,以及现在的MySQL, Redis, PostgreSQL,Oracle数据库勒索案例中,可以发现受害数据库都是因为基线安全问题,才被黑客劫持而勒索。

这些被勒索的自建数据库服务都开放在公网上,并且存在空密码或者弱口令,使得攻击者可以轻易暴力破解出密码,连接数据库,下载并清空数据。再加上不正确的安全组配置,甚至没有配置任何网络访问控制策略,导致问题被放大。

基线安全问题已经成了Web漏洞之外入侵服务器的主要途径,特别是无网络访问控制、默认账号和空口令、默认账号弱口令、后台暴露、后台无口令、未授权访问等情况。错误的配置可以导致相关服务暴露在公网上,成为黑客攻击的目标;加上采用空密码和弱口令,更方便了黑客以极低的攻击成本入侵这些服务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_42832278

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值