书接上回,好不容易配置好了服务器却发现没有公网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
截至这里整个搭建工作就完成了,接下来就可以愉快的用外网访问服务器啦