zaki work log

作業ログやら生活ログやらなんやら

[VyOS] NAT設定を使ったネットワーク間のルーティング (手動 & Ansible / vyos_config)

VyOS自体のIPアドレス設定は前回までにできたので、ようやく(?)ネットワーク間でNATを使ったルーターとして動作するための設定をやってみる。

(試行錯誤でやってるんで「こうした方がいい」とか「いや、そのりくつはおかしい」とかあったらぜひ教えて欲しい…)

f:id:zaki-hmkc:20210415085905p:plain

  • オレンジの"network A"(172.16.0.0/23)と、グリーンの"network B"(172.29.0.0/24)があり、VyOSが両方のネットワークに接続されている
  • VyOSのIPアドレス設定は、"network A"が172.16.1.3/23(eth0)で、"network B"が172.29.0.3/24(eth1)
  • VyOSに対して設定を行うAnsibleがインストールされているホストは"network A"の左端の172.16.1.119/23
  • 今回設定するのは、"network A"にあるFedoraのホスト(172.16.1.17/23)と、"network B"にあるCentOSのホスト(172.29.0.89/24)の相互通信
  • Fedoraのホスト名はclient-dev
  • CentOSのホスト名はrestricted-node

VyOSの簡単なNAT設定はQuick Startに載っている。

docs.vyos.io

あとはNATのページ。

docs.vyos.io

NAT44とNAT66ってあるけど、66の方はIPv6用なのかな?(無知)

環境

restricted-node (CentOSホスト)

NICは1つ

[zaki@restricted-node ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:77:f6:c4 brd ff:ff:ff:ff:ff:ff
    inet 172.29.0.89/24 brd 172.29.0.255 scope global noprefixroute ens192
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe77:f6c4/64 scope link 
       valid_lft forever preferred_lft forever
[zaki@restricted-node ~]$ nmcli c s "System ens192" | grep ipv4.gateway
ipv4.gateway:                           172.29.0.3

Fedoraのホストへはpingは届かない。

[zaki@restricted-node ~]$ ping -c 4 172.16.1.17
PING 172.16.1.17 (172.16.1.17) 56(84) bytes of data.

--- 172.16.1.17 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 2999ms

client-dev (Fedoraホスト)

図には描いてないけどNICは2つで上位ネットワークにもつながってる。(今回は関係ない)

[root@client-dev ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:22:fb:ed brd ff:ff:ff:ff:ff:ff
    altname enp11s0
    inet 192.168.0.17/24 brd 192.168.0.255 scope global noprefixroute ens192
       valid_lft forever preferred_lft forever
3: ens224: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:22:fb:f7 brd ff:ff:ff:ff:ff:ff
    altname enp19s0
    inet 172.16.1.17/23 brd 172.16.1.255 scope global noprefixroute ens224
       valid_lft forever preferred_lft forever

デフォルトゲートウェイは上位ネットワークに向いている。

[root@client-dev ~]# nmcli c s ens192 | grep ipv4.gateway
ipv4.gateway:                           192.168.0.1
[root@client-dev ~]# nmcli c s ens224 | grep ipv4.gateway
ipv4.gateway:                           --
[root@client-dev ~]# ping -c 4 172.29.0.89
PING 172.29.0.89 (172.29.0.89) 56(84) bytes of data.

--- 172.29.0.89 ping 統計 ---
送信パケット数 4, 受信パケット数 0, 100% packet loss, time 3078ms

CentOSのホストへpingは届かない。

Ansible

(a2.10) [zaki@cloud-dev vyos (master)]$ ansible --version
ansible 2.10.7
  config file = /home/zaki/.ansible.cfg
  configured module search path = ['/home/zaki/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/zaki/src/ansible-sample/venv/a2.10/lib64/python3.6/site-packages/ansible
  executable location = /home/zaki/src/ansible-sample/venv/a2.10/bin/ansible
  python version = 3.6.8 (default, Nov 16 2020, 16:55:22) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]

VyOS

show versionで確認できたのね。
以下の通り。

vyos@vyos:~$ show version 

Version:          VyOS 1.4-rolling-202104061641
Release Train:    sagitta

Built by:         autobuild@vyos.net
Built on:         Wed 07 Apr 2021 01:17 UTC
Build UUID:       467750e8-bd03-4562-a102-c2e895328517
Build Commit ID:  9c63b99198c829

Architecture:     x86_64
Boot via:         installed image
System type:      VMware guest

Hardware vendor:  VMware, Inc.
Hardware model:   VMware Virtual Platform
Hardware S/N:     VMware-56 4d 5d 6e 4f 25 4a d1-64 a3 ff d0 e1 3b 48 8c
Hardware UUID:    6e5d4d56-254f-d14a-64a3-ffd0e13b488c

Copyright:        VyOS maintainers and contributors

ネットワークの状態

vyos@vyos:~$ show interfaces 
Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
Interface        IP Address                        S/L  Description
---------        ----------                        ---  -----------
eth0             172.16.1.3/23                     u/u  
eth1             172.29.0.3/24                     u/u  
lo               127.0.0.1/8                       u/u  
                 ::1/128       

network Bからnetwork AへのNAT (手動)

まずは手動で設定してみる。

VyOS設定

'172.16.0.0/23'宛のパケットでeth0からのアウトバウンドをIPマスカレード設定、という内容。
(Quick Startは「入力」でルール定義してたけど、今回は「出力」を基準にしてる)

vyos@vyos:~$ configure 
[edit]
vyos@vyos# set nat source rule 100 outbound-interface eth0
[edit]
vyos@vyos# set nat source rule 100 destination address 172.16.0.0/23
[edit]
vyos@vyos# set nat source rule 100 translation address masquerade
[edit]

これでshowを実行すると投入される↑の設定内容を確認できるので問題無ければcommitを実行。

確認

[zaki@restricted-node ~]$ ping -c 4 172.16.1.17
PING 172.16.1.17 (172.16.1.17) 56(84) bytes of data.
64 bytes from 172.16.1.17: icmp_seq=1 ttl=63 time=0.481 ms
64 bytes from 172.16.1.17: icmp_seq=2 ttl=63 time=0.501 ms
64 bytes from 172.16.1.17: icmp_seq=3 ttl=63 time=0.256 ms
64 bytes from 172.16.1.17: icmp_seq=4 ttl=63 time=0.357 ms

--- 172.16.1.17 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.256/0.398/0.501/0.102 ms

CentOS -> Fedoraへのpingが繋がるようになった。

save

再起動後も有効になるよう設定をほじするため、saveを実行。

network Aからnetwork BへのNAT (Ansible)

同じ要領で172.29.0.0/24宛のeth1からのアウトバウンド設定を今度はAnsibleで。

playbook

なんだけど、NATを設定するためのモジュールがどれかわからず…なさそう。
ということで、vyos.vyos.vyos_configモジュールを使って設定する。

---
- hosts: vyos
  gather_facts: false

  tasks:
    - name: configure nat (A to B)
      vyos.vyos.vyos_config:
        lines:
          - set nat source rule 110 outbound-interface eth1
          - set nat source rule 110 destination address 172.29.0.0/24
          - set nat source rule 110 translation address masquerade

この内容のplaybookでansible-playbook-v付けて実行すると以下の通り。

changed: [172.16.1.3] => changed=true 
  ansible_facts:
    discovered_interpreter_python: /usr/bin/python
  commands:
  - set nat source rule 110 outbound-interface eth1
  - set nat source rule 110 destination address 172.29.0.0/24
  - set nat source rule 110 translation address masquerade
  filtered: []

vyos_factsを使っても下記の情報を確認できる。

    set nat source rule 110 destination address '172.29.0.0/24'
    set nat source rule 110 outbound-interface 'eth1'
    set nat source rule 110 translation address 'masquerade'

configureモードでshowしても、natに関しては以下のように設定を確認できる。

 nat {
     source {
         rule 100 {
             destination {
                 address 172.16.0.0/23
             }
             outbound-interface eth0
             translation {
                 address masquerade
             }
         }
         rule 110 {
             destination {
                 address 172.29.0.0/24
             }
             outbound-interface eth1
             translation {
                 address masquerade
             }
         }
     }
 }

確認

デフォルトゲートウェイ設定が別ネットワークになってるので、これをVyOSに向くように変更する。

ens192の設定をいったん削除

[root@client-dev ~]# nmcli c m ens192 ipv4.gateway ""
[root@client-dev ~]# nmcli c m ens224 ipv4.gateway "172.16.1.3"

ens224にVyOS向きの設定追加

[root@client-dev ~]# nmcli c m ens192 ipv4.gateway ""
[root@client-dev ~]# nmcli c m ens224 ipv4.gateway "172.16.1.3"

設定の有効化
※ CentOS7のときはsystemctl restart networkで反映できたけどFedora33は対応するサービスがなかったのでupしてる。(reloadだけでもダメだった)

[root@client-dev ~]# nmcli c up ens192
接続が正常にアクティベートされました (D-Bus アクティブパス: /org/freedesktop/NetworkManager/ActiveConnection/3)
[root@client-dev ~]# nmcli c up ens224
接続が正常にアクティベートされました (D-Bus アクティブパス: /org/freedesktop/NetworkManager/ActiveConnection/4)
[root@client-dev ~]# ping -c 4 172.29.0.89
PING 172.29.0.89 (172.29.0.89) 56(84) bytes of data.
64 バイト応答 送信元 172.29.0.89: icmp_seq=1 ttl=63 時間=0.371ミリ秒
64 バイト応答 送信元 172.29.0.89: icmp_seq=2 ttl=63 時間=0.219ミリ秒
64 バイト応答 送信元 172.29.0.89: icmp_seq=3 ttl=63 時間=0.333ミリ秒
64 バイト応答 送信元 172.29.0.89: icmp_seq=4 ttl=63 時間=0.293ミリ秒

--- 172.29.0.89 ping 統計 ---
送信パケット数 4, 受信パケット数 4, 0% packet loss, time 3058ms
rtt min/avg/max/mdev = 0.219/0.304/0.371/0.056 ms

ちなみにこのnmcli c mによる設定変更はリブートでリセットします。今度はこの辺をまとめたい ← 勘違い。リブートしてもリセットはしない。(手動で戻したのを勘違いしてたかも)

save

(しつこいけどw)ただしこれだけのplaybookだと、VyOSをリブートしたら設定が(ry

Ansibleのvyos.vyos.vyos_configモジュールの場合は、saveパラメタをtrueに指定しておけば保存される。

    - name: configure nat (A to B)
      vyos.vyos.vyos_config:
        lines:
          - set nat source rule 110 outbound-interface eth1
          - set nat source rule 110 destination address 172.29.0.0/24
          - set nat source rule 110 translation address masquerade
        save: true

ただしこのsaveは、指定タスクの設定内容だけをsaveするのではなく、これまでの未saveの設定全てが保存される。

vyos_configの冪等性

OSコマンドを実行するためのshellcommandと異なり、ネットワークOS用のconfig系モジュールは、冪等性がある。 というのも、コマンド投入前に同じコマンドが設定済みか無いかどうかを確認しているため。(言いかえると確認する術があるため)

ただしそのとき、taskに定義した投入予定のコマンドが省略形で記載されていると比較ができなくなるため、再実行されてしまうので(taskに定義するコマンド名は省略しないように)注意が必要。

docs.ansible.com

この辺の処理をコードから追いたかったけどちょっと時間かかりそうだったので覚えてたらまた別途。


CentOSをfirewalld使ってルーター設定するのに比べると、さすがにネットワークOSは設定のコマンドやパラメタが直観的でわかりやすいな。。

zaki-hmkc.hatenablog.com


そういえば、Fedora 33のNetworkManager、設定スクリプトって/etc/NetworkManager/system-connections以下にあるのね。
/etc/sysconfig/network-scripts 以下にあるものと思い込んでたから探しちゃいましたw

あと中を見ると書式も変わってた。バージョンかなぁ。