RouterOS通过脚本更新当前IP

有段时间没有更新折腾内容,这样的最近买了个新东西,Gen8!折腾记录有空在叙述。在Gen8上跑了一个NAS系统,根据当前互联网环境实在不太平,所以不敢直接将Gen8的端口映射到外网。解决办法就是通过RouterOS的脚本定期向一个公网的主机发送ip,对比与之前的ip是否一致。

接下来通过VPN就能够访问到内网中的NAS主机了,虽然有点繁琐但是总归算是一个比较安全的解决方案。如何在ROS中建立VPN请见《ROS(Router OS)路由设置笔记一》。

57c57c01ecb8b.jpg


如上图System -> Scripts 新建一个脚本。脚本代码如下:

:local ipaddr
:set ipaddr [/ip address get [/ip address find interface=pppoe-out1] address]
:set ipaddr [:pick $ipaddr 0 ([len $ipaddr] -3)]
/tool fetch url=("http://domain.cn/index.php/IPGroup/dynamic/update/ip/".$ipaddr."/client/【终端号】")

该段脚本其实是通过修改花生壳的脚本代码来实现的,这里的url是一个公网的主机,使用的是ThinkPHP框架。

    IPGroup:ThinkPHP应用分组

    dynamic:ThinkPHP的类

    update:类中的函数

    ip:当前的外网IP

    client:当前设备的终端号

然后还需要一个数据库用来存储路由器发过来的ip,数据库的表结构如下:

    表名:tp_iplist

    id:主键

    ip:varchar(25)

    client:varchar(255)

    uptime:datetime

下面是服务器的代码部分用于接受处理发送来的ip以及ip查询请求:

<?php
namespace RealtimeIP\Controller;
use Think\Controller;
class IndexController extends Controller
{
    public function index()
    {
      $this->display('html5/index');
    }
    public function getIPinfo($client,$isjson=false)//用于通过终端号获取ip
    {
        $iplist = M('iplist');
        $ipresult = $iplist->where('client="'.$client.'"')->select();
        if (sizeof($ipresult) == 1) {
            $rlt = $ipresult[0];
            $currentTime = date('Y-m-d H:i:s', time());
            $time1 = strtotime($currentTime);
            $time2 = strtotime($rlt['uptime']);
            if (ceil(($time1 - $time2) / 60) > 30) {
                $rlt['isOnline'] = false;
            } else {
                $rlt['isOnline'] = true;
            }
            if(!$isjson)
            {
              echo $rlt['ip'].';'.$rlt['isOnline'];
            }else {
              echo json_encode($rlt);
            }

        }
    }
    public function updataIP($ip, $client)//用于更新ip
    {
        $iplist = M('iplist');
        $ipresult = $iplist->where('client="'.$client.'"')->select();
        $data['ip'] = $ip;
        $data['client'] = $client;
        $data['uptime'] = date('Y-m-d H:i:s', time());
        if (sizeof($ipresult) > 1) {
            $iplist->where('client="'.$client.'"')->delete();
            $iplist->data($data)->add();
        } elseif (sizeof($ipresult) == 0) {
            $iplist->data($data)->add();
        } elseif (sizeof($ipresult) == 1) {
            $id = $ipresult[0]['id'];
            $iplist->where('id='.$id)->data($data)->save();
        }
    }
}

网页查询效果如下:

57c584da23073.png  57c585052fd56.png 57c585aa2060a.png

其中getIPinfo函数支持json返回,这样就能投通过自制的其他vpn程序获得vpnserver的ip地址,接下来是C#通过json方式获取ip

public string getHomeIP()
{
    string strBuff = "";
    char[] cbuffer = new char[256];
    int byteRead = 0;
    HttpWebRequest httpReq;
    HttpWebResponse httpResp;
    Uri httpURL = new Uri(@"http://domain.cn/index.php/IPGroup/dynamic/index/getipfun/client/终端号/isjson/ture");
    httpReq = (HttpWebRequest)WebRequest.Create(httpURL);
    httpResp = (HttpWebResponse)httpReq.GetResponse();
    Stream respStream = httpResp.GetResponseStream();
    StreamReader respStreamReader = new StreamReader(respStream, Encoding.UTF8);
    byteRead = respStreamReader.Read(cbuffer, 0, 256);
    while (byteRead != 0)
    {
        string strResp = new string(cbuffer, 0, byteRead);
        strBuff = strBuff + strResp;
        byteRead = respStreamReader.Read(cbuffer, 0, 256);
    }
    respStream.Close();
    JObject obj = JsonConvert.DeserializeObject<JObject>(strBuff);
    return obj["ip"].ToString();
}

下面是自制的VPN客户端,可以在外面的任何电脑拨号回内网访问NAS主机

57c5878c9f6b2.png

标签: ThinkPHP  c sharp  C#  ROS  RouterOS  

有0条评论

添加新评论