【Linux】Network Namespace ルーティング

# はじめに
以前のNamespaceの記事の続きを記載します。
[前回の投稿：Linux Network Namespace1](https://qiita.com/akihide-kato/items/9c861ded948e1bf9c81c)
今更ですが、`netns`って何かと思ったら、NETwork NameSpaceの頭文字でした。
再び気付いたことなども含めてQiita記載していきます。

#### 前回のルータがなくても通信ができた理由
本来であれば、IPを使用して構成されたネットワークはルータによる
パケットのバケツリレーによって成り立っている
ただ以前構成したIPは __"同じネットワークのセグメントに所属"__ していたため
ルータがなくても通信ができていた

つまり、ルータが必要になる場合というのは
`セグメントが異なる相手と通信をしたいときだけ`に限る

####セグメントとは
>一つのものを分割した一部分のこと
コードセグメントやデータセグメントなど複数あるらしいですが
今回は関係ないと思うので割愛します。

## IPアドレスは2つの部分に分けられている
### IPv4
32bit間の2進数の整数
例)　XXXXXXXX00000000XXXXXXXX00000000

=>　これを8bit間隔で区切ってみる
それぞれの区切られた空間を__オクテット__という
例)　XXXXXXXX00000000XXXXXXXX00000000
=>　XXXXXXXX.00000000.XXXXXXXX.00000000

これを10進数に直してみる
例)　XXXXXXXX.00000000.XXXXXXXX.00000000
=>　XXX.X.X.0

そしてこのIPアドレスはこう見えて2つの部分に分かれている
例)　XXX.X.X.__1__のIPアドレス
前半のXXX.X.Xを__ネットワーク部__
後半の1を__ホスト部__という

ネットワーク部を`ネットワークアドレス`
ホスト部を`ホストアドレス`とも言われる

### なぜ分けられているのか
__セグメント__を識別するためにある
=>　つまりネットワークアドレスが同じIPアドレスは同じセグメントに属している

- XXX.X.X.1 
- XXX.X.X.0  

24bit目で分けてみると
同じ__XXX.X.X__というネットワークアドレスになる

また前回作成したvethの値は
XXX.X.X.X/24などというものだった
この__/24__という文字列こそ`24bit目までがネットワークアドレス`であることを示している

- XXX.X.X.1/24
- XXX.X.X.2/24

よって上記2つは同じネットワーク内のセグメントに所属しているということになる

# ルータを入れてみる
前回のns1とns2というNamespaceの間にルータを介して通信ができるように設置する

```ruby:ターミナル
$ sudo ip netns add ns1
$ sudo ip netns add router
$ sudo ip netns add ns2

```
再び1から作ります。
橋渡しをする “ router “ というNamespaceも加えて作成する
続いてそれぞれのNamespace同士を繋ぐvethインターフェースを作成する
3つのNamespaceがあるので計2本のインターフェースが必要になる

```ruby:ターミナル
$ sudo ip link add ns1-veth0 type veth peer name gw-veth0
$ sudo ip link add ns2-veth0 type veth peer name gw-veth1

```

作成したvethインターフェースにそれぞれのNamespaceを所属させ、upさせる

```ruby:ターミナル
$ sudo ip link set ns1-veth0 netns ns1
$ sudo ip link set gw-veth0 netns routes
$ sudo ip link set gw-veth0 netns router
$ sudo ip link set ns2-veth0 netns ns2

$ sudo ip netns exec ns1 ip link set ns1-veth0 up
$ sudo ip netns exec router ip link set gw-veth0 up
$ sudo ip netns exec router ip link set gw-veth0 up
$ sudo ip netns exec ns2 ip link set ns2-veth0 up

```

## IPアドレスの設定をする
ns1~router間を設定
それぞれのネットワーインターフェースに同じセグメントのIPアドレスを付与する
両者は同じ__192.0.2.0/24__というセグメントに設定

```ruby:ターミナル
$ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0
$ sudo ip netns exec router ip address add 192.0.2.254/24 dev gw-veth0

```
ns2 とrouter 間も同じセグメントのIPアドレスを付与する
両者は同じ198.51.100.0/24というセグメントに設定

```ruby:ターミナル
$ sudo ip netns exec router ip address add 198.51.100.254/24 dev gw-veth1
$ sudo ip netns exec ns2 ip address add 198.51.100.1/24 dev ns2-veth0
```
図のような設定ができる
<img width="904" alt="netns3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581998/d8837f4b-b728-6d70-36ef-13d75a044b88.png">

##  ルータ越しに通信をする
ルータを介してセグメントを超えた通信ができることを確認する
今の状態でns1からns2のIPアドレスに向けてPingを打ってみる


```ruby:ターミナル
$ sudo ip netns exec ns1 ping -c 3 198.51.100.1. -I 192.0.2.1

PING 198.51.100.1 (198.51.100.1) from 192.0.2.1 : 56(84) bytes of data.
ping : sendmsg : Network is unreachable
ping : sendmsg : Network is unreachable
ping : sendmsg : Network is unreachable

—- 198.51.100.1 ping statisics —
3 packets transmitted, 0 received, 100% packet loss , time 2000ms
```

"Network is unreachable"
ネットワークに到達できないと言われ怒られてしまう。
通信が失敗する原因はNetwork Namespaceにルーティングの設定がないため
通信をするためのリレーに必要な情報はルーティングテーブルに記載されていたので
現在のルーティングテーブルを確認してみる

```ruby:ターミナル
$ sudo ip netns exec ns1 ip route show
192.0.2.0/24 dev ns1-veth0 proto karnel scope link src 192.0.2.1
```

ns1のルーティングテーブルにはルーティングエントリが1つある
192.0.2.0/24宛はns1-veth0というネットワークインターフェースで通信するという内容しかない
つまりパケット先の送信元である198.51.100.1はどのルーティングエントリにも一致しないので
`ns1がパケットを次に誰に渡せばいいのかわからなかったのが原因`

解決するにはルーティングテーブルにルーティングエントリを追加する必要がある

```ruby:ターミナル
$ sudo ip netns exec ns1 ip route add default via 192.0.2.254
```
`$ ip route add`にとってルーティングエントリを追加できる
続いてns2にも同じ悩みを抱えているので同様に設定をする

```ruby:ターミナル
$ sudo ip netns exec ns2 ip route add default via 198.51.100.254
```
改めてns1からns2にPingを打ってみる

```ruby:ターミナル
$ sudo ip netns exec ns1 ping -c 3 198.51.100.1 -I 192.0.2.1
PING 198.51.100.1 (198.51.100.1) from 192.0.2.1 : 56(84) butes of data.

— 198.51.100.1 ping statistics—
3 packets transmitted , 0 received , 100% packet loss, time 2000ms
```

errorは無くなったが、送ったpingに対して返答が戻ってきていない
`sysctlというカーネルのパラメータを設置するためのコマンドを打たないといけないらしい`
このコマンドによってカーネルのnet.ipv4.ip_forwardを1にする、パラメータを1にして有効にした
Linuxはこの`パラメータが有効になっていないとルータとして起動しない`らしい



```ruby:ターミナル
$ sudo ip netns exec router sysctl net.ipv4.ip_forward=1 net.ipv4.ip_forward=1

$ sudo ip netns exec ns1 ping -c 3 198.51.100.1 -I 192.0.2.1
PING 198.51.100.1 (198.51.100.1) from 192.0.2.1 : 56(84) butes of data.
64 bytes from 198.51.100.1 : icmp_seq=1 ttl=63 time=0022ms
64 bytes from 198.51.100.1 : icmp_seq=2 ttl=63 time=0044ms
64 bytes from 198.51.100.1 : icmp_seq=3 ttl=63 time=0066ms

—198.51.100.1 ping statistics —
```

#終わりに
ns1とns2の間をルータを介して通信が通りました。
ほとんど書籍から引用したというのもあり,,まだまだ知識不足です,,
少しずつ単語などを調べならが学んでいこうと思います。