ウィズコロナ時代の10GBpeホームネットワーク

## Introduction


<div align="center" style="text-align: center;">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img  width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87692/38137b43-e309-d1d6-9c1a-e8d31a8faa98.jpeg">
</div>


**自作ルータという存在**

コロナウイルスによりリモートワークが流行り、IT業の方では一般化しつつあります。そんな中、問題となるのが自宅のネットワーク回線になります。  

自宅でPS4, Switch, PC複数台, iPhone, iPadその他いろいろをつなぐと回線速度は落ち、pppoeなどの従来型の回線を用いていると、ネットワークが混雑している際に通信品質が低下するなど、仕事のアウトプットにも影響してきます。

自宅とインターネットとの外界をつなぐデバイスの役割は増大し、いかに高速に、いかに大容量を送受信できるかがその人の人生のQoLを担っているといっても過言ではありません。

私の自分の人生の中で最強に近いホームネットワークを構築できたので、ご紹介したいと思います。

## OS

Linuxを前提とします。今回、私はUbuntu 20.04を利用しており、他のディストロでもできると考えられます。

個人的には、UbuntuやDebianなどDebianベースのLinuxのほうがドキュメントが豊富でまとまっている印象です。

### 知っておく前提知識

pppoe、ipoe、ipアドレス、Linuxの基本的なコマンド等を知っていることが前提となります。知らない人は、このYouTuberが詳しく説明しているので見てみるのがいいでしょう。

<div align="center" style="text-align: center;">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://www.youtube.com/channel/UCMXjwK6-rRw-la5SN5j0M6g"><img  width="500px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87692/b3ea8bd9-61df-0f95-fda2-67e90d62343b.png"><br>スマサポチャンネル</a>
</div>

### 機器

**Mellanox Connectx-3**

 Amazon.co.jpでは1万円前後でRJ45ソケット（通常のLAN）が入るタイプの10GBpeのNICが売っていますが、安定性と速度において、SFP+形式のMellanox connectxが安いです。現行モデルはconnectx-6なのですが、非常に高いので、connectx-3がeBayで3500円程度で買うことが可能です。

**注**: アメリカから買うMCX311A-XCATというモデルで構築しました。同様の価格帯でeBayで売っている別モデルは中国で改造されたモデルのようで、性能が十分に出なかったりPCに刺さりませんでした。

<div align="center">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img  width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87692/b54ac719-9d7a-8f2a-78cc-064e4610835c.png">
</div>

**Mikrotik** 

Miktotikは東ヨーロッパのネットワーク企業で非常に安価に10GBpeのスイッチを販売しています。こちらもeBayで買うことが可能ですが、Aamzon.com等でも売っており、どちらで買っても良いと思います。

私が買ったのは10G・8ポート + 10G・4ポート + 10G・4ポートの合計16ポートでの利用でした。

<div align="center">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img  width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87692/2e3a7de8-d012-9188-a294-5936b3b7138a.png">
</div>


### IPoEとPPPOEのメリット・デメリット

**PPPoE**

PPPoEはADSL時代からある接続方式で、NTTの網終端で非常に混雑した状態になりがちなので、光でも遅いと言われています。

夜間などは非常に遅いのですが、メリットもあり、後述するIPoEがポート数にかなり厳しい制約があるのに、PPPoEはこれらの制約を受けていません。

つまり、遅くても大量に通信する場合はPPPoE, 早くてなんとかしたい場合はIPoEのような使い分けが期待できます。

**IPoE(ds-lite)**

IPoEにはいくつかの種類がありますが、MAP-E方式はLinuxで利用する際かなり面倒だったので、ds-lite方式がおすすめです。

ds-lite方式は、割り振られたipv6アドレスをNTT東日本の境界域サーバに接続し、ipv6アドレスでNTTにある境界域サーバというものにつなぎ、ipv4アドレスをトンネリングするという仕組みになります。

PPPoEのように網終端装置を通らなくていいので早いのですが、使用できるポートが非常に少ない1024個となっています（普通の使い方では超えない想定なのでしょうが、私は余裕で超えてしまいます）

IPoEには速度がクリティカルとなるzoomやYouTubeやGoogleなどの通信を流し、PPPoEには無駄に帯域を消耗するIT業務を割り振りたいというモチベーションがあった場合、 `ip route` でroutingを適切に設定すれば可能です。

<div align="center" style="text-align: center;">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87692/df1af935-229d-8dae-4b10-e782a26e1680.png">
(Huawei社のDS-lite説明資料より引用)
</div>

### ds-lite方式でipip6トンネリングをする

ds-lite形式でのトンネリングは `netplan` というソフトを使うと非常に楽に設定できます。これは、ipアドレスの固定だったり、DNSサーバの指定だったりとそういった内容のことを `yaml` 形式で記述し、適応することができます。

私の設定を入れているので、適宜、ご自身の環境に置き換えて設定してください

```yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    mellanox0:
      addresses:
      - 192.168.50.1/24 # 自分のLANのIP
      - 192.168.50.10/24
      dhcp4: true
      dhcp6: true
      accept-ra: true
      routes:
          - to: 0.0.0.0/0
            via: 192.168.40.1 # バックアップのネットワーク
            metric: 1
  tunnels:
    tunnel0:
      mode: ipip6
      remote: 2404:8e00::feed:100 # NTT東日本の境界サーバ
      local: 2409:10:************ # ds-liteのプロバイダからNICに振られたIPV6を記述
      routes:
        - to: 0.0.0.0/0
          metric: 100 # 優先度、0にするとすべてをtunnel経由で通信する
          scope: link
```

別途netplanの設定は自身で他のインターフェースについては設定してほしいです。

これができると `$ sudo netplan apply` でtunnelの生成から接続まで一気にやってくれます。 

### pppoeのセッションを張る

`pppoeconf` というソフトウェアを入れると対話式で、pppoeのセッションを貼ることができます。

一度セットアップが完了すると  `$ pon dsl-provider` とコマンドを打つことで `ppp0` のインターフェースが作られるので、そのインターフェースにてインターネットに接続することができます。

**最初に設定**

```bash
$ sudo pppoeconf ${INTERFACE_NAME}
```

### ip routeでIP毎のメトリクスを調整する

- DNSサーバや高応答が必要な通信はIPoE
- 大容量通信ではPPPoE

IPoEのインターフェース名を `tunnel0` 、PPPoEのインターフェース名を `ppp0` としたとき、 `ip` というコマンドを用いることでIPアドレス単位で、どちらを使うかを指定することができます。

私の場合、高応答が必要ないつも観るサイト + DNSサーバは `tunnel0` に流しており、その他の通信は `ppp0` に割り振っています。

例えば、デフォルトを `ppp0` にして、GoogleのDNSを `tunnel0` に流そうとするとき、以下のようなコマンドで実行します。

Google ChromeのhistoryをダンプしてホストからIPを引き出し、自分なりの最適化ルールを作ることができます。

```bash
$ sudo ip route add default dev ppp0 # ppp0を全体のデフォルトに設定
$ sudo ip route add 8.8.8.8/32 dev tunnel0 # 8.8.8.8/32をtunnel0に
```

### DHCPサーバ

Ubuntuでは如何のパッケージでインストールすることができます。

```bash
$ sudo apt install isc-dhcp-server -y
```

設定ファイル `/etc/dhcp/dhcpd.conf` をvim等で開き、設定したいIPの範囲を決定して書き込みます。以下の例では、 IP 192.168.50.20 ~ 192.168.50.250までのIPを自動的に付与するものです。

```bash
option domain-name-servers 8.8.8.8, 8.8.8.4;

option subnet-mask 255.255.255.0;
option broadcast-address 192.168.50.255;
subnet 192.168.50.0 netmask 255.255.255.0 {
        range 192.168.50.20 192.168.50.250;
        option routers 192.168.50.1;
}
```

設定が正しく行えたら、sysmtedを再起動します。

```bash
systemctl restart isc-dhcp-server
```

このとき、LAN側のIFに適切にIPアドレスが振られていないと、起動に失敗します。

### IPv4フォワーディングを有効にする

`/etc/sysctl.conf` をvim等で開き、以下の設定を書き込みます。これはipv4の転送を有効にするオプションです。

```bash
net.ipv4.ip_forward=1
```

設定が完了したら、以下のコマンドで設定を反映します。

```bash
$ sudo sysctl -p
```

次に、iptablesというコマンドで入ってきたデータをどのデバイスに転送するかのルールを記述します。

この設定は再起動毎にこれらの内容は消えてしまうので、スタート時に起動するようにしておくと便利です。

ここではLAN側のデバイスを `mellanox0` としており、 WAN側のデバイスを `ppp0` としていますが、後述する `ip route` コマンドも使うことでIPoEとの共存が可能になります。

```bash
export DEV_IN="mellanox0"
export DEV_EX="ppp0"
# Accept incoming packets from localhost and the LAN interface.
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i $DEV_IN -j ACCEPT
# Accept incoming packets from the WAN if the router initiated the connection.
iptables -A INPUT -i $DEV_EX -m conntrack \
--ctstate ESTABLISHED,RELATED -j ACCEPT
# Forward LAN packets to the WAN.
iptables -A FORWARD -i $DEV_IN -o $DEV_EX -j ACCEPT
# Forward WAN packets to the LAN if the LAN initiated the connection.
iptables -A FORWARD -o $DEV_IN -i $DEV_EX -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# NAT traffic going out the WAN interface.
iptables -t nat -A POSTROUTING -o $DEV_EX -j MASQUERADE
# rc.local needs to exit with 0
```

### IPv6のフォワーディングは必要がない

家のLANの作り方にもよりますが、インターネットにすべてのデバイスが接続できる状況にすると、IPv6のフォワード等は必要ありません。

IPv6が露出しているのでデバイスのfirewallが必要になる等、セキュリティのリスクがあることはあるので、個々人の判断に任せますが、この状態の運用で現在問題が起きたことがありません。

### DNS cacheサーバ

unboundと呼ばれるDNSサーバをルータにインストールすると2度以上アクセスするサイトで超高速でアクセスすることができます。

仕組みは単純で、unbound知らないホストは `8.8.8.8` や `1.1.1.1` などにアクセスして取得しますが、二度目はキャッシュされた内容に基づいて内容を返します。

```bash
$ sudo apt install unbound
```

 設定は、 `/etc/unbound/unbound.conf` でvim等で編集し、以下のような設定を書き込みます。

```bash
server:
  access-control: 10.0.0.0/8 allow
  access-control: 127.0.0.0/8 allow
  access-control: 192.168.0.0/16 allow
  aggressive-nsec: yes
  cache-max-ttl: 144000
  cache-min-ttl: 12000
  interface: 0.0.0.0
  interface-automatic: yes # ホストにいくつかIPが割り当てられているときに、複数のIPアドレスでアクセスを許可するのに必要
  rrset-roundrobin: yes
  use-caps-for-id: yes
  verbosity: 1
  num-threads: 128
  msg-cache-slabs: 128
  rrset-cache-slabs: 128
  infra-cache-slabs: 128
  key-cache-slabs: 128
  prefetch: yes
  
  rrset-cache-size: 1035m
  msg-cache-size: 512m
  so-rcvbuf: 512m

  forward-zone:
    name: "."
    forward-addr: 1.0.0.1@53#one.one.one.one
    forward-addr: 1.1.1.1@53#one.one.one.one
    forward-addr: 8.8.4.4@53#dns.google
    forward-addr: 8.8.8.8@53#dns.google
    forward-addr: 9.9.9.9@53#dns.quad9.net
    forward-addr: 149.112.112.112@53#dns.quad9.net
```

systemdの再起動を行い、正常に機能していることを確認します。

```bash
$ sudo systemctl restart unbound
```

### 実際に早くなったのか

体感値ではかなり早くなりました。

満足してメルカリ等で古いルータ等を売ってしまったので、詳細なベンチマークはできませんが、OCNさんでIPoE専用のルータを借りて運用していたときは、いろいろなソフトウェアを立ち上げると10分に一回程度クラッシュしていたので、それがなくなり改善したというのが現状です。

**LocalAreaネットワークも早い**

Network File System(nfs)を多用しているのですが、1GBpeのときはせいぜい100mbpsが限界でしたが、1gbpsまで高速化しました。夜寝る前に分散処理を走らせて寝るとかを良くするのですが、10倍早くなると、10倍の効率になるのでものすごい時短になりました。

**TorSocksを用いた接続が爆速になった**

TorSocksという、Tor回線を用いて匿名化する方法ですが、これを個人の都合でよく使う機会があります。通信が複雑でポートを大量に消費するのか、とても重くて使い物にならかなったのですが、この方法で使うことで常用ができるレベルになりました。

**会社へのVPN接続、ZOOMが安定した**

仕事で使っているVPN回線が唐突に切れる、ZOOMが唐突に切れるなどに長らく悩まされていたのですが（おそらく貧弱なルータが回線をドロップしてしまう）、だいぶ安定して用いることができるようになりました。

## YouTube
この説明はもともとYouTubeで弱小底辺YouTuberをやっている中で、リクエストが多かったルータの作り方を教えてくれというものに対応したものです。

独学なのと、ネットワークの素人が四苦八苦しながら作ったものなので粗削りで研ぎ澄まされていない側面はありすが、素人がなんかやってんなぐらいで優しい目で見ていただけますと幸いです。

<div align="center">
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://youtu.be/ei0OeTdT4m4"><img  width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87692/f3c717df-dfaf-6312-4103-6e8716aea559.png"></a>
</div>