🛣️

Debianでルーターを作る

2025/03/04に公開

Proxmox VEのVMのためにDebianでルーターを構築しました。その方法を記しておきます。

  • Debian 12

構築したルーターはProxmox VEホストの中にあるふたつのブリッジvmbr0とvmbr1を接続します(下の図を参照)。vmbr0はホストのEthernetポートと直結しています。また、ホスト自身もこのブリッジに接続しています。vmbr1は外部ネットワークからは隔離されており、複数のVMが接続しています。

ルーターのLinuxはふたつのネットワークインターフェースを持っています。

インターフェース 接続先 IP アドレス
ens18 vmbr0 外部ネットワークからDHCPにより割り当てられる
ens19 vmbr1 192.168.100.1/24

ルーターとして、ufw/iptablesを用いてこれらのポート上でNATを構成しています。具体的にはens19から入ってens18から出ていくパケットに対して、ソースアドレスを書き換えて仮装してしまいます(マスカレード)。また、ens18から入ってens19から出ていくパケットは、返信を除くと原則としてブロックされます。

さらにルーター機能に加えて、ens19を通して他のVMにDHCPサービスを提供しています。

ルーターの構築

ルーターの構築作業は以下の3ステップになります。

  1. 固定アドレスを与える
  2. DHCPサービスを構築する
  3. NATサービスを構築する

固定アドレスを与える

最初にens19に固定アドレスを与えます。ens19はvmbr0に接続されており、サブネット192.168.100.255にとってのゲートウェイですので固定アドレスである必要があります。

Debian 12のネットワークはNetworkManagerで管理されており、ポートの設定は/etc/netowork/interfacesで行います。

変更方法については別稿の『NetworkManagerを使ってDebian/UbuntuのIPアドレスを固定にする』を参照してください。

DHCPサービスを構築する

DHCPサーバーにはkeaを使用します。ネットにはisc-dhcp-serverを使用する例を多く見ますが、この製品はEOLであり開発元はkeaを推奨しています。isc-dhcp-serverもkeaもオープンソースです。

keaをインストールする

sudo apt install kea

/etc/kea/kea-dhcp4.confの編集

編集箇所が多いため、/etc/kea/kea-dhcp4.confの内容をすべて上書きします。

/etc/kea//etc/kea/kea-dhcp4.conf
{
   "Dhcp4": {
      "interfaces-config": {
         "interfaces": [ "ens19" ]
      },
      "control-socket": {
         "socket-type": "unix",
         "socket-name": "/run/kea/kea4-ctrl-socket"
      },
      "lease-database": {
         "type": "memfile",
         "lfc-interval": 3600
      },
      "valid-lifetime": 600,
      "max-valid-lifetime": 7200,
      "subnet4": [
         {
            "id": 1,
            "subnet": "192.168.100.0/24",
            "pools": [
               {
                  "pool": "192.168.100.150 - 192.168.100.200"
               }
            ],
            "option-data": [
               {
                  "name": "routers",
                  "data": "192.168.100.1"
               },
               {
                  "name": "domain-name-servers",
                  "data": "219.110.4.80, 219.110.5.7, 8.8.8.8, 8.8.8.4"
               }
            ]
         }
      ]
   }
}

kea-dhcp4-serverをリスタートする

sudo systemctl restart kea-dhcp4-server.service

NATサービスを構築する

NATサービスにはufwを使います。ufwはiptablesのフロントエンドです。

設定について

ネット上の解説の中には/etc/ufw/defaultを編集してデフォルトのフォワードポリシーをACCEPTにしている例があります。こういった設定では次の双方のフォワードがオンになります。

  • 内部から外部へのフォワード
  • 外部から内部へのフォワード

そのため、別のルールで外部から内部へのフォワードをふさぐ必要があります。しかし、それをしていない例を見かけます。

以下に挙げる設定では、/etc/ufw/defaultに手を加えていませんので、デフォルトの転送ルールはオフです。代わりに、/etc/ufw/before.rulesの中で明示的に内部から外部へのフォワードをオンにしています。

なお、/etc/ufw/defaultには多くのデフォルト設定があり、ICMPパケットの許可、DHCPの許可、返信パケットの許可などを行っています。それらには手を付けていません。

まとめると、この設定では内部から外部へ抜けていくパケットは/etc/ufw/before.rulesのnat設定によって送信元IPアドレスがマスクされ、次にfilter設定によってフォワードされます。外部から帰って来た返信パケットは/etc/ufw/before.rulesのデフォルトルールにより内部へのフォワードが許可されます。一方で、単に外部から来ただけのTCPパケットはどのルールからも許可されないため内部へフォワードされません。

ufwをインストールする

インストール後にsshを許可しておきます。

sudo apt install ufw
sudo apt ufw allow ssh
sudo apt ufw enable

/etc/ufw/sysctl.confを編集する

ufwはカーネルの転送機能を利用するため、カーネルのパケット転送機能を有効にしておきます。/etc/ufw/sysctl.confでコメントアウトされているフォワード機能をオンにします(例はdiff形式です)。

/etc/ufw/sysctl.conf
--- sysctl.conf.bak     2025-03-03 17:52:57.900774057 +0900
+++ sysctl.conf 2025-03-03 17:51:40.660245903 +0900
@@ -7,7 +7,7 @@
 #

 # Uncomment this to allow this host to route packets between interfaces
-#net/ipv4/ip_forward=1
+net/ipv4/ip_forward=1
 #net/ipv6/conf/default/forwarding=1
 #net/ipv6/conf/all/forwarding=1

/etc/ufw/before.rulesを編集する

/etc/ufw/before.ruleの末尾にふたつのルールを追加します。

  • ens18から出ていくフォワード・パケットに対するマスカレード処理。
  • ens19から入ってens18から出ていくフォワードの許可。

以下の例はdiff形式です。

/etc/ufw/before.rule
--- before.rules.bak    2025-03-03 17:56:15.046145807 +0900
+++ before.rules        2025-03-04 07:06:59.175480738 +0900
@@ -73,3 +73,29 @@

 # don't delete the 'COMMIT' line or these rules won't be processed
 COMMIT
+
+# rules on the nat table.
+*nat
+
+# flush existing rules
+-F
+
+# accept packets by default
+:POSTROUTING ACCEPT [0:0]
+:PREROUTING ACCEPT [0:0]
+
+# apply masquerade to all forward packet to port ens18. The port number is randomized.
+-A POSTROUTING -o ens18 -j MASQUERADE --random
+
+# apply above rules.
+COMMIT
+
+# rules on the filter table.
+*filter
+
+# accept the forward packet from ens19 to ens18
+-A ufw-before-forward -i ens19 -o ens18 -j ACCEPT
+
+# apply above rules.
+COMMIT

ufwを再ロードする

sudo ufw reload

参考文献

Discussion