概要
- オープンソースで開発されているネットワークOS
- 主にソフトウェアルータとして運用される
- Routing, VPN, Firewall, NAT, High Availabilityといった多くの機能をサポートしている
- AnsibleやAPIを利用しての設定も可能
- 推奨スペックも1CPU, 512MB Memory, 2GB Storageと軽量
検証で利用したソフトウェア
ソフトウェア | バージョン |
---|---|
VirtualBox | 6.1.26 r145957 |
Vagrant | 2.2.10 |
vagrant-vyos | 1.1.10 |
VyOS | 1.4-rolling-202204060217 |
CentOS | 7.9.2009 |
構成図
やってみたこと
- Vagrant上でVyOSのFWを構築し、動作検証する
- vagrant upからVyOSへのログイン、バージョン確認まで
- FWポリシー追加
- 動作確認
やってないこと
- IF設定, HA構成, ログ転送, Ansible, API, ゾーンベースのFWについては検証してません(リクエストあればまた検証して発表します)
参考サイト
検証内容
Vagrant上での起動
pluginのインストール
$ vagrant plugin install vagrant-vyos
(略)
Installed the plugin 'vagrant-vyos (1.1.10)'!
vagrant up
する
$ vagrant up
(略)
起動状態を確認する
$ vagrant status
Current machine states:
vyos01 running (virtualbox)
web01 running (virtualbox)
sv01 running (virtualbox)
sv02 running (virtualbox)
vyos01にログインする。初期パスワードの入力を求められる場合はvyos
$ vagrant ssh vyos01
Welcome to VyOS!
Check out project news at https://blog.vyos.io
and feel free to report bugs at https://phabricator.vyos.net
You can change this banner using "set system login banner post-login" command.
VyOS is a free software distribution that includes multiple components,
you can check individual component licenses under /usr/share/doc/*/copyright
バージョンの確認
vyos@vyos:~$ show version
Version: VyOS 1.4-rolling-202204060217
Release train: sagitta
Built by: autobuild@vyos.net
Built on: Wed 06 Apr 2022 02:17 UTC
Build UUID: 1434d2b1-ac6d-4703-9587-eb7428a1ebbc
Build commit ID: c522ff506d8544
Architecture: x86_64
Boot via: installed image
System type: KVM guest
Hardware vendor: innotek GmbH
Hardware model: VirtualBox
Hardware S/N: 0
Hardware UUID: 86d999cf-7433-4fec-9f10-2d1b334e3333
Copyright: VyOS maintainers and contributors
FWポリシー設定
- 細かい粒度でのポリシーを設定することが可能。内部的にはLinuxのnetfilterを使っている。サービス(port)、IPアドレス、ネットワーク単位でのグループ作成可能
、インターフェースまたはゾーンベースのファイアウォールポリシーをサポートしている。 -
各種ルールを定義、ルールをインターフェースに割り当てる
ことで適用される。 -
IN・OUT・LOCAL
というルールの適用形式がある- in
- IptablesのFORWARDチェインのINに該当する定義
実際にパケットが入ってくるインターフェイスに割り当てることで通信を制御する
ex.) set interfaces ethernet eth0 firewall in
- IptablesのFORWARDチェインのINに該当する定義
- out
- iptablesのFORWARDチェインのOUTに該当する定義
実際にパケットが出ていくインターフェイスに割り当てることで通信を制御する
ex.) set interfaces ethernet eth1 firewall out
- iptablesのFORWARDチェインのOUTに該当する定義
- local
- ルータ自身を宛先にしたパケットを制御する
ex.) set interfaces ethernet eth2 firewall local
- ルータ自身を宛先にしたパケットを制御する
- in
- パケットに対する制御は以下の通り
- accept:トラフィックを受け入れる
- drop:トラフィックを破棄する
- inspect:トラフィックをIPSで処理する
- reject:トラフィックを停止する.その際TCPリセットを返す.
- デフォルトはall:allでacceptされている
- デフォルトはステートレス、ステートフルにも変えられるらしいが今回は試してない
通信許可設定
以下、設定コマンド(より良い設定方法もあると思われる)
vyoq01へのpingを無効にする
# set firewall all-ping disable
web01からvyos01へ送られるパケットに対するルール設定(vyos_eth1)
# set firewall name rule_eth1_in default-action drop
# set firewall name rule_eth1_in enable-default-log
# set firewall name rule_eth1_in rule 10 action accept
# set firewall name rule_eth1_in rule 10 source address 192.168.0.0/24
# set firewall name rule_eth1_in rule 10 destination address 192.168.10.0/24
# set interface ethernet eth1 firewall in name rule_eth1_in
sv01とsv02からvyos01へ送られるパケットに対するルール設定(vyos_eth2)
# set firewall name rule_eth2_in default-action drop
# set firewall name rule_eth2_in enable-default-log
# set firewall name rule_eth2_in rule 20 action accept
# set firewall name rule_eth2_in rule 20 source address 192.168.10.0/24
# set firewall name rule_eth2_in rule 20 destination address 192.168.0.0/24
# set interface ethernet eth2 firewall in name rule_eth2_in
vyosからsv01とsv02へ送られるパケットに対するルール設定(vyos_eth2)
# set firewall name rule_eth2_out enable-default-log
# set firewall name rule_eth2_out rule 30 action drop
# set firewall name rule_eth2_out rule 30 destination port 8280
# set firewall name rule_eth2_out rule 30 protocol tcp
# set interface ethernet eth2 firewall out name rule_eth2_out
vyosからweb01へ送られるパケットに対するルール設定(vyos_eth1)
# set firewall name rule_eth1_out enable-default-log
# set firewall name rule_eth1_out rule 40 action drop
# set firewall name rule_eth1_out rule 40 source address 192.168.10.12/32
# set firewall name rule_eth1_out rule 40 destination port 80
# set firewall name rule_eth1_out rule 40 protocol tcp
# set interface ethernet eth1 firewall out name rule_eth1_out
簡易的なDos攻撃対策
# set firewall name rule_eth1_out rule 50 action reject
# set firewall name rule_eth1_out rule 50 destination port 8080
# set firewall name rule_eth1_out rule 50 protocol tcp
# set firewall name rule_eth1_out rule 50 recent count 3
# set firewall name rule_eth1_out rule 50 recent time 1
# set firewall name rule_eth1_out rule 50 state new enable
3回目のcurlまでは200 OKだが、4回目からConnection refusedが返却される
どれくらい時間をあけると解除されるかは調べても見つかりませんでした
[root@sv02 ~]# curl -v http://192.168.0.1:8080
* About to connect() to 192.168.0.1 port 8080 (#0)
* Trying 192.168.0.1...
* Connected to 192.168.0.1 (192.168.0.1) port 8080 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 192.168.0.1:8080
> Accept: */*
>
< HTTP/1.1 200 OK
(省略)
[root@sv02 ~]# curl -v http://192.168.0.1:8080
* About to connect() to 192.168.0.1 port 8080 (#0)
* Trying 192.168.0.1...
* Connected to 192.168.0.1 (192.168.0.1) port 8080 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 192.168.0.1:8080
> Accept: */*
>
< HTTP/1.1 200 OK
(省略)
[root@sv02 ~]# curl -v http://192.168.0.1:8080
* About to connect() to 192.168.0.1 port 8080 (#0)
* Trying 192.168.0.1...
* Connected to 192.168.0.1 (192.168.0.1) port 8080 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 192.168.0.1:8080
> Accept: */*
>
< HTTP/1.1 200 OK
(省略)
[root@sv02 ~]# curl -v http://192.168.0.1:8080
* About to connect() to 192.168.0.1 port 8080 (#0)
* Trying 192.168.0.1...
* Connection refused
* Failed connect to 192.168.0.1:8080; Connection refused
* Closing connection 0
curl: (7) Failed connect to 192.168.0.1:8080; Connection refused
所感
- 軽いスペックで動作する点が魅力的と感じました。商用利用する際は、VyOS稼働サーバに対するセキュリティ対策が必要ですが、ささっと構築/検証できるため、NWの勉強としても良いと感じました。
参考(構築後config)
vyos@vyos01:~$ show configuration commands
set firewall all-ping 'disable'
set firewall group
set firewall name rule_eth1_in default-action 'drop'
set firewall name rule_eth1_in enable-default-log
set firewall name rule_eth1_in rule 10 action 'accept'
set firewall name rule_eth1_in rule 10 destination address '192.168.10.0/24'
set firewall name rule_eth1_in rule 10 source address '192.168.0.0/24'
set firewall name rule_eth1_out enable-default-log
set firewall name rule_eth1_out rule 40 action 'drop'
set firewall name rule_eth1_out rule 40 destination port '80'
set firewall name rule_eth1_out rule 40 protocol 'tcp'
set firewall name rule_eth1_out rule 40 source address '192.168.10.12/32'
set firewall name rule_eth1_out rule 50 action 'reject'
set firewall name rule_eth1_out rule 50 destination port '8080'
set firewall name rule_eth1_out rule 50 protocol 'tcp'
set firewall name rule_eth1_out rule 50 recent count '3'
set firewall name rule_eth1_out rule 50 recent time 'minute'
set firewall name rule_eth1_out rule 50 state new 'enable'
set firewall name rule_eth2_in default-action 'drop'
set firewall name rule_eth2_in enable-default-log
set firewall name rule_eth2_in rule 20 action 'accept'
set firewall name rule_eth2_in rule 20 destination address '192.168.0.0/24'
set firewall name rule_eth2_in rule 20 source address '192.168.10.0/24'
set firewall name rule_eth2_out enable-default-log
set firewall name rule_eth2_out rule 30 action 'drop'
set firewall name rule_eth2_out rule 30 destination port '8280'
set firewall name rule_eth2_out rule 30 protocol 'tcp'
set interfaces ethernet eth0 address 'dhcp'
set interfaces ethernet eth0 hw-id '08:00:27:8d:c0:4d'
set interfaces ethernet eth0 offload gro
set interfaces ethernet eth0 offload gso
set interfaces ethernet eth0 offload sg
set interfaces ethernet eth0 offload tso
set interfaces ethernet eth1 address '192.168.0.2/24'
set interfaces ethernet eth1 firewall in name 'rule_eth1_in'
set interfaces ethernet eth1 firewall out name 'rule_eth1_out'
set interfaces ethernet eth2 address '192.168.10.10/24'
set interfaces ethernet eth2 firewall in name 'rule_eth2_in'
set interfaces ethernet eth2 firewall out name 'rule_eth2_out'
set interfaces loopback lo
set service ssh
set system config-management commit-revisions '100'
set system conntrack modules ftp
set system conntrack modules h323
set system conntrack modules nfs
set system conntrack modules pptp
set system conntrack modules sip
set system conntrack modules sqlnet
set system conntrack modules tftp
set system host-name 'vyos01'
set system login user vyos authentication encrypted-password '$6$MjV2YvKQ56q$QbL562qhRoyUu8OaqrXagicvcsNpF1HssCY06ZxxghDJkBCfSfTE/4FlFB41xZcd/HqYyVBuRt8Zyq3ozJ0dc.'
set system login user vyos authentication plaintext-password ''
set system login user vyos authentication public-keys vagrant key 'AAAAB3NzaC1yc2EAAAADAQABAAABAQCmB7BUjRYVGn/eDCJu/ZG9OIdIfpN4LKfcjLrxnjCUEEHjxouiTZNsEq+1iLgKTWyIwK2iux+sziax8HtdwQtwnWlVJEH8S5ftWrA53K86IHAH16O6ct6MbIzqQKUTUYHs6hxgW5tfD3oCVRV7WFWyPQ3sVTCno+5yaJSW/q/pbXTz93DKFJvLDptw7i4OTduhAOURv4++zIQi4YgXXGtuMwwRzDvqdKk8wCPGUN3HzRdOWN2EJf1Lj+YNHbk6LoJzvKFMhCOPR4ytSYZBa0JGjE35Z8mY1FBHUjFWaM5YNwpOHoE63515WhM/uoO89/1JvlXBwHQgE+vD+xvxh72x'
set system login user vyos authentication public-keys vagrant type 'ssh-rsa'
set system name-server 'eth0'
set system ntp server time1.vyos.net
set system ntp server time2.vyos.net
set system ntp server time3.vyos.net
set system syslog global facility all level 'notice'
set system syslog global facility protocols level 'debug'
参考(初期config)
vyos@vyos01:~$ show configuration commands
set interfaces ethernet eth0 address 'dhcp'
set interfaces ethernet eth0 hw-id '08:00:27:8d:c0:4d'
set interfaces ethernet eth0 offload gro
set interfaces ethernet eth0 offload gso
set interfaces ethernet eth0 offload sg
set interfaces ethernet eth0 offload tso
set interfaces ethernet eth1 address '192.168.0.2/24'
set interfaces ethernet eth2 address '192.168.10.10/24'
set interfaces loopback lo
set service ssh
set system config-management commit-revisions '100'
set system conntrack modules ftp
set system conntrack modules h323
set system conntrack modules nfs
set system conntrack modules pptp
set system conntrack modules sip
set system conntrack modules sqlnet
set system conntrack modules tftp
set system host-name 'vyos01'
set system login user vyos authentication encrypted-password '$6$MjV2YvKQ56q$QbL562qhRoyUu8OaqrXagicvcsNpF1HssCY06ZxxghDJkBCfSfTE/4FlFB41xZcd/HqYyVBuRt8Zyq3ozJ0dc.'
set system login user vyos authentication plaintext-password ''
set system login user vyos authentication public-keys vagrant key 'AAAAB3NzaC1yc2EAAAADAQABAAABAQCmB7BUjRYVGn/eDCJu/ZG9OIdIfpN4LKfcjLrxnjCUEEHjxouiTZNsEq+1iLgKTWyIwK2iux+sziax8HtdwQtwnWlVJEH8S5ftWrA53K86IHAH16O6ct6MbIzqQKUTUYHs6hxgW5tfD3oCVRV7WFWyPQ3sVTCno+5yaJSW/q/pbXTz93DKFJvLDptw7i4OTduhAOURv4++zIQi4YgXXGtuMwwRzDvqdKk8wCPGUN3HzRdOWN2EJf1Lj+YNHbk6LoJzvKFMhCOPR4ytSYZBa0JGjE35Z8mY1FBHUjFWaM5YNwpOHoE63515WhM/uoO89/1JvlXBwHQgE+vD+xvxh72x'
set system login user vyos authentication public-keys vagrant type 'ssh-rsa'
set system name-server 'eth0'
set system ntp server time1.vyos.net
set system ntp server time2.vyos.net
set system ntp server time3.vyos.net
set system syslog global facility all level 'notice'
set system syslog global facility protocols level 'debug'
参考(Vagrantfile)
Vagrant.configure("2") do |config|
config.vm.box = "vyos/current"
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.define :vyos01 do | vyos01 |
vyos01.vm.hostname = "vyos01"
vyos01.vm.network :private_network, ip: "192.168.0.2", virtualbox__intnet: "A-LAN"
vyos01.vm.network :private_network, ip: "192.168.10.10", virtualbox__intnet: "B-LAN"
vyos01.vm.network "forwarded_port", guest: 22, host: 10022, id: "ssh"
end
config.vm.define :web01 do | web01 |
web01.vm.box = "centos/7"
web01.vm.hostname = "web01"
web01.vm.network :private_network, ip: "192.168.0.1", virtualbox__intnet: "A-LAN"
web01.vm.network "forwarded_port", guest: 22, host: 12221, id: "ssh"
end
config.vm.define :sv01 do | sv01 |
sv01.vm.box = "centos/7"
sv01.vm.hostname = "sv01"
sv01.vm.network :private_network, ip: "192.168.10.11", virtualbox__intnet: "B-LAN"
sv01.vm.network "forwarded_port", guest: 22, host: 12222, id: "ssh"
end
config.vm.define :sv02 do | sv02 |
sv02.vm.box = "centos/7"
sv02.vm.hostname = "sv02"
sv02.vm.network :private_network, ip: "192.168.10.12", virtualbox__intnet: "B-LAN"
sv02.vm.network "forwarded_port", guest: 22, host: 12223, id: "ssh"
end
end
参考(試験サーバの設定と接続確認結果)
共通
# yum install -y docker
# systemctl start docker
# systemctl enable docker
Web01
# docker run --name web01_nginx -d -p 8080:80 nginx
# docker run --name web01_httpd -d -p 80:80 httpd
# ip route add 192.168.10.0/24 via 192.168.0.2 dev eth1
SV01,SV02
# ip route add 192.168.0.0/24 via 192.168.10.10 dev eth1
SV01
# docker run --name sv01_nginx -d -p 8180:80 nginx
SV02
# docker run --name sv02_nginx -d -p 8280:80 nginx
コンテナ起動状態
[root@web01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4d43793253e9 httpd "httpd-foreground" 9 seconds ago Up 7 seconds 0.0.0.0:80->80/tcp web01_httpd
9814ea12cf14 nginx "/docker-entrypoin..." 40 seconds ago Up 38 seconds 0.0.0.0:8080->80/tcp web01_nginx
[root@sv01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0edfcf25ca85 nginx "/docker-entrypoin..." 36 seconds ago Up 34 seconds 0.0.0.0:8180->80/tcp sv01_nginx
[root@sv01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0edfcf25ca85 nginx "/docker-entrypoin..." 36 seconds ago Up 34 seconds 0.0.0.0:8180->80/tcp sv01_nginx
疎通確認
[root@web01 ~]# curl http://192.168.10.11:8180
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
(省略)
[root@web01 ~]# curl http://192.168.10.12:8280
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
(省略)
[root@sv01 ~]# curl http://192.168.0.1:80
<html><body><h1>It works!</h1></body></html>
[root@sv01 ~]# curl http://192.168.0.1:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
(省略)
[root@sv02 ~]# curl http://192.168.0.1:80
<html><body><h1>It works!</h1></body></html>
[root@sv02 ~]# curl http://192.168.0.1:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
(省略)
以上