加密与安全

openssl enc -e -des3 -a -salt  -in ./fstab -out fstab.xipher
openssl enc -d -des3 -a -salt -in fstab.cipher -out f1
openssl dgst -md5 fstab
md5sum fstab
openssl passwd -1 
passwd:
生成加密口令
openssl rand -hex 3 # 16进制数

(umask 066;openssl genrsa)

-----------------------------------------------------------------------------------------------------------------

实验:向ca申请证书
1、建立Root CA
1)生成私钥
2)自签名证书

2、用户服
1)生成私钥
2)生成证书申请
3)将申请文件发给CA

3、CA颁发证书
4、证书发送客户端
5、应用软件使用证书
openssl ca -status 10
openssl ca -revoke newcerts/10.pem
openssl ca -status 10
ll index.txt
cat /etc/pki/tls/
openssl ca -gencrl -out crl.pem
ssh [email protected]
ssh-keygen  -t rsa
ssh-copy-id -i id_rsa.pub
-----------------------------------------------------------------------
gpg 对称加密
gpg -c file  #对file文件加密,并生成加密文件:file.gpg
gpg -o file -d file.gpg  #将加密文件解密成file文件

使用gpg工具实现公钥加密
1)在主机A上生成密钥对
gpg -gen-key # 可将密钥命名为:rootA,不用对密钥设密码(密码为空)
查看主机上的公钥
gpg --list-keys
2)导出主机A的公钥
gpg -a --export -o magedu.pubkey  # -o 将导出的公钥命名为:magedu.pubkey
3)将主机A的公钥文件传送给主机B
scp magedu.pubkey 172.20.0.1:  # 主机B的IP:172.20.0.1

4)在主机B上生成密钥对
gpg -gen-key #可将密钥命名为:rootB,不用对密钥设密码(密码为空)
gpg --list-keys
5)在主机B上导入主机A的公钥
gpg --import magedu.pubkey
gpg --list-keys
6)在主机B上,用导入的A的公钥,加密文件file,并生成加密文件:file.gpg
gpg -e -r rootA file
file file.gpg
7)复制加密文件file.gpg到主机A上
scp file.gpg 172.20.0.2:  # 主机A的IP:172.20.0.2

8)在主机A上解密加密文件
gpg -d file.gpg # 解密并查看加密文件
gpg -o file -d file.gpg # 解密加密文件,并将加密文件导出命名为file

9)删除公钥和私钥
gpg --delete-keys rootA  # 删除A的公钥
gpg --delete-secret-keys rootA  # 删除A的私钥

SSL防重放:
用户的用户名和密码放在数据报文里,被截获以后,直接把加密的用户名和密码重发一遍,服务器能自己解密,从而绕过网站的检查,成功登录
重放:捕获刚刚用户发过来的合法的用户名和密码,重新发一遍,网站不做任何检查,虽然是加密的,但网站可以自己解密,然后就可以登陆(09:58)
放重放:捕获下来以后,再发已经过期了;第一次发是正确的,第二次发,同样的数据包他认为是过期的
握手阶段:协商阶段;协商什么加密算法
应用阶段:
http 协议是不加密
SSL在应用层和传输层加一层,应用层的数据到达中间以后,它把数据加密了,然后再到传输层封装TCP报文的头部,端口号什么的,即使被黑客解惑数据也只能看见端口号,数据已经被加密了
https协议
客户端:hello 
服务器:hello,把证书发给客户端,CA私钥签名过的服务器的公钥
客户端:用CA的公钥解开,然后就拿到了服务器的公钥
   然后在浏览器里面生成一个对称秘钥,用服务器的公钥加密,然后加密的对称秘钥发给服务器
服务器:用服务器的私钥解开,得到对称秘钥,以后就可以用对称秘钥进行数据通信了

openssl:开源项目
三个组件:
openssl:多用途的命令行工具,包openssl 
libcrypto:加密算法库,包openssl-lib
libssl:加密模块应用库,实现了ssl及tls,包nss 
备注:
base64:64个字符分别表示我们的编码
6bit,6位的编码 # 2^6=64种组合
a-z,A-Z,0-9,/,+
0 A 
1 B
:
:
24 Y
25 Z
26 a
27 b
:
:
51 z
52 0
53 1
:
:
62 +
63 /

   a         b        c    
   97        98       99
01100001  01100010 01100011
011000 010110 001001 100011
24     
Y

对称加密算法:
openssl enc -des3 -a -salt -in fstab -out fstab.cipher
对称秘钥,3des加密的,输入俩遍密码
enter des-ede3-cbc encryption password:
Verifying - enter des-ede3-cbc encryption password:
加密以后,用base64重新进行编码,不可反推;base64本身不是加密的
== 是最后的而数字不够6位,用=补全
解密:
openssl enc -d -des3 -a -salt -in fstab.cipher -out fstab

支持哈希算法:
mad5sum fstab
24d73dce90b15731444032acfea06806  ../etc/fstab
openssl dgst -md5 fstab
MD5(../etc/fstab)= 24d73dce90b15731444032acfea06806

生成加密口令:
openssl passwd -1 # -1表示生成md5加密的口令,默认会添加盐
Password: 
Verifying - Password: 
$1$IwCuDyhP$2PszmpZeHp.uoosd3N64d.
openssl passwd -1 -salt "IwCuDyhP" # 可以指定盐,只要盐一样,相同的密码会生成相同的口令;反之,盐不一样,即使密码相同,生成的口令也会不一样
Password: 
$1$IwCuDyhP$2PszmpZeHp.uoosd3N64d.

生成随机数:
[root@centos7 ~]# openssl rand -base64 12
qpZVHw+M/1HsRuQI
[root@centos7 ~]# openssl rand -base64 11
bbB3c8q6T+tp0gg=
[root@centos7 ~]# openssl rand -base64 10
gqK9Z7j3exqLUw==
[root@centos7 ~]# openssl rand -base64 9
QeXMyNV/WwDP
[root@centos7 ~]# openssl rand -base64 8
rJltiakAKg8=
[root@centos7 ~]# openssl rand -base64 7
oaGqHrS/2Q==
[root@centos7 ~]# openssl rand -base64 6
/7AhxyTn
[root@centos7 ~]# openssl rand -base64 5
dkMQ0Jc=
[root@centos7 ~]# openssl rand -base64 4
Nnjx4Q==
[root@centos7 ~]# openssl rand -base64 3
GC0D
[root@centos7 ~]# openssl rand -base64 2
ubQ=
[root@centos7 ~]# openssl rand -base64 1
Yw==
base64编码 是二进制的6位,一个字节8bit,3个字节24位,可以被6整除,所以没有无效数据!
我们输入的是字符数,所以只要是3的倍数,就可以用base64编码完整的表示,所以也就没有 = 号了

生成8个字符,数字加字母的随机密码:
openssl rand -base64 20 | tr -dc '[:alnum:]' |head -c8
KlvJWuyg

生成16进制数:
openssl rand -hex 3 
d7c6bc
# 一个16进制数可以表达4位二进制数,我们输入的是3个字节24位二进制数,所以最后生成6个16进制数

生成私钥,并临时设置权限:
(umask 066;openssl genrsa -out private.key 1024)

对生成的私钥进行加密:
(umask 066;openssl genrsa -out private.key -des 1024)
Enter pass phrase for private.key:
Verifying - Enter pass phrase for private.key:
cat ./private.key
Proc-Type: 4,ENCRYPTED  #表示已经加密了

解密加密的私钥:
openssl rsa -in private.key -out private.key2

用私钥提取对应的公钥:
openssl rsa -in private.key -pubout -out public.key
Enter pass phrase for private.key: # 由于私钥被加密了,所以得输入口令
cat public.key

实验:向ca申请证书
1、建立Root CA
1)生成私钥
2)自签名证书

2、用户或服务器
1)生成私钥
2)生成证书申请文件
3)将证书申请文件发给CA

3、CA颁发证书
4、证书发送客户端:拷贝给用户
5、应用软件使用证书
openssl ca -status 10
openssl ca -revoke newcerts/10.pem
openssl ca -status 10
ll index.txt
cat /etc/pki/tls/
openssl ca -gencrl -out crl.pem

ssh [email protected]
ssh-keygen  -t rsa
ssh-copy-id -i id_rsa.pub
-----------------------------------------------------------------------------------------------------------------
vim /etc/pki/tls/openssl.cnf
CA的配置文件
####################################################################
[ ca ]
default_ca      = CA_default            # The default ca section


####################################################################
[ CA_default ]


dir             = /etc/pki/CA           # Where everything is kept
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
serial          = $dir/serial           # The current serial number
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


# 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


# Extension copying option: use with caution.
# copy_extensions = copy


# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions        = crl_ext


default_days    = 365                   # how long to certify for
default_crl_days= 30                    # how long before next CRL
default_md      = sha256                # use SHA-256 by default
preserve        = no                    # keep passed DN ordering


# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy          = policy_match


# For the CA policy
[ policy_match ]
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional


# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional


####################################################################

服务器申请证书:
# 服务器IP:172.20.0.1
1)生成私钥:
cd /ect/pki/CA
(umask 077;openssl genrsa -out ./private/cakey.pem 4096)
 
2)自签名的证书:
cd /etc/pki/CA
openssl req -new -x509 -key ./private/cakey.pem -out ./cacert.pem -days 3650
# req 发出申请 
# new 一个新的申请
# x509 自签名的证书
# -key ./private/cakey.pem 私钥文件
# ./cacert.pem 生成的证书文件
# days 证书的有效期
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:magedu       
Organizational Unit Name (eg, section) []:M30
Common Name (eg, your name or your server's hostname) []:www.magedu.com                                                                 '
Email Address []:

以人类可读的方式查看证书:
openssl x509 -in cacert.pem -noout -text
# 当然如果传到windows上查看,须把后缀改成: cacert.crt/cacrt.cer

客户端申请证书:app服务
# 客户端IP:172.20.0.2
1) 生成私钥
cd ./app
(umask 077;openssl genrsa -out ./app.key 1024)
# 在生产中这个证书是给谁用的,这个文件就放在和这个服务相关的配置文件所在的文件里

2) 利用私钥生成证书的申请文件
openssl req -new -key ./app.key  -out ./app.csr
# ./app.csr 私钥证书的申请文件
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:magedu       
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:www.app.com                                                                 '
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

3)将证书申请文件发给服务器CA
scp ./app.csr 172.20.0.1:/etc/pki/CA

服务器:
cd /etc/pki/CA
1) 颁发证书
有两个空文件没有,必须事先创建好
touch ./index.txt 存放已颁发证书的数据库
touch ./serial 存放颁发下一个证书编号的文件
echo 0F > ./serial 指定下一个证书的编号:0F

openssl ca -in ./app.csr -out ./certs/app.crt -days 100  # 证书存放在./certs/app.crt 有效期100天

#Certificate is to be certified until Aug 27 06:40:14 2018 GMT (100 days)
#Sign the certificate? [y/n]:y

#1 out of 1 certificate requests certified, commit? [y/n]y
#Write out database with 1 new entries
#Data Base Updated

最终颁发的证书存放在俩个位置,分别为:
ll ./certs/ newcerts/
./certs/:
total 8
-rw-r--r--. 1 root root 4931 May 19 14:40 app.crt
newcerts/:
total 8
-rw-r--r--. 1 root root 4931 May 19 14:40 0F.pem

2)将颁发的证书发送给客户端:
scp ./certs/app.crt 172.20.0.2:./app

小注:
1、如果,证书申请文件的填写信息和CA不一致怎么办,实际可以修改服务器端的策略:
vim /etc/pki/tls/openssl.cnf
将:policy          = policy_match
修改为:policy          = policy_anything

2、证书申请不允许重复提交一摸一样的证书申请文件
它是通过文件index.txt.attr来控制的
cat index.txt.attr
unique_subject = yes  # 如果是no,就可以重复提交

cat index.txt
V 180827064014Z 0F unknown /C=CN/ST=beijing/O=magedu/CN=www.app.com

查看证书状态,是否有效:
openssl ca -status 0F  
Using configuration from /etc/pki/tls/openssl.cnf
0F=Valid (V)  # V 代表有效

吊销证书:
openssl ca -revoke ./newcerts/0F.pem 

证书吊销列表:CRL(crl.pem)
得事先创建证书吊销列表文件crlnumber 存放下一个被吊销的编号
echo 1F > ./crlnumber  先建一个已被吊销的编号,存放在文件crlnumber.old
openssl ca -gencrl -out ./crl.pem 

查看吊销列表:
openssl crl -in crl.pem -noout -text

搭建CA以及证书的申请过程写成脚本

[root@centos7 Packages]# rpm -qp --scripts mod_ssl-2.4.6-67.el7.centos.x86_64.rpm 
postinstall scriptlet (using /bin/sh):
umask 077

if [ -f /etc/pki/tls/private/localhost.key -o -f /etc/pki/tls/certs/localhost.crt ]; then
   exit 0
fi

/usr/bin/openssl genrsa -rand /proc/apm:/proc/cpuinfo:/proc/dma:/proc/filesystems:/proc/interrupts:/proc/ioports:/proc/pci:/proc/rtc:/proc/uptime 2048 > /etc/pki/tls/private/localhost.key 2> /dev/null

FQDN=`hostname`
if [ "x${FQDN}" = "x" -o ${#FQDN} -gt 59 ]; then
   FQDN=localhost.localdomain
fi

cat << EOF | /usr/bin/openssl req -new -key /etc/pki/tls/private/localhost.key \
         -x509 -sha256 -days 365 -set_serial $RANDOM -extensions v3_req \
         -out /etc/pki/tls/certs/localhost.crt 2>/dev/null
--
SomeState
SomeCity
SomeOrganization
SomeOrganizationalUnit
${FQDN}
root@${FQDN}
EOF

待研究的脚本
cat  /etc/pki/tls/certs/Makefile 
-----------------------------------------------------------
Secure shell:
1、ssh: secure shell, protocol, 22/tcp, 安全的远程登录
2、具体的软件实现: 
OpenSSH: ssh协议的开源实现,CentOS默认安装  
dropbear:另一个开源实现 
SSH协议版本 
v1:基于CRC-32做MAC,不安全;man-in-middle  
v2:双方主机协议选择安全的MAC方式  
基于DH算法做密钥交换,基于RSA或DSA实现身份认证 
两种方式的用户登录认证:  
基于password  
基于key 
-----------------------------------------------------------
ssh服务登陆验证

一、基于用户名口令登陆的验证:

cat /root/.ssh/known_hosts
此文件记录了曾经连接过的主机的公钥,所以ssh服务,可以通过此公钥来判断,它连接的主机是否被冒充! 

主机的公钥路径:
cat /etc/ssh/ssh_host_rsa_key.pub

如果我非要冒充咋办?
当用ssh 172.20.0.2 去连接对方主机的时,会问yes/no? 当输入yes/no的时候,会将对方主机的公钥复制下来!
当再次链接的时候,它就不会再问yes/no,为什么?
当第二次连接的时候,它会要求对方发一个指令过来,验证对方是不是旧的机器
对方会用自己的私钥签名一个数据发过来
如果我能用对方的公钥解开,那么对方就是合法的
如果我不能解开,那么证明公钥和私钥对不上号,那么对方就不是原来的机器了
如果我们要冒充,就得拿到对方得私钥

主机得私钥路径:
cat /etc/ssh/ssh_host_rsa_key

ssh -v 172.20.0.2  # -v 可以查看连接得过程
--------------------------------------------------------------------
二、ssh服务基于key验证登陆

ssh-keygen -t rsa  #172.20.0.1
ssh-copy-id -i id_rsa.pub [email protected]  #默认就是root的家目录,默认拷贝私钥
scp /etc/fstab [email protected]:/root/
ssh [email protected] 'id'
# 远程管理主机,批量执行命令

vim ip.txt
172.20.0.2
172.20.0.3
172.20.0.4

vim f1.sh
#!/bin/bash
hostname

for iP in `cat ip.txt`;do scp f1.sh $ip:/data/ ;done  # 拷贝文件
for iP in `cat ip.txt`;do scp $ip "/data/f1.sh"       # 执行脚本命令
-----------------------------------------------------------
多台机器基于key验证,互相不用输密码

方法一:
第一步:每台机器都执行以下俩个命令
ssh-keygen  # 交互式命令,选择密钥保存的路径,可以选择给私钥加密
ssh-copy-id 172.20.0.1

第二步,在主机172.20.0.1执行以下命令
scp /root/.ssh/authorized_keys 172.20.0.2:/root/.ssh/
scp /root/.ssh/authorized_keys 172.20.0.3:/root/.ssh/
scp /root/.ssh/authorized_keys 172.20.0.4:/root/.ssh/

方法二:
所有人共有一把公钥和私钥
ssh-keygen
ssh-copy-id 172.20.0.1
scp -pr /root/.ssh 172.20.0.2:/root/   # -p 保留权限 -r 目录递归
scp -pr /root/.ssh 172.20.0.3:/root/
scp -pr /root/.ssh 172.20.0.4:/root/
 
重设私钥口令:
ssh-keygen -p
Enter file in which the key is (/root/.ssh/id_rsa): 
Enter new passphrase (empty for no passphrase): 
Enter same passphrase again: 

启用代理,不用输口令:  
ssh-agent bash      #  代理程序需要每次手动开启,退出登陆失效
口令托管:
ssh-add
-----------------------------------------------------------
scp
scp -pr ./  172.20.0.2:/temp
-C: 压缩数据流  
-r: 递归复制  
-p: 保持原文件的属性信息  
-q: 静默模式  
-P PORT: 指明remote host的监听的端口

rsync 只复制不同的而文件
rsync -av ./  172.20.0.2:/temp #复制远程主机的目录和目录下的文件到当前目录下
rsync -av ./  172.20.0.2:/temp #复制远程主机的目录下的文件到当前目录下
-v 显示详细过程
-r 递归复制目录树
-p 保留权限
-t 保留时间戳
-g 保留组信息 
-o 保留所有者信息 
-l  将软链接文件本身进行复制(默认) 
-L 将软链接文件指向的文件复制 
-a 存档,相当于–rlptgoD,但不保留ACL(-A)和SELinux属性(-X) 

sftp
利用ssh服务实现安全的文件上传和下载 
使用ls cd mkdir rmdir pwd get put等指令,
可用?或help获取帮助信息  
sftp 172.20.0.2
sftp> help

pssh 批量执行命令
pssh -H 172.20.0.2 -i 'hostname' # -H 执行单个的ip
vim ./ip.txt
172.168.190.1
172.168.190.2
172.168.190.3
pssh -h ./ip.txt -i 'hostname' # -i 每个服务器内部处理信息输出
pssh -h ./ip.txt -o /data/ 'hostname' # -o 把标准输出信息文件存放在/data/目录下,并以主机ip命名

当不支持ssh的key认证时,通过 -A选项,使用密码认证批量执行指令 
pssh -H [email protected]  -A -i  hostname 
--version:查看版本
-h:主机文件列表,内容格式”[user@]host[:port]”
-H:主机字符串,内容格式”[user@]host[:port]”
-l:登录使用的用户名
-p:并发的线程数
-o:输出的文件目录
-e:错误输入文件
-t:TIMEOUT超时时间设置,0无限制
-O:SSH的选项
-v:详细模式
-A:手动输入密码模式
-x:额外的命令行参数使用空白符号,引号,反斜线处理
-X:额外的命令行参数,单个参数模式,同-x
-i:每个服务器内部处理信息输出
-P:打印出服务器返回信息

pscp.pssh
功能是将本地文件批量复制到远程主机 
pscp [-vAr] [-h hosts_file] [-H [user@]host[:port]] [-l user] [-p par] [-o outdir] [-e errdir] [-t timeout] [-O options] [-x args] [-X arg] local remote
Pscp-pssh选项 
-v 显示复制过程 
-a 复制过程中保留常规属性 
-r 递归复制目录
将本地curl.sh复制到/app/目录 
pscp.pssh -H 172.20.0.2 /root/test/curl.sh /app/
pscp.pssh -h ip.txt  /root/test/curl.sh /app/
将本地多个文件批量复制到/app/目录
pscp.pssh -H 172.20.0.2  /root/f1.sh /root/f2.sh /app/ 
将本地目录批量复制到/app/目录
pscp.pssh -H 172.20.0.2  -r /root/test/ /app/

pslurp.pssh
功能是将远程主机的文件批量复制到本地
pslurp [-vAr] [-h  hosts_file] [-H [user@]host[:port]] [-l user] [-p par][-o outdir] [-e errdir] [-t timeout] [-O options] [-x args] [-X arg] [-L localdir] remote local(本地名) 
Pslurp-pssh选项 
-L 指定从远程主机下载到本机的存储的目录,local是下载到本地后的名称 
-r 递归复制目录
批量下载目标服务器的passwd文件至/app下,并更名为user 
pslurp -H 172.20.0.1 -L /app/ /etc/passwd user
pslurp -h ./ip.txt -L /app/ /etc/passwd user
-----------------------------------------------------------
ssh端口转发

一、本地转发
企业内部有一个希望被外界访问服务器,但服务器是一个不安全协议服务器,比如:telnet-server smtp协议邮件 http协议
直接让外部访问很不安全,考虑可以借助于ssh的功能:
前端准备一个ssh-server服务器;互联网用户先连到这里,通过它再连到telnet-server
由于走的是ssh协议,所以数据是加密的 
步骤:
利用ssh的隧道功能,把telnet不安全的流量封装到ssh(telnet),用ssh的加密来保障telnet不安全的流量;
数据到ssh-server后,再解封装成为普通的telnet流量,再发送到telnet-server
# 局域网中,公司内部通常认为是安全的

准备工作:
iptables -A INPUT -s ip -j REJECT  # 把外部主机client扔进防火墙,防止它与telnet-server直连
yum install telnet-server
systemctl start telnet.socket
yum install telnet
ss -ntl
ss -nt

ssh -L localport:remotehost:remotehostport sshserver
       # 本机端口 远程主机ip  远程主机的端口   ssh ip
       # 确保本机端口没被使用 
-f 后台启用
-N 不打开远程shell
-g 启用网关功能

ssh -L 9527:telnetsrv:23 -Nf sshsrv  # -Nf 后台启用且不登录ssh-server
# 此命令是在企业外部的客户端执行的
telnet 127.0.0.1 9527  # 互联网的电脑连接本机的9527端口
当访问本机的9527的端口时,被加密后转发到sshsrv的ssh服务,再解密被转发到telnetsrv:23
data<->localhost:9527<->localhost:XXXXX<->sshsrv:22<->sshsrv:YYYYY<->telnetsrv:23

二、远程转发
企业内部的分支机构的员工基于开发目的想连接企业内部的服务器telnet-sever,但由于防火墙策略,他没法直接连接;
步骤:
前提:防火墙没有禁止企业内部的机器连接外部的服务器
企业内部的机器充当:ssh-client
企业外部的机器充当:ssh-server # 它也会开启一个9527端口

ssh -R sshserverport:remotehost:remotehostport  sshserver
# 此命令实在企业内部的服务器:ssh-client上执行的
示例:
ssh -R 9527:telnetsrv:23 -N  sshsrv
telnet 127.0.0.1 9527 # 互联网电脑连接本机的9527端口 
让sshsrv侦听9527端口的访问,如有访问,就加密后通过ssh服务转发请求到本机ssh客户端,再由本机解密后转发到telnetsrv:23
Data<->sshsrv:9527<->sshsrv:22<->localhost:XXXXX<->localhost:YYYYY<->telnetsrv:23 

三、动态端口转发
当用firefox访问internet时,本机的1080端口做为代理服务器,firefox的访问
请求被转发到sshserver上,由sshserver替之访问internet     
ssh -D 1080 root@sshserver     
在本机firefox设置代理socket proxy:127.0.0.1:1080     
curl  --socks5 127.0.0.1:1080  http://www.qq.com  #命令行方式设置

步骤:
google服务器:
yum install httpd
systemctl start httpd
echo www.google.com > /var/www/html/index.html

proy代理服务器:

本机:
ssh -D 1080 root@ip  # ip:是代理服务器的ip
配置浏览器就可以通过代理服务器上网了
图形界面:
首先打开浏览器
浏览器设置:Preferences
网络连接设置:Network
Connection----------------Settings
Manual proxy configuration
SOCKS Host:127.0.0.1 Port:1080
SOCKS v5
-----------------------------------------------------------
ssh服务器

配置文件:/etc/ssh/sshd_config
端口号:Port 22   # 生产中默认22,可以改成非标准端口,比如:9527
监听地址:ListenAddress 192.168.190.4   # 基于安全考虑一般只绑定内网ip
                       # 默认 0.0.0.0 任何人都可以访问
登录时长:LoginGraceTime 2m  # 2分钟不登录就自动断开
PermitRootLogin yes  # 是否允许root账户登陆,生产中建议no,用普通用户登陆,然后用su切换比较安全
StrictModes yes   #检查.ssh/文件的所有者,权限等
MaxAuthTries   6    # 最大的验证次数,实际只有一半:3次  man sshd_config  /MaxAuthTries
MaxSessions  10  #同一个连接最大会话,一个会话最多复制10次
PubkeyAuthentication yes  # 基于key验证
PermitEmptyPasswords no
PasswordAuthentication yes  # 基于用户名和密码的验证
GatewayPorts no 
ClientAliveInterval:30  # 单位:秒  #连上后,如果有30秒不动的情况,自动断开;0表示不断开
ClientAliveCountMax:3  # 默认3  # 配合ClientAliveInterval使用,提醒3次,然后才断开;
UseDNS yes   #是否反向解析成名字,如果没有配DNS的话,会很慢,建议设置成no
GSSAPIAuthentication yes  # 提高速度可改为no 
MaxStartups 10:30:100  # 未认证连接最大值,默认值10;10个以上拒绝30%;100个以上全部断开,变相限制并发连接数过多
Banner /path/file  # ssh 登陆警告语,提示信息
限制可登录用户的办法:   
AllowUsers user1 user2 user3   # 白名单
DenyUsers   # 黑名单,黑名单优先生效
AllowGroups   
DenyGroups 
利用防火墙设置ssh访问策略:
iptables -A INPUT -s 192.168.190.0/24 -j ACCEPT  # 只内网这个网段的才能访问

此服务基于以下两个软件包提供服务的:
rpm -qi openssh 
rpm -qi openssh-sever
-----------------------------------------------------------
sudo
配置文件: /etc/sudoers  /etc/sudores.d
时间戳文件: /var/db/sudo  # 5分钟之内不需要重复输入口令
日志文件: /var/log/secure
配置文件支持使用通配符glob:  
?:任意单一字符  
* :匹配任意长度字符  
[wxc]:匹配其中一个字符  
[!wxc]:除了这三个字符的其它字符  
\x : 转义    
[[alpha]] :字母  示例: /bin/ls [[alpha]]*
配置文件规则有两类;  
1、别名定义:不是必须的  
2、授权规则:必须的

授权规则格式:用户 登入主机=(代表用户) 命令
示例: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 

sudo别名和示例:
别名有四种类型: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

sudo命令 
ls -l /usr/bin/sudo 
sudo –i –u wang 切换身份 
sudo [-u user] COMMAND   
-V 显示版本信息等配置信息  
-u user  默认为root  
-l,ll 列出用户在主机上可用的和被禁止的命令  
-v 再延长密码有效期限5分钟,更新时间戳  
-k 清除时间戳(1970-01-01),下次需要重新输密码  
-K 与-k类似,还要删除时间戳文件  
-b 在后台执行指令 
-p 改变询问密码的提示符号    
示例:-p "password on %h for user %p:"

vim /etc/sudoers
# user   Machine=(user)  Commands  授权谁在哪个主机上代表哪个用户执行什么操作
root ALL=(ALL)    ALL  # 授权root在任何主机上代表任何用户执行任何操作

export EDITOR=vim  # 让visudo调用vim,默认调用vi
visudo # 编辑配置文件
wang  192.168.190.4=(root)  /bin/mount /dev/cdrom /mnt/
授权wang用户,在主机192.168.190.4上,代表root,执行关盘挂载操作
sudo mount /dev/cdrom /mnt/   # 操作的命令必须与配置文件里写的一致


%wheel  ALL=(ALL)    ALL  # wheel组的人可以任何主机代表任何人执行任何操作
# 权限太大,一般用不到,建议注释掉
usermod -aG "wheel" wang   # 把wheel组作为wang的附加组
gpasswd  -d wang wheel  # 把wang移除附加组wheel

如果root账户不是管理员,wang是管理员了;但是没用,sudo已经默认授权了root账户
sudo -u wang  vi /etc/passwd  # 修改root用户的UID

如果有两人a,b用户,a有权限,b没有权限;可以让b用户通过sudo获取a用户的权限
cd /etc/sudores.d/
vi b
b ALL=(a)  ALL  # b用户,在任何主机代表a用户,执行任何操作
su - b
sudo -u a cat /data/file1
sudo # 默认代表root;所以要指定代表谁:-u a 指定带表a用户
visudo -f /etc/sudoers.d/b 
visudo -c  # -c 语法检查,配置文件的权限应为440
7.0  时间戳路径:/var/run/sudo/ts
6.0  时间戳路径:/var/db/sudo

visudo -f /etc/sudoers.d/wang
wang ALL=(ALL) /bin/cat /var/log/messages*

sudoedit # 特殊授权,授权编辑文件/etc/sudoers,这种授权慎重
/usr/bin/sudoedit
wang ALL=(ALL)   sudoedit

授权wang用户,可以读取/var/log/messages开头的文件
wang   192.168.30.7=(root)  /bin/cat /var/log/messages*, !/bin/cat /var/log/message* *   (centos6)
wang   192.168.30.7=(root)  /usr/bin/cat /var/log/messages*, !/usr/bin/cat /var/log/message* *   (centos7)
-----------------------------------------------------------
TCP_Wrappers
配置文件:/etc/hosts.allow, /etc/hosts.deny 
帮助参考:man 5 hosts_access,man 5 hosts_options 
检查顺序:hosts.allow,hosts.deny(默认允许)    
注意:一旦前面规则匹配,直接生效,将不再继续 
基本语法: 
daemon_list@host: client_list  [ :options :option… ] 
Daemon_list@host格式 
单个应用程序的二进制文件名,而非服务名,例如vsftpd 
以逗号或空格分隔的应用程序文件名列表,如:sshd,vsftpd 
ALL表示所有接受tcp_wrapper控制的服务程序 
主机有多个IP,可用@hostIP来实现控制 如:[email protected]

客户端Client_list格式 
以逗号或空格分隔的客户端列表 
基于IP地址:192.168.10.1   192.168.1. (网段模式,批量ip都可以拒绝服务)
基于主机名: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 
# LOCAL 匹配任意主机名,但名字里不带点的
EXCEPT用法: 示例:vsftpd: 172.16. EXCEPT 172.16.100.0/24 EXCEPT 172.16.100.1 
# except 排除

示例:只允许192.168.1.0/24的主机访问sshd    
/etc/hosts.allow     sshd: 192.168.1.             
/etc/hosts.deny        sshd:ALL  
示例:只允许192.168.1.0/24的主机访问telnet和vsftpd服务   
/etc/hosts.allow    vsftpd,in.telnetd: 192.168.1.   
/etc/host.deny    vsftpd,in.telnetd:  ALL

[:options]选项: 
帮助:man 5 hosts_options  
deny 主要用在/etc/hosts.allow定义“拒绝”规则   
如:vsftpd: 172.16. :deny  
allow 主要用在/etc/hosts.deny定义“允许”规则   
如:vsftpd:172.16. :allow  
spawn 启动一个外部程序完成执行的操作   
twist  实际动作是拒绝访问,使用指定的操作替换当前服务,标准I/O和ERROR 发送到客户端,默认至/dev/null 
测试工具:  tcpdmatch [-d] daemon[@host] client  
-d 测试当前目录下的hosts.allow和hosts.deny

示例 
sshd: ALL :spawn echo "$(date +%%F) login  attempt  from  %c  to  %s,%d" >>/var/log/sshd.log 
说明: 
在/etc/hosts.allow中添加,允许登录,并记录日志 
在/etc/hosts.deny中添加,拒绝登录,并记录日志 
%c 客户端信息   
%s 服务器端信息 
%d 服务名   
%p 守护进程的PID 
%% 表示% 
vsftpd: 172.16.  :twist /bin/echo “connection prohibited”

libwrap.so # 只有调用了这个库文件,才能被TCP_Wrappers控制
判断服务程序是否能够由tcp_wrapper进行访问控制的方法:  
ldd  /PATH/TO/PROGRAM|grep libwrap.so  
strings PATH/TO/PROGRAM|grep libwrap.so

which xinetd
ldd /usr/sbin/xinted |grep libwrap.so
那么centos6,上的非独立服务都可以通过libwrap控制

sshd:192.168.30.7  # 直接生效;拒绝192.168.30.7 ssh连接;默认所有ip都拒绝
[email protected]:192.168.30.7  # 在192.168.190.6上跑的sshd服务是拒绝的,但是此主机上的其它IP不拒绝
sshd,in.telentd:192.168.30.7  # 同时拒绝192.168.190.30.7的sshd和telnetd访问
vim /etc/hosts.deny
sshd:ALL  # 只要前面没有允许,后面全都拒绝,用作兜底用
vim /etc/hosts.allow
sshd:192.168.30. EXCEPT 192.168.30.7 :deny  # 此网段除了192.168.30.7全都拒绝
vim /etc/hosts.deny
sshd:192.168.30. EXCEPT 192.168.30.7 :allow  # 在黑名单里除了192.168.30.7其他都允许访问,但同时并没有拒绝192.168.30.7的访问
如果白名单和黑名单都为空,默认是允许访问的
白名单优先级高;hosts.allow

vim /etc/hosts.allow
sshd:ALL:spawn echo AT `date +'%%F %%T'` login from client %c to sever %s >> /data/sshd.log
# 当有人ssh连接我的时候,记录下日志
sshd:ALL:spawn echo AT `date +'%%F %%T'` login from client\:%c to sever\:%s >> /data/sshd.log
 如果有冒号的话,必须加斜线转义 "\:"

sshd:ALL:twist /bin/echo "go away"
twist: # 后面跟命令,实际是拒绝访问,去调用或者执行其后跟的命令

sshd -v 192.168.30.6   # -v可以看到提示信息
hosts.allow 和 hosts.deny # 可以实现简单的防火墙功能
局限性:必须依赖于是否调用对应的库libwrap.so,所以centos7,由于systemd没有调用对应的库libwrap.so,多以好多服务都不支持了,比如:telent
注意:别设错了,不然自己都连不上
测试:  # 测试某个ip sshd访问的时候是否允许还是拒绝
tcpdmatch -d sshd 192.168.30.17  # -d 当前目录   测试192.168.30.17  sshd 访问我的时候到底是允许还是拒绝
client:   address  192.168.30.17
server:   process  sshd
access:   denied # 拒绝
-----------------------------------------------------------
PAM认证机制
它提供了对所有服务进行认证的中央机制,适用于login,远程登录(telnet,rlogin,fsh,ftp,点对点协议(PPP)),su等应用程序中。
系统管理员通过PAM配置文件来制定不同应用程序的不同认证策略;
应用程序开发者通过在服务程序中使用PAM,API(pam_xxxx( ))来实现对认证方法的调用;
而PAM服务模块的开发者则利用PAM 
SPI来编写模块(主要是引出一些函数 pam_sm_xxxx( )供PAM接口库调用),将不同的认证机制加入到系统中;
PAM接口库(libpam)则读取配置文件,将应用程序和相应的PAM服务模块联系起来

PAM相关文件 
模块文件目录:/lib64/security/*.so  
环境相关的设置:/etc/security/ 
主配置文件:/etc/pam.conf,默认不存在 
为每种应用模块提供一个专用的配置文件:/etc/pam.d/APP_NAME 
注意:如/etc/pam.d存在,/etc/pam.conf将失效

PAM认证一般遵循这样的顺序:Service(服务)→PAM(配置文件)→pam_*.so 
PAM认证首先要确定那一项服务,然后加载相应的PAM的配置文件(位于 /etc/pam.d下),最后调用认证文件(位于/lib/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认证机制
通用配置文件/etc/pam.conf格式   application  type  control  module-path  arguments 
专用配置文件/etc/pam.d/*格式  type control  module-path  arguments 
说明: 
服务名(application)telnet、login、ftp等,服务名字“OTHER”代表所有没有在该文件中明确配置的其它服务 
模块类型(module-type) 
control,PAM库该如何处理与该服务相关的PAM模块的成功或失败情况 
module-path用来指明本模块对应的程序文件的路径名 
Arguments用来传递给该模块的参数 

PAM认证机制 
模块类型(module-type) 
Auth账号的认证和授权 
Account与账号管理相关的非认证类的功能,如:用来限制/允许用户对某个服务的访问时间,当前有效的系统资源(最多可以有多少个用户),限制用户的位置(例如:root用户只能从控制台登录) 
Password用户修改密码时密码复杂度检查机制等功能 
Session用户获取到服务之前或使用服务完成之后需要进行一些附加的操作,如:记录打开/关闭数据的信息,监视目录等 
-type表示因为缺失而不能加载的模块将不记录到系统日志,对于那些不总是安装在系统上的模块有用 

PAM认证机制 
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目录下的模块可使用相对路径   
如:pam_shells.so、pam_limits.so 
绝对路径: 
模块通过读取配置文件完成用户对系统资源的使用控制  
/etc/security/*.conf 
注意:修改PAM配置文件将马上生效 
建议:编辑pam规则时,保持至少打开一个root会话,以防止root身份验证错误 

Arguments 用来传递给该模块的参数

PAM模块示例 
模块:pam_shells  
功能:检查有效shell 
man pam_shells 
示例:不允许使用/bin/csh的用户本地登录 
vim /etc/pam.d/login     
auth required pam_shells.so  
vim /etc/shells    
去掉 /bin/csh 
useradd –s /bin/csh testuser 
testuser将不可登录 
tail /var/log/secure 

PAM模块示例 
模块:pam_securetty.so 
功能:只允许root用户在/etc/securetty列出的安全终端上登陆 
示例:允许root在telnet登陆 
vi /etc/pam.d/remote 
#auth required pam_securetty.so #将这一行加上注释 
 
或者/etc/securetty文件中加入  pts/0,pts/1…pts/n 
 
PAM模块示例 
模块:pam_nologin.so 
功能: 
如果/etc/nologin文件存在,将导致非root用户不能登陆 
如果用户shell是/sbin/nologin时,当该用户登陆时,会显示/etc/nologin文件内容,并拒绝登陆 
 
PAM模块示例 
模块:pam_limits.so 
功能:在用户级别实现对其可使用的资源的限制,例如:可打开的文件数量,可运行的进程数量,可用内存空间
修改限制的实现方式: 
(1)ulimit命令,立即生效,但无法保存  
-n   最多的打开的文件描述符个数  
-u   最大用户进程数  
-S   使用 soft(软)资源限制  
-H   使用 hard(硬)资源限制 
(2) 配置文件:/etc/security/limits.conf, /etc/security/limits.d/*.conf 

配置文件:每行一个定义;        

pam_limits.so 
应用于哪些对象 
Username 单个用户 
@group 组内所有用户 
*  所有用户 
限制的类型 
Soft 软限制,普通用户自己可以修改 
Hard 硬限制,由root用户设定,且通过kernel强制生效 
-  二者同时限定 
限制的资源 
nofile 所能够同时打开的最大文件数量,默认为1024 
nproc 所能够同时运行的进程的最大数量,默认为1024 
指定具体值 
示例:pam_limits.so 
限制用户最多打开的文件数和运行进程数 
/etc/pam.d/system-auth  
session    required   pam_limits.so 
vim /etc/security/limits.conf
apache  –  nofile 10240 apache用户可打开10240个文件 
student  hard nproc 20 不能运行超过20个进程

你可能感兴趣的:(加密与安全)