Site cover image

mat2uken-blog

going further, being lazy

OpenWRTでtransix固定IP1接続(フレッツ 光クロス ONU直収)

いろんなところでやられているので、そこまで苦労せずに接続できたけど一応メモ。

これまではER-4で雑にipip6でトンネル設定して接続していたが、一応10Gなんで1Gでリンクしてるのもったいないなというのと、TailscaleのExit Nodeにするにはちょっと非力だなぁと思っていたので、年末年始の時間をつかってN100のミニPCで2.5G x2ポートあるPCにOpenWRTを入れた環境に移行した。

自宅の環境は下記のような感じ。

  • OpenWRTを入れるのはN100の2万円くらいで買ったPC。RAMは16GB。
  • フレッツ 光クロス 10G(クロスだとどちらにせよ、DHCPv6-PDで/56のprefixが降ってくるようなので、関係なさそうだが、ひかり電話はなし)
  • OpenWRTのWAN側にするポートとONUは直結
  • ISPはInterlinkのZOOT Native 固定IP1
  • メイン回線は別途コミュファが引かれているので固定IPが欲しい時に出ていく経路として使う

まずはOpenWRTのインストール。特にプリインストールしたWindowsを使うつもりもないのだが、とりあえずはUSBメモリにインストールしてそちらから起動する。

これ自体は、OpenWRTのext4のイメージを公式から持ってきてRufusで書き込むだけ。

とりあえずはIPv4が使えればそれで良いので、192.168.99.1/24で固定IP設定して、SSHで繋がることを確認したら、それ以降はリモートで作業する。

WAN側のポートはすでにONUと直結していて、2.5Gでリンクアップされていることは確認できた。

Image in a image block

まずはフレッツ側からv6のアドレスをもらうところから。

とりあえず、DUID-LLなるものをちゃんと送らないと、DHCPv6でprefixは降ってこないということだったのでどうしようかなと思ったが、どうやら今はそういうことはなく、設定はせずとも普通にDHCPv6-PDでprefixが降ってくるようだ。

Image in a image block

これで、/56のprefixが受け取れたことが下記のようにWebUIから確認できる。

まずはv4の疎通を目指すことにして、ipip6トンネルを張れるようにする。

interlinkのマイページから設定を見ると、トンネルの対向アドレスが書かれていて、こちら側は::feedのアドレスから接続せねばならないということのようなので、下記のように設定してwan6のv6アドレスをインターフェースIDが::feedになるようにする。

Image in a image block

IPv6 assignment lengthを56にして、IPv6 suffixを::feedにすると設定されたのでこれで良さそう。

Image in a image block

次は、ipip6トンネルのインターフェースを追加するのが良さそうだが、どうやら公式のリポジトリのパッケージだけでは不足のようで、GitHubの方からのパッケージを上書きしてファイルを追加するとよい、というのを見つけたので、opkgでインストール。

https://qiita.com/kouhei-ioroi/items/b864c1571202799d6d53

これで、Interfaceにipip6の選択肢が増えるので、ここにトンネルの設定を足していく。

といっても、Tunnel remote IPを設定して、とりあえず設定用のIPにcurlでリクエストを送る(prefixを登録してる?)だけでサクッと繋がる。

Image in a image block

Local IPv6 addressは空白にしておけば::feedのアドレスが使われるようなので空白に。これで一応、prefixが変わっても追従してくれる?ことを期待。

これで、とりあえず、ping 1.1.1.1とかやると疎通することが確認できる。

設定更新用のHTTPリクエストは定期的に送っておいたほうが良さそうなので、Scheduled Taskにcurlでリクエストを送る設定を入れておく。

13 * * * * /etc/config/transix_update_config_request.sh

シェルスクリプトの中身は、

#!/bin/sh

curl "http://update.transix.jp/request?username=xxxxx&password=yyyyy"

とリクエストを送るだけ。

あとはFirewallの設定で、lanから来たパケットをt6sのzoneに対してはacceptになるように設定すると、LAN内の端末からの通信も外に出ていくようになる。(当然だが、デフォルトゲートウェイをこのOpenWRTにしておく必要はある)

とりあえずこれで固定IPで出て行きたい時はデフォルトゲートウェイをこちらにすれば普通に使えるようになる。

Tailscaleのインストール

opkgでインストールすると入れられるようなので入れてみる。ただ、ちょっと古いようなので、tailscale update実行してみたところ容量不足。そういえば、rootfsは100MBくらいしかなかったんだった。

ext4のイメージを選んでいたので、resizefsすれば良さそうだと思って検索したところ、サクッとやってくれるスクリプトが公開されていたので、これでUSBメモリ分まで拡大(64GB)

https://openwrt.org/docs/guide-user/advanced/expand_root

Image in a image block

これで容量を空けたあとに、再度アップデートしたところ最新になった。

この状態で、tailscaleはsubnet routerとexit nodeのadvertiseをするようにしてupする。

公式にも書かれているが、subnet routerで指定するネットマスクを自宅のLANと同様に/24にしてしまうと、同一サブネット内にいて、tailscaleのクライアントが動いているとLAN内の通信にも関わらず、subnet routerを経由してしまうようになるので、advertizeするネットマスクを無駄に広くする。今回の場合は、宅内は/24だが、設定は/23にする。

https://tailscale.com/kb/1023/troubleshooting#lan-traffic-prioritization-with-overlapping-subnet-routes

また、Exit Nodeに関しては、Firewallでtailscale0からの通信をWANに向けても許可する必要がある。

--snat-subnet-routes=falseを設定している場合は、コミュファ側のルータにstatic routeを設定して100.64.0.0/64に対してパケットがこのOpenWRTのルータ経由で戻るようにしておく必要がある(そもそもマスカレードをOFFにしなければよいだけだが)

ここまでで、ざっくり

  • フレッツネクストでONUから直収でDHCPv6-PDでprefixを受け取る&ipip6でトンネルを張る
  • TailscaleのExit Nodeとして振る舞うための諸々を整える

までができた。

ただ、これだと、Exit Nodeとして指定されたときに、v6の疎通ができないようだ。wan6に::feedのアドレスがあって、OpenWRTからだとwww.google.comとかにping6が通るのでv6で出て行けないわけではないはずではあるのだが。

と思いながら、そういえばtailscale0のv6アドレスはfd7a:115c:afe0::/48というULAなアドレスが振られているだけなので、このルータを経由してWANに出てきたいならv6のマスカレードをしてやらねばいけないのか、というのに気づいて、NAT Ruleを設定する。

Image in a image block

とりあえず、ソースアドレスが上記fd7a:115c:afe0::/48で、WANに出ていくときにはマスカレードするように設定した。

実際はこれだけではダメで、source routingも無効にしないと正常にNATしてくれないようだ。

Image in a image block

::feedのインターフェースIDが設定されているインターフェース(ここではwan6)のAdvanced Settingsの中のIPv6 source routingの設定を外したところ、無事マスカレードされるようになり、Exit Nodeに指定されたときにもv6での疎通が可能になった

Image in a image block

あとは、DHCPサーバもER-Xで動作している状態だったのでせっかくなのでこちらに集約する。

といっても、こちらは特に難しいことはなく、lanインターフェースのDHCP Serverを有効にする以外はこれといって必要なし。

端末によって配りたいデフォルトゲートウェイやDNSサーバを変えたいのので、Static Leaseにして、t6sgatewayというtagをつくって、個別に割り当てるようにしている。

ちなみに、tagはWebUI(luci)からはどうやって作るかわからなかったので、/etc/config/dhcpのファイルを直接編集してtagを追加した。

あとはNextDNS CLIを入れようかと思ったが、そもそもTailscaleが普通にうごいているので、dnsmasqのforwarderとして100.100.100.100を設定すればTailscale経由でNextDNSを見れる(Tailscale側でDNS設定でglobal DNS serverにNextDNSのprofile IDを指定する)のでそれでいいかということにした。

ちなみに、100.100.100.100をリゾルバとして使えるようにするためには、tailscale upのときに、—accept-dns=trueにする必要があるが、こうしてしまうと、/etc/resolv.confが書き換えられてしまうので、OpenWRT自身がDNSで名前を引くときに100.100.100.100を使ってしまい、内部DNSでしか引けないupdate.transix.jpの名前解決ができなくなってしまう。/etc/resolv.confを書き換えないようにできないかとも思ったが、なんかめんどくさそうだったので、Tailscale側で、update.transix.jpを引く場合には、2001:a7ff:5f01::aを使うように設定を足した。

Image in a image block

profileを切り替えたい&Tailscaleをインストールできない端末の扱いだけが若干めんどくさいのだが、それ用にはひきつづきAmlogicが入っているSTBで動いているNextDNS CLIがいるので、その端末向けのDHCPのリースでDNSサーバをそちらに向ける形で対処した。集約できるならそれに越したこともないが、dnsmasqとNextDNS CLIの連携よくわからんのだよな。

DNSサーバ周りは、NextDNSやupdate.tranisx.jpのためのサーバなど分散してしまっているのをまとめたいところだが、今のところいいかんじの構成がおもいつかないので保留。

まとめ

とりあえず、ER-4で惰性で使っていたtransix 固定IPのほうを2.5GでリンクするOpenWRTに変えて、ついでにDHCPサーバも集約できた。

速度としては、ざっくり1Gbps弱、fast.comだけは1.1Gbpsくらい出たので、2.5Gリンクに変えたことは微妙に意味はなくはなさそうだが、まあ自己満足の世界。どちらかというと、Tailscaleのバイナリが大きくなってER-XやER-4に入れるのはちょっとつらいのと、Exit Nodeで動かすとさすがにそこそこな負荷があったので、そのあたりはまるっと解消されたので満足。