openWrtとOpenVPN

プライベートなサービスを公開するサーバーが欲しい。しかし、サーバーの購入代金、維持費用、置き場所のことを考えると、つい購入が億劫になってしまう。例えば自宅のLANからのみ通信できるVPSを契約できれば便利そうだ。

そんなある日、ルーターとVPSをVPNで繋げば、それが実現できることを知った。VPNに対応している業務用のルーターは高いが、openWrtを家庭用ルーターにインストールすることで安価に高機能なルーターが手に入る。自宅にあった古いNECの無線LANのAPはopenWrtが使えなかったので、物は試しに中古でルーターを購入した。VPSを契約し、OpenVPNをインストールして認証局を作る。まずはPCとの1:1通信を確認する。その後、openWrtをOpenVPN ClientとしてVPSと通信することで、LAN -> VPN -> VPS と通信することができた。

高機能なルーターを手に入れたことで、ネットワークのことを全然しらないことが分かった。用語は理解していても、実際に構築した経験はないからだ。ルーターの世界は奥深い。ルーティングとファイアウォールが難しい。というか、ネットワークが難しい。ネットワークが分からないとopenWrtが設定できない。

  • NAT ... ファイアウォールでやること
  • NAPT ... IPマスカレードという。
  • 拠点間VPN ... ルーターがDHCPとして機能し、VPNのプライベートIPを配ってくれるものではなさそう。例えば192.168.1.5から遠隔地にある192.168.2.3と通信するときに、組織内ならば静的ルーティングで192.168.1.1ルータが192.168.2.1/24のルーターに転送するが、代わりに10.8.0.3のVPNのゲートウェイに転送することで、10.8.0.1に届ける・・・そんな機能のようだ。

openWrtのファイアウォール

セキュアな設定には理解が不可欠だけど難しい。最下層にはkernelモジュールのnetfilterがあり, それを操作するiptablesと、そのルールを生成するfw3 (openWrt)がある。ファイアウォールといえばiptablesのイメージがあるが、openWrtのiptablesの設定はfw3から機械的に生成されている。

iptables -Lの出力、rulesは消している。

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain forwarding_lan_rule (1 references)
target     prot opt source               destination

Chain forwarding_rule (1 references)
target     prot opt source               destination

Chain forwarding_wan_rule (1 references)
target     prot opt source               destination

Chain input_lan_rule (1 references)
target     prot opt source               destination

Chain input_rule (1 references)
target     prot opt source               destination

Chain input_wan_rule (1 references)
target     prot opt source               destination

Chain output_lan_rule (1 references)
target     prot opt source               destination

Chain output_rule (1 references)
target     prot opt source               destination

Chain output_wan_rule (1 references)
target     prot opt source               destination

Chain reject (7 references)
target     prot opt source               destination

Chain syn_flood (1 references)
target     prot opt source               destination

Chain zone_lan_dest_ACCEPT (4 references)
target     prot opt source               destination

Chain zone_lan_forward (1 references)
target     prot opt source               destination

Chain zone_lan_input (1 references)
target     prot opt source               destination

Chain zone_lan_output (1 references)
target     prot opt source               destination

Chain zone_lan_src_ACCEPT (1 references)
target     prot opt source               destination

Chain zone_wan_dest_ACCEPT (2 references)
target     prot opt source               destination

Chain zone_wan_dest_REJECT (1 references)
target     prot opt source               destination

Chain zone_wan_forward (3 references)
target     prot opt source               destination

Chain zone_wan_input (3 references)
target     prot opt source               destination

Chain zone_wan_output (3 references)
target     prot opt source               destination

Chain zone_wan_src_REJECT (1 references)
target     prot opt source               destination

初見だとなんだこれ・・・となるが、さほど難しくはない。

iptablesには4つのテーブル(filter, nat, mangle, raw)がある。それぞれ異なる役割を持つが、今はfilterテーブルの話をする。

テーブルの中にはchainと呼ばれるルールの集合がある。iptablesは上から順番に処理され、条件に合致した場合に別のChainに飛ばすことができる。これに関してはgotoとラベルのイメージでもよいと思う。

Chain FORWARD (policy DROP)
target            prot opt source     destination
forwarding_rule   all  --  anywhere   anywhere
ACCEPT            all  --  anywhere   anywhere     ctstate RELATED,ESTABLISHED
zone_lan_forward  all  --  anywhere   anywhere            
zone_wan_forward  all  --  anywhere   anywhere            
zone_wan_forward  all  --  anywhere   anywhere            
zone_wan_forward  all  --  anywhere   anywhere            
reject            all  --  anywhere   anywhere            

openWrtのfw3 (firewall3)はゾーンと呼ばれるNetwork I/Fのグループに対してルールを設定する。そのため、ゾーンごとにチェインが定義される。

各テーブルには組み込みチェインが存在する。組み込みチェインはINPUT, FORWARD, OUTPUT, PREROUTING, POSTROUTINGの5種類で、filterテーブルはINPUT, OUTPUT, FORWARDが、natテーブルはPREROUTING, OUTPUT, POSTROUTINGが組み込まれている。組み込みチェインは処理の始点となる。それ以外のチェインは自由に定義してもよい。

Chain INPUT (policy ACCEPT)
...
Chain FORWARD (policy DROP)
...
Chain OUTPUT (policy ACCEPT)

初期設定ではFORWARD通信のみpolicy DROPが指定されている。サーバーにインストールするファイアウォールと異なり、ルーターとしてのファイアウォールはその通信のほとんどがFORWARDになる。(LAN to WAN または WAN to LAN)。

openWrtのfw3は次のような設定ファイルで設定する[1][2]

config zone
    option name         lan
    list   network      'lan'
    option input        ACCEPT
    option output       ACCEPT
    option forward      ACCEPT
  • config defaults: グローバルな設定
  • config zone: ゾーンの定義。ゾーンは複数のNIC I/Fをまとめる。
  • config forwarding: フォワーディングルールを定義する。
  • config rule: ゾーンに対して許可・拒否のルールを定義する
  • config redirect: ポートフォワーディングや仮想サーバーのルールを定義する。
  • config ipset: IPの範囲をまとめるIPSETを定義する
  • config include: 別の設定ファイルへのパスを指定する

  1. https://openwrt.org/docs/guide-user/firewall/firewall_configuration ↩︎

  2. https://github.com/openwrt/openwrt/blob/master/package/network/config/firewall/files/firewall.config ↩︎