利用云服务器的内网穿透搭建指南

4,569 阅读5分钟

书接上回,好不容易配置好了服务器却发现没有公网IP,没有公网IP的服务器就没办法从外网访问。为了解决这个问题,只能买一个云服务器用于内网穿透,接下来就讲一讲架这个内网穿透的全过程。这个过程的大致原理如下图所示:

云服务器购买配置

我买的是阿里云的云服务器,现在用学生优惠答题通过还能白嫖半年,一般个人使用就选普通的ECS就好了,按照阿里云官网的配置说明创建实例即可。

安全组配置

在实例列表中对服务器进入服务器管理界面。

之后配置安全组规则

这部分配置完毕之后就可以从阿里云提供的公网IP进入云服务器进行配置。

云服务器配置

我选择的云服务器是CentOS 7的系统,首先在系统中开放需要的端口,在终端输入

iptables -I INPUT -p tcp --dport [想要开放的端口号] -j ACCEPT

之后输入

iptables -nL

检查是否开放成功,以开放2110端口为例,显示如下则开放成功

之后还要配置ssh服务,配置文件地址为/etc/ssh/sshd_config,输入如下命令

vi /etc/ssh/sshd_config

进入ssh配置文件修改以下各参数,部分参数默认是被注释掉的,修改时记得去掉注释

PermitRootLogin yes #禁止远程登录root账户
AuthorizedKeysFile .ssh/authorized_keys #指定存放公钥/私钥的路径
AddressFamily any       #监听任何地址的请求
ListenAddress 0.0.0.0   #任何IPv4地址
ListenAddress ::        #任何IPv6地址
AllowAgentForwarding yes    #以下三项都要为yes
AllowTcpForwarding yes
GatewayPorts yes

完成以上步骤之后云服务器就配置完毕了。

本地服务器配置

完成云服务器配置之后就要对本地服务器进行配置了。

本地服务器也需要配置ssh配置文件,在与云服务器同样的位置,配置如下各项

Port 22 #可选择修改默认ssh端口
PermitRootLogin yes #禁止远程登录root账户
AuthorizedKeysFile .ssh/authorized_keys #指定存放公钥/私钥的路径

如果没有生成ssh密钥就生成密钥,已经生成了可以直接按如下步骤操作密钥

#未生成密钥从此开始
ssh-keygen #生成密钥对,运行后按三次回车,生成默认的密钥,公钥为id_rsa.pub,私钥为id_rsa,存放路径为/home/用户名/.ssh
#密钥已生成从此开始
cd ~/.ssh #密钥默认存放在这里
cat id_rsa.pub >> authorized_keys #把生成的公钥添加到authorized_keys文件中,之后用来免密登录B
ssh-copy-id [云服务器]@[云服务器的公网IP地址]  #将公钥添加到服务器A的authorized_keys文件中,使B能够免密登录A
service sshd restart #重启sshd服务

之后输入如下命令测试本地服务器能否免密登录云服务器

ssh [云服务器用户名]@[云服务器的公网IP地址]

之后ctrl + D退出云服务器登录,在本地服务器输入如下命令

ssh -fNR [云服务器上用于转发的端口]:[内网服务器B的内网ip地址]:[内网服务器的ssh端口(通常是22)] [云服务器登录用户名]@[云服务器的ip地址] -p [云服务器的ssh端口(通常是22)] "vmstat 30" #"vmstat 30"是每30秒发送一次vmstat命令,防止长时间没有数据收发使通道自动关闭

例如:
ssh -fNR 8387:127.0.0.1:22 root@xxx.xxx.xxx.xxx -p 22  "vmstat 30"

完成之后就可以使用任意网络设备ssh方式连接云服务器接入本地服务器进行测试

ssh [内网服务器登录用户名]@[云服务器的ip地址] -p [云服务器上自定义用于转发的端口]

成功之后,配置就完成了,但是由于ssh命令建立的隧道非常不稳定,需要在本地服务器建立一个定时执行的脚本,对远程端口进行监视,实现自动重建隧道

在任意目录下创建远程端口监视脚本autossh.sh,实现的功能是先查找有没有开启远程端口转发,还没有开启的话就开启,如果已经开启了则测试端口是否连通,不连通则杀掉原来的进行,重新开启;并且在脚本所在目录输出日志文件。脚本示例代码如下

#!/bin/bash 
#第一行用来选择编译器
PIDS=`ps -ef| grep "ssh -fNR 2110" |grep -v grep | awk '{print $2}'` #查找监听进程pid
IP=`ip addr|grep 192.168.1|grep -v grep|awk '{print $2}'|awk -F '/' '{print $1}'` #查找本地内网ip
if [ -z "$PIDS" ]; then #如果进程不存在
         ssh -fNR [云服务器上用于转发的端口]:$IP:22 root@[云服务器的公网IP] "vmstat 30" #启动进程
         echo "start ssh exporter 2110:`date`" >> [监视脚本所在目录]/log.txt #输出到日志
else #如果进程存在
        nc -w 3 -z [云服务器的公网IP] [] > [监视脚本所在目录]/null 2>&1 #检查通道是否连通
        if [ $? -ne 0 ]; then #如果上一条命令输出0,则说明未连通
                sudo kill -9 $PIDS #杀掉这条进程
                ssh -fNR [云服务器上用于转发的端口]:$IP:22 root@[云服务器的公网IP] "vmstat 30" #重新启动进程
                echo "kill and start ssh exporter 2110:`date`" >> [监视脚本所在目录]/log.txt #输出到日志
        fi
fi

echo $IP #输出ip
echo $PIDS #输出pid

定时任务配置文件在/etc/crontab中,进入这个文件并编辑,在最后一行添加如下文本,表示每分钟执行一次autossh.sh

*/1 * * * * [监视脚本所在目录]/autossh.sh

截至这里整个搭建工作就完成了,接下来就可以愉快的用外网访问服务器啦