我写了一个small bash script,需要一个ssh隧道从远程服务器中绘制数据,因此它会提示用户:
echo "Please open an ssh tunnel using 'ssh -L 6000:localhost:5432 example.com'"
我想检查用户是否已打开此隧道,如果没有隧道,则退出并显示错误消息。有没有办法查询ssh
隧道,即检查本地端口6000是否真的隧道到该服务器?
这是我的考验。希望它有用。
# $COMMAND is the command used to create the reverse ssh tunnel
COMMAND="ssh -p $SSH_PORT -q -N -R $REMOTE_HOST:$REMOTE_HTTP_PORT:localhost:80 $USER_NAME@$REMOTE_HOST"
# Is the tunnel up? Perform two tests:
# 1. Check for relevant process ($COMMAND)
pgrep -f -x "$COMMAND" > /dev/null 2>&1 || $COMMAND
# 2. Test tunnel by looking at "netstat" output on $REMOTE_HOST
ssh -p $SSH_PORT $USER_NAME@$REMOTE_HOST netstat -an | egrep "tcp.*:$REMOTE_HTTP_PORT.*LISTEN" \
> /dev/null 2>&1
if [ $? -ne 0 ] ; then
pkill -f -x "$COMMAND"
$COMMAND
fi
如果您在后台使用ssh,请使用以下命令:
sudo lsof -i -n | egrep '\<ssh\>'
Netcat是你的朋友:
nc -z localhost 6000 || echo 'no tunnel open'; exit 1
Autossh是最佳选择 - 检查过程在所有情况下都不起作用(例如僵尸进程,网络相关问题)
例:
autossh -M 2323 -c arcfour -f -N -L 8088:localhost:80 host2
这实际上更像是一个serverfault类型的问题,但您可以使用netstat。
就像是:
# netstat -lpnt | grep 6000 | grep ssh
这将告诉您是否有ssh进程侦听指定的端口。它还会告诉你进程的PID。
如果你真的想要仔细检查ssh进程是否使用正确的选项启动,那么你可以通过PID查找过程
# ps aux | grep PID
使用autossh。它是用于监视ssh连接的工具。
stunnel是在主机之间建立半永久连接的好工具。
这些是测试或排除SSH隧道故障的更详细步骤。您可以在脚本中使用其中一些。我正在添加这个答案,因为我必须在两个应用程序停止工作后对其进行故障排除。只是为了ssh过程而进行的操作还不够,因为它仍然存在。我无法使用nc -z
因为我的咒语netcat没有这个选项。
让我们从头开始。假设有一台机器,在10.0.3.12处称为本地IP地址10.0.0.1,另一台称为远程机器。我将这些主机名添加到下面的命令中,因此很明显它们被执行的地方。
目标是创建一个隧道,将TCP流量从端口123上的远程计算机上的环回地址转发到端口456上的本地计算机。这可以通过以下命令在本地计算机上完成:
local:~# ssh -N -R 123:127.0.0.1:456 10.0.3.12
要检查进程是否正在运行,我们可以:
local:~# ps aux | grep ssh
如果在输出中看到命令,我们可以继续。否则,请检查远程控制台中是否安装了SSH密钥。请注意,在远程IP之前排除用户名,使ssh使用当前用户名。
接下来,我们要检查远程隧道是否已打开:
remote:~# netstat | grep 10.0.0.1
我们应该得到类似于这样的输出:
tcp 0 0 10.0.3.12:ssh 10.0.0.1:45988 ESTABLISHED
很高兴看到从远程到主机的一些数据。这就是netcat的用武之地。在CentOS上,可以安装yum install nc
。
首先,在本地计算机上打开一个侦听端口:
local:~# nc -l 127.0.0.1:456
然后在遥控器上建立连接:
remote:~# nc 127.0.0.1 123
如果打开本地计算机的第二个终端,则可以看到该连接。像这样的东西:
local:~# netstat | grep 456
tcp 0 0 localhost.localdom:456 localhost.localdo:33826 ESTABLISHED
tcp 0 0 localhost.localdo:33826 localhost.localdom:456 ESTABLISHED
更好的是,继续在遥控器上键入内容:
remote:~# nc 127.0.0.1 8888
Hallo?
anyone there?
您应该在本地终端上看到它被镜像:
local:~# nc -l 127.0.0.1:456
Hallo?
anyone there?
隧道正在运转!但是如果你有一个名为appname的应用程序应该在本地计算机上的端口456上监听呢?在两侧终止nc然后运行您的应用程序。您可以使用this检查它是否正在侦听正确的端口:
local:~# netstat -tulpn | grep LISTEN | grep appname
tcp 0 0 127.0.0.1:456 0.0.0.0:* LISTEN 2964/appname
顺便说一句,在远程控制器上运行相同的命令应该显示sshd监听端口127.0.0.1:123。
我们可以使用ps命令检查
# ps -aux | grep ssh
将显示所有shh服务正在运行,我们可以找到列出的隧道服务
#!/bin/bash
# Check do we have tunnel to example.com server
lsof -i tcp@localhost:6000 > /dev/null
# If exit code wasn't 0 then tunnel doesn't exist.
if [ $? -eq 1 ]
then
echo ' > You missing ssh tunnel. Creating one..'
ssh -L 6000:localhost:5432 example.com
fi
echo ' > DO YOUR STUFF < '