经过N次尝试和折腾,终于把blog迁移到了家里的树莓派上。总结一下过程:
首先要判断家中网络是否为公网独立IP 1.访问ip138或者cip,可以找到家中宽带的IP。以我家的某个公网IP118.133.129.193为例。 2.win下使用tracert,linux下使用traceroute,如果跟踪结果显示没有中转只跳了一下直接到了家中IP,则是独立公网IP,否则不是公网独立IP或者假公网独立IP。 例如:独立公网IP
然后开启路由器端口转发功能,我家的小米路由器: 目前一般情况下,家里宽带即使给了公网IP,但80端口也会被封掉,路由器转发了80端口也无法访问,那该怎么办呢。只能带非80端口访问或者另外找一台机器做端口转发,这样下来貌似增加了成本,幸亏有1元腾讯学生云或者8元阿里学生云这样的便宜VPS。 使用rinetd做端口转发:
1 2 3 4 5 6 7 8 9 wget http://www.boutell.com/rinetd/http/rinetd.tar.gz tar -xvf rinetd.tar.gz cd rinetd sed -i 's/65536/65535/g' rinetd.c mkdir /usr/man/ make && make install vi /etc/rinetd.conf 0.0.0.0 80 118.133.129.193 80 /usr/sbin/rinetd //启动服务
最后域名解析到VPS的IP上就可以访问了。家里的宽带是上海有线通,属于二级小ISP,应该是租的网通或者电信的带宽,虽然给了独立公网IP,很奇怪的是,公网telnet任何端口,都显示已经被关闭。因为这个原因差点放弃迁移,后来意外发现在VPS上居然可以访问任意端口,包括80。至今没有查到有线通是如何做到的,但是他们的目的可以猜到就是不让用户在公网直接访问宽带IP。 因为宽带IP经常会换,所以需要同步最新的IP到VPS并重启rinetd服务。树莓派上环境是node,写了个简单的IP同步脚本,使用node来执行。
同步宽带IP 同步脚本:
1 2 3 4 #!/bin/bash ip=$1 ssh root@115.159.23.71 "echo '0.0.0.0 80 ${ip} 80' > /etc/rinetd.conf;pkill rinetd;/usr/sbin/rinetd > /dev/null 2>&1 &" echo "done"
nodejs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 var fs = require('fs'), Child_process = require('child_process'), exec = Child_process.exec, ipFilePath = '/root/syncIp/ip', ip = null; function getIp() { fs.readFile(ipFilePath, function(err, data) { err ? console.log(new Date() + err + 'getIp fail') : getNewIp(data); }); } function saveIp(ip) { fs.writeFile(ipFilePath, ip, function(err) { err ? console.log(new Date() + err + 'saveIp fail') : syncConf(ip); }); } function getNewIp(oldIp) { var cmd = 'curl ip.cip.cc', newIp = null; exec(cmd, function(err, stdout, stderr) { if(err) { console.log(err + stderr); } else { newIp = stdout.toString('utf8').replace(/(\n)+|(\r\n)+/g, ""); if(newIp != oldIp) { saveIp(newIp); console.log(new Date() + newIp); } } }); } function syncConf(ip) { var args = []; args.push(ip); Child_process.execFile('/root/syncIp/syncIp.sh', args, null, function(err, stdout, stderr) { err? console.log(err) : console.log(new Date() + 'sync ok'); }); } setInterval(getIp, 60000);
每隔1分钟查询一次IP,和/root/syncIP/目录下的ip文件中的旧IP进行比较。如果不同,则认为IP已更换,执行shell更新rinted的配置文件并重启服务。