如何实现外网访问本地服务?

/ 0评 / 0

为什么需要通过外网访问

  1. 异地联调时接口的实时更新,双方远程联调时不需要再将服务部署到服务器上更新
  2. 减少域名认证、IP认证、回调地址问题,如使用企业微信、微信支付的接口时,需要填写回调地址,传统开发模式限定了开发只能部署到线上测试,而拥有外网服务后,可以在本地实时调试更改接口
  3. 本地服务器的实现,不再需要高昂的成本购买云服务器搭建建设性服务(如GIT、SonarQube等),只要本地运行任意一台,就是一台完整的服务器

实现外网访问有哪几种方式?

  1. 公网IP + DDNS
  2. FRP等内网穿透转发服务

公网IP

预备知识点

公网IP知识点

公网IP的限制

通过以上内容可以简单得到公网IP的几项限制

  1. 公网IP的承接点是拨号端,而现在默认由光猫拨号,光猫的管理端普通用户无法登录
  2. 公网IP的承接点是拨号端,我们怎么让我们局域网内的服务运行在拨号端
  3. 移动宽带是没有公网IP的
  4. 公网IP会随着拨号,或网络的波动而变化
  5. 公网IP无法访问80端口

需要公网IP访问的前提

  1. 不能是移动宽带
  2. 必须让宽带安装人员设置光猫为桥接模式,由路由器拨号
  3. 需要解决IP变动问题
  4. 需要解决如何将路由器端口转发到局域网主机端口问题

解决方案

解决IP变化问题:DDNS

何为DDNS

DDNS是指动态域名服务,DDNS负责实时更新DNS服务器上域名和用户IP的对应关系。
DDNS会每隔几分钟检查主机的IP地址,若IP变更则向DNS服务器发送更新IP地址请求。

DDNS如何实现

以阿里云为例,需要开通阿里云的AccessKey,以调用阿里云的API实时更新DNS

代码如下:

#!/bin/sh
aliddns_name="nas"
aliddns_domain="51zidan.com"
aliddns_ak="LTAI**********RQ4DGdP"
aliddns_sk="4N1A**********3Gl3hA"

aliddns_curl="curl -s whatismyip.akamai.com"
aliddns_dns="8.8.8.8"
aliddns_ttl="600"

ip=`$aliddns_curl 2>&1`

current_ip=`nslookup $aliddns_name.$aliddns_domain $aliddns_dns 2>&1`

if [ "$?" -eq "0" ]
then
    current_ip=`echo "$current_ip" | grep 'Address 1' | tail -n1 | awk '{print $NF}'`
    if [ "$ip" = "$current_ip" ]
    then
        exit 0
    fi 
fi

timestamp=`date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ"`

urlencode() {
    # urlencode <string>
    out=""
    while read -n1 c
    do
        case $c in
            [a-zA-Z0-9._-]) out="$out$c" ;;
            *) out="$out`printf '%%%02X' "'$c"`" ;;
        esac
    done
    echo -n $out
}
enc() {
    echo -n "$1" | urlencode
}
send_request() {
    local args="AccessKeyId=$aliddns_ak&Action=$1&Format=json&$2&Version=2015-01-09"
    local hash=$(echo -n "GET&%2F&$(enc "$args")" | openssl dgst -sha1 -hmac "$aliddns_sk&" -binary | openssl base64)
    curl -s "http://alidns.aliyuncs.com/?$args&Signature=$(enc "$hash")"
}
get_recordid() {
    grep -Eo '"RecordId":"[0-9]+"' | cut -d':' -f2 | tr -d '"'
}
query_recordid() {
    send_request "DescribeSubDomainRecords" "SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&SubDomain=$aliddns_name.$aliddns_domain&Timestamp=$timestamp"
}
update_record() {
    send_request "UpdateDomainRecord" "RR=$aliddns_name&RecordId=$1&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&TTL=$aliddns_ttl&Timestamp=$timestamp&Type=A&Value=$ip"
}
add_record() {
    send_request "AddDomainRecord&DomainName=$aliddns_domain" "RR=$aliddns_name&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&TTL=$aliddns_ttl&Timestamp=$timestamp&Type=A&Value=$ip"
}
if [ "$aliddns_record_id" = "" ]
then
    aliddns_record_id=`query_recordid | get_recordid`
fi
if [ "$aliddns_record_id" = "" ]
then
    aliddns_record_id=`add_record | get_recordid`
    echo "added record $aliddns_record_id"
else
    update_record $aliddns_record_id
    echo "updated record $aliddns_record_id"
fi

主要包含几点

  1. 通过 <code>curl -s whatismyip.akamai.com 获取当前主机的公网ip
  2. 与当前DNS的IP比对,若改变则请求阿里云服务更新
  3. 设置脚本定时运行

解决端口访问问题:端口转发

需要在路由器配置 打开UPNP或者手动配置端口转发

UPNP是被动式端口转发服务,需要端口服务的提供者主动向UPNP服务请求
手动配置端口转发,只需要更新IP和端口号就行

FRP等内网穿透转发服务(以FRP为例)

与公网IP对比优点

  1. 对公网IP无要求,移动宽带也能用,不需要端口转发更不用DDNS
  2. 支持80端口
  3. 搭建简单,没有弯弯绕绕的网络只是,只需要远程转发浏览即可

与公网IP对比缺点

  1. 需要一台拥有公网IP的服务器做转发(任意一台服务器,如阿里云VPS)
  2. 访问速度不仅受限于当前网络的速度,也要受限于服务器的速度。(一般家庭500M的宽带有50M的下载、5M的下载上传,但若服务器只有2M,那么速度将仅限于2M)
  3. 中间的转发让延迟更高,速度更慢

frp服务搭建

http://blog.mokevip.top/2020/06/29/1minute-frp/

其他的内网穿透方法

结语

以上内容都是凭本人的知识点和平时的使用总结而来,若有不对的地方,敬请更正。
原创不易,感谢支持。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注