SSH是
Secure Shell Protocol
的简写,由IETF网络工做小组(Network working Group
)指定;在进行数据传输以前,SSH先对联机数据包经过加密技术进行加密处理,加密后在进行数据传输。确保了传递的数据安全.nodeSSH是专为
远程登陆会话
和其余网络服务提供的安全性协议
。利用SSH协议能够有效的放置远程管理过程当中的信息泄露问题,在当前的生产环境运维工做中,绝大多数企业广泛采用SSH协议服务来代替传统的不安全的远程联机服务软件,如telnet
(23端口,非加密)linux在默认状态下,SSH服务主要提供了两个服务功能,一个是提供相似Telnet远程联机服务器的服务,即上面提到的SSH服务;另外一个是相似FTP服务的
sftp-server
,借助SSH协议来传输数据的,提供更安全的SFTP服务(vsftp,proftp
)nginxssh 客户端(ssh命令)还包含一个远程安全拷贝命令scp,也是经过ssh协议工做.git
小结
算法
# 一、SSH是安全的加密协议,用于远程链接linux服务器 # 二、SSH默认端口是22,安全协议版本SSH2,除了2以外还有SSH1(漏洞) # 三、SSH服务端主要包含两个服务协议SSH远程链接,SFTP服务 # 四、Linux SSH客户端包含ssh远程链接命令,以及远程拷贝scp命令
# SSH服务由服务端软件OpenSSH (openssl) # 客户端(常见的有SSH(linux),SecureCRT,Putty,Xshell)组成 # SSH服务默认使用22端口提供服务,它有两个不兼容的SSH协议版本分别是1.x和2.x rpm -qa openssh openssh-6.6.1p1-31.el7.x86_64 # 远程链接安装包 rpm -qa openssl openssl-1.0.2k-19.el7.x86_64 # 加密安装包
OpenSSH同时支持SSH
1.x
和2.x
用SSH 2.x的客户端程序不能连接到SSH1.x的服务程序上shellSSH服务是一个
守护进程
(daemon),他在后台运行并响应来自客户端的链接请求,SSH服务端的进程名为sshd
,负责实时监听远程
SSH客户端的链接请求,并进行处理,通常包括公共密钥认证、密钥交换、对称密钥加密和非安全链接等。vimSSH客户端包含
ssh
以及像scp
(远程拷贝)slogin
(远程登陆)sftp
(安全FTP文件传输)等应用程序
centos
SSH
的工做机制大体是本地的ssh客户端发送一个链接请求到远程的ssh服务器,服务器检查链接的客户端发送的数据包和ip地址,若是确认合法
,就会发送密钥给SSH的客户端,此时,客户端本地再将密钥发回给服务端,本身创建链接。SSH1.x和SSH2.x在链接协议上有一些安全方面
的差别安全
SSH加密技术是将人类能够看得懂的数据,经过必定的特殊的程序算法,把这些数据变成杂乱的无心义的信息,而后,经过网络进行传输,二挡到了目的地后,在经过对应的解密算法,把传过来的加密的数据信息解密成加密前的可读取的正常数据。所以,当数据在互联网上传输时即便被有心的黑客监听窃取了,也很难获取到真正须要的数据服务器
网络上的数据包加密技术通常是经过所谓的一对
公钥
和私钥
(Public key and Pivate key)组合撑的密钥对进行加密
与解密
操做。
每一台SSH服务器主机均可以使用RSA加密方式来产生一个
1024-bit
的RSA Key 这个RSA的加密方式就是用来产生公钥和私钥的算法之一。当服务
启
动时,就会产生一个768 bit的临时公钥存放在Server
中
grep ServerKey /etc/ssh/sshd_config #ServerKeyBits 1024
在
SSH 1.x
的联机过程当中,当Server接收Clinet端
的Private Key
后,就再也不针对该次联机的Key pair进行检验。若此时有而已黑客对该联机key pair
插入而已的程序代码时,因为服务端你不会在检验联机的正确性,所以可能会接收该程序代码,从而致使系统被黑.为了改正这个缺点,SSH version2多加了一个确认联机
正确
性的Diffie-Hellman机制
在每次数据传输中,Server都会以该机制检查数据的来源是否正确,这样,能够避免联机过程当中被插入而已程序代码的问题
另外,SSH2同时支持
RSA
和DSA
密钥,可是SSH1仅支持RSA密钥因为SSH1协议自己存在较大问题,建议使用SSH2的
联机模式
当Client端SSH联机请求传送过来时,Server就会将这个768-bit的公钥传给Client端
此时Client会将此公钥与先前存储的公钥进行对比,看是否一致,判断标准是Client端联机用户目录下
~/.ssh/known_hosts
文件的内容(linux-客户端
)
不加用户默认是
root 不加
-p 指定端口 默认是
22`
ssh -p22222 root@39.108.140.0 The authenticity of host '39.108.140.0 (39.108.140.0)' can't be established. ECDSA key fingerprint is 17:33:ef:9b:05:b3:69:d3:20:48:49:e1:28:9b:7c:c8. Are you sure you want to continue connecting (yes/no)? # 链接密码文件存放路径 cat /root/.ssh/known_hosts 121.36.43.223 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDgQ7H6KDIPTzOklwMSOxgFI0Xc3rgvwPnCLIuXIuzaCfYQBouM6owCArpj2CXEyk40lSn96ktW1vETbP1JmjEY= # 第一次SH链接的时候,本地会产生一个密钥文件~/.ssh/known_hosts
# 一、用密钥登陆,不用密码登陆 # 二、牤牛阵法:解决SSH安全问题 # 三、防火墙封闭SSH,指定源限制(局域网,信任公网) # 四、开启SSH只监听本地内网IP(ListenAddress 10.0.0.8) # 五、尽可能不给服务器外网IP
scp的基本语法使用:
scp -sercure copy
(remote file copy program
)
推push
scp -P22 -rp /root/test.txt root@39.108.140.0:/root/
拉pull
scp -p22 -rp root@39.108.140.0:/root/test.txt ./ # -P 指定端口,默认22,可忽略 # -p 表示拷贝先后保持文件或目录属性 # -r 递归,表示拷贝目录 # -l 限制速度 # 小结 # 一、scp是加密的远程拷贝,而cp仅为本地拷贝 # 二、能够把数据从一台机器推送到另外一台机器,也能够从其余服务器把数据拉回到本地执行命令的服务器 # 三、每次都是全量完成拷贝,所以效率不高,适合第一次拷贝用,若是须要增量拷贝,用rsync
# 1. rz,sz(lrzsz) # 2. winscp WinSCP-v4.0.5 基于SSH,sftp # 3. SFX(xshell) 4) SFTP 基于SSH加密传输 # 4. samba,http,ftp,nfs # FTP工具:vsftp、proftpd、SFTP # linux sftp客户端登陆sftp服务方法 # 登陆FTP的方法就是 sftp -oPort=22 root@39.108.140.0: sftp> put test.txt Uploading test.txt to /root/test.txt test.txt 100% 0 0.0KB/s 00:00 sftp> ls test.txt test.txt
基于口令的安全验证的方式就是你们如今一直在用的,只要知道服务器的SSH
端口号
和口令
,应服务器的IP
及开放的端口
,默认都为22
,就能够经过ssh客户端登陆到主机,此时联机过程当中全部传输都是加密
的
基于密钥的安全验证方式是指,须要依靠
密钥
,也就是必须事先创建一对密钥
,而后把公用密钥(Publickey
)放在须要访问的目标服务器上,另外,个还须要把私有密钥
(Private key)放到SSH客户端或对应的客户端服务器上此时,若是要想链接到这个带有
公用密钥
的SSH服务器,客户端SSH软件或者客户端端服务就会想SSH服务端发出请求,请求用联机用户密钥进行安全链接。SSH服务会在收到请求以后,会如今改SSH服务器上链接的用户的加密路下 放上去的对应用户密钥,而后把它和链接的SSH客户端发来进行密钥,若是两个密钥一直SSH服务就会用公用密钥加密“质询
”(challenge)并把它发送给SSH客户端
修改SSH服务的运行参数,是经过修改配置文件
/etc/ssh/sshd_config
实现的通常来讲SSH服务使用默认的配置已经够很好的工做,若是对安全要求不高,仅仅提供SSH服务的状况不须要修改任何配置
sshd_config配置文件说明:
cp /etc/ssh/sshd_config{,.bak} vim /etc/ssh/sshd_config Port 52113 # ssh链接端口默认为22,修改端口号能够提升级别 PermitRootLogin no # 禁止root远程登陆 PermitEmptyPasswords no # 禁止空密码的用户登陆 UseDNS no # 不使用DNS进行解析 GSSAPIAuthentication no # 会致使SSH链接慢 # ssh远程链接服务满解决方法 sed -ri '13 iPort 52113\nPermitRootLogin no\nPermitEmptyPasswords no\nUseDNS no\nGSSAPIAuthentication no' /etc/ssh/sshd_config
sed -i '13 iPort 52113\nPermitRootLogin no \n 禁止root登陆 PermitEmptyPasswords no \n # 禁止使用密码 UseDNS no\n # 禁用DNS GSSAPIAuthentication no' # 禁用GSSAPI sshd_config
cat >>/etc/hosts <<EOF 39.108.140.0 blog 149.129.38.117 blog2 121.36.43.223 huawei 49.233.69.195 tenxun 116.196.83.113 jd EOF useradd oldboy echo "123456"|passwd --stdin youmen su – youmen ssh-keygen -t dsa //非交互式建立密钥 #ssh-keygen是生产密钥的工具 -t参数是指定密钥的类型,这里是创建dsa类型密钥 #也可使用ssh-keygen -t rsa来创建rsa类型密钥 #RSA与DSA加密算法的区别 #RSA:是一种加密算法(PS:RSA也能够进行数字签名的)它的简写的来由是RonRivest、Adi Shamir和LeonAdleman 这三个姓氏加在一块儿就是RSA #DSA就是数字签名算法的英文全称的简写,即Digital Sigenature Algorithm=DSA # RSA既能够进行加密,也能够进行数字签名实现认证,而DSA只能用于数字签名
yum -y install sshpass ssh-keygen -t rsa -P '' -f ~/.ssh/id_dsa &>/dev/null sshpass -p youmen ssh -o StrictHostKeyChecking=no root@192.168.43.159 # 一键生成密钥对 ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa >/dev/null 2>&1 ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.43.159 # -i 表明要发送的文件 # ssh-copy-id 只能发公钥,不能发私钥 # 1 免密码登陆是单向的,方向从私钥(钥匙)==》公钥(锁) # 2 SSH免密码登陆基于用户的,最好不要跨不一样的用户 # 3 ssh链接慢的问题解决
# 一、ssh优化和hosts解析 # 二、建立用户 # 三、生成密钥对 # 四、分发公钥到全部服务器 ssh-copy-id # 五、测试 远程链接ssh 远程执行命令ssh ifconfig # 远程拷贝文件scp rsync-e隧道模式
1. sudo提权实现没有权限用户拷贝
echo“youmenALL= NOPASSWD:/usr/bin/rsync ”>>/etc/sudoers visudo -c scp -P52113 hosts oldboy@192.168.43.159:~ # 最好发送到家目录下,直接发送到/下是没有权限 ssh -p22 -t youmen@192.168.43.159 sudo rsync ~/hosts /etc/hosts # 须要受权sudo权限
2. 使用suid实现没有权限用户拷贝
chmod u+s `which rsync` scp -P22 hosts oldboy@192.168.43.159:~ ssh -p22 youmen@192.168.43.159 rsync ~/hosts /etc/hosts
3. 使用root进行操做
# rsync使用 rsync -avz hosts -e ‘ssh -p 22’youmen@192.168.43.159:~ # 能够增量备份
cat view.sh #!/bin/sh for n in blog2 tenxun jd huawei do echo -n "====$n====" ssh -p 22 $n $1 done [root@nginx_test ~]# sh view.sh "cat /etc/redhat-release" ====blog2====CentOS Linux release 7.3.1611 (Core) ====tenxun====CentOS Linux release 7.6.1810 (Core) ====jd====CentOS Linux release 7.6.1810 (Core) ====huawei====CentOS Linux release 7.4.1708 (Core)
cat file.sh #!/bin/sh . /etc/init.d/functions if [ $# -ne 1 ];then echo "USAGE:/bin/sh $0 FILENAME" $ exit 1 fi for n in blog2 tenxun jd huawei do echo -n "====$n====" scp -P22 $1 $n: &>/dev/null if [ $? -eq 0 ];then action "dis $1 to $n" /bin/true else action "$n" /bin/false fi done sh file.sh /etc/hosts ====blog2====dis /etc/hosts to blog2 [ OK ] ====tenxun====dis /etc/hosts to tenxun [ OK ] ====jd====dis /etc/hosts to jd [ OK ] ====huawei====dis /etc/hosts to huawei [ OK ]
SSH会自动加密和解密全部SSH客户端与服务端之间的网络数据。可是,SSH还可以将其余TCP端口的网络数据通SSH连接来转发,而且自动提供了相应的加密及解密服务。这一过程也被叫作"隧道"(tunneling),这是由于SSH为其余TCP连接提供了一个安全的通道来进行传输而得名。例如,Telnet ,SMTP ,LDAP这些TCP应用均可以从中得益,避免了用户名,密码以及隐私信息的明文传输。而与此同时,若是工做环境许中的防火墙限制了一些网络端口的使用,可是容许SSH的链接,也可以将经过将TCP用端口转发来使用SSH进行通信。
# 1. 加密SSH Client端至SSH Server端之间的通信数据。 # 2. 突破防火墙的简直完成一些以前没法创建的TCP链接。
命令 -L localport:remotehost:remotehostport sshserver
说明
localport # 本机开启的端口号 remotehost # 最终链接机器的IP地址 remotehostport # 转发机器的端口号 sshserver # 转发机器的IP地址 # -L 本机端口 # -f 后台启用,能够在本机直接执行命令,无需另开新终端 # -N 不打开远程shell,处于等待状态,不跳到远程主机,还在主机上,只是搭好了隧道,桥搭好,不ssh上去 # -g 启用网关功能 # -R 服务端口 # 举例: ssh –L 9527:telnetsrv:23 -N sshsrv telnet 127.0.0.1 9527 # 当访问本机的9527的端口时,被加密后转发到sshsrv的ssh服务,再解密被转发到telnetsrv:23 data < >localhost:9527 < > localhost:XXXXX < > sshsrv:22 < > sshrv:yyyyy < > telnetsrv:23
背景:企业内部C服务器只容许telnet链接(23端口)访问,不容许外部直接访问,B服务器是一个ssh服务器;有一个用户须要从外部链接到企业内部的C服务器。
前提:防火墙容许22端口进来(或者企业内部有一个堡垒机,ssh -t经过堡垒机进去)。
原理: 数据一旦telnet之后,数据会发送到本机9527端口,再在本机开一个随机端口,充当ssh客户端,再把数据流量发送到22端口的ssh服务端,收到数据之后,解密数据,临时开一个随机端口充当客户端,再把流量发送到23端口telnet服务端
机器: blogA用户,huawei模拟B机器,tenxun模拟C机器
节点名 | IP | 软件版本 | 硬件 | 网络 | 说明 |
---|---|---|---|---|---|
CentOS7-A | 39.108.140.0 | 1C2G | 公有云 | 阿里云 | |
CentOS6-B | 121.36.43.223 | 1C2G | 公有云 | 华为云 | |
CentOS6-C | 49.233.69.195 | 1C2G | 公有云 | 腾讯云 |
# ssh协议里面封装了telnet,一旦A链接了B主机,当即使用telnet链接C主机,此过程能够突破防火墙的限制 # 实验 # A->C 访问被限制 # A-B->C 使用B主机做为跳板突破访问限制
C机器经过iptables拒绝A机器登陆
[root@C ~]# iptables -A INPUT -s 39.108.140.0 -j REJECT [root@C ~]# yum -y install telnet-server xinetd [root@C ~]# systemctl start telnet.socket [root@C ~]# systemctl start xinetd [root@C ~]# ss -tnl |grep 23 LISTEN 0 128 [::]:23 [::]:* # 此时咱们A机器是直接链接不上C机器的 [root@A ~]# ssh 49.233.69.195 ssh: connect to host 49.233.69.195 port 22: Connection refused # 开启端口转发(telnet隧道) [root@A ~]# ssh -L 10000:49.233.69.195:23 -Nf 121.36.43.223 # 经过本地9527端口访问centos6-1服务器IP地址使用telnet协议23端口,跳板机ip地址 # 隧道已经搭建好了,此时A主机能够经过telnet访问C主机 telnet 127.0.0.1 10000 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. Kernel 3.10.0-1062.9.1.el7.x86_64 on an x86_64 c login: youmen Password: Last login: Fri Jun 12 22:32:04 from centos-b [root@C ~]$ # 如何须要删除这个链接使用killall ssh便可 killall ssh # 删除搭建的桥 telnet 127.0.0.1 10000 Trying 127.0.0.1... telnet: connect to address 127.0.0.1: Connection refused
远程转发机制
# -R sshserverport:remotehost:remotehostportsshserver # 举例 ssh–R 9527:telnetsrv:23 –N sshsrv # 让sshsrv侦听9527端口的访问,若有访问,就加密后经过ssh服务转发请求到本机ssh客户端,再由本机解密后转发到telnetsrv:23 Data < > sshsrv:9527 < > sshsrv:22 < > localhost:XXXXX < > localhost:YYYYY< >telnetsrv:23 # 需求: # 在A(Centos7)上开启smtp服务(postfix),B(Centos6)作跳板,C(Centos6-1)客户端给Centos7发送邮件 # 流程解释 C-x->A (拒绝访问) C-B->A (经过远程代理,接受访问)
环境依然是上面三台机器,只是C服务器换成116.196.83.113 (JD)这台服务器
[root@A ~]# vim /etc/postfix/main.cf # inet_interfaces = localhost # 注释此行,不让接口直接绑定在127.0.0.1上 [root@A ~]# systemctl restart postfix [root@A ~]# ss -tnl |grep 25 LISTEN 0 100 *:25 *:* LISTEN 0 100 :::25 :::* [root@A ~]# yum -y install telnet-server [root@A ~]# systemctl start telnet.socket # 若是B上面有一些影响的防火墙规则就将它删掉 [root@B ~]# iptables -nL --line-number [root@B ~]# iptables -D INPUT 1 # 测试下C能不能telnet 25端口链接A [root@C ~]# 39.108.140.0 25 Trying 39.108.140.0... Connected to 39.108.140.0. Escape character is '^]'. 220 nginx_test.localdomain ESMTP Postfix # 设置防火墙策略,使A不接受C的一切请求 [root@A ~]# iptables -A INPUT -s 39.108.140.0 -j REJECT [root@C ~]# telnet 39.108.140.0 25 Trying 39.108.140.0... telnet: connect to address 39.108.140.0: Connection refused # 使用B远程转发,发送邮件到 [root@B ~]# ssh-copy-id root@116.196.83.113: # 使用B远程转发,发送邮件到A,最好免密,不然须要手动口令验证 [root@B ~]# ssh -R 50000:39.108.140.0:25 -fN 121.36.43.223 # 此时能够到C跳板机看到已经有端口在监听了 [root@C ~]# ss -tnl |grep 50000 LISTEN 0 128 127.0.0.1:50000 *:* [root@C ~]# telnet 127.0.0.1 5000 Trying 127.0.0.1... telnet: connect to address 127.0.0.1: Connection refused [root@zabbix ~]# telnet 127.0.0.1 50000 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. 220 nginx_test.localdomain ESMTP Postfix mail from:youmen@163.com 250 2.1.0 Ok
下载地址
http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/
# 记录sshd.pid路径 find / -name sshd.pid # 查看openssh现有版本 ssh -V # 使用rpm删除现有的openssh rpm -e --nodeps $(rpm -qa | grep openssh) # 删除旧的配置文件 rm -rf /etc/ssh/* # 安装openssl-devel yum -y install openssl-devel # 下载tar.gz包,配置编译,安装 wget http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-8.0p1.tar.gz # 编译并安装 tar xvf openssh-8.0p1.tar.gz cd openssh-8.0p1 ./configure --prefix=/usr/ --sysconfdir=/etc/ssh/ --with-ssl-dir=/etc/ssl --with-md5-passwords --mandir=/usr/share/man/ make && make install # 设置ssh服务开机自启动 # 复制启动文件至/etc/init.d/ cp -a contrib/redhat/sshd.init /etc/init.d/sshd # 编辑/etc/init.d/sshd文件, 将PID_FILE改成以前记下的sshd.pid路径 sed -i "s/PID_FILE=\/var\/run\/sshd.pid/PID_FILE=\/run\/sshd.pid/" /etc/init.d/sshd # 设置开机启动sshd chkconfig sshd on chkconfig --list sshd # 编辑/etc/ssh/sshd_config, 设置一些经常使用参数 sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/" /etc/ssh/sshd_config sed -i "s/#PubkeyAuthentication yes/PubkeyAuthentication yes/" /etc/ssh/sshd_config sed -i "s/#PasswordAuthentication yes/PasswordAuthentication yes/" /etc/ssh/sshd_config sed -i "s/#AllowTcpForwarding yes/AllowTcpForwarding yes/" /etc/ssh/sshd_config sed -i "s/#X11Forwarding no/X11Forwarding yes/" /etc/ssh/sshd_config sed -i "s/#PidFile \/var\/run\/sshd.pid/PidFile \/run\/sshd.pid/" /etc/ssh/sshd_config # 加入系统服务 cat > /usr/lib/systemd/system/sshd.service << EOF [Unit] Description=OpenSSH server daemon Documentation=man:sshd(8) man:sshd_config(5) #After=network.target sshd-keygen.service #Wants=sshd-keygen.service After=network.target [Service] ExecStart=/usr/sbin/sshd [Install] WantedBy=multi-user.target EOF # 启用sshd服务 systemctl enable sshd # 重启服务 systemctl restart sshd # 查看服务状态 systemctl status sshd # 验证 ssh -V OpenSSH_8.0p1, OpenSSL 1.0.2k-fips 26 Jan 2017
到/etc/motd里面编写内容,看我的爱好
[root@nginx_test ~]# cat /etc/motd /\/\ (_人|人_) /‥\ ミ(_Y_)ミ > < (/ \) _( )_ (_>―<_) # 关闭当前会话再登陆 /\/\ (_人|人_) /‥\ ミ(_Y_)ミ > < (/ \) _( )_ (_>―<_) [root@nginx_test ~]#
┴┬┴┬/ ̄\_/ ̄\ ┬┴┬┴▏ ▏▔▔▔▔\ ┴┬┴/\ / ﹨ ┬┴∕ / ) ┴┬▏ ● ▏ ┬┴▏ ▔█ ┴◢██◣ \___/ ┬█████◣ / ┴█████████████◣ ◢██████████████▆▄ █◤◢██◣◥█████████◤\ ◥◢████ ████████◤ \ ┴█████ ██████◤ ﹨ ┬│ │█████◤ ▏ ┴│ │ ▏ ┬ ∕ ∕ /▔▔▔\ ∕ ┴/___/﹨ ∕ ﹨ /\ ┬┴┬┴┬┴\ \ ﹨/ ﹨ ┴┬┴┬┴┬┴ \___\ ﹨/▔\﹨ ▔\ ▲△▲▲╓╥╥╥╥╥╥╥╥\ ∕ /▔﹨/▔﹨ **╠╬╬╬╬╬╬╬╬*﹨ / //