253

一.主要将加密协议的基础:是在第三章
  1.加密方法:
    Randrom Number Generator: 随机数生成器
    One Way Hashs:单向加密
    Symmetric Algorithms:对称加密
    Asymmetric (Pub Key) Algorithms:非对称加密,也叫公共加密
    Public Key Infrastructure:公钥加密,简称:API,核心 是CA
    Digital certificates:双向加密
    
    实现上述的加密工具有:openssl,gpg

  2.Randrom Number Generator:随机数生成器
    生成随机数的工具:
    /dev/random
    /dev/urandom
    这两个工具是到熵池中找随机数的,不同的是,如果熵池的随机数用完了,random会停止提供随机数的;而urandom在熵池的随机数用完了,它会转而到一个伪随机数的生成器中找,伪随机数都是软件中生成的,不×××全。
 
   我们可以查看一下我们的随机数生成的过程,这个事在系统中,在远程登录中是看不到的。
    # cat /dev/random

    生成加密数字:openssl rand 后面跟的是数字,不是字母,rand是openssl的一个选项:模板,openssl rand num
    # openssl rand 21
     这个命令是根据:base64将二进制随机转换成ASK码的

   3.One Way Hashs:单向加密
    这种机制只是提取数据特征码的,不对数据进行加密。
   
       单项加密的特点:
         随意输入
         定长输出
         雪崩效应
         数据不能逆转
   
      常用的加密算法:
      md2,md5,mdc2,rmd160,sha,sha1
   
    使用地方有两点:
       保证传数据的完整性,即:保证那串数据还是那串数据;
       实现加密密码的,在linux就是用它来实现用户密码的存储的;

     常用的命令:
     shalsum [--check] file
     md5sum [--check] file
     openssl.gpg
     rpm -v

  4.Symmetric Algorithms:对称加密
    对称加密的特征:
       对称加密就是加密解密双方使用同一个密钥;
       将数据切成块,然后再加密;

     目前对称加密的方式有两种:
       ECB:Electronic CodeBook,each block is encrypted as a separate message using the same key.
       CBC:Cipher Block Chaining,
 
     常用的加密算法:
      DES,3DES,AES,Blowfish,RC6,IDEA,CAST5

  5.Asymmetric (Pub Key) Algorithms:非对称加密,也叫公共加密
     利用单向函数功能实现的。

     密钥是成对出现的:
      p/s:  p是public,指公钥   s是secret,指私钥
     任何一个数据既可以用公钥加密,又可以用私钥加密,解密的时候,必须用对称的密钥来解密,即:公钥加密的,必须用私钥来解密;

      公钥算法很好的解决了密钥分发的问题;

      公钥加密算法工具:
        RSA,EIGamal

      公钥加密算法的应用场景主要有两个:
         一个叫数字签名,一个叫密钥分发;

      密钥分发:
         概念:如果使用对称算法,必须使用一种机制,将密钥分发给对方,有了公约加密算法以后,这种对称算法的问题就解决了,公钥加密的方法是,用对方的公钥加密,这样只有对方的私钥能解密了,公钥是公开的。这样就相对安全一点了,但是,还是安全隐患,就是,密码仍然在网上过了一遍,因此,实际上,我们不这样加密,我们ike工具加密;

      ike:Internet Key Exchange   就是在网上发的暗号,这就是密钥交换

      现在常使用的的密钥交换叫DH,(在RH333中的75页)
       DH的实现步骤,
         两两个主机:分别选择一个大素数(a large prime)p,而后选择小的生成器(genrate)g(通常大小为2),然后双方主机(A,B主机)各自生成一个随机数x,y;这两个随机数是各自保留的;而后,A主机发送gx对p取余,发送给B主机;同理,B主机发送gy对p取余,发送给A主机;这样,A和B主机分别拿到对方运行的结果;那么A拿到gy mod p后,与x计算;同理,B拿到gx mod p与y计算;他们这两个的运算结果是一样的;

         p,g(2)
          A:x gx mod p  --->B  (gy mod p)x  = gxy mod p
          B:y gy mod p  --->A  (gx mod p)y  = gxy mod p

       为了防止别人篡改我们的在计算的过程中发送的数据,因此,我们的密钥交换算法通常要结合我们的公钥加密算法,实现数据签名的,这就用到了数字签名;

        数字签名:
           先用单项加密来加密特征码,发送给对方;数字认证是用来网络连接和分配加密钥匙;

二.openssl实现通信安全和系统安全的基础
   1.openssl主要有三部分组成:主要是两个库和一个命令行工具
     libcrypto:Genric encryption support       是个加密库,实现本地加密解密工具的一个库;
     libssl:Support for TLS/SSL portocols      是实现TLS/SSL协议的,实现网络连接的认证;实现网络通信的库;
           SSL:Security Socket Layer   叫安全的套接字层
           TLS:Transport layer Security   这是有标准化组织的,叫安全传输层(在RHS33中的77页)
     openssl:

三.获得证书的途径:一般有两种
  1.第一种途径:就是我自己是一个服务器或者客户端,需要证书颁发机构给我颁发一个证书
        下面是第一种方法的生成步骤:
    1)作为客户端,要生成以对公钥私钥对:Generate Pub_key/Sect_key pair
    2)作为客户端,要生成证书签署请求:Generate Signature Request against Pub_key
    3)生成了证书签署请求之后,要发给CA:Send it to CA
    4)然后CA开始签署并生成证书:CA sign the CSR to generate Certificate
    5)作为客户端,可以收到证书了:Receive the Certificate

****************************************************************************************************************
    第一种途径的密钥生成命令:
       # openssl genrsa 1024 > my.key               --->genrsa是生成密钥对的子命令,1024表示密钥长度,注意:私钥通常是以key结尾的

    第一种途径的公钥隐藏在私钥的里面,即是我们输出重定向导出的那个文件中,这就是我们的公钥和私钥为什么会成对出现的原因,下面是提取公钥的方法:
       # openssl rsa -in my.key -pubout -out my.pubkey   -->rsa是公钥加密工具,-in表示从哪个文件中读取,-out表示提取之后的输出文件,-pubout表示导出我的公钥的,注意:公钥通常是以pubkey结尾的

     上面的这两步就是生成一对密钥的,下面我们就需要生成证书签署请求:
       # openssl req -new -key /root/httpd.key -out /root/httpd.csr    -->req是证书签署请求工具,-new表示生成一个新的请求,-key表示我们的私钥再在哪里,它会从我们的私钥中提取出来,-out表示提取的信息输出到那个文件中去,注意:证书签署请求通常是以csr结尾的
     
     在填写证书签署请求时候,有一项如下,记住,这一项一定要填写你自己的服务器的名字,
      Common Name (eg, your name or your server's hostname) []:

       下面,我们就需要把我们生成的证书签署请求,(这里是httpd.scr)发给对方就行了,
****************************************************************************************************************
    下面,我们做一个自签的证书,即:自己即做CA又做服务器,这样自己就可以给自己签证了
      
     做自签证书的步骤:
      1.# openssl req -new -x509 -key /root/httpd.key -out /root/httpd.crt -days 3655  -->-x509这是定义我们的证书格式为自谦证书,-key 表示从哪里读入我们的key,如果我们即做CA又做服务器用,-key后面的文件最好分开用,-out表示我们生成的证书存放地,注意:这里是以crt结尾的,crt是certificate的简写,-days是指证书的有效期限,这个命令就是将自己做成了CA,不过这样的CA是不能用的,下面,我们有详细的步骤;

      2.查看我们的证书请求的内容:
       # openssl req -noout -in my.csr -text
          eg:# openssl req -noout -in /root/httpd.csr -text

      3.证书的查看命令
*****************************************************************************************************************  
   2.第二种:我自己假设自己作为一个颁发机构:

三.我们做CA的步骤:
  1.我们上面做的CA是不能用的,因为必须在CA目录中做的CA才能发证
   # cd /etc/pki/CA/      --->这就是我们的证书存放目录,我们的私钥放在这个目录里的private目录中
  2.修改我们openssl的配置文件:因为这台机器把自己扮演成CA的时候,回到这里来读取数据的;
     我们的openssl配置文件放在/etc/pki/tls目录中,叫openssl.cnf

     下面修改我们的配置文件
       # vim openssl.cnf
       这里我们主要修改[ CA_default ]下面的内容,如下:
[ CA_default ]

dir             = /etc/pki/CA           # Where everything is kept         这是我们CA的存放的绝对路径
certs           = $dir/certs            # Where the issued certs are kept  这里是我们证书的放置目录,需要手动建立
crl_dir         = $dir/crl              # Where the issued crl are kept    这是证书吊销列表放置目录,手动建立
database        = $dir/index.txt        # database index file. 这是索引文件,记录发给谁证书了的文件,手动建立
#unique_subject = no                    # Set to 'no' to allow creation of
                                        # several ctificates with same subject.
new_certs_dir   = $dir/newcerts         # default place for new certs.  新证书的存放目录,手动建立

certificate     = $dir/cacert.pem       # The CA certificate     这里是作为CA,证书的存放目录,和证书的名字
serial          = $dir/serial           # The current serial number 这是证书的序列号,16进制
crlnumber       = $dir/crlnumber        # the current crl number    当前证书吊销列表序列号,可以不用建立
                                        # must be commented out to leave a V1 CRL
crl             = $dir/crl.pem          # The current CRL  如果不笑笑,这个也可以不建立
private_key     = $dir/private/cakey.pem# The private key  这是自己私钥证书的存放位置,和私钥名字
RANDFILE        = $dir/private/.rand    # private random number file  这个叫随机文件

x509_extensions = usr_cert              # The extentions to add to the cert 证书名字的扩展,叫usr_cert

# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt        = ca_default            # Subject Name options
cert_opt        = ca_default            # Certificate field options

   下面,我们就可给自己生成一个私钥,并生成一个自谦证书,建立上面提到的必须建立的几个目录;

  3.我们要给自己发一个证,也必须生成一个私钥文件,在这之前,还不许修改openssl的配置文件,上面已修改过
    下面我们生成一个私钥文件:
     # cd /etc/pki/CA/
     # openssl genrsa 1024 > private/cakey.pem    --->生成密钥

    生成密钥之后,给自己发一个证,这时候,我们就可以扮演CA了,注意:生成自签署证书,是不用发送证书签署请求,直接可以生成;
     # openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3655
    
    下面创建我们需要的目录和文件
     # mkdir certs newcerts crl
     # touch index.txt serial
     # echo 01 > serial             ---->因为序列号是从01或10开始的
     到这里,CA可以用了,这是在组织内用的

   4.下面我们找一台机器,作为客户端,来申请证书,这里我们是给我们的https服务申请证书
     # cd /etc/httpd
     # mkdir certs        --->这个目录是用来放置公钥和私钥文件的
     # cd certs
     # umask 077;openssl genrsa 1024 > httpd.key    --->这里修改了umask,目的是让其他用户没有修改权限的

     key有了之后下面生成一个申请
      # openssl req -new -key httpd.key -out httpd.car
      这里注意:我们这里的申请必须以我们的CA保持一致

   5.我们的证书生成之后,就需要将我们的 申请证书发给CA签一下,就好了
      # scp httpd.csr 192.168.0.254:/tmp

   6.下面切换到CA服务器上,签署一下我们的证书申请请求
     # cd /tmp/
     # openssl ca -in httpd.csr -out http.crt  -->ca是证书签署请求时证书认证管理工具,是openssl的子命令;注意:签署的证书应该保存在CA目录下一份,即/etc/pki/certs/目录一份;这里就省略了;

    这时候,在CA服务器上面就生成一个证书了

   7.下面,我们将生成的证书发送给客户端就好了
     这里切换到客户端:
      # cd /etc/httpd/certs/
      # scp 192.168.0.254:/tmp/http.crt ./   --->将服务器端的证书拷贝过来,以后,就有证书了

四.如果我们只是想测试一下,做个自签证书可以用下面的简单方法
    # cd /etc/pki/tls/certs/
    在该目录内直接用make命令创建自签证书文件名加后缀名pem就好了,还可以创建私钥,公钥等
     eg:# make de.pem

五.修改生成证书的默认选项:
  1.我们在生成证书的时候,总是需要添加国家,省份,城市等等,一些信息,我们可以修改CA服务器上的生成证书的文件的默认选项,来简化我们的输入。
     eg:# cd /etc/pki/tls/
        # vim openssl.cnf
          我们在这个文件中找到以下这些,并对其做相应的修改,
[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = GB
countryName_min                 = 2
countryName_max                 = 2

stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = Berkshire

localityName                    = Locality Name (eg, city)
localityName_default            = Newbury

0.organizationName              = Organization Name (eg, company)
0.organizationName_default      = My Company Ltd

# we can do this but it is not needed normally :-)
#1.organizationName             = Second Organization Name (eg, company)
#1.organizationName_default     = World Wide Web Pty Ltd

organizationalUnitName          = Organizational Unit Name (eg, section)
#organizationalUnitName_default =

commonName                      = Common Name (eg, your name or your server\'s hostname)
commonName_max                  = 64

emailAddress                    = Email Address
emailAddress_max                = 64

  2.证书吊销的相关知识在(RH333的83和84页)

六.有关ssh的相关信息
   1.ssh:Secure SHell,版本有,sshv1, sshv2
   2.在linux上,由于事先ssh协议的软件叫OpenSSH;
     OpenSSH有一下几个软件包组成:这里指的是RPM包
        openssh:这个包提供的组件有scp,ssh-keygen
        openssh-clients:这个包提供的组件有ssh, slogin, ssh-agent,sftp
        openssh-askpass:这个软件包是当我们在实现基于密钥的认证的时候,为了防止用户每一次使用证书的时候都要实现加密码,而提供的一种机制,就是与ssh-agent通信的一种机制,或者一个组件;
        openssh-askpass-gnome:同openssh-askpass,只不过这是在图形界面下用的,

       这四个组件是作为客户端必须要用到的;这四个组件是用来访问别人的。

       如果我们想让别人访问我们,还需要下面的组件
        openssh-server                    --->这是提供服务器组件的

   3.同时,我们的openssh还要依赖openssl中的两个库文件,不是openssh本身;

   4.ssh之所以成为安全的shell,就是它在传输的时候是加密的,代替telnet,还能提供隧道的功能;
     X-forwarding实现图形的转发

   5.openssh的认证:Authenticatiion
     基于以下几种认证:
       password        -->基于密码的认证
       RSA/DSA         -->基于密钥的认证
       kerberos        -->基于令牌的认证

    这里我们介绍一下RSA/DSA的认证:
      我们在自己电脑上生成一对密钥,私钥自己保留,公钥追加到自己在服务器上的用户的家目录中的一个隐藏文件.ssh目录中的authorized_keys文件中,下次我们登陆就会自动认证了;

   6.当我们在用ssh远程登录一个服务器时,会让我们回到yes/no,这是有自己的主机发起的,因为第一次访问,双方没有证书,为了防止第三方***,这里才会出现这个选择;

    这里,我们的连接过程:如果我们回答了no,服务器会发送给我们一个公钥文件;如果回到yes,我们主机会把服务器的公钥保存下来的,这个公钥我们称为主机公钥;

    主机公钥的作用:是用来两台主机之间,用户发送账号密码之前,就能事先协调处一个双方使用的对称加密密钥,就是实现用户在输入账号密码,就能实现用户账号密码加密的作用;

    当我们用ssh登录以后,就会在家目录中生成一个.ssh的目录,里面有一个known_hosts文件,里面存储是服务器的地址,加密机制,和对方的公钥信息,这种公钥信息,是基于主机实现的,而不是基于用户实现的;

   7.上面提到,一种基于用户认证的密钥,就是用户在远程登录的时候,不需要输入密码,就可以登录了
      下面是实现用户密钥的步骤:
        第一步,必需在本地生成一对密钥;
        第二步,就是让生成的公钥放在远程服务中的用户家目录中的.ssh目录中的authorized-keys中;

         # ssh-keygen -t rsa        -->rsa是密钥认证的一种机制
          这时候,会让我们修改密钥和公钥的名字,和密钥密码,我们可以做修改,都默认;
         # cd /root/.ssh  
         这时候,我们可以用传输工具cp到服务器上,也可以使用专用工具传输到服务器上,如下
         # ssh-copy-id -i /root/.ssh/id_rsa root@192.168.0.254   -i 指定私钥文件放置的位置
         # ssh root@192.168.0.254       -->这里是测试,我们可以看到不用再输入密码了

         然后,我们切换到服务器上,
         # cd /etc/.ssh
         # cat authorized_keys      --->我们会发现我们的公钥信息都保存到这个文件中了,
     
   8.openssh是c/s架构的,有以上几个组件组成,要想可以正常工作,他们需要配置文件
     Client:/etc/ssh/ssh_config
     Server:/etc/ssh/sshd_config  -->这个服务是有sshd进程提供给我们的
     
     sshd的启动脚本是/etc/init.d/sshd,所以我们可以用service sshd start来启动sshd的服务

   9.我们在用ssh登录的时候,会读取/etc/motd文件里的内容,显示在登录界面上,因此,我们可以在这个文件里随便写。

   10.我们的ssh有两种转发,一种叫做本地转发,一种叫远程转发;
        -L 表示本地转发
        -R 表示远程转发

   11.要想远程登录是,可以将远程的图形窗口显示在本机上,可以使用过-X,远程主机必须支持图形界面
     eg:# ssh -X 192.168.0.79
        # system-config-date &          --->这一步可以测试出我们可以打开远程主机上的图形界面

   12.在sshd的配置文件sshd_config中,最后一句话是:Subsystem       sftp    /usr/libexec/openssh/sftp-server,这是启用的,表示本机支持sftp的请求;
      eg:# sftp 192.168.0.79       --->用这个命令来远程登录,就好像和直接登录一样

七.有关SELinux的知识
   1.SELinux: Security Enhanced Linux      安全加强的linux
     SELinux是一种极大的提升了linux的安全性,将linux默认的自主访问控制策略提升为强制访问策略,即DAC -->MAC;
     将linux的等级从C2等级到B1等级的提升;
     linux的等级从低到高是:C2,C1,B3,B2,B1,A1
     DAC:Discretionary Acess Control    --->自主访问权限,就是用户可以将它自己的文件权限修改成随意的,权限指的是可读写执行,不是属主属组;
     MAC:Mandatory
   2.ls -Z   -->-Z是查看文件的安全上下文
     eg:# ls -Z 之后,查看的文件格式如下:
     -rw-------  root root system_u:object_r:etc_t          moduli
                          SELinux属主  角色  类型

     类型就是给文件打一个标记,就是在MAC下,给文件打一个沙箱;

     SELinux Policy :SELinux策略库    --->就是定义那些类型可以访问那些类型,就是在文件的原有属性附加了一层属性

     SELinux的默认策略在/etc/selinux/targeted/policy/policy.21这个文件中定义的,是二进制文件;
  
   3.SELinux有两种方式定义崩溃级别的:
    第一种:strict,叫严格级别;在这种级别下,访问任何一个文件,都要严格符合SELinux的级别,只要不符合,就不让访问

    第二种:targeted,这种级别是只对系统中某些我可以定义的、有必要定义的、别人访问可能给我带来危险的,进行定义好,而不那些我们认为可有可无的,我们不知道怎么定义的就不定义策略了;

    eg:假如我们这里只想1000个SELinux进程的90个进程,我们的做法如下:
       我们要想限定着90进程,就需要给这90个进程打标签,
       标签是什么呢?如下是ls -Z显示的结果,而ystem_u:object_r:etc_t就是标签;
       -rw-------  root root system_u:object_r:etc_t          moduli   

       而一个要想被SELinux限制的必须有一个类型,就是标签的最后一段,对于那些我们不想定义的就不在有类型,我们称这种为未定义的类型;

    4.# ps auxZ     在前面多一个LABEL,就是标签;
         LABEL                         USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    system_u:system_r:init_t      root         1  0.0  0.3   2072   620 ?        Ss   09:19   0:01 init [5]   
  5.假如我们想让两个不同类型的进程可以访问,我们可以改变一个进程的类型,然后就可以访问了;
      一个进程是否可以访问一个文件,需要类型一致外,还需要SELinux的策略;

   6.SELinux策略给我们定义了很多策略,有一种策略叫做boolean型
     bool值可以定义是否打开我们的规则;
     eg:# getsebool -a  显示我们系统上的所有的bool值
  
   7.selinux的targeted策略在/etc/selinux/config 文件中定义的;(67页)
     eg:# vim /etc/selinux/config

        getenforce 是用来查看SELinux的状态
        setenlinux 是用来设置SELinux的状态
           eg:# setenforce 0           --->这是临时关闭SELinux,当重启系统之后,就又会恢复到默认状态
              # setenforce 1           --->这是临时开启SELinux
            要想永久开启SELinux或者关闭SELlinux,需要修改SELinux的配置文件/etc/selinux/config,这个文件的连接文件是/etc/selinux/selinux
     
        我们还可以在启动系统时,在grub界面下敲e键,在内核后面添加selinux=1|0,还可以在grub的配置文件/etc/grub.conf中的kernel那一行的最后面添加selinux=0|1;这就是在定义selinux在开机的时候是否启动;

   8.我们linux上的安全上下文:所有的文件和进程都有一个安全上下文;(68页)

     我们的安全上下文有5个,只是我们的targeted用不到后面两个,所以我们用ls -Z只看到三个,就是用户、角色、类型
     eg:-rw-------  root root system_u:object_r:etc_t          moduli
                              属主(用户) 角色   类型

      用户:表示登录到系统上的用户的类型;登录到系统的上的用户只有三类:
            第一类是管理员,它的用户是root;
               eg:-rw-r--r--  root root root:object_r:user_home_t        install.log
            第二类是普通用户,他们的用户通常是user_u;
               eg:-rw-r--r--  student student user_u:object_r:user_home_t      .bash_logout
            第三类是system_u,表示是个进程:system_u表示的是SELinux的用户,而不是系统用户
               eg:-rw-------  root root system_u:object_r:user_home_t    anaconda-ks.cfg

      角色:是用来定义权限的集合的,即用来定义一个进程、文件或者user的目的

      类型:主要被类型强制来使用的;
             对于进程而言,它的类型通常称为域;对与object而言,它的类型才称为类型;

   9.文件有标签,我们也可以修改文件的标签:chcon命令修改
       chcon
           -t   是修改文件的类型的
           -R   递归修改的:即把一个目录和目录内的文件都改一改
           --reference=RFILE  表示以我们在这里给的文件为标准,修改后面我们给定的文件的类型
         eg:# cp /etc/fstab /tmp
            # cd /tmp/
            # ls -Z         --->这时候我们会发现cp到/tmp目录下,它的类型就会变成tmp_t,当fstab在/etc/目录中的时候,它的类型是etc_t;这就说明文件的类型要随附它的目录
            # chcon -t etc_t fstab       -->这是修改/tmp目录下的fstab文件的类型的;
            # chcon --reference=fstab wjun      -->这是修改一个文件的类型与另一个文件的类型一样

   10.restorecon是修改文件的默认类型的
      eg:# restorecon wjun

   11.修改服务的bool值持久有效,需要加一个-P,如果不加-P是临时修改,一旦重启了,就会失效
      eg:# setsebool -P allow_ssh_keysign 1

  
八.做证书的总结
   1.下面是在/etc/pki/CA目录中做的
       这里是做CA
     openssl genrsa 1024 > private/cakey.pem
     openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3655       自签的证书做好了
     mkdir crl certs newcerts
     touch index.txt serial
     echo 01 > serial
      到这里一个CA算是完成了

     这里在客户机上执行
     openssl genrsa 1024 > private/cakey.pem  
     openssl req -new -key /tmp/httpd.key -out /tmp/httpd.csr -days 3655         生成证书签署请求
     做好证书签署请求之后,发给CA
     下面CA签署客户机发来的证书签署请求
      openssl ca -in /root/httpd.csr -out /root/httpd.crt