加密和安全

加密算法

对称加密算法

加密和解密使用同一个密钥

DES、3DES、AES、Blowfish、Twofish、IDEA、RC6、CAST5

特点:

  1. 加密、解密使用同一个密钥,效率高
  2. 将原始数据分割成固定大小的块,逐个进行加密

缺点:

  1. 密钥过多
  2. 密钥分发
  3. 数据来源无法确认

非对称加密算法

公钥:public key,公开给所有人
私钥:secret key,自己留存,必须保证其私密性

公钥加密

RSA、DSA、ELGamal

特点:用公钥加密数据,只能使用与之配对的私钥解密,反之亦然

功能:

  1. 数字签名:主要在于让接收方确认发送方身份
  2. 对称密钥交换:发送方用对方的公钥加密一个对称密钥后发送给对方
  3. 数据加密:适合加密较小数据

缺点:密钥长,加密解密效率低下

单向散列

将任意数据缩小成固定大小的“指纹”

md5、sha1、sha224、sha256、sha384、sha512

特点:

  1. 任意长度输入
  2. 固定长度输出
  3. 若修改数据,指纹也会改变
  4. 无法从指纹中重新生成数据

功能:校验数据完整性

数字签名

数字签名.jpg

密钥交换

IKE( Internet Key Exchange)

DH (Deffie-Hellman):

  1. A: g,p 协商生成公开的整数g, 大素数p

    B: g,p

  2. A:生成隐私数据 :a (a<p ),计算得出 g^a%p,发送给B

    B:生成隐私数据 :b,计算得出 g^b%p,发送给A

  3. A:计算得出 [(gb%p)x] %p = g^ab%p,生成为密钥

    B:计算得出 [(ga%p)y] %p = g^ab%p,生成为密钥

校验RPM包完整性

被安装的文件:

  1. MD5单向散列
  2. rpm --verify package_name (or -V)

发行的软件包文件:

  1. GPG公钥签名
  2. rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat*
  3. rpm --checksig pakage_file_name (or -K)

gpg

对称加密:

  1. gpg -c file:对称加密file文件
  2. gpg -o file -d file.gpg:在另一台主机上解密file,-o指定输出文件,注意-o选项位置不能放在后面

公钥加密:实现hostA和hostB双向通信

  1. gpg --gen-key:在hostA主机上生成公钥/私钥对
  2. gpg --list-keys:在hostA主机上查看公钥
  3. gpg -a --export -o fanjie.pubkey:在hostA主机上导出公钥到fanjie.pubkey
  4. scp fanjie.pubkey hostB::从hostA主机上复制公钥文件到需加密的B主机上
  5. gpg --gen-key;gpg --list-keys:在需加密数据的hostB主机上生成公钥/私钥对
  6. gpg --import fanjie.pubkey;gpg --list-keys:在hostB主机上导入公钥
  7. gpg -e -r fanjie file:用从hostA主机导入的公钥,加密hostB主机的文件file,生成file.gpg
  8. scp fstab.gpg hostA::复制加密文件到hostA主机
  9. gpg -o file -d file.gpg:在hostA主机解密文件
  10. gpg --delete-keys fanjie;gpg --delete-secret-keys fanjie:删除公钥和私钥

CA和证书

PKI:Public Key Infrastructure

  1. 签证机构:CA(Certificate Authority)
  2. 注册机构:RA(Register Authority)
  3. 证书吊销列表:CRL(Certificate Revocation List )

X.509:一种非常通用的证书格式

1、X.509版本号:指出该证书使用了哪种版本的X.509标准,版本号会影响证书中的一些特定信息。目前的版本是3。

2、证书持有人的公钥:包括证书持有人的公钥、算法(指明密钥属于哪种密码系统)的标识符和其他相关的密钥参数。

3、证书的序列号:由CA给予每一个证书分配的唯一的数字型编号,当证书被取消时,实际上是将此证书序列号放入由CA签发的CRL(Certificate Revocation List证书作废表,或证书黑名单表)中。这也是序列号唯一的原因。

4、主题信息:证书持有人唯一的标识符(或称DN-distinguished name)这个名字在 Internet上应该是唯一的。DN由许多部分组成,看起来象这样:

CN=Bob Allen, OU=Total Network Security Division

O=Network Associates, Inc.

C=US

这些信息指出该科目的通用名、组织单位、组织和国家或者证书持有人的姓名、服务处所等信息。

5、证书的有效期:证书起始日期和时间以及终止日期和时间;指明证书在这两个时间内有效。

6、认证机构:证书发布者,是签发该证书的实体唯一的CA的X.509名字。使用该证书意味着信任签发证书的实体。(注意:在某些情况下,比如根或顶级CA证书,发布者自己签发证书)

7、发布者的数字签名:这是使用发布者私钥生成的签名,以确保这个证书在发放之后没有被撰改过。

8、签名算法标识符:用来指定CA签署证书时所使用的签名算法。算法标识符用来指定CA签发证书时所使用的公开密钥算法和HASH算法。

获取证书的两种方式:

  1. 使用证书授权机构:生成签名请求(csr),将csr发送给CA,从CA处接收签名
  2. 自签名的证书:自已签发自己的公钥

SSL协议

SSL:(Secure Socket Layer,安全套接字层),位于可靠的面向连接的网络层协议和应用层协议之间的一种协议层。SSL通过互相认证、使用数字签名确保完整性、使用加密确保私密性,以实现客户端和服务器之间的安全通讯。该协议由两层组成:SSL记录协议和SSL握手协议。

SSL.png
  1. Handshake协议:包括协商安全参数和密码套件、服务器身份认证(客户端身份认证可选)、密钥交换
  2. ChangeCipherSpec 协议:一条消息表明握手协议已经完成
  3. Alert 协议:对握手协议中一些异常的错误提醒,分为fatal和warning两个级别,fatal类型错误会直接中断SSL链接,而warning级别的错误SSL链接仍可继续,只是会给出错误警告
  4. Record 协议:包括对消息的分段、压缩、消息认证和完整性保护、加密等
  5. HTTPS 协议:就是“HTTP 协议”和“SSL/TLS 协议”的组合
SSL.png

SSL协议的工作流程:

服务器认证阶段:

1. 客户端向服务器发送一个开始信息“Hello”以便开始一个新的会话连接;
  2. 服务器根据客户的信息确定是否需要生成新的主密钥,如需要则服务器在响应客户的“Hello”信息时将包含生成主密钥所需的信息;
  3. 客户根据收到的服务器响应信息,产生一个主密钥,并用服务器的公开密钥加密后传给服务器;
  4. 服务器恢复该主密钥,并返回给客户一个用主密钥认证的信息,以此让客户认证服务器。

用户认证阶段:在此之前,服务器已经通过了客户认证,这一阶段主要完成对客户的认证。经认证的服务器发送一个提问给客户,客户则返回(数字)签名后的提问和其公开密钥,从而向服务器提供认证。

HTTPS协议

HTTPS结构.jpg
HTTPS工作原理.png

OpenSSL

openssl ?:查看openssl支持的工具

加密

对称加密:man enc

  1. openssl enc -e -des3 -a -salt -in testfile
    -out testfile.cipher:加密
  2. openssl enc -d -des3 -a -salt –in testfile.cipher
    -out testfile:解密

单项加密:man dgst

  1. openssl dgst -md5 [-hex默认] /PATH/SOMEFILE
  2. openssl dgst -md5 testfile
  3. md5sum /PATH/TO/SOMEFILE

生成用户密码:man sslpasswd

openssl passwd -1 -salt SALT(最多8位):-1选项表示md5加密

生成随机数:man sslrand

openssl rand -base64|-hex NUM:NUM: 表示字节数;-hex时,每个字符为十六进制,相当于4位二进制,出现的字符数为NUM*2

生成密钥对儿:man genrsa

  1. (umask 077; openssl genrsa –out test.key –des 2048):生成私钥,通过在子shell中修改umask值,来修改私钥权限,保障私钥安全
  2. openssl rsa -in test.key –out test2.key:将加密的私钥解密
  3. openssl rsa –in test.key –pubout –out test.key.pub:从私钥中提取公钥

生成随机数:

  1. /dev/random:仅从熵池返回随机数;随机数用尽,阻塞
  2. /dev/urandom:从熵池返回随机数;随机数用尽,会利用软件生成伪随机数,非阻塞
  3. cat /dev/urandom | tr -cd [[:alnum:]]| head -c8:生成8位随机字母数字

创建私有CA

配置文件:/etc/pki/tls/openssl.cnf

  1. cd /etc/pki/CA
  2. touch index.txt:生成证书索引数据库文件,用于存放颁发证书的信息
  3. echo 01 > serial:指定第一个颁发证书的序列号,注意:第一次更新serial,才需要执行
  4. (umask 066;openssl genrsa -out private/cakey.pem 2048):生成私钥
  5. openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650:生成自签名证书,-509选项专用于CA生成自签证书

证书管理

颁发证书:

  1. cd /app
  2. (umask 066;openssl genrsa -out app.key 2048):给web服务器生成私钥
  3. openssl req -new -key app.key -out app.csr:给web服务器生成证书申请文件
  4. 将证书请求文件传输给CA
  5. cd /etc/pki/CA
  6. openssl ca -in app.csr -out app.cer -days 300:签署CA
  7. 将签署好的证书传输给web服务器

查看证书中的信息:

  1. openssl x509 -in /PATH/FROM/CERT_FILE -noout -text|issuer|subject|serial|dates:查看证书文件中的信息
  2. openssl ca -status SERIAL:查看指定编号的证书状态
[root@centos7 CA]# openssl x509 -in app.cer -noout -serial
serial=01
[root@centos7 CA]# openssl ca -status 01
Using configuration from /etc/pki/tls/openssl.cnf
01=Valid (V)

吊销证书:

  1. openssl x509 -in app.cer -noout -serial -subject:在客户端获取要吊销的证书的serial和subject
  2. 在CA上,对比index.txt中对应的信息是否一致
  3. openssl ca -revoke newcerts/01.pem:吊销证书
  4. echo 01 > /etc/pki/CA/crlnumber:指定第一个吊销证书的编号,注意:第一次更新证书吊销列表前,才需要执行
  5. openssl ca -gencrl -out /etc/pki/CA/crl.pem:更新证书吊销列表
  6. openssl crl -in /etc/pki/CA/crl.pem -noout -text:查看crl文件

同步时间

centos6:

  1. ntpdate 172.18.0.1
  2. vim /etc/ntp.conf加上server 172.18.0.1 iburst
  3. chkconfig ntpd on:开机自启动
  4. service ntpd start:启动服务

centos7:

  1. ntpdate 172.18.0.1
  2. vim /etc/chrony.conf加上server 172.18.0.1 iburst
  3. systemctl start chronyd:启动服务
  4. systemctl enable chronyd:开机自启动

SSH

相关包:

openssh
openssh-clients
openssh-server

ssh客户端

配置文件:/etc/ssh/ssh_config

注意配置文件中此行:StrictHostKeyChecking no(首次登录不显示检查提示)

格式:ssh [user@]host [COMMAND]

常见选项:

  • -p port:远程服务器监听的端口
  • -b:指定连接的源IP
  • -v:调试模式
  • -C:压缩方式
  • -X:支持x11转发
  • -Y:支持信任x11转发
  • -t:强制伪tty分配,跳转连接时使用

当用户远程连接ssh服务器时,会复制ssh服务器/etc/ssh/ssh_host*key.pub(CentOS7默认是ssh_host_ecdsa_key.pub)文件中的公钥到客户机的~./ssh/know_hosts中。下次连接时,会自动匹配相应私钥,不能匹配,将拒绝连接

实际上,ssh并非直接比对host key,因为host key太长了,比对效率较低。所以ssh将host key转换成host key指纹,然后比对两边的host key指纹即可

ssh服务登录验证

基于用户和口令登录验证:

  1. 客户端发起ssh请求,服务器会把自己的公钥发送给用户
  2. 用户会根据服务器发来的公钥对密码进行加密
  3. 加密后的信息回传给服务器,服务器用自己的私钥解密,如果密码正确,则用户登录成功
SSH口令登录过程.jpg

基于密钥的认证:

  1. 首先在客户端生成一对密钥(ssh-keygen)
  2. 并将客户端的公钥ssh-copy-id 拷贝到服务端
  3. 当客户端再次发送一个连接请求,包括ip、用户名
  4. 服务端得到客户端的请求后,会到authorized_keys中查找,如果有响应的IP和用户,就会随机生成一个字符串,例如:acdf
  5. 服务端将使用客户端拷贝过来的公钥进行加密,然后发送给客户端
  6. 得到服务端发来的消息后,客户端会使用私钥进行解密,然后将解密后的字符串发送给服务端
  7. 服务端接受到客户端发来的字符串后,跟之前的字符串进行对比,如果一致,就允许免密码登录
SSH密钥登录过程.jpg

如何免密登录:可以实现一台主机控制所有主机,而且只需要给这台主机私钥加密即可,只需要记住加密私钥的密码即可

  1. ssh-keygen -t rsa:在客户端交互式环境下生成密钥对

    ssh-keygen -t rsa -P '' -f "~/.ssh/id_rsa":非交互式生成密钥对

  2. ssh-copy-id [-i [identity_file]][user@]host:把公钥文件传输至远程服务器对应用户的家目录,装用命令,也可以使用scp命令

  3. cat ~/.ssh/authorized_keys:在服务器端查看是否导入成功,成功后测试连接是否免密,如要取消免密,删除对应文件中的公钥即可

  4. ssh-keygen –p:重设私钥口令

  5. ssh-agent bash;ssh-add:开启代理托管口令,把口令添加给代理,这样实现在此shell环境实现免密登录

expect实现批量部署ssh-key,从而实现批量基于密钥的登录

[root@centos6 ~]#cat hostlist.txt 
192.168.30.7 root centos
192.168.30.17 root magedu

[root@centos6 ~]#cat pushkey.sh
#!/bin/bash
ssh-keygen -t rsa -P ''  -f ~/.ssh/id_rsa &> /dev/null && echo "Ssh key is created"
while read line;do
        ip=`echo $line|awk '{print $1}'`
        user=`echo $line|awk '{print $2}'`
        password=`echo $line|awk '{print $3}'`

        expect <<-EOF # 注意加-是为了让后面的EOF可以缩进
        set timeout 50
        spawn ssh-copy-id  -i /root/.ssh/id_rsa.pub $user@$ip
        expect {
        "yes/no" { send "yes\n";exp_continue }
        "password" { send "$password\n" }
        }
        expect eof
        EOF
        echo "$ip is finished"
done < hostlist.txt # 注意此文件最好写绝对路径

scp

scp [options][user@]host:/sourcefile /destpath,常用选项:

  • -C:压缩数据流
  • -r:递归复制
  • -p:保持原文件的属性信息
  • -q:静默模式
  • -P PORT:指明remote host的监听的端口

scp由于基于ssh,所以其端口也是使用ssh的端口。其实,scp拷贝的实质是使用ssh连接到远程,并使用该连接来传输数据。下文有scp执行过程的分析。

另外,scp还非常不占资源,不会提高多少系统负荷,在这一点上,rsync远不及它。虽然 rsync比scp会快一点,但rsync是增量拷贝,要判断每个文件是否修改过,在小文件众多的情况下,判断次数非常多,导致rsync效率较差,而scp基本不影响系统正常使用。

scp每次都是全量拷贝,在某些情况下,肯定是不及rsync的。

rsync

rsync的最终目的或者说其原始目的是实现两端主机的文件同步 ,默认情况下,rsync使用"quick check"算法快速检查源文件和目标文件的大小、mtime(修改时间)是否一致,如果不一致则需要传输 ,常用选项:

  • -n:模拟复制过程
  • -v:显示详细过程
  • -r:递归复制目录树
  • -p:保留权限
  • -t:保持mtime属性。强烈建议任何时候都加上"-t",否则目标文件mtime会设置为系统时间,导致下次更新 :检查出mtime不同从而导致增量传输无效
  • -g:保留组信息
  • -o:保留所有者信息
  • -l:将软连接文件本身进行复制(默认)
  • -L:将软连接文件指向的文件复制
  • -a:相当于–rlptgoD,但不保留ACL(-A)和SELinux属性(-X)
  • --exclude:指定排除规则来排除不需要传输的文件
  • --delete:以SRC为主,对DEST进行同步。多则删之,少则补之。注意"--delete"是在接收端执行的,所以它是在exclude/include规则生效之后才执行的

如果仅有一个SRC或DEST参数,则将以类似于"ls -l"的方式列出源文件列表(只有一个路径参数,总会认为是源文件),而不是复制文件

[root@xuexi ~]# rsync /etc/fstab /tmp                # 在本地同步
[root@xuexi ~]# rsync -r /etc 172.16.10.5:/tmp       # 将本地/etc目录拷贝到远程主机的/tmp下,以保证远程/tmp目录和本地/etc保持同步
[root@xuexi ~]# rsync -r 172.16.10.5:/etc /tmp       # 将远程主机的/etc目录拷贝到本地/tmp下,以保证本地/tmp目录和远程/etc保持同步
[root@xuexi ~]# rsync /etc/                          # 列出本地/etc/目录下的文件列表
[root@xuexi ~]# rsync 172.16.10.5:/tmp/              # 列出远程主机上/tmp/目录下的文件列表

另外,使用rsync一定要注意的一点是,源路径如果是一个目录的话,带上尾随斜线和不带尾随斜线是不一样的,不带尾随斜线表示的是整个目录包括目录本身,带上尾随斜线表示的是目录中的文件,不包括目录本身

[root@xuexi ~]# rsync -a /etc /tmp # 在/tmp目录下创建etc目录,并把/etc/zhong所有文件放在etc目录下
[root@xuexi ~]# rsync -a /etc/ /tmp # 不会在/tmp目录下创建etc目录,源路径/etc/中的所有文件都直接放在/tmp目录下

sftp

交互式文件传输工具,利用ssh服务实现安全的文件上传和下载,和ftp工具类似,不同的是sftp连接客户端必须验证密码,不可以像ftp访客登录,直接下载文件

pssh

pssh是一个python编写可以在多台服务器上批量执行命令的工具,也可实现文件复制,最好基于密钥认证,常用选项:

  • --version:查看版本
  • -h:主机文件列表,内容格式”[user@]host[:port]”
  • -H:主机字符串,内容格式”[user@]host[:port]”、
  • -A:手动输入密码模式
  • -i:每个服务器内部处理信息输出
  • -l:登录使用的用户名
  • -p:并发的线程数【可选】
  • -o:输出的文件目录【可选】
  • -e:错误输入文件【可选】
  • -t:TIMEOUT 超时时间设置,0无限制【可选】
  • -O:SSH的选项
  • -P:打印出服务器返回信息
  • -v:详细模式
[root@centos6 cd]# pssh -H 192.168.39.136 -H 192.168.39.137 -o /app/ -i hostname # -o选项指定输出文件目录,每个目标处理结果都分别存放在指定文件,便于分析
[1] 20:39:28 [SUCCESS] 192.168.39.136
centos6.magedu.com
[2] 20:39:29 [SUCCESS] 192.168.39.137
centos6.magedu.com
[root@centos6 cd]# cd /app
[root@centos6 app]# ls
192.168.39.136  192.168.39.137  hostlist.txt  -i  nihao  nishuo  pushkey.sh
[root@centos6 app]# cat 192.168.39.136
centos6.magedu.com

[root@centos6 app]# pssh -H 192.168.39.134 -o /app/ -i "echo $HOSTNAME"
[1] 20:50:18 [SUCCESS] 192.168.39.134
centos6.magedu.com
[root@centos6 app]# pssh -H 192.168.39.134 -o /app/ -i 'echo $HOSTNAME'
[1] 20:50:43 [SUCCESS] 192.168.39.134
centos7.magedu.com # pssh中变量引用必须用单引号,双引号的话会默认引用当前主机的变量

批量关闭selinux:

pssh -H root@192.168.1.10 -i "sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config"

pscp.pssh

pscp.pssh功能是将本地文件批量复制到远程主机,常用选项:

  • -v:显示复制过程
  • -r:递归复制目录

将本地curl.sh 复制到/app/目录:

pscp.pssh -H 192.168.1.10 /root/test/curl.sh /app/
pscp.pssh -h host.txt /root/test/curl.sh /app/

将本地多个文件批量复制到/app/目录:pscp.pssh -H 192.168.1.10 /root/f1.sh /root/f2.sh /app/

将本地目录批量复制到/app/目录:pscp.pssh -H 192.168.1.10 -r /root/test/ /app/

pslurp.pssh

pslurp.pssh功能是将远程主机的文件批量复制到本地,常用选项:

  • -L:指定从远程主机下载到本机的存储的目录
  • -r:递归复制目录

批量下载目标服务器的passwd文件至/app下,并更名为user

[root@centos6 app]# pslurp -H 192.168.39.136 -H 192.168.39.137 -L /app/ /etc/passwd user
[1] 09:21:37 [SUCCESS] 192.168.39.136
[2] 09:21:56 [SUCCESS] 192.168.39.137
[root@centos6 app]# ls # 复制过来的文件会保存在各自ip为名的目录下,便于查看
192.168.39.136  192.168.39.137  -i
[root@centos6 app]# cd 192.168.39.136
[root@centos6 192.168.39.136]# ls
user

ssh端口转发

SSH 会自动加密和解密所有 SSH 客户端与服务端之间的网络数据。但是,SSH 还能够将其他 TCP 端口的网络数据通过 SSH 链接来转发,并且自动提供了相应的加密及解密服务。这一过程也被叫做“隧道”(tunneling),这是因为 SSH 为其他 TCP 链接提供了一个安全的通道来进行传输而得名。例如,Telnet,SMTP,LDAP 这些 TCP 应用均能够从中得益,避免了用户名,密码以及隐私信息的明文传输。而与此同时,如果工作环境中的防火墙限制了一些网络端口的使用,但是允许 SSH 的连接,也能够通过将 TCP 端口转发来使用 SSH 进行通讯

SSH 端口转发能够提供两大功能:

  1. 加密 SSH Client 端至 SSH Server 端之间的通讯数据
  2. 突破防火墙的限制完成一些之前无法建立的 TCP 连接

本地转发

适合本人出差在外地,需要连接内网

ssh -L localport:remotehost:remotehostport sshserver

选项:

  • -f:后台启用
  • -N:不打开远程shell,处于等待状态
  • -g:启用网关功能

示例:

  1. ssh –L 9527:telnetsrv:23 -N sshsrv
  2. telnet 127.0.0.1 9527

当访问本机的9527的端口时,被加密后转发到sshsrv的ssh服务,再解密被转发到telnetsrv:23

data ⇔ localhost:9527 ⇔ localhost:XXXXX ⇔ sshsrv:22 ⇔ sshsrv:YYYYY ⇔ telnetsrv:23

远程转发

适合其他人出差在外地,需要连接内网

ssh -R sshserverport:remotehost:remotehostport sshserver

示例:ssh –R 9527:telnetsrv:23 –N sshsrv

让sshsrv侦听9527端口的访问,如有访问,就加密后通过ssh服务转发请求到本机ssh客户端,再由本机解密后转发到telnetsrv:23

Data ⇔ sshsrv:9527 ⇔ sshsrv:22 ⇔ localhost:XXXXX ⇔ localhost:YYYYY ⇔ telnetsrv:23

动态转发

适合翻墙

ssh -D 1080 root@sshserver:在本机操作

在本机firefox设置代理socket proxy:127.0.0.1:1080

curl --socks5 127.0.0.1:1080 http://www.qq.com

x协议转发

ssh -X user@remotehost gedit

remotehost主机上的gedit工具,将会显示在本机的X服务器上,用的显卡时本机的显卡,传输的数据将通过ssh连接加密

ssh服务器

服务器端:sshd

配置文件:/etc/ssh/sshd_config

日志文件:/var/log/secure

常用参数:

Port:端口号
ListenAddress ip:绑定端口ip,限制只能通过指定ip和端口访问
LoginGraceTime 2m:登录时宽限期
PermitRootLogin yes:限制root直接登录,如被限制,可以使用普通账户登录,再su - root
StrictModes yes:检查.ssh/文件的所有者,权限等
MaxAuthTries 6:最大验证次数,输错密码的次数
MaxSessions 10:同一个连接最大会话
PubkeyAuthentication yes:公钥验证
PermitEmptyPasswords no:
PasswordAuthentication yes:密码验证
GatewayPorts no:
ClientAliveInterval:非活动时间单位:秒
ClientAliveCountMax:非活动时间的次数,,超时断开,默认3
UseDNS yes:提高速度可改为no
GSSAPIAuthentication yes:提高速度可改为no
MaxStartups:未认证连接最大值,默认值10
Banner /path/file:欢迎词,为了安全不要设置

AllowUsers user1 user2 user3:用户白名单
DenyUsers:用户黑名单
AllowGroups:组白名单
DenyGroups:组黑名单

ssh推荐设置

  1. 建议使用非默认端口
  2. 禁止使用protocol version 1
  3. 限制可登录用户
  4. 设定空闲会话超时时长
  5. 利用防火墙设置ssh访问策略
  6. 仅监听特定的IP地址
  7. 基于口令认证时,使用强密码策略:tr -dc A-Za-z0-9_ < /dev/urandom | head -c 30| xargs
  8. 使用基于密钥的认证
  9. 禁止使用空密码
  10. 禁止root用户直接登录
  11. 限制ssh的访问频度和并发在线数
  12. 经常分析日志/var/log/secure

dropbear

Dropbear是一个相对较小的SSH服务器和客户端

源码编译安装:

  1. 安装开发包组:yum groupinstall “Development tools”
  2. 下载dropbear-2017.75.tar.bz2
  3. tar xvf dropbear-2017.75.tar.bz2
  4. less INSTALL README
  5. cd到解压好的目录里面
  6. ./configure
  7. make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
  8. make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install

启动ssh服务:

  1. ls /usr/local/sbin/ /usr/local/bin/

  2. /usr/local/sbin/dropbear -h

  3. mkdir /etc/dropbear

  4. dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key -s 2048

  5. dropbearkey -t dss -f /etc/dropbear/dropbear_dsa_host_key

  6. dropbear -p :2222 -F –E #前台运行

    dropbear -p :2222 #后台运行

客户端访问:

  1. ssh -p 2222 root@127.0.0.1
  2. dbclient -p 2222 root@127.0.0.1

AIDE

AIDE(Advanced Intrusion Detection Environment),是一个入侵检测工具,主要用途是检查文件的完整性,审计计算机上的那些文件被更改过了。

AIDE能够构造一个指定文件的数据库,它使用aide.conf作为其配置文件。AIDE数据库能够保存文件的各种属性,包括:权限(permission)、索引节点序号(inode number)、所属用户(user)、所属用户组(group)、文件大小、最后修改时间(mtime)、创建时间(ctime)、最后访问时间(atime)、增加的大小以及连接数。AIDE还能够使用下列算法:sha1、md5、rmd160、tiger,以密文形式建立每个文件的校验码或散列号。

这个数据库不应该保存那些经常变动的文件信息,例如:日志文件、邮件、/proc文件系统、用户起始目录以及临时目录

配置文件:/etc/aide.conf

!/etc/mtab:表示忽略这个文件的检查
R=p+i+n+u+g+s+m+c+md5 权限+索引节点+链接数+用户+组+大小+最后一次修改时间+创建时间+md5校验值
NORMAL = R+rmd60+sha256:组合策略

初始化默认的AIDE的库:/usr/local/bin/aide --init

生成检查数据库(建议初始数据库存放到安全的地方):cd /var/lib/aide;mv aide.db.new.gz aide.db.gz

检测:/usr/local/bin/aide --check

更新数据库:aide --update

sudo

sudo能够授权指定用户在指定主机上运行某些命令。如果未授权用户尝试使用 sudo,会提示联系管理员

sudo可以提供日志,记录每个用户使用sudo操作

sudo为系统管理员提供配置文件,允许系统管理员集中地管理用户的使用权限和使用的主机

sudo使用时间戳文件来完成类似“检票”的系统,默认存活期为5分钟的“入场券”

通过visudo命令编辑配置文件,具有语法检查功能

visudo –c:检查语法
visudo -f /etc/sudoers.d/test:编辑指定文件

配置文件(支持glob通配符):/etc/sudoers, /etc/sudoers.d/(针对每个用户单独授权,便于管理)

时间戳文件:/var/db/sudo

日志文件:/var/log/secure

授权规则格式:用户 登入主机=(代表用户) 命令

root ALL=(ALL) ALL

user: 运行命令者的身份
host: 通过哪些主机
(runas):以哪个用户的身份
command: 运行哪些命令

Users和runas:
    username
    #uid
    %group_name
    %#gid
    user_alias|runas_alias
host:
    ip或hostname
    network(/netmask)
    host_alias
command:
    command name
    directory
    sudoedit
    Cmnd_Alias

别名

别名有四种类型:User_Alias, Runas_Alias, Host_Alias ,Cmnd_Alias

别名格式:[A-Z]([A-Z][0-9]_)*

别名定义:Alias_Type NAME1 = item1, item2, item3 : NAME2 = item4, item5

示例:

  1. Student ALL=(ALL) ALL

    %wheel ALL=(ALL) ALL

  2. student ALL=(root) /sbin/pidof,/sbin/ifconfig
    %wheel ALL=(ALL) NOPASSWD: ALL

  3. User_Alias NETADMIN= netuser1,netuser2
    Cmnd_Alias NETCMD = /usr/sbin/ip
    NETADMIN ALL=(root) NETCMD

  4. User_Alias SYSADER=wang,mage,%admins
    User_Alias DISKADER=tom
    Host_Alias SERS=www.magedu.com,172.16.0.0/24
    Runas_Alias OP=root
    Cmnd_Alias SYDCMD=/bin/chown,/bin/chmod
    Cmnd_Alias DSKCMD=/sbin/parted,/sbin/fdisk
    SYSADER SERS= SYDCMD,DSKCMD
    DISKADER ALL=(OP) DSKCMD

  5. User_Alias ADMINUSER = adminuser1,adminuser2
    Cmnd_Alias ADMINCMD = /usr/sbin/useradd,/usr/sbin/usermod, /usr/bin/passwd [a-zA-Z]*, !/usr/bin/passwd root
    ADMINUSER ALL=(root) NOPASSWD:ADMINCMD,PASSWD:/usr/sbin/userdel

  6. Defaults:wang runas_default=tom
    wang ALL=(tom,jerry) ALL

  7. wang 192.168.1.6,192.168.1.8=(root) /usr/sbin/,!/usr/sbin/useradd

  8. wang ALL=(ALL) /bin/cat /var/log/messages*

    存在安全隐患,这样设置的话,可以使用cat /var/log/messages /etc/shadow来访问密码文件

命令

sudo [-u user] COMMAND,常用选项:

  • -V:显示版本信息等配置信息
  • -u user:指定runas,默认是root
  • -l:列出用户在主机上可用的和被禁止的命令
  • -ll:详细列出用户在主机上可用的和被禁止的命令
  • -v:再延长密码有效期限5分钟,更新时间戳
  • -k:清除时间戳(1970-01-01),下次需要重新输密码
  • -K:与-k类似,还要删除时间戳文件
  • -b:在后台执行指令
  • -p:改变询问密码的提示符号

TCP_Wrappers

TCP_Wrappers是一个工作在第四层(传输层)的的安全工具,对有状态连接的特定服务进行安全检测并实现访问控制,凡是包含有libwrap.so库文件的的程序就可以受TCP_Wrappers的安全控制。它的主要功能就是控制谁可以访问,常见的程序有rpcbind、vsftpd、sshd,telnet。

工作原理

TCP_Wrappers有一个TCP的守护进程叫作tcpd。以ssh为例,每当有ssh的连接请求时,tcpd即会截获请求,先读取系统管理员所设置的访问控制文件,符合要求,则会把这次连接原封不动的转给真正的ssh进程,由ssh完成后续工作;如果这次连接发起的ip不符合访问控制文件中的设置,则会中断连接请求,拒绝提供ssh服务。

工作原理.png

使用

TCP_Wrappers的使用主要是依靠两个配置文件/etc/hosts.allow, /etc/hosts.deny,用于拒绝和接受具有TCP_Wrappers控制全的程序,详细信息具体可以查看man帮助,这里我们就做简单的演示和使用(man 5 hosts_access, man 5 hosts_options)

要说明的是当我们启动一个受控制的软件的时候,比如ssh

不过在刚开始的时候,/etc/hosts.allow,/etc/hosts.deny什么都没有添加,此时没有限制,是都可以连接的,现在我们来说如何设置,禁止和允许连接,配置文件格式遵循如下规则:

daemon_list@host: client_list [:options :option…]

daemon_list: 是程序的列表,可以是多个,是多个时,使用,隔开 
@host:可以没有,是我们的限制的网卡访问接口(自己的),设置允许或禁止他人从自己的那个网口进入。这一项不写,就代表全部
client_list:是访问者的地址,如果需要控制的用户较多,可以使用空格或,隔开,格式如下:
    基于IP地址: 192.168.10.1 192.168.1.
    基于主机名: www.magedu.com .magedu.com 较少用
    基于网络/掩码: 192.168.0.0/255.255.255.0
    基于net/prefixlen: 192.168.1.0/24(CentOS7)
    基于网络组(NIS 域): @mynetwork
    内置ACL: ALL, LOCAL, KNOWN, UNKNOWN,PARANOID 
        ALL:所有主机 
        LOCAL:本地主机 
        KNOWN:主机名可解析成ip的 
        UNKNOWN:主机名无法解析成IP的 
        PARANOID:正向解析与反向解析不对应的主机

示例:

准备三个主机:

centOS 7:192.168.111.120
centOS 6:192.168.111.110
centOS 5:192.168.111.130

  1. 现在,我的centOS 6想拒绝centOS 7 的ssh访问: 我在hosts.deny中写:

    sshd@192.168.111.110:192.168.111.120
    

    然后我使用centOS 7 连接,就无法连接:

    [root@CT73 ~]$ssh 192.168.111.110
    ssh_exchange_identification: read:Connection reset by peer
    
  2. 或者我们还可以这样写(hosts.deny):

    in.telnetd,sshd: ALL
    

    这就意味着我们使用ssh,或者telnetd访问这个机器都是无法访问的,然后,我们就在hosts.allow中添加如下一行:

    sshd:192.168.111.120
    

    出现了下面的效果:

    [root@CT73 ~]$ssh 192.168.111.110
    root@192.168.111.110's password:
    Last login: Thu Sep 28 14:51:57 2017 from 192.168.111.120
    

    我们就可以连接了,我们想要访问其他主机的资源,在连接过程中,对方的机器会按照顺序先检查/etc/hosts.allow,再检查/etc/hosts.deny。如果在allow中允许连接,就可以连接的上,即便是又在deny中添加了限制也没效果,但是在allow中没有添加你的机器,但是在deny中设置了你的主机无法连接,那你是无法连接上对方的主机的。

  3. 我们还可以禁止后允许某个网段进行连接,以禁止为例:

    in.telnetd,sshd@192.168.111.110:192.168.37.
    

    这样的话192.168.37.网段的所有机器都无法通过这连个程序访问到我的机器。

  4. 现在,我们使用一个关联词,EXCEPT,host.deny文件配置如下:

    in.telnetd,sshd: ALL
    

    hosts.allow文件配置如下:

    sshd:192.168.111. EXCEPT 192.168.111.120
    

    此时,centOS 7 能否访问centOS 6呢:

    [root@CT73 ~]$ssh 192.168.111.110
    ssh_exchange_identification: read:Connection reset by peer
    

    实验证明,我们是无法连接的,这是由于,虽然我们在hosts.allow文件中设置了整个192.168.111.这个网段都可以访问,但是使用EXCEPT关键字将192.168.111.120排除, 所以我们还是不能连接。 然后,我们重写一下hosts.allow文件:

    sshd:192.168.111. EXCEPT 192.168.111.
    

    然后,我们使用centOS 5和centOS 7连接:

    [root@CT511 ~]#ssh 192.168.111.110
    ssh_exchange_identification:Connection closed by remote host
    
    [root@CT73 ~]#ssh 192.168.111.110
    ssh_exchange_identification:Connection closed by remote host
    

选项

上面还有 [ :options :option… ]选项,我们我们看看他们是咋用的 (更多使用方法查看 man 5 hosts_options)

deny 主要用在/etc/hosts.allow定义“拒绝”规则
allow 主要用在/etc/hosts.deny定义“允许” 规则
spawn 启动一个外部程序完成执行的操作
twist 实际动作是拒绝访问,使用指定的操作替换当前服务,标准I/O和ERROR发送到客户端,默认至/dev/null

示例:

  1. 在hosts.allow拒绝连接:

    sshd:192.168.111.120:deny
    

    这样,虽然我们虽然在allow文件中添加可用规则,但是我们使用了:deny,生生的还是将该地址给拒绝了:

    [root@CT73 ~]$ssh 192.168.111.110
    ssh_exchange_identification: read:Connection reset by peer
    
  2. 在hosts.deny拒绝连接:

    sshd:192.168.111.120:allow
    

    这样,虽然我们虽然在deny文件中添加不可用规则,但是我们使用了:allow,依旧允许该IP连接:

    [root@CT73 ~]$ssh 192.168.111.110
    root@192.168.111.110's password:
    Last login: Thu Sep 28 15:44:27 2017 from 192.168.111.130
    
  3. 我们可以使用spawn启用外部命令,那么我们就能使用外部命令写日志文件: 在hosts.allow中:

    sshd,in.telnetd:192.168.111.:spawn echo "`date +'%%F %%T'` login from client\: %c to %d">>/var/log/tcpwrap.log
    

    我们在使用centOS 7 访问后,看一下日志:

    [root@CT691 ~]#tail /var/log/tcpwrap.log
    2017-09-2816:27:28 login from client:192.168.111.120 to sshd
    

    在/etc/hosts.allow中添加,允许登录,并记录日志

    在/etc/hosts.deny中添加,拒绝登录, 并记录日志

    %c 客户端信息 %s 服务器端信息 %d 服务名 %p 守护进程的PID %% 代表% : 符号转义

  4. 我们可以使用twist拒绝用户访问,并返回一个信息:

    sshd,in.telnetd:192.168.111.:twist echo "Hello I am T_T !"
    

    然后我们进行连接,使用调试模式,因为默认ssh是看不到返回信息的,telnet可以:

    [root@centos6 ~]# ssh -v 192.168.111.110
    OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013
    debug1: Reading configuration data /etc/ssh/ssh_config
    debug1: Applying options for *
    debug1: Connecting to 192.168.39.129 [192.168.39.129] port 22.
    debug1: Connection established.
    debug1: permanently_set_uid: 0/0
    debug1: identity file /root/.ssh/identity type -1
    debug1: identity file /root/.ssh/identity-cert type -1
    debug1: identity file /root/.ssh/id_rsa type -1
    debug1: identity file /root/.ssh/id_rsa-cert type -1
    debug1: identity file /root/.ssh/id_dsa type -1
    debug1: identity file /root/.ssh/id_dsa-cert type -1
    debug1: identity file /root/.ssh/id_ecdsa type -1
    debug1: identity file /root/.ssh/id_ecdsa-cert type -1
    debug1: ssh_exchange_identification: Hello I am T_T !    # 返回的信息
    
    ssh_exchange_identification: Connection closed by remote host  # 被拒绝访问
    

调试工具

tcpdmatch [-d] daemon[@host] client

-d 测试当前目录下的 hosts.allow和hosts.deny

这样,在别人没有连接的时候,我们就可以知道我们设置的那些IP是否可以连接我们的主机: (hosts.deny)

sshd:192.168.111.120
[root@CT691 ~]#tcpdmatch -d ssh 192.168.111.120
client: address 192.168.111.120
server: process ssh
access: granted

PAM

Pluggable Authentication Modules

PAM 是关注如何为服务验证用户的 API,通过提供一些动态链接库和一套统一的API,将系统提供的服务和该服务的认证方式分开。使得系统管理员可以灵活地根据需要给不同的服务配置不同的认证方式而无需更改服务程序。是一种认证框架,自身不做认证。

它提供了对所有服务进行认证的中央机制,适用于login,远程登录(telnet,rlogin,fsh,ftp,点对点协议(PPP)),su等应用程序中。系统管理员通过PAM配置文件来制定不同应用程序的不同认证策略;应用程序开发者通过在服务程序中使用PAM API(pam_xxxx( ))来实现对认证方法的调用;而PAM服务模块的开发者则利用PAM SPI来编写模块(主要调用函数pam_sm_xxxx( )供PAM接口库调用,将不同的认证机制加入到系统中;PAM接口库(libpam)则读取配置文件,将应用程序和相应的PAM服务模块联系起来

架构

PAM架构.jpg

配置文件

模块文件目录:/lib64/security/*.so

环境相关的设置:/etc/security/

主配置文件:/etc/pam.conf,默认不存在,格式如下:

application type control module-path arguments

服务名(application)
telnet、login、ftp等,服务名字“OTHER”代表所有没有在该文件中明确配置的其它服务
模块类型(module-type)
    Auth 账号的认证和授权
    Account 与账号管理相关的非认证类的功能,如:用来限制/允许用户对某个服务的访问时间,当前有效的系统资源(最多可以有多少个用户),限制用户的位置(例如:root用户只能从控制台登录)
    Password 用户修改密码时密码复杂度检查机制等功能
    Session 用户获取到服务之前或使用服务完成之后需要进行一些附加的操作,如:记录打开/关闭数据的信息,监视目录等
    -type 表示因为缺失而不能加载的模块将不记录到系统日志,对于那些不总是安装在系统上的模块有用
control PAM库该如何处理与该服务相关的PAM模块的成功或失败情况
    简单方式实现:一个关健词实现
        required :一票否决,表示本模块必须返回成功才能通过认证,但是如果该模块返回失败,失败结果也不会立即通知用户,而是要等到同一type中的所有模块全部执行完毕再将失败结果返回给应用程序。即为必要条件
        requisite :一票否决,该模块必须返回成功才能通过认证,但是一旦该模块返回失败,将不再执行同一type内的任何模块,而是直接将控制权返回给应用程序。是一个必要条件
        sufficient :一票通过,表明本模块返回成功则通过身份认证的要求,不必再执行同一type内的其它模块,但如果本模块返回失败可忽略,即为充分条件
        optional :表明本模块是可选的,它的成功与否不会对身份认证起关键作用,其返回值一般被忽略
        include: 调用其他的配置文件中定义的配置信息
    复杂详细实现:使用一个或多个“status=action”
        [status1=action1 status2=action …]
            Status:检查结果的返回状态
            Action:采取行为 ok,done,die,bad,ignore,reset
                ok 模块通过,继续检查
                done 模块通过,返回最后结果给应用
                bad 结果失败,继续检查
                die 结果失败,返回失败结果给应用
                ignore 结果忽略,不影响最后结果
                reset 忽略已经得到的结果
module-path 用来指明本模块对应的程序文件的路径名
    /lib64/security目录下的模块可使用相对路径
    其他位置需要使用绝对路径
Arguments 用来传递给该模块的参数

为每种应用模块提供一个专用的配置文件:/etc/pam.d/APP_NAME,格式如下:

type control module-path arguments

注意:

  1. 如/etc/pam.d存在,/etc/pam.conf将失效
  2. 修改PAM配置文件将马上生效
  3. 编辑pam规则时,保持至少打开一个root会话,以防止root身份验证错误

认证原理

PAM认证首先要确定那一项服务,然后加载相应的PAM的配置文件(位于/etc/pam.d下),最后调用认证文件(位于/lib/security下)进行安全认证

PAM认证原理.jpg

PAM认证机制

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回传的结果决定下一个动作(重新输入密码或者通过验证)

示例1:

模块:pam_shells

功能:检查有效shell

man pam_shells

示例:不允许使用/bin/csh的用户本地登录

  1. vim /etc/pam.d/login

    加上 auth required pam_shells.so
    
  2. vim /etc/shells

    去掉 /bin/csh
    
  3. useradd –s /bin/csh testuser

  4. testuser在终端不可登录,但可以su-登录,因为没有修改/etc/pam.d/su配置文件中的规则

  5. tail /var/log/secure

示例2:

模块:pam_securetty.so

功能:只允许root用户在/etc/securetty列出的安全终端上登陆

示例:允许root在telnet登陆(默认telnet不允许root账号直接登录)

  1. vim /etc/pam.d/remote

    #auth required pam_securetty.so #将这一行加上注释
    
  2. 或者/etc/securetty文件中加入

    pts/0,pts/1…pts/n

示例3:

模块:pam_nologin.so

功能:如果/etc/nologin文件存在,将导致非root用户不能登陆;如果用户shell是/sbin/nologin 时,当该用户登陆时,会显示/etc/nologin文件内容,并拒绝登陆

示例:禁止所有非root用户登录

  1. touch /etc/nologin
  2. 通过tty终端测试

示例4:

模块:pam_limits.so

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

修改限制的实现方式:

  1. ulimit命令,立即生效,但无法保存,常用选项:

    ulimit.jpg
  2. 配置文件:/etc/security/limits.conf, /etc/security/limits.d/*.conf,格式如下:

    <domain> <type> <item> <value>
    
    <domain> 应用于哪些对象
        Username 单个用户
        @group 组内所有用户
        * 所有用户
    <type> 限制的类型
        Soft 软限制,普通用户自己可以修改
        Hard 硬限制,由root用户设定,且通过kernel强制生效
        - 二者同时限定
    <item> 限制的资源
        nofile 所能够同时打开的最大文件数量,默认为1024
        nproc 所能够同时运行的进程的最大数量,默认为1024
    <value> 指定具体值
    
    [j@centos7 ~]$ cat /etc/security/limits.conf 
    # /etc/security/limits.conf
    #
    #This file sets the resource limits for the users logged in via PAM.
    #It does not affect resource limits of the system services.
    #
    #Also note that configuration files in /etc/security/limits.d directory,
    #which are read in alphabetical order, override the settings in this
    #file in case the domain is the same or more specific.
    #That means for example that setting a limit for wildcard domain here
    #can be overriden with a wildcard setting in a config file in the
    #subdirectory, but a user specific setting here can be overriden only
    #with a user specific setting in the subdirectory.
    #
    #Each line describes a limit for a user in the form:
    #
    #<domain>        <type>  <item>  <value>
    #
    #Where:
    #<domain> can be:
    #        - a user name
    #        - a group name, with @group syntax
    #        - the wildcard *, for default entry
    #        - the wildcard %, can be also used with %group syntax,
    #                 for maxlogin limit
    #
    #<type> can have the two values:
    #        - "soft" for enforcing the soft limits
    #        - "hard" for enforcing hard limits
    #
    #<item> can be one of the following:
    #        - core - limits the core file size (KB)
    #        - data - max data size (KB)
    #        - fsize - maximum filesize (KB)
    #        - memlock - max locked-in-memory address space (KB)
    #        - nofile - max number of open file descriptors
    #        - rss - max resident set size (KB)
    #        - stack - max stack size (KB)
    #        - cpu - max CPU time (MIN)
    #        - nproc - max number of processes
    #        - as - address space limit (KB)
    #        - maxlogins - max number of logins for this user
    #        - maxsyslogins - max number of logins on the system
    #        - priority - the priority to run user process with
    #        - locks - max number of file locks the user can hold
    #        - sigpending - max number of pending signals
    #        - msgqueue - max memory used by POSIX message queues (bytes)
    #        - nice - max nice priority allowed to raise to values: [-20, 19]
    #        - rtprio - max realtime priority
    #
    #<domain>      <type>  <item>         <value>
    #
    
    #*               soft    core            0
    #*               hard    rss             10000
    #@student        hard    nproc           20
    #@faculty        soft    nproc           20
    #@faculty        hard    nproc           50
    #ftp             hard    nproc           0
    #@student        -       maxlogins       4
    
    # End of file
    

示例:限制用户最多打开的文件数和运行进程数

  1. vim /etc/pam.d/system-auth

    加上 session required pam_limits.so
    
  2. vim /etc/security/limits.conf

    apache – nofile 10240 apache用户可打开10240个文件
    student hard nproc 20 不能运行超过20个进程
    

推荐阅读更多精彩内容