ros ddns portmap

RouterOS 配置ddns、端口转发、内网回流

需要有公网IP

RouterOS DDNS配置

System->Scripts 添加一个脚本,内容如下,依赖 https://github.com/kirileec/Aliddns-Ros 这个我自己写的小服务(同时还支持群晖的自定义DDNS调用)

PS:注意ROS版本升级后,fetch中需要移除 mode=http 否则会报错导致请求失败,仓库那边还没更新

 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
#xxxx处替换为需要解析的域名AccessKeyID  
:local AccessKeyID "xxxxx"  
#xxxx处替换为需要解析的域名AccessKeySecret  
:local AccessKeySecret "xxxx"   
#xxxx处替换为需要解析的域名,如baidu.com, 这里是根域名
:local DomainName "xxxx"  
#xxxx处替换为需要解析的子域名,如home.baidu.com只需要填home即可   
:local RR "nas"   
#xxxx处替换为网络出口名称,如pppoe-out1  
:local pppoe "xxxx"   

# 获取拨号接口的公网地址
:local IpAddr [/ip address get [/ip address find interface=$pppoe] address]  
:set IpAddr [:pick $IpAddr 0 ([len $IpAddr] -3)]  
:log warning "当前公网IP地址:$IpAddr"  

# 拼接请求地址
:local aliddns "https://ros.linx.run/aliddns?AccessKeyID=$AccessKeyID&AccessKeySecret=$AccessKeySecret&RR=$RR&DomainName=$DomainName&IpAddr=$IpAddr"  

# 调用
:local result [/tool fetch url=("$aliddns") http-method=get as-value output=user];  
:log warning $result  

:if ($result->"status" = "finished") do={  

:if ($result->"data" = "loginerr") do={  
:log warning "阿里云登录失败!!";  
}  
:if ($result->"data" = "iperr") do={  
:log warning "修改解析地址信息失败!";  
}  
:if ($result->"data" = "ip") do={  
:log warning "修改解析地址信息成功!";  
}  
:if ($result->"data" = "domainerr") do={  
:log warning "添加新域名解析失败!";  
}  
:if ($result->"data" = "domain") do={  
:log warning "添加新域名解析成功!";  
}  
:if ($result->"data" = "same") do={  
:log warning "当前配置解析地址与公网IP相同,不需要修改!";  
}  
:if ($result->"data" = "ip") do={  
:log warning "更新IP信息成功!";  
:log warning "$IpAddr!";  
}  
:if ($result->"data" = "domain") do={  
:log warning "增加域名信息成功!";  
}  
}  
} 

每个需要DDNS的子域名都配置一个脚本即可。

System->Scheduler 添加一个定时任务,间隔随意,内容就调用上面的脚本即可

RouterOS端口转发

IP->Firewall->NAT

1
2
3
4
5
6
7
0    ;;; portmap
      chain=dstnat action=dst-nat to-addresses=内部IP to-ports=内部端口 protocol=tcp dst-address=公网IP in-interface=拨号接口 dst-port=外部端口 log=no 
      log-prefix="" 

 0    ;;; portmap
      chain=dstnat action=dst-nat to-addresses=内部IP to-ports=内部端口 protocol=tcp dst-address=公网IP in-interface=lan桥接接口 dst-port=外部端口 log=no 
      log-prefix=""  

这里两条的注释都为portmap,是为了方面后面脚本进行查找。第一条为外部进来的端口转发,第二条为局域网内部如果也使用ddns域名访问时的转发

自动更新上面两条的公网IP部分,脚本如下,依然是加个定时任务。 这样就可以在pppoe重新拨号后,更新 dst-address的值了

1
2
3
4
5
6
7
8
# 获取当前公网IP
:global ddnsinterface 拨号接口
:global ddnsip ""
:set ddnsip [/ip address get [find interface=$ddnsinterface] address]
:set ddnsip [:pick $ddnsip 0 [:find $ddnsip "/"]]
# 这里偷懒就不进行if判断了,把nat里所有注释为portmap的都更新一下
# 主要是还不知道如何批量进行if判断,(lll¬ω¬)
/ip firewall nat set [find comment="portmap"] dst-address=$ddnsip

RouterOS内网回流

迫于局域网也想使用同一个域名访问特定的服务(比如不想加好几个书签之类的)

1
2
0    ;;; huiliu
      chain=srcnat action=masquerade protocol=tcp src-address=10.10.0.0/24 out-interface=lan桥接接口 dst-port=内部端口 log=no log-prefix=""

这一句的意思是,当10.10.0.0/24这个网段的设备要访问lan内部的服务时,进行伪装。假设 10.10.0.5:5001 是我们需要端口转发的服务,当使用 http://10.10.0.5:5001 访问时,是不会匹配到这条masquerade规则,因为局域网内使用ip访问时,并不会经过ROS,会直接被交换机转发给对应设备

Licensed under CC BY-NC-SA 4.0
记录平时瞎折腾遇到的各种问题, 方便查找
使用 Hugo 构建
主题 Stack 3.29.0Jimmy 设计