利用SSH 反向代理 ,实现跨局域网连接家里的linux 主机 (树莓派)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28766327/article/details/82117409

最近我买了一台树莓派主机 ,并且装上了官方系统(Raspbian )。打算用它来跑跑脚本之类的。但是遇到一个问题,我在外的时候,怎么远程连接家里的在局域网中的主机呢?
我已经成功的解决了这个问题,期间也遇到了各种坑,我在这里也会详细的说一下这些坑。如果您还有任何其他问题,可以在下面评论留言给我。

软硬件环境:
1.树莓派 3b+ 1个,安装于我租住的房间中。联网经过多层NAT(网络地址转换),故无公网IP
2.一个有公网IP的VPS(虚拟主机),我使用的是国外的vultr,您也可以选择阿里云,亚马逊等各种厂商产品。这台机器的操作系统为 centos 7.0 ,IP 为 A.A.A.A
3.一台普通的电脑


操作步骤:

  1. 修改公网服务器 ssh 配置文件 sshd_config 文件:
# vi /etc/ssh/sshd_config
添加 GatewayPorts yes
# 重启 ssh 服务
# centos 7
systemctl reload sshd.service
# centos 7 以下
service sshd reload
  1. 局域网中的树莓派连接公网服务器反向代理端口:

    这段代码在本地树莓派中执行,这段代码是将本地机器的22端口绑定公网服务器的7233端口

ssh -CqTfnN -R 0.0.0.0:7233:127.0.0.1:22 root@A.A.A.A
  1. 检查反向代理是否成功:
    在公网服务器中执行如下代码,如果出现相同结果则表明 SSH反向代理成功
netstat -anp | grep 7233
tcp        0      0 0.0.0.0:7233                0.0.0.0:*                   LISTEN      2392/sshd  
tcp        0      0 :::7233                     :::*                        LISTEN      2392/sshd
  1. 测试是否能通过反向代理连接局域网中的树莓派:
    这时,你可以通过普通电脑的ssh客户端 连接 公网服务器的7233端口。测试连接是否成功
ssh -p 7233 root@A.A.A.A

编写脚本守护反向代理
1.设置树莓派免密码登录公网服务器:

# 在内网树莓派中执行
ssh-keygen -t rsa -P ''
# 然后一直按回车, 于是在~/.ssh/中 会生成两个文件 id_rsa 与 id_rsa.pub
# 将id_rsa.pub 复制到公网服务器中
scp ~/.ssh/id_rsa.pub [email protected]:~
#输入密码

#切换到公网服务器中执行如下代码
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
#修改文件权限,这一步很必要
chmod 600 .ssh/authorized_keys
chmod 700 .ssh/

2.编写公网服务器关闭代理脚本

#!/bin/sh

if [ -n "$1" ] && [ "$1" -gt "0" ];then
    PID=$(netstat -anp | grep $1 | awk '/sshd/ && !/awk/{print $7}')
    PID=${PID%%/*}

    if [ -n "${PID}" ];then
        kill -9 $PID && exit 0
    fi
fi

exit 1

3.编写客户端代理守护脚本 (注意配置服务器端口及IP)

#!/bin/bash

ROMOTE_USERNAME=root
ROMOTE_SERVER_IP="A.A.A.A"
ROMOTE_PORT=7233 
###[ /sbin/ifconfig|sed -n '/inet addr/s/^[^:]*:\([0-9.]\{7,15\}\) .*/\1/p'|grep -v 127.0.0.1 ]
LOCALHOST_IP=`/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"`
LOCALHOST_PORT=22

while true ;
do
    PID=$(ssh -l root ${ROMOTE_SERVER_IP}  netstat -anp | grep ${ROMOTE_PORT} | awk '/sshd/ && !/awk/{print $7}')
    PID=${PID%%/*}
    if [ -n "$PID" ] && [ "$PID" -gt "0" ];then
        sleep 30s
    else
        /usr/bin/ssh -l root ${ROMOTE_SERVER_IP} /bin/sh /data/kill_ssh_agent.sh ${ROMOTE_PORT}
        /usr/bin/ssh -CqTfnN -R 0.0.0.0:${ROMOTE_PORT}:${LOCALHOST_IP}:${LOCALHOST_PORT} ${ROMOTE_USERNAME}@${ROMOTE_SERVER_IP}
    fi
done

exit 0

4.设置 SSH 连接为长连接 (在公网服务器操作)

vi /etc/ssh/sshd_config

#每1分钟发送一个心跳信号给客户端
ClientAliveInterval 60
#最大超时次数,客户端不响应则关闭连接
ClientAliveCountMax 3
  1. 设置为开机启动 (在内网机器操作):
vi /etc/rc.local

/bin/sh /data/ssh_agent_deamon.sh &

遇到的问题:
理论上按照上面的步骤操作,反向代理就能成功了。但是操作中我还是遇到了不少问题。我这里把他们列出来
1.防火墙
防火墙会阻止未经许可端口的数据通过,所以允许端口的防火墙通过是很有必要的。您需要确认每台机器是否有防火墙,如果有防火墙,是否正确的配置了防火墙。
另外,在公网服务器中,很多服务商提供了额外的防火墙服务。在他们的网页控制台可以看到。我的公网服务器就有服务商提供的额外防火墙。我的做法是将centos自带的防火墙关掉,并禁止开机启动。然后配置服务商提供的防火墙,允许反向代理的端口通过。当然您也可以两个防火墙都开着,但要确保他们都通过了您需要的端口。
2.ssh自动登录失败:
自动登录失败,可能因为你的秘钥文件权限不对。ssh秘钥登录对文件权限很敏感。还有我犯了一个错误,我在公网服务器生成秘钥,然后放到本地。导致一度登录失败。正确的做法应是在内网生成秘钥,放到外网服务器中
3.守护脚本不能成功设置反向代理问题:
守护代理是通过 /etc/rc.local 开机启动的,其默认用户为root。我在生成秘钥的时候一直用的普通用户,于是导致在开启自动启动时运行失败。解决办法是,切换到内网机器的root用户,再生成一次秘钥,将秘钥追加到公网服务器的authorized_keys文件中。如果新买的机器不知道root用户的密码是什么,可以看一下参考文章的第4个连接

参考的文章:
https://www.cnblogs.com/phpdragon/p/5314650.html
https://blog.csdn.net/Post_Yuan/article/details/78603212
http://www.mamicode.com/info-detail-2128504.html
https://blog.csdn.net/faryang/article/details/50779767

猜你喜欢

转载自blog.csdn.net/qq_28766327/article/details/82117409