家用网络下构建外网可访问的内网服务器
原文链接
欢迎大家对于本站的访问 - AsterCasc
前言
对于资源需求低的或者对于稳定性要求比较高的服务,我们一般是放在运营商的服务器上进行访问。但是如果面对一些资源需求比较高的服务,比如编译运算、模型训练等等,如果在服务器上进行处理那么需要花费的钱就比较多了,所以我们这里一般的处理方式是在内网放一台编译机,然后将端口映射到外网进行访问
实现
网络转发
这里我们需要解决两个问题,IP
和端口:
IP
首先家庭环境的IP
一般是变化的,随运营商分配的,不差钱的小伙伴可以直接买固定IP
即可。勤俭持家的小伙伴的处理方式也比较简单,在你常用的云平台(腾讯云、阿里云之类)申请一个域名,然后在内网写一个服务,定时获取当前的公网IP
,然后根据不同云平台的API
将该IP
和域名映射起来,当检测到IP
改变的时候,重新映射即可,腾讯云示例如下:
// 定时任务
@Scheduled(cron = "*/10 * * * * ?")
public void updateDnsForInner() {
if (lock.tryLock()) {
try {
// 获取当前公网IP地址
String url = ipAddressApiService.getIpAddress();
if (!Objects.equals(currentIpAddress, url)) {
// 内存暂存
currentIpAddress = url;
// 更新记录IP值
Long recordId = tencentDnsBiz.getDnsList();
tencentDnsBiz.updateDnsRecord(recordId, currentIpAddress);
log.info("[op:NezukoScheduled:updateDnsForInner] update success for {}", currentIpAddress);
}
} catch (Exception exception) {
log.error("", exception);
} finally {
lock.unlock();
}
} else {
log.error("[op:NezukoScheduled:updateDnsForInner] Update Dns timeout!");
}
}
// 更新映射
public Long getDnsList() {
try {
Credential cred = new Credential(secretId, secretKey);
DnspodClient client = new DnspodClient(cred, null);
DescribeRecordListRequest req = new DescribeRecordListRequest();
// 配置文件域名和子域名
req.setDomain(domain);
req.setSubdomain(innerSubdomain);
DescribeRecordListResponse resp = client.DescribeRecordList(req);
if (Arrays.stream(resp.getRecordList()).findFirst().isPresent()) {
RecordListItem firstData = Arrays.stream(resp.getRecordList()).findFirst().get();
if (Objects.equals(firstData.getName(), innerSubdomain)) {
return firstData.getRecordId();
}
} else {
log.error(JSON.toJSONString(resp));
}
} catch (Exception exception) {
log.error("", exception);
}
return null;
}
对于获取当前内网的公网IP
可以直接curl https://www.ifconfig.me
获取,Spring
项目下直接使用OpenFeign
即可:
@FeignClient(name = "ip-helper", url = "${nezuko.dns.check-server}")
public interface IpAddressApiService {
@GetMapping()
String getIpAddress();
}
端口
这个就比较简单了,直接在路由器和光猫里面配置端口映射即可,注意最好不要使用常用端口,比如22
、443
、8080
、80
等等。而且最好将内网设备的MAC
地址和IP
地址绑定,比如在路由器中设置设备的MAC
地址12:85:4e:0f:3d:a7
绑定到192.168.1.100
,谨慎起见,可以对于光猫也进行相同设置,将路由器MAC
地址和分配IP
绑定
比如光猫映射为7777
到10.0.0.1:7777
,路由器映射为7777
到192.168.1.100:22
即可
连接实现
命令行连接
假设申请域名为domin.com
,内网子域名为home
,按照上文的配置示例,使用命令行ssh your_username@home.domin.com -p 7777
即可完成连接
注意:这里如果你是在内网进行测试的,会遇到NAT
回流问题(即,内网中的设备通过公网IP
地址访问同一内网中的另一个设备时,由于网络地址转换NAT
的存在,可能会导致访问失败或行为异常的问题)无法连接上。如果只是测试,可以将远程连接设备连上手机热点进行测试。如果希望解决这个问题,可以参考本站文章:使用Docker搭建轻量级内网DNS服务器
桌面连接
在windows
端可以通过mstsc
使用RDP
(Remote Desktop Protocol
)实现与远程计算机的连接和控制。本身还是基于TCP/IP
协议,通过用户名和密码完成身份验证,并且使用TLS
对连接加密,保证传输数据的安全性。RDP
的协议内容,允许客户端和服务器自主定义屏幕分辨率、压缩级别、设备支持、传输模式,在高于RDP 8.0
的版本中可以使用UDP
协议加速性能,让连接更加流畅
所以对于远程桌面连接,我们需要先让Linux
有一个桌面,如果不需要桌面的小伙伴可以不用处理了,但是如果需要远程访问桌面,那么需要在Linux
中安装xrdp
让内网机器也支持RDP
协议:
sudo apt update
sudo apt install xrdp
这里如果内网上行带宽不是非常充裕的小伙伴可以调整配置,进行压缩降低传输量:
sudo vim /etc/xrdp/xrdp.ini
bitmap_compression=true
bulk_compression=true
crypt_level=low
max_bpp=16
或者如果可以使用更轻量级的桌面的环境XFCE
或者LXDE
,这种桌面环境可能对小部分应用软件支持不太好,(比如Jetbrains Toolbox
😓),但是大部分应用程序肯定是没问题的,重要的是它减少了很多体验的部分,比如动画,所以在流畅度上会提高很多:
sudo apt install xfce4 xfce4-goodiesg
echo "xfce4-session" >~/.xsession
在完成配置后,启动服务:
sudo systemctl enable xrdp
sudo systemctl start xrdp
注意:如果使用mstsc
连接,已经连接上,比如出现xrog
屏幕,要求输入密码,但是输入完成后直接崩溃的情况,可以尝试重启内网电脑
这里如果要继续压缩画质提高流畅度,可以在mstsc
连接客户端设置,在高级选项中在显示
选项卡中调低像素,以及颜色深度,在体验
选项卡中性能调成低速带宽,以及取消所有附加功能,即可获得相对更加流畅的远程体验
原文链接
欢迎大家对于本站的访问 - AsterCasc