«前の日記(2019-08-06) 最新 編集

meta's blog - The Power To Serve

筆者について - No Unix, No Life

日本xrdpユーザ会発起人。

とある元大学院生の UNIX 系日記。FreeBSDを通じてOSSに囁かな貢献を。 FreeBSD ports committer やってます。

HTTPS化したいとは思っているんです…


2019-09-24 SoftEtherをパッケージングするための技術 [長年日記]

SoftEtherをパッケージングするための技術

SoftEther VPN (以下SoftEther)は言わずと知れた優れたオープンソースの複数プロトコル、複数プラットフォームVPNソフトウェアです。とても優れたソフトウェアであるにも関わらず、Linuxディストリビューションなどの公式パッケージとしての提供状況は芳しくありません。

ここでは、FreeBSD portsを例に「SoftEtherをパッケージングするための技術」について解説します(技術というほどのものではありませんが…)。

SoftEtherがディストリビューションの公式パッケージで提供されにくい理由

SoftEtherがLinuxディストリビューションに敬遠される理由として、SoftEtherの設計に起因する、ディストリビューションのお作法と相反する部分が原因だと考えます。単に需要がないだけではないかという説は、一旦置いておいておきます(SoftEtherは大変優れたソフトウェアであるため)。

そのお作法に反する部分というのは以下に挙げる、ログファイル、PIDファイル、設定ファイル(以下ログなど)の出力先です。その他の部分に関しては、SoftEther自身の依存関係が最小であるため特にパッケージングの障害となる要素は見られませんでした。

ログファイルの出力先

一般的にLinuxディストリビューションにおいて、ログファイルの出力先といえば /var/logやサブディレクトリの/var/log/softetherといった場所をイメージすることが多いのではないでしょうか。

ところが、3.10.1 ログの保存形式と保存周期 にあるように、実行ファイルのある場所にサブディレクトリを作成しログを書き出します。

すべてのログファイルは、「vpnserver」プロセス (VPN Bridge では、「vpnbridge」プロセス) の実行可能ファイルが設置されているディレクトリに、「server_log」、「security_log」および「packet_log」の 3 つのサブディレクトリを作成し、そこに各々「サーバーログ」「セキュリティログ」、および「パケットログ」をそれぞれ書き出します。なお、仮想 HUB ごとに書き出されるセキュリティログおよびパケットログについては、さらに「仮想 HUB 名のサブディレクトリ」が作成され、そこに書き出されます。

これは、www.softether-download.com からコンパイル済みのバイナリのtarballをダウンロードして展開する場合にはとても都合がよく、妥当な設計です。なぜなら、実行中に書き出される一切のファイルは展開先のディレクトリの下に作成されるため、不要になった場合はディレクトリごと削除してしまえば一切後を濁さず綺麗サッパリとアンインストールできるからです。

ところが、ディストリビューションのパッケージを作る立場からするとこれはとても困った設計です。実行可能ファイルが設置されているディレクトリにサブディレクトリを作成するということは、/usr/bin/usr/libexecといったディレクトリに勝手にディレクトリを掘ってログファイルを書くことになるからです。パッケージシステム以外のソフトウェアがこれらのパスに書き込むのは行儀が悪いですし、なによりこれらのパスが書き込み可能である保証がありません。

これではオリジナルのSoftEtherをそのままパッケージにするのが難しく、公式パッケージとして提供されにくいのも頷けます。

PIDファイルの出力先

PIDファイルの出力先も同様で、実行可能ファイルと同じディレクトリに出力されます。これもログファイルと同様に行儀がよくないですね。

/var/run/runといったディレクトリ、またはそのサブディレクトリに書くのが一般的ではないでしょうか。前述の通り、実行ファイルと同じディレクトリというのは書き込み可能である保証がないため、避けるべきでしょう。

設定ファイルの出力先

同じく設定ファイルも、実行可能ファイルと同じディレクトリに出力されます。一般に設定ファイルというと/etc以下に置かれることをイメージすると思います。

SoftEtherの場合は、設定ファイルをテキストエディタで書き換えて設定を行うという使い方がメインではなく、vpncmdという管理コマンドやサーバ管理マネージャを使用して設定を行い、設定の内部データのダンプがテキストファイルに書き出されるというイメージです。もちろん設定ファイルを書き換えての設定変更も可能ですが、ここでは省略します。

また、SoftEtherは自動的に一定時間ごとに設定内容の履歴を取り、バックアップしています。詳しくはSoftEtherのマニュアルの 3.3.7 コンフィグレーションファイルの項を参照ください。

このように、設定ファイルはSoftEtherによって単に読み取られるのではなく、プログラムの実行により更新される状態を保持するファイルという性質があるため、置き場所としては/var/libあたりがFHS的には適切でしょう。

FreeBSD portsの場合

以上のように、SoftEtherが実行中に書き込むディレクトリは大きく分けて3つに区別されます。

  • ログファイルの出力先
  • PIDファイルの出力先
  • 設定(状態)ファイルの出力先

オリジナルのSoftEtherではこれらの3つが区別されず、全て実行ファイルのディレクトリとされています。内部ではGetExeDir()GetExeDirW()という関数で取得しています。

FreeBSD portsでは、オリジナルのSoftEtherにパッチを当ててこれらのディレクトリを取得する関数を追加、GetExeDir()を呼んでいる箇所をみてログなのか、PIDなのか、設定ファイルなのかコンテキストによって書き換えました。詳しくはportのMakefileや実際のパッチを参照ください。

  • GetLogDir()/var/log/softether
  • GetPidDir()/var/run/softether
  • GetDbDir()/var/db/softether

先程 /var/lib が適切といった部分が、/var/db に変わっているのは、FHSの/var/libに相当するパスがFreeBSDでは/var/dbだからです。hier(7)参照

また、冒頭で示した3.10.1 ログの保存形式と保存周期の通りログの保存先には server_log, security_log, packet_log というサブディレクトリが作成されるため、最終的なパスが以下のようにlogがダブり、些か冗長であるため _log を取り除く改変も合わせて加えています。

  • /var/log/softether/server_log → /var/log/softether/server
  • /var/log/softether/security_log → /var/log/softether/security
  • /var/log/softether/packet_log → /var/log/softether/packet

このようにして、FreeBSD portsにおいてはオリジナルのSoftEtherにある「ログなどを変な場所に吐く問題」を解決しし、FreeBSDのお作法に沿った場所にログやPIDファイルなどを出力するようにしています。通常のportsのようにmake installpkg installで簡単にインストールでき、バージョンの管理もOSの仕組みにそって行えるため、扱いやすいのではないでしょうか。

余談ですが、FreeBSD portsにはSoftEtherは3つのバージョンが収録されています。3つのバージョンを並行してサポート・メンテナンスする必要があるのかというと正直微妙なところですが、SoftEther 4系はFreeBSDにおいてはx86, x86-64アーキテクチャしかサポートしないため、主にRaspberryPiなどのARMアーキテクチャで使用するために5系を用意しています。

  • security/softether → 4.29 安定版の正式リリース(RTM)
  • security/softether-devel → 4.30 安定版のbeta版
  • security/softether5 →5.01 開発版

upstreamに投げないのか?

それほど難しいパッチではありませんが、数行の簡単なパッチではないためupstreamに投げた方が後の運用が楽ではないかという疑問が出てくると思いますが、これをupstreamに投げるかどうかはまだ悩んでいます。

本記事中でも言及したように、コンパイル済みの公式バイナリのtarballをダウンロードして展開して実行するというユースケースにおいては、展開したディレクトリ以外を散らかさない全てを展開したディレクトリ以下に書き込むという設計には一定の妥当性を感じているからです。

ディストリビューションのパッケージを作成する立場としては、ログなどをOSの標準的なパスに書き出してくれないと扱いづらいのは事実ですが、一方で現状の設計にも一定の妥当性を感じているため一概にどちらがいいと言い切れるものではなくこの程度の方向性の違いはローカルパッチで対処してもいいかなとも思っています。

とにかく1回PRを投げみてupstreamの判断を仰げ?その通りです。

まとめ

  • SoftEtherは優れたソフトウェアにも関わらず、ディストリビューションの公式パッケージとして提供されにくい現状がある
  • その理由はSoftEtherの独特な設計(ログなどの書き出し先)にあるのではないか
  • FreeBSD ports ではログをOSのお作法に沿った場所に書くように改変している

他のLinuxディストリビューション向けにSoftEtherをパッケージングする際の助けとなれば幸いです。