⑴ SSH 之远程登录
从客户端来看,SSH提供两种级别的安全验证。
对于第二种级别,你必须知道自己密匙的口令。但是,与第一种级别相比,第二种级别不需要在网络上传送口令。第二种级别不仅加密所有传送的数据,而且“中间人”这铅乎种攻击方式也是不可能的(因为他没有用户的私人密匙)。但是整个登录的过程可能需要10秒。
将本地用户生成的公钥推送至远程服务器后,远程主机将用户的公钥,保存在登录后的用户主目录的$HOME/.ssh/authorized_keys文件中。公钥就是一段字符串,只要把它追加在authorized_keys文件的末尾就行了。
这里不使用ssh--id命令,改用下面的命令,来解释公钥的保存过程:
输入命令 ssh user@host ,然后根据提示输入远程服务器的登录密码
也可在配置文件/etc/ssh/ssh_config 中设置user和host(ip), 来简化命令, 配置如下:
配置后, 登录请求时只需输入如洞悉下命令:
使用密码登录,每次都必须输入密码,非常麻烦。好在SSH还提供了公钥登录,可以省去输入密码的步骤。
公钥登录原理 :就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果解密验证成功,就证明用户是可信的,直接允许登录shell,不再要求密码。
执行上述命令首先会让你输入生成密钥的文件名: myPemKey (自定义),之后一路回车。
配置后,登录远槐颤悉程服务器时只需输入一下命令,便可直接登录成功:
修改后重启ssh服务
则远程连接时指定端口
(1) 通过iptables设置ssh端口的白名单,如下设置只允许192.168.1.0/24网段的客户机可以远程连接本机
(2) 通过/etc/hosts.allow里面进行限制(如下),/etc/hosts.deny文件不要任何内容编辑,保持默认!
例如:
修改远程服务器ssh服务配置文件/etc/ssh/sshd_config
修改远程服务器配置文件/etc/ssh/sshd_config, 如下:
如果本机系统有些账号没有设置密码,而ssh配置文件里又没做限制,那么远程通过这个空密码账号就可以登陆了,这是及其不安全的,所以一定要禁止空密码登陆。
修改远程服务器配置文件/etc/ssh/sshd_config,如下:
参考:
⑵ 本地shell脚本中ssh到远程服务器并执行命令
在实际运用中在当前服务器执行命令后,需要在另一台服务器继续执行某些命令,分开去到另一台服务器执行也是比较麻烦的,因此整理下集中执行的方式
1、首先配置ssh免密操作
linux 下实现SSH互信: https://www.jianshu.com/p/2456d98aa607
2、简单命令
ssh [email protected] "cd /var/lib; ls; cd "
2.1 使用时注意,双引号必须有。若没加双引号,第二条及之后的命令会在本地执行
2.2 分号是将两条语句间隔开
2.3 单双引的区别:单引号不会解析值,是什么就传什么;双引号会解析值,将解析结果传过去
3、多条命令
ssh [email protected]<< reallssh
cd /var/lib/test
tar -zxvf api.com.tar.gz
......
exit
reallssh
3.1 命令写在 << reallssh(开始) 至 reallssh(结束) 之间
3.2 reallssh可自己定义为其他形式
3.3 在结束前加上exit退出远程
4、可能遇到的问题
问题:远程登录主机时出现Pseudo-terminal will not be allocated because stdin is not a terminal. 错误
解决方案:字面意思是伪终端将无法分配,因为标准输入不是终端。
所以需要增加-t -t参数来强制伪终端分配,即使标准输入不是终端。
to force pseudo-tty allocation even if stdin isn’t a terminal.
参考样例如下:
ssh -t -t [email protected] -p 22
--------------------------------------------------------------------------------
参考:https://blog.csdn.net/jinking01/article/details/84386769
⑶ ssh远程连接服务器执行命令
首先说一下使用ssh远程连接服务器执行命令的方法:
为了方便描述,这里把测试服务器称之为A1,目标服务器称之为A2
如果可以直接登录到A2,则配置成功!
下面来说问题:
ssh在远程连接服务器执行命令的时候,经常会遇到环境变量的问题,如下:
如果出现上面的提示,则说明环境变量配置有问题。
先来说解决办法
问题解决!
这里就要说明bash有两种方式interactive + login shell模式和non-interactive + non-login shell模式
在服务器上执行命令,走的是interactive + login shell模式,而通过远程登录执行命令,走的是non-interactive + non-login shell模式。
这两种模式对于环境变量的读取是有区别的。
Shell首先会加载/etc/profile文件,然后再尝试依次去加载下列三个配置文件之一,一旦找到其中一个便不再接着寻找:
~/.bash_profile
~/.bash_login
~/.profile
所以当远程执行命令时,我们只需要让~/.bashrc文件中的环境变量与/etc/profile中的环境变量一致即可!
参考:
如何解决SSH远程执行命令找不到环境变量的问题
⑷ ssh连接centos远程服务器运行指令的问题
总结下使用ssh远程执行命令需要注意点:
一般我们会使用ssh ip "执行命令"这种格式来执行远程是shell命令,但是如果是简单的一些操作还好,比如cd,rm,ls,mv等命令一般不会出问题
,但是如果你的脚本任务是,杀死多台机器上的hadoop或者elasticsearch进程,你会怎么做?
伦理片http://www.dotdy.com/
直接使用:
ssh h1 "kill -9 `jps | grep Elastic* | gawk '{print $1}' ` " 杀死es进程,你会发现,它竟然没有生效? 明明在本地执行
kill -9 `jps | grep Elastic* | gawk '{print $1}' `
这个命令是可以生效的,为啥,放到远程执行命令中就失效了呢?
其实原因很简单,就是因为没有转义造成的,包括awk变量名引用都需要转义,否则,你会发现,虽然能执行,但结果依旧是不准确的,注意linux中
单引号(所有命令均被当成普通字符处理)
双引号(可引用变量名)
反引号(可以执行linux脚本命令)的区别
看最终的正确的写法:
Java代码
ssh$host"es_pid=`jps|grepElasticsearch|gawk'{print$1}'`&&kill$es_pid"
⑸ Linux-两种ssh远程执行命令方式加载环境变量区别
最近在编写脚本的时候发现一个问题,在执行 kubectl -n kube-system get pods 这个命令的时候,通过 ssh root@ip command 和 ssh root@ip command 登录后执行得到了不同的结果,
从上面可以看到哪贺SSH远程执行获取pods失败了,但是shell窗口执行却成功了,所以我们可以猜到两者之间一定有什么区别导致结果的不同。那么区别在哪里呢?通过研究发现两者的环境变量存在区别,通过执行printenv可以查看所有设置的环境变量:
通过上面可以看到SSH远程执行的时候是没有KUBECONFIG这个环境变量,而Shell窗口是有的,为什么有这个区别呢?这就要从Linux的bash的四种模式说起。
bash的四种模式:
从上面可以看出不同方式下加载的配置文件不同,那么怎么知道我们是加载了那些配置文袜凯件呢? 这里有一个验证的方法,就是在上面的每个配置告缓唤文件中添加一句 echo $/etc/profile 这样的命令,把每个文件的路径打印出来。当配置文件被加载时,会输出相应的文件名,本例中在两个文件中加了该命令:/etc/pfoile, ~/.bashrc,然后使用不同SSH方式执行命令的结果如下。
只加载了.bashrc文件,未加载/etc/profile。
从输出可以看到两个配置都加载了,而KUBECONFIG只定义在/etc/profile中,没有定义在.bashrc文件中,所以通过 ssh root@ip command 执行时没有拿到KUBECONFIG这个环境变量从而导致报错。知道原因后我们就可以将KUBECONFIG环境变量添加到.bashrc文件即可。
⑹ SSH远程操作与端口转发的原理
SSH不仅可以用于远程主机登录,还可以直接在远程主机上执行操作。
上一节的操作,就是一个例子:
单引号中间的部分,表示在远程主机上执行的操作;后面的输入重定向,表示数据通过SSH传向远程主机。
这就是说,SSH可以在用户和远程主机之间,建立命令和数据的传输通道,因此很多事情都可以通过SSH来完成。
下面看几个例子。
【例1】
将 HOME/src/目录。
【例2】
将远程主机$HOME/src/目录下面的所有文件,复制到用户的当前目录。
【例3】
查看远程主机是否运行进程httpd。
既然SSH可以传送数据,那么我们可以让那些不加密的网络连接,全部改走SSH连接,从而提高安全性。
假定我们要让8080端口的数据,都通过SSH传向远程主机,命令就这样写:
SSH会建立一个socket,去监听本地的8080端口。一旦有数据传向那个端口,就自动把它转移到SSH连接上面,发往远程主机。可以想象,如果8080端口原来是一个不加密端口,现在将变成一个加密端口。
有时,绑定本地端口还不够,还必须指定数据传送的目标主机,从而形成点对点的"端口转发"。为了区别后文的"远程端口转发",我们把这种情况称为"本地端口转发"(Local forwarding)。
假定host1是本地主机,host2是远程主机。由于种种原因,这两台主机之间无法连通。但是,另外还有一台host3,可以同时连通前面两台主机。因此,很自然的想法就是,通过host3,将host1连上host2。
我们在host1执行下面的命令:
命令中的L参数一共接受三个值,分别是"本地端口:目标主机:目标主机端口",它们之间用冒号分隔。这条命令的意思,就是指定SSH绑定本地端口2121,然后指定host3将所有的数据,转发到目标主机host2的21端口(假定host2运行FTP,默认端口为21)。
这样一来,我们只要连接host1的2121端口,就等于连上了host2的21端口。
"本地端口转发"使得host1和host3之间仿佛形成一个数据传输的秘密隧道,因此又被称为"SSH隧道"。
下面是一个比较有趣的例子。
它表示将本机的5900端口绑定host3的5900端口(这里的localhost指的是host3,因为目标主机是相对host3而言的)。
另一个例子是通过host3的端口转发,ssh登录host2。
这时,只要ssh登录本机的9001端口,就相当于登录host2了。
上面的-p参数表示指定登录端口。
既然"本地端口转发"是指绑定本地端口的转发,那么"远程端口转发"(remote forwarding)当然是指绑定远程端口的转发。还是接着看上面那个例子,host1与host2之间无法连通,必须借助host3转发。但是,特殊情况出现了,host3是一台内网机器,它可以连接外网的host1,但是反过来就不行,外网的host1连不上内网的host3。这时,"本地端口转发"就不能用了,怎么办?
解决办法是,既然host3可以连host1,那么就从host3上建立与host1的SSH连接,然后在host1上使用这条连接就可以了。
我们在host3执行下面的命令:
R参数也是接受三个值,分别是"远程主机端口:目标主机:目标主机端口"。这条命令的意思,就是让host1监听它自己的2121端口,然后将所有数据经由host3,转发到host2的21端口。由于对于host3来说,host1是远程主机,所以这种情况就被称为"远程端口绑定"。
绑定之后,我们在host1就可以连接host2了:
这里必须指出,"远程端口转发"的前提条件是,host1和host3两台主机都有sshD和ssh客户端。
SSH还有一些别的参数,也值得介绍。
N参数,表示只连接远程主机,不打开远程shell;T参数,表示不为这个连接分配TTY。这个两个参数可以放在一起用,代表这个SSH连接只用来传数据,不执行远程操作。
f参数,表示SSH连接成功后,转入后台运行。这样一来,你就可以在不中断SSH连接的情况下,在本地shell中执行其他操作。
要关闭这个后台连接,就只有用kill命令去杀掉进程。