其他分享
首页 > 其他分享> > 个人电脑也能做服务器

个人电脑也能做服务器

作者:互联网

一般家庭网络是没有固定 ip 的,这就导致了外部无法方便地访问家里电脑上的文件或网络服务。花生壳等内网穿透工具免费的又不好使,收费的又划不来,怎么办?今天我来给大家分享一个方法,轻松搞定。

准备

思路

阿里云解析DNS提供接口可以让我们通过程序更新域名设置,这是核心要点。查看文档
另外我们还需要知道家里的IP地址。
然后只要我们根据运营商跟换ip的频率(一般一天换一个)定时执行任务,进行更新域名指向,这样就能实现只要访问固定域名就能指向指定IP了。
然后再设置一下路由器,映射到内网ip地址(即提供网路服务的主机地址),可以使用树莓派、老旧电脑或者NAS作为主机,搭建自己的博客或者提供简单的网络服务。
大功告成!

widows 可以利用计划任务,Linux 可以利用 crontab,来完成定时任务。

话不多说,都在代码里:

import logging
import requests
import hmac
import random
import string
from datetime import datetime, timezone
import base64

logger = logging.getLogger('test')
logger.setLevel(logging.DEBUG)

# 控制台输出
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# 输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)

logger.addHandler(ch)


class DynamicRouter:
    """ 利用阿里云解析接口,将域名动态解析到指定 ip

    适用于家庭宽带的IP是公网IP的小伙伴,配合路由器的转发功能对外提供服务。类似花生壳的功能。
    注意:80 端口一般被运营商封掉,在可以尝试其他端口。
    """

    def __init__(self, access_key_id, access_key_secret):
        self.APP_ID = access_key_id
        self.APP_SECRET = access_key_secret
        self.base_host = "https://alidns.aliyuncs.com/"
        self._common_req_params = {
            "Format": "JSON",
            "Version": "2015-01-09",
            "AccessKeyId": self.APP_ID,
            "SignatureMethod": "HMAC-SHA1",
            "Timestamp": datetime.now(tz=timezone.utc).isoformat().split('.')[0] + 'Z',
            "SignatureVersion": "1.0",
            "SignatureNonce": ''.join([random.choice(string.ascii_letters + string.digits) for i in range(10)]),
        }

    def get_signature(self, **kwargs) -> bytes:
        """ 根据规则生成签名

        :return  signature
        """
        signature_string_base = 'POST' + '&' + '%2F' + '&'
        signature_string_to_params = ''
        for key in sorted(kwargs):
            if key == "Timestamp":
                kwargs[key] = kwargs[key].replace(':', '%253A')
            signature_string_to_params += f'{key}%3D{kwargs[key]}%26'
        signature_string_to_sign = signature_string_base + signature_string_to_params.rstrip('%26')

        signature = hmac.new(key=(self.APP_SECRET + '&').encode(), msg=signature_string_to_sign.encode(),
                             digestmod="SHA1").digest()
        return base64.b64encode(signature)

    def get_record_id(self, domain_name: str, rr: str) -> str:
        """ 获取该域名下二级域名的解析记录 id

        :param domain_name:域名名称
        :param rr:主机记录(二级域名,若没有,默认为'@')
        :return record_id or None
        """
        data = {}
        data.update(self._common_req_params)
        data.update({'Action': 'DescribeDomainRecords', "DomainName": domain_name})
        signature = self.get_signature(**data)
        data['Signature'] = signature
        res = requests.post(self.base_host, data=data).json()

        records = res['DomainRecords']['Record']
        for i in records:
            if i['RR'] == rr:
                return i['RecordId']
        else:
            logger.error('未获取到解析记录,检查参数是否正确。')
            raise Exception("can't get value")

    def update_domain_record(self, record_id: str, rr, value: str, ttl: int = 600, rtype: str = 'A') -> None:
        """ 更新解析记录为 record_id 的设置,包括但不限于ip地址、主机记录、解析类型等

        :param record_id : 解析记录
        :param rr : 主机记录(二级域名)
        :param value : 解析记录(若是 记录类型 A,则为 ip地址)
        :param ttl:解析生效时间
        :param rtype:记录类型(默认为'A',即跳转到 ip4 地址)
        :return None
        """
        data = {
            'Action': 'UpdateDomainRecord',
            'RecordId': record_id,
            "RR": rr,
            "Type": rtype,
            "Value": value,
            "TTL": ttl
        }
        data.update(self._common_req_params)

        signature = self.get_signature(**data)
        data['Signature'] = signature
        res = requests.post(self.base_host, data=data)
        logger.info("更新域名记录结果:" + res.text)
        return None

    @staticmethod
    def get_ip():
        """
        获取本机外网ip
        接口是利用阿里云函数计算服务(有免费额度)提供,比爬取网络获取方便。
        """
        req_url = 'https://1142905836248003.cn-shanghai.fc.aliyuncs.com/2016-08-15/proxy/musicApi/get_ip/'
        return requests.get(req_url).text


if __name__ == "__main__":
    eg = DynamicRouter(access_key_id='your-appid', access_key_secret='your-secret')
    record_id = eg.get_record_id('your-DomainName', 'your-RR')
    eg.update_domain_record(record_id=record_id, rr='blog', value=eg.get_ip())

标签:self,record,key,signature,服务器,data,id,个人电脑
来源: https://blog.csdn.net/big__v/article/details/90084227