摘要:前段时间买了个树莓派,打电信客服开通了外网ip,相当于在家里搭了一个云服务器。今天有时间记录一下当时的搭建过程。
开通外网IP地址 我家用的电信宽带,拨打电话10000,找人工客服,就说开通外网IP业务,等待办理成功即可。
办理成功后,便可通过外网IP访问到你的天翼网关。(注意:80、443端口会被屏蔽,其它端口可以正常使用。)
再到阿里云配置一下域名解析,即可通过域名访问。操作方法见文档 。
天翼网关端口映射
输入超级管理员的账号密码,注意不是普通用户的账户密码。
如果没改过的话,账号:telecomadmin
密码:nE7jA%5m
如果密码不对,那就只能问电信工作人员了。
登录成功之后,进入【应用】-【高级NAT配置】-【虚拟服务器设置】,添加端口映射规则。即将你外网ip的端口映射到内网ip的端口。
这里两种情况:
如果家里装了路由器,所有设备(手机、电脑、树莓派)都是连的路由器,这里就映射到路由器的IP,然后再在路由器设置一次端口映射。
如果家里没装路由器,设备直接连接的天翼网关,那么这里就直接映射设备的ip。注意这里要给设备设置为固定ip地址。
路由器设置IP与MAC绑定
路由器端口转发
最终转发效果 graph LR
用户 --> http://domain.com:10000 --> 天翼网关10000端口 --> TPLink路由器10000端口 --> 树莓派80端口
动态域名解析(DDNS) 这一套搞好之后,刚开始用着还比较舒服,用了一段时间后,问题暴露出来了。电信的外网IP是不固定的,隔一段时间就会变。虽然我可以上阿里云控制台,去修改域名对应的ip地址,但是手动去改是很烦的。能不能实现自动修改呢?答案是肯定的。
阿里云提供了修改域名解析的API 和SDK 。我们可以根据这些自己写程序来实现动态域名解析。
思路大概就是,定时(每隔15分钟)查询一下当前的外网IP,看是否发生了变化,如果变化了,则调用阿里云API修改域名解析。
废话少说,python代码如下,只需加入系统定时任务即可。
1 2 3 4 root@raspberrypi:~ 0,15,30,45 * * * * /opt/alidns/main.py
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 import osimport jsonimport loggingfrom urllib2 import urlopenfrom aliyunsdkcore.client import AcsClientfrom aliyunsdkcore.acs_exception.exceptions import ClientExceptionfrom aliyunsdkcore.acs_exception.exceptions import ServerExceptionfrom aliyunsdkalidns.request.v20150109 import DescribeDomainRecordsRequestfrom aliyunsdkalidns.request.v20150109 import UpdateDomainRecordRequestimport sysreload(sys) sys.setdefaultencoding('utf8' ) logging.basicConfig(level=logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' ,filename='/opt/alidns/log/alidns.log' ) class DnsHandler : access_key_id = " " access_key_secret = " " domain_name = "domain.com" rr_keyword = "test" record_type = "A" file_name = "/opt/alidns/ip_addr.txt" client = None record = None current_ip = '' def __init__ (self ): self.client = AcsClient( self.access_key_id, self.access_key_secret ) self.record = self.get_record() self.current_ip = self.get_current_ip() def reset (self ): if self.current_ip <> self.get_record_value(): self.update_record(self.current_ip) else : logging.info('ip 地址未发生变化:' + self.current_ip) def get_record (self ): if os.path.isfile(self.file_name) : file_handler = open (self.file_name, 'r' ) r = file_handler.read() file_handler.close() else : request = DescribeDomainRecordsRequest.DescribeDomainRecordsRequest() request.set_PageSize(10 ) request.set_action_name("DescribeDomainRecords" ) request.set_DomainName(self.domain_name) request.set_RRKeyWord(self.rr_keyword) request.set_TypeKeyWord(self.record_type) r = self.client.do_action_with_exception(request) file_handler = open (self.file_name, 'w' ) file_handler.write(r) file_handler.close() return json.loads(r) def get_record_id (self ) : return self.record["DomainRecords" ]["Record" ][0 ]["RecordId" ] def get_record_value (self ) : return self.record["DomainRecords" ]["Record" ][0 ]["Value" ] def update_record (self, value ): request = UpdateDomainRecordRequest.UpdateDomainRecordRequest() request.set_action_name("UpdateDomainRecord" ) request.set_RecordId(self.get_record_id()) request.set_Type(self.record_type) request.set_RR(self.rr_keyword) request.set_Value(value) self.client.do_action_with_exception(request) os.remove(self.file_name) logging.info('ip地址变化,更新DNS解析:' + value); def get_current_ip (self ): currentip = json.load(urlopen('https://ipv4.jsonip.com' ))['ip' ] logging.debug('currentip:' + currentip) return currentip dns = DnsHandler() dns.reset()