<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>OpenWrt on 華鳥風月</title>
    <link>https://blog.9-ch.com/tags/openwrt/</link>
    <description>Recent content in OpenWrt on 華鳥風月</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh-cn</language>
    <lastBuildDate>Wed, 20 Apr 2022 17:59:11 +0800</lastBuildDate><atom:link href="https://blog.9-ch.com/tags/openwrt/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>RouterOS 通过 OSPF IP分流至 OpenWrt</title>
      <link>https://blog.9-ch.com/post/homelab-ros-ospf/</link>
      <pubDate>Wed, 20 Apr 2022 17:59:11 +0800</pubDate>
      
      <guid>https://blog.9-ch.com/post/homelab-ros-ospf/</guid>
      <description>ROS ip 分流方案</description>
      <content:encoded><![CDATA[<h3 id="更新">更新</h3>
<ul>
<li>2022-05-17 修改后的方案(带配置) <a href="https://blog.9-ch.com/post/homelab-no-cn-routes/">RouterOS 通过 OSPF IP分流非CN流量</a></li>
</ul>
<h3 id="组网参考">组网参考</h3>
<p>Reflist:</p>
<ul>
<li><a href="https://www.truenasscale.com/2021/12/13/195.html">使用RouterOS，OSPF 和OpenWRT给国内外 IP 分流</a></li>
<li><a href="https://www.kn1f4.com/news/767.html">RouterOS路由OSPF协议+树莓派分流国外流量</a></li>
</ul>
<p>主要适用于不想折腾PS/XBOX/Switch设备网关配置,又不希望出口网关为卵漏油/AIB的,或者怕折腾网络时家里断网影响家人的</p>
<p>遇到一些问题记录一下</p>
<h3 id="ros-ddns失效">ROS DDNS失效</h3>
<p>表现: 域名解析ip不正确</p>
<p>原因: 分流后ROS内置ip cloud(DDNS)流量同样会被指向OpenWrt导致错误,尝试打标签bypass对应udp流量未成功,因为有公网IP所以直接改为通过域名服务商API更新对应解析为PPPOE接口地址</p>
<p>解决: 修改以下脚本中&quot;CloudFlare variables&quot;段内容即可.原始脚本见<a href="https://github.com/mike6715b/Mikrotik_CF_DDNS">Mikrotik_CF_DDNS</a></p>
<details>
  <summary>Cloudflare DDNS ROS脚本(IPV4)</summary>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">#########################################################################
</span></span><span class="line"><span class="cl">#         ==================================================            #
</span></span><span class="line"><span class="cl">#         $ Mikrotik RouterOS update script for CloudFlare $            #
</span></span><span class="line"><span class="cl">#         ==================================================            #
</span></span><span class="line"><span class="cl">#                                                                       #
</span></span><span class="line"><span class="cl"># - You need a CloudFlare account &amp; api key (look under settings),      #
</span></span><span class="line"><span class="cl">#   a zone and A record in it                                           #
</span></span><span class="line"><span class="cl"># - All variables in first section are obvious,                         #
</span></span><span class="line"><span class="cl">#   except CFid and CFzoneid                                            #
</span></span><span class="line"><span class="cl"># - Obtain CFzoneid from Cloudflare Dashboard,                          #
</span></span><span class="line"><span class="cl">#   on Overview tab scroll down                                         # 
</span></span><span class="line"><span class="cl">#   To obtain CFid use following command in any unix shell:             #
</span></span><span class="line"><span class="cl">#    curl -X GET &#34;https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/dns_records?name=YOUR_DOMAIN&#34; -H &#34;Authorization:Bearer $CFtkn&#34; -H &#34;Content-Type: application/json&#34; | python -mjson.tool
</span></span><span class="line"><span class="cl"># - You can use my Postman script to get those variables                #
</span></span><span class="line"><span class="cl"># - Enable CFDebug if needed - it&#39;ll print some info to logs            #
</span></span><span class="line"><span class="cl"># - Enable CFcloud if you don&#39;t get a public IP on interface            #
</span></span><span class="line"><span class="cl"># - Put script under /system scripts giving &#34;read,write,ftp&#34; policy access.       #
</span></span><span class="line"><span class="cl">#   For 6.29 and older &#34;test&#34; policy is also needed.                    #
</span></span><span class="line"><span class="cl"># - Add script to /system scheduler using it&#39;s name in &#34;on-event&#34;       #
</span></span><span class="line"><span class="cl"># - Requires at least RouterOS 6.44beta75 for multiple header support   #
</span></span><span class="line"><span class="cl">#                                                                       #
</span></span><span class="line"><span class="cl">#              Credits for Samuel Tegenfeldt, CC BY-SA 3.0              #
</span></span><span class="line"><span class="cl">#                        Modified by kiler129                           #
</span></span><span class="line"><span class="cl">#                        Modified by viritt                             #
</span></span><span class="line"><span class="cl">#                        Modified by asuna                              #
</span></span><span class="line"><span class="cl">#                        Modified by mike6715b                          #
</span></span><span class="line"><span class="cl">#                                                                       #
</span></span><span class="line"><span class="cl">#               Tested and working as of February 22, 2021              #
</span></span><span class="line"><span class="cl">#########################################################################
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">################# CloudFlare variables #################
</span></span><span class="line"><span class="cl">:local CFDebug &#34;false&#34;
</span></span><span class="line"><span class="cl">:local CFcloud &#34;false&#34;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:global WANInterface &#34;[YOUR_WAN_INTERFACE_NAME]&#34;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:local CFdomain &#34;[YOUR_DOMAIN]&#34;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:local CFtkn &#34;[YOUR_CF_TOKEN]&#34;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:local CFzoneid &#34;[YOUR_CF_ZONE_ID]&#34;
</span></span><span class="line"><span class="cl">:local CFid &#34;[YOUR_CF_ID]&#34;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:local CFrecordType &#34;&#34;
</span></span><span class="line"><span class="cl">:set CFrecordType &#34;A&#34;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:local CFrecordTTL &#34;&#34;
</span></span><span class="line"><span class="cl">:set CFrecordTTL &#34;60&#34;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">#########################################################################
</span></span><span class="line"><span class="cl">########################  DO NOT EDIT BELOW  ############################
</span></span><span class="line"><span class="cl">#########################################################################
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:log info &#34;Updating $CFDomain ...&#34;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">################# Internal variables #################
</span></span><span class="line"><span class="cl">:local previousIP &#34;&#34;
</span></span><span class="line"><span class="cl">:global WANip &#34;&#34;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">################# Build CF API Url (v4) #################
</span></span><span class="line"><span class="cl">:local CFurl &#34;https://api.cloudflare.com/client/v4/zones/&#34;
</span></span><span class="line"><span class="cl">:set CFurl ($CFurl . &#34;$CFzoneid/dns_records/$CFid&#34;);
</span></span><span class="line"><span class="cl"> 
</span></span><span class="line"><span class="cl">################# Get or set previous IP-variables #################
</span></span><span class="line"><span class="cl">:if ($CFcloud = &#34;true&#34;) do={
</span></span><span class="line"><span class="cl">    :set WANip [/ip cloud get public-address]
</span></span><span class="line"><span class="cl">};
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:if ($CFcloud = &#34;false&#34;) do={
</span></span><span class="line"><span class="cl">    :local currentIP [/ip address get [/ip address find interface=$WANInterface ] address];
</span></span><span class="line"><span class="cl">    :set WANip [:pick $currentIP 0 [:find $currentIP &#34;/&#34;]];
</span></span><span class="line"><span class="cl">};
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:if ([/file find name=ddns.tmp.txt] = &#34;&#34;) do={
</span></span><span class="line"><span class="cl">    :log error &#34;No previous ip address file found, createing...&#34;
</span></span><span class="line"><span class="cl">    :set previousIP $WANip;
</span></span><span class="line"><span class="cl">    :execute script=&#34;:put $WANip&#34; file=&#34;ddns.tmp&#34;;
</span></span><span class="line"><span class="cl">    :log info (&#34;CF: Updating CF, setting $CFDomain = $WANip&#34;)
</span></span><span class="line"><span class="cl">    /tool fetch http-method=put mode=https output=none url=&#34;$CFurl&#34; http-header-field=&#34;Authorization:Bearer $CFtkn,content-type:application/json&#34; http-data=&#34;{\&#34;type\&#34;:\&#34;$CFrecordType\&#34;,\&#34;name\&#34;:\&#34;$CFdomain\&#34;,\&#34;ttl\&#34;:$CFrecordTTL,\&#34;content\&#34;:\&#34;$WANip\&#34;}&#34;
</span></span><span class="line"><span class="cl">    :error message=&#34;No previous ip address file found.&#34;
</span></span><span class="line"><span class="cl">} else={
</span></span><span class="line"><span class="cl">    :if ( [/file get [/file find name=ddns.tmp.txt] size] &gt; 0 ) do={ 
</span></span><span class="line"><span class="cl">    :global content [/file get [/file find name=&#34;ddns.tmp.txt&#34;] contents] ;
</span></span><span class="line"><span class="cl">    :global contentLen [ :len $content ] ;  
</span></span><span class="line"><span class="cl">    :global lineEnd 0;
</span></span><span class="line"><span class="cl">    :global line &#34;&#34;;
</span></span><span class="line"><span class="cl">    :global lastEnd 0;   
</span></span><span class="line"><span class="cl">            :set lineEnd [:find $content &#34;\n&#34; $lastEnd ] ;
</span></span><span class="line"><span class="cl">            :set line [:pick $content $lastEnd $lineEnd] ;
</span></span><span class="line"><span class="cl">            :set lastEnd ( $lineEnd + 1 ) ;   
</span></span><span class="line"><span class="cl">            :if ( [:pick $line 0 1] != &#34;#&#34; ) do={   
</span></span><span class="line"><span class="cl">                #:local previousIP [:pick $line 0 $lineEnd ]
</span></span><span class="line"><span class="cl">                :set previousIP [:pick $line 0 $lineEnd ];
</span></span><span class="line"><span class="cl">                :set previousIP [:pick $previousIP 0 [:find $previousIP &#34;\r&#34;]];
</span></span><span class="line"><span class="cl">            }
</span></span><span class="line"><span class="cl">    }
</span></span><span class="line"><span class="cl">}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">######## Write debug info to log #################
</span></span><span class="line"><span class="cl">:if ($CFDebug = &#34;true&#34;) do={
</span></span><span class="line"><span class="cl"> :log info (&#34;CF: hostname = $CFdomain&#34;)
</span></span><span class="line"><span class="cl"> :log info (&#34;CF: previousIP = $previousIP&#34;)
</span></span><span class="line"><span class="cl"> :log info (&#34;CF: currentIP = $currentIP&#34;)
</span></span><span class="line"><span class="cl"> :log info (&#34;CF: WANip = $WANip&#34;)
</span></span><span class="line"><span class="cl"> :log info (&#34;CF: CFurl = $CFurl&amp;content=$WANip&#34;)
</span></span><span class="line"><span class="cl"> :log info (&#34;CF: Command = \&#34;/tool fetch http-method=put mode=https url=\&#34;$CFurl\&#34; http-header-field=&#34;Authorization:Bearer $CFtkn,content-type:application/json&#34; output=none http-data=\&#34;{\&#34;type\&#34;:\&#34;$CFrecordType\&#34;,\&#34;name\&#34;:\&#34;$CFdomain\&#34;,\&#34;ttl\&#34;:$CFrecordTTL,\&#34;content\&#34;:\&#34;$WANip\&#34;}\&#34;&#34;)
</span></span><span class="line"><span class="cl">};
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">######## Compare and update CF if necessary #####
</span></span><span class="line"><span class="cl">:if ($previousIP != $WANip) do={
</span></span><span class="line"><span class="cl"> :log info (&#34;CF: Updating CF, setting $CFDomain = $WANip&#34;)
</span></span><span class="line"><span class="cl"> /tool fetch http-method=put mode=https url=&#34;$CFurl&#34; http-header-field=&#34;Authorization:Bearer $CFtkn,content-type:application/json&#34; output=none http-data=&#34;{\&#34;type\&#34;:\&#34;$CFrecordType\&#34;,\&#34;name\&#34;:\&#34;$CFdomain\&#34;,\&#34;ttl\&#34;:$CFrecordTTL,\&#34;content\&#34;:\&#34;$WANip\&#34;}&#34;
</span></span><span class="line"><span class="cl"> /ip dns cache flush
</span></span><span class="line"><span class="cl">    :if ( [/file get [/file find name=ddns.tmp.txt] size] &gt; 0 ) do={
</span></span><span class="line"><span class="cl">        /file remove ddns.tmp.txt
</span></span><span class="line"><span class="cl">        :execute script=&#34;:put $WANip&#34; file=&#34;ddns.tmp&#34;
</span></span><span class="line"><span class="cl">    }
</span></span><span class="line"><span class="cl">} else={
</span></span><span class="line"><span class="cl"> :log info &#34;CF: No Update Needed!&#34;
</span></span><span class="line"><span class="cl">}
</span></span></code></pre></td></tr></table>
</div>
</div></details>
<h3 id="tcp流量握手缓慢">TCP流量握手缓慢</h3>
<p>表现: 访问网站时打开缓慢,F12查看SSL阶段时间长度接近甚至超过10秒</p>
<p>原因: OP与ROS在同一网段,进出流量路由不对称,触发ROS防火墙动作</p>
<p>解决: 禁用ROS防火墙drop invalid规则(位于ip-firewall-filter rules)</p>
<h3 id="icmpping异常">ICMP(Ping)异常</h3>
<p>表现: ping 被分流网段ip时黑洞</p>
<p>原因: 出口Op通过TProxy只能处理TCP/UDP流量</p>
<p>解决:</p>
<ul>
<li>A: Op添加 ICMP劫持(假响应,可规避一些软件的报错)</li>
<li>B: ROS给ICMP流量打上bypass的route标签,再创建一个bypass路由表,该表不包含OSPF宣告的分流规则,所以如果没有被ISP之类的劫持就是裸连的真响应</li>
</ul>
<h3 id="openwrt无法与被分流网段通信循环">Openwrt无法与被分流网段通信(循环)</h3>
<p>表现: OpenWrt与被分流网段通信时不通</p>
<p>原因: ROS接到宣告的表后循环Op-&gt;ROS-&gt;Op-&gt;&hellip;</p>
<p>解决: 给Op流量打上标签,直接走bypass表</p>
<p>防火墙规则(Mangle)可参考</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">chain=prerouting action=mark-routing new-routing-mark=bypass passthrough=yes src-address=[BYPASS_DEVICE_IP] dst-address-list=!private log=no log-prefix=&#34;&#34;
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="dns-cdn优化">DNS CDN优化</h3>
<p>表现: 不需要分流区域域名CDN解析为分流区域</p>
<p>原因: Op全局流量隧道,DNS解析也被隧道处理,导致CDN失效</p>
<p>解决: dnsmasq-full分流list外走国内DNS服务,list内走DoH,Op故障时回落全国内DNS服务</p>
<h3 id="openwrt访问内网异常">OpenWrt访问内网异常</h3>
<p>表现: Op所在子网广播域外的其他子网访问Op时,无法正常响应</p>
<p>原因: Op走了bypass表,未添加其他子网路由,下一跳直接从pppoe-out出去了</p>
<p>解决: 防火墙匹配src address为op的ip,dst address为需要支持访问子网流量打上main标签走main路由表</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
