朝日ネットでのインフラ設計・構築を担当しているラピー・ステファンです。 前回の構成説明に続き、今回は具体的な構築について紹介します。
pfSenseの構築
初期インストール
https://www.pfsense.org/download/ からCD ISOまたはUSBメムスティック用インストーラーをダウンロードする。
pfSenseの仮想マシンで立てる場合、下記の設定にします:
- メモリ:1GB から 2GB (乗るサービスに応じて)
- OSの種類: FreeBSD 64-bit
- NIC
- ドライバー:Intel E1000 (FreeBSDと相性が良い)
- 3つ準備する:
- フロントエンド側(WAN)
- 設定後、該当の仮想インターフェースのポリシーをCARP用に修正
- 管理側(LAN)
- バックエンド側(OPT1)
- フロントエンド側(WAN)
通常の手順に従って、コンソールからOSを入れます。 管理者パスワードもこのタイミングで決めます。 ウェブ管理画面を使うために、LANのみとりあえず設定して、 DHCPで自動的にアドレスを割り当てる様にします。
運用するに当たっての推奨設定とそのテンプレート化
大々的に使う場合、下記を推奨します:
- 基本設定を済ませた状態の仮想マシンを整備して、「仮想マシンテンプレート」として保存します
- 認証等(AD連携、管理者グループ等)
- 参照するNTPサーバー、DNSサーバー
- 社内で利用する証明局等
- 社内で簡単に証明書を発行出来るPKI(公開鍵インフラ)がある場合、展開を簡単にするために、「*.admin.internal.example.jp」等のワイルドカード証明書を作り、常備させます
- 予めパッケージや必要なパッチを適用する
- VMwareツール
- HAproxy
- 管理画面がWANインターフェースにバインドしないためのパッチ(上記のNIC3つ使う構成が前提):
--- pfsense.old/system.inc 2018-09-20 22:02:22.000000000 +0900 +++ pfsense.new/system.inc 2018-10-26 17:04:09.495919000 +0900 @@ -1451,8 +1451,21 @@ if ($cert <> "" and $key <> "") { $nginx_config .= "\n"; $nginx_config .= "\tserver {\n"; - $nginx_config .= "\t\tlisten {$nginx_port} ssl http2;\n"; - $nginx_config .= "\t\tlisten [::]:{$nginx_port} ssl http2;\n"; + if (($config['interfaces']['lan']['ipaddr'] == "" or + $config['interfaces']['lan']['ipaddr'] == "dhcp") and + ($config['interfaces']['opt1']['ipaddr'] == "" or + $config['interfaces']['opt1']['ipaddr'] == "dhcp")) { + $nginx_config .= "\t\tlisten {$nginx_port} ssl http2;\n"; + $nginx_config .= "\t\tlisten [::]:{$nginx_port} ssl http2;\n"; + } + if ($config['interfaces']['lan']['ipaddr'] <> "" and + $config['interfaces']['lan']['ipaddr'] <> "dhcp") { + $nginx_config .= "\t\tlisten {$config['interfaces']['lan']['ipaddr']}:{$nginx_port} ssl http2;\n"; + } + if ($config['interfaces']['opt1']['ipaddr'] <> "" and + $config['interfaces']['opt1']['ipaddr'] <> "dhcp") { + $nginx_config .= "\t\tlisten {$config['interfaces']['opt1']['ipaddr']}:{$nginx_port} ssl http2;\n"; + } $nginx_config .= "\n"; $nginx_config .= "\t\tssl_certificate {$g['varetc_path']}/{$cert_location};\n"; $nginx_config .= "\t\tssl_certificate_key {$g['varetc_path']}/{$key_location};\n"; @@ -1484,8 +1497,21 @@ } else { $nginx_config .= "\n"; $nginx_config .= "\tserver {\n"; - $nginx_config .= "\t\tlisten {$nginx_port};\n"; - $nginx_config .= "\t\tlisten [::]:{$nginx_port};\n"; + if (($config['interfaces']['lan']['ipaddr'] == "" or + $config['interfaces']['lan']['ipaddr'] == "dhcp") and + ($config['interfaces']['opt1']['ipaddr'] == "" or + $config['interfaces']['opt1']['ipaddr'] == "dhcp")) { + $nginx_config .= "\t\tlisten {$nginx_port};\n"; + $nginx_config .= "\t\tlisten [::]:{$nginx_port};\n"; + } + if ($config['interfaces']['lan']['ipaddr'] <> "" and + $config['interfaces']['lan']['ipaddr'] <> "dhcp") { + $nginx_config .= "\t\tlisten {$config['interfaces']['lan']['ipaddr']}:{$nginx_port};\n"; + } + if ($config['interfaces']['opt1']['ipaddr'] <> "" and + $config['interfaces']['opt1']['ipaddr'] <> "dhcp") { + $nginx_config .= "\t\tlisten {$config['interfaces']['opt1']['ipaddr']}:{$nginx_port};\n"; + } } $nginx_config .= <<<EOD
- Status→System Logs→Settingsで、全体のsyslogサーバーの設定をする
- Advanced→Firewall & NATで:
- Firewall Maximum Statesの値が十分(10万以上がまず妥当)
- Firewall Maximum Table Entriesの値が十分(40万以上がまず妥当)
- Advanced→Miscellaneous→Cryptographic & Thermal Hardwareで:
- Cryptographic Hardwareが「AES-NI and BSD Crypto Device」の両方を使う様に設定する
- Advanced→Notificationsで:
- メール通知が行ける様に、サーバーと通知先のメールアドレスを設定する
- HAproxyの事前の微調整:
- syslogサーバーの設定をする
- Max SSL Diffie-Hellman size設定を4096にする
- Global Advanced設定で暗号種類を限定する
ssl-default-bind-ciphers EECDH+AESGCM:EDH+AESGCM
- Internal stats portを2200に定義する
- Maximum connectionsを定めておく
- 微調整を経た段階のコンフィグを保存・管理して、簡単に使いまわせる様にする
- pfSenseには「Auto Configuration Backup」という機能が付いていて、pfSenseを提供するNetgate社で保存する事が出来ます: https://docs.netgate.com/pfsense/en/latest/backup/autoconfigbackup.html
- 社外のサーバーに保存出来ない場合、XML形式でのダウンロードも出来る
- 物理機材の場合、pfSense媒体とセットで、コンフィグをUSB等に入れてインストール時にロードすることも可能
- ログインした後に出るダッシュボードに、下記のWidgetを追加する:
- Interfaces → リンク状態表示
- Interface Statistics → Packet / Byte / Errorの状態表示
- Firewall Logs → 直近のブロック等のログ
- HAProxy → 特にこのwidgetから、バックエンドサーバ−の状態表示だけでなく、簡単にメンテナンスモード切り替えの操作も可能
- Services Status → 重要プロセスの稼働状態表示
- CARP Status → MASTER / BACKUP / INIT等の状態表示
2台構成の展開、構成同期の設定
上記の既定設定を反映してテンプレートから、2台の仮想マシンを展開する。 展開後のNIC設定を行います:
- WAN : 設定なし → 固定のアドレスを割り当てる
- LAN : DHCP → 固定の管理アドレスを割り当てる
OPT1 : 設定なし → 固定のアドレスを割り当てる 1号機の管理画面にアクセスして、System→High Avail. Syncの設定画面でConfiguration Synchronization Settings (XMLRPC Sync)を下記の様に設定する:
Synchronize Config to IP : 2号機のLANアドレスを入力する
- Remote System Username : admin
- Remote System Password : <設定した管理用パスワード>
- Select options to sync : 全部選択する 構成を説明している事例においては、pfSenseが担う部分がレイヤー7(L7)の処理のため、pfsyncの設定は不要です。
ゲートウエイやネットワークインターフェースの設定の注意事項
ゲートウエイ定義
ゲートウエイは、LANとWANそれぞれ定義します。 なお、デフォルトゲートウエイはLANを採用します。
この構成の理由は、「管理ネットワーク」(LAN)と「サービスネットワーク」(WAN)の通信の切り分けです。 メンテナンス作業の際、WANインターフェースを切ってサービスを受けないようにしても、 pfSenseから発せられた通信はすべてLAN(この場合、管理ネットワーク)から行くことになります。
インターフェース調整
ただし、正しくサービストラフィックを処理するためにWANインターフェースの設定で、IPv4 Upstream gatewayを明示的に定義する必要があります。 そうすることで、HTTP・HTTPSトラフィック等を許可するファイヤウオールのルールを定義する際、自動的に「reply-to (emX 10.0.0.1)」という定義が追加され、 許可されたパケットに対して、返事が入ったルートから行われます。
ポリシーベースルーティングにより、デフォルトゲートウエイがLANでも、WANから入ったサービストラフィックに対する返事はWANインターフェースから出ます。
-pass in quick on em1 inet proto tcp from ! <DenyAccess> to 10.0.0.2 port = http flags S/SA keep state label "USER_RULE: Allow traffic to proxies" -pass in quick on em1 inet proto tcp from ! <DenyAccess> to 10.0.0.2 port = https flags S/SA keep state label "USER_RULE: Allow traffic to proxies" +pass in quick on em1 reply-to (em1 10.0.0.1) inet proto tcp from ! <DenyAccess> to 10.0.0.2 port = http flags S/SA keep state label "USER_RULE: Allow traffic to proxies" +pass in quick on em1 reply-to (em1 10.0.0.1) inet proto tcp from ! <DenyAccess> to 10.0.0.2 port = https flags S/SA keep state label "USER_RULE: Allow traffic to proxies"
上記事例ですと、WANインターフェースはプライベートアドレスを使い、死活監視も上流装置(ファイヤウオール又はロードバランサー)に行われているので、 インターフェース設定画面の「Block private networks and loopback addresses」を無効にしなければ、正しく動きません。
CARP仮想IPアドレスの設定
CARP を設定する場合は、下記の設定が前提になります:
- System→High Avail. Syncで1号機から2号機の同期が設定されている
- 仮想基盤上でWANインターフェースに対して「無差別モード」、「送信パケットの偽造」、「MACアドレスの偽造」を許可する(第1回参照) VMwareの場合、NICの切断をする等してポリシー例外定義は容易に外れる上、複数サービスのトラフィックが集中してしまうと、無駄な負荷が他のサービスにも回ってしまう恐れがある Firewall→Virtual IPsから新規定義をします:
- Type : CARP
- Interface : WAN
- Address : 共有されるアドレス(サブネットマスクの指定も必要)
- VHIDグループの番号と同期パスワードを定義し、設定する(同じネットワーク内で使用されているものと被ってはならない) 1号機で定義しただけで、2号機に定義が伝播し、自動的に2号機の優先度が低く設定されます。
ファイヤーウオールのルール定義
管理を簡単にするために、下記の定義を推奨します:
- CARPに基づいた設計を使う場合、Firewall→Aliases→IPで「VirtualIPs」というアドレス単体のリストを作って、そこにCARPのIPアドレスを入力する (CARPアドレスが複数ある場合、ルールを共通化するためのもの)
- Firewall→Aliases→IPで「DenyAccess」というネットワークのリストを作って、空っぽにしておく (これは、今後通信を一切遮断したい対象が発生した場合に備えてのもの)
- Firewall→Aliases→IPで「Crawlers」というネットワークのリストを作って、空っぽにしておく (これは、今後通信にレートリミットをかけたい対象が発生した場合に備えてのもの)
- Firewall→Aliases→IPで「Monitoring」というネットワークのリストを作って、空っぽにしておく (これは、ICMP死活監視を許可するためのもの、例えば上流の通信装置のファイヤーウオールやロードバランサー等)
Firewall→Aliases→Portsで、「HTTPTraffic」というリストを作って、HTTPとHTTPSのポート番号80と443を入力する Firewall→Rules→WANでルールを定義する:
監視通信をCARPアドレス宛に許可するルール:
- Action / 操作:通過(Pass)
- Address Family / アドレス形式:IPv4
- Protocol / プロトコル: ICMP
- Source / 通信元: Single host or alias → Monitoring
- Destination / 通信先:
- CARPの場合: Single host or alias → VirtualIPs
- そうでない場合: WAN address
通信遮断したい相手からのHTTPトラフィックを拒否するルール:
- Action / 操作:拒否(Reject)
- Address Family / アドレス形式:IPv4
- Protocol / プロトコル: TCP
- Source / 通信元: Single host or alias → DenyAccess
- Destination / 通信先:
- CARPの場合: Single host or alias → VirtualIPs
- そうでない場合: WAN address
- Destination Port Range / 通信先ポートレンジ: (other) → HTTPTraffic
- TCPレートリミットをかけながら、通信許可したい相手(Crawler)からのHTTPトラフィックを許可するルール
- Action / 操作:通過(Pass)
- Address Family / アドレス形式:IPv4
- Protocol / プロトコル: TCP
- Source / 通信元: Single host or alias → Crawlers
- Destination / 通信先:
- CARPの場合: Single host or alias → VirtualIPs
- そうでない場合: WAN address
- Destination Port Range / 通信先ポートレンジ: (other) → HTTPTraffic
Advanced Options :
- Max. src. conn. Rate : 100 (ホスト毎の新規接続;こちらはあくまで明らかに過剰なトラフィックの一例)
- Max. src. conn. Rates : 1 (該当期間、秒単位)
- 通信許可したい相手からのHTTPトラフィックを許可するルール
- Action / 操作:通過(Pass)
- Address Family / アドレス形式:IPv4
- Protocol / プロトコル: TCP
- Source / 通信元: Single host or alias → Crawlers
- Invert matchで条件反転をさせる(Crawlersでないものを許可する)
- Destination / 通信先:
- CARPの場合: Single host or alias → VirtualIPs
- そうでない場合: WAN address
- Destination Port Range / 通信先ポートレンジ: (other) → HTTPTraffic
次回予告
ここまでで思ったより文量が多くなってしまったため、「CARP+VMware冗長設計の欠点の回避策」については次回の紹介といたします。
採用情報
朝日ネットでは新卒採用・キャリア採用を行っております。