通过反向代理访问你的树莓派

本文教程需要有一台公网服务器

【本文参考链接】
利用SSH 反向代理 ,实现跨局域网连接家里的linux 主机 (树莓派)
centos7查看端口是否开放


最近新入了一台树莓派4,顺便把我的2b出了。以前只是拿来当作3D打印服务器,虽然公司的网络有公网IP,但是这个IP也不固定,每次重新拨号或者停电之类的操作都会使得公网IP改变。
以前试过花生壳等内网穿透软件,最近想试试新的方法,公司刚好也有公网服务器(阿里云),所以才有了这篇文章。
关于反向代理的介绍,可以查看百度百科:反向代理

注:本文中的公网服务器地址为11.22.33.44,公网服务器端口为8022,树莓派端口为22,一定要根据你自己的实际情况修改为你的配置。

一、修改公网服务器ssh配置文件

#vi /etc/ssh/sshd_config

找到GatewayPorts,默认设置为no,将其修改为yes

GatewayPorts yes

然后重启ssh服务:

# centos 7
systemctl reload sshd.service
# centos 7以下
service sshd reload

二、将局域网中的树莓派连接到公网服务器反向代理端口

# ssh -CqTfnN -R 0.0.0.0:8022:127.0.0.1:22 [email protected]

其中,8022为公网反向代理端口,22为树莓派的ssh端口,11.22.33.44为公网服务器的IP地址。
上述代码即:将树莓派的22端口反向代理到IP地址11.22.33.44的8022端口

三、检查公网服务器反向代理是否成功

公网服务器执行netstat -anp | grep 8022,如果出现类似下面的结果,则表示SSH反向代理成功。

tcp    0    0 0.0.0.0:8022    0.0.0.0:*    LISTEN    6520/sshd: root

四、测试反向代理是否成功

完成上面的步骤以后,就可以通过其他电脑的ssh客户端,连接公网服务器的8022端口了。

# ssh -p 8022 [email protected]

如果连接失败,继续往下看~

五、开放公网服务器端口

如果按照前面的步骤操作以后,发现第四步连接不上,可能是公网服务器需要开放端口。

  1. 首先需要在服务器管理面板开放8022端口,每个供应商可能操作不同,这里不再赘述。
  2. 我用的服务器系统是centos 7,输入命令netstat -tlunp | grep 8022,得到以下结果:
tcp        0      0 0.0.0.0:8022            0.0.0.0:*               LISTEN      6520/sshd: root

可以看到系统开放了8022端口。然后检查防火墙端口,输入iptables-save | grep 8022,发现什么也没有输出。说明防火墙将8022端口拦截了,需要开放防火墙的端口:

firewall-cmd --zone=public --add-port=8022/tcp --permanent
firewall-cmd --reload

第一条命令是添加端口,第二条命令是重载防火墙。看到success字样后,再次输入iptables-save | grep 8022可以看到如下字样,则表示防火墙配置成功。这时候再回到第四步测试就可以连接了。

-A IN_public_allow -p tcp -m tcp --dport 8022 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT

以下内容为复制参考链接一中的原文,并做了注释,已经测试正常

六、编写脚本守护反向代理

1. 设置树莓派免密码登录公网服务器

在内网树莓派中切换到root账户:sudo su,然后执行以下命令生成ssh公钥

ssh-keygen -t rsa -P ''

/root/.ssh/中 会生成两个文件id_rsaid_rsa.pub,然后将id_rsa.pub复制到公网服务器中

scp /root/.ssh/id_rsa.pub [email protected]:~

切换到公网服务器中执行如下代码

cat ~/id_rsa.pub >> ~/.ssh/authorized_keys

修改文件权限,这一步很必要

chmod 600 /root/.ssh/authorized_keys
chmod 700 /root/.ssh/

2. 在公网服务器总新建关闭代理的脚本

从树莓派上调用此脚本,可以从公网服务器关闭反向代理进程。
执行sudo vi /root/kill_ssh_agent.sh,并输入以下内容:

#!/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

将此脚本保存为kill_ssh_agent.sh,并记住路径,我的是保存在了/root/kill_ssh_agent.sh,然后添加可执行权限:

sudo chmod +x /root/kill_ssh_agent.sh

3. 在树莓派上创建反向代理进程守护脚本

在树莓派上执行sudo vi /root/ssh_agent_daemon.sh,并输入以下内容:

#!/bin/bash

REMOTE_USERNAME=root
REMOTE_SERVER_IP="11.22.33.44"
REMOTE_PORT=8022
#原文中用此命令获取IP
#LOCALHOST_IP=`/sbin/ifconfig -a | grep inet | grep -v 127.0.0.1 | grep -v inet6 | awk '{print $2}' | tr -d "addr:"`
#其实用下面的代码就可以获取到
#LOCALHOTST_IP=$(hostname -I)
#但是经测试,这么写可能会连接不上的,所以按照之前的写法,直接如下写成本机地址即可
LOCALHOTST_IP="127.0.0.1"
LOCALHOST_PORT=22

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

exit 0

保存,并添加可执行权限:

sudo chmod +x /root/ssh_agent_daemon.sh

这个路径也要用到。

4. 在公网服务器中,设置 SSH 连接为长连接

sudo vi /etc/ssh/sshd_config

找到ClientAliveIntervalClientAliveCountMax,并按照下面修改:

#每1分钟发送一个心跳信号给客户端
ClientAliveInterval 60
#最大超时次数,客户端不响应则关闭连接
ClientAliveCountMax 3

5. 在树莓派中将守护进程脚本设置为开机启动

sudo vi /etc/rc.local

将下面这一行添加到exit 0之前

/bin/sh /root/ssh_agent_daemon.sh &

注意脚本路径,这里必须写完整路径/root/ssh_agent_daemon.sh,一定不要写成~/ssh_agent_daemon.sh,否则会启动失败

你可能感兴趣的:(通过反向代理访问你的树莓派)