はじめに
このところリモートワーク推進の流れでVPNの設定をいじることが増えてきました。
いちいち手動で変更するのは管理が大変なので、今回はSoftEther VPN/PacketiX VPNの設定をAnsibleで更新するようにしてみました。
検証した環境は商用ライセンスのPacketiX VPNですが、無償版のSoftEther VPNも同じと思われます。以下ではまとめてSoftEther VPNと呼びます。
環境
- PacketiX VPN Server 4.0 (Version 4.29 Build 9680)
- Ansible 2.7.1
作成するロール
Ansibleのロールとしてvpn_config
を作成することにします。すなわち以下のようなディレクトリ構成を想定しています。
$ tree roles
roles
`-- vpn_config
|-- files
`-- tasks
設定ファイルの準備
SoftEther VPNの設定ファイルはサーバのバイナリと同じディレクトリにvpn_server.config
というファイル名で存在します。
設定ファイルを一から準備するのは大変なので、このファイルをベースにAnsibleで同期したい設定ファイルを作っていきます。
設定ファイルのフォーマットは以下のようになっています。
declare root
{
uint ConfigRevision 112
bool IPsecMessageDisplayed true
string Region JP
bool VgsMessageDisplayed false
...
}
この中から設定したくない項目を削っていきます。削るべき項目としては
-
ConfigRevision
: これは設定更新毎にサーバ側でインクリメントされる値なので、必ずしも同期の必要はないです。 -
declare DDnsClient{}
のkey
とLocalHostname
: ホスト毎に違う値が生成されるので削っておきます。 -
declare LicenseManager{}
: ライセンス情報です。これもJinja2で埋め込んでもいいですが、今回は除外して手動で設定することにしました - 各種統計情報: サーバ側で勝手にカウントアップしていくような値は除外します。具体的には
BroadcastBytes
,BroadcastCount
,UnicastBytes
,UnicastCount
,LastCommTime
,LastLoginTime
,NumLogin
です。これらはそもそも設定不能なので、設定ファイルに残っていても悪さはしませんが、Ansible側の更新判定がやりにくいので削ります。
が考えられます。不要な項目については行ごと削除します。
できた設定ファイルをroles/vpn_config/files/vpn_server.config.master
として保存しておきます。
設定チェックスクリプト
次に現在のサーバ設定と先ほど用意した設定が一致しているかどうかを判定するスクリプトを作ります。
#!/bin/sh
cd `dirname $0`
./vpncmd localhost:8888 /server /PASSWORD:xxx /CMD ConfigGet vpn_server.config.tmp
diff vpn_server.config.tmp vpn_server.config.master | grep "^>"
ret=$?
rm vpn_server.config.tmp
if [ $ret = 0 ]; then
exit 1
else
exit 0
fi
vpncmd
はコマンドラインからサーバを操作するツールで、サーバのバイナリと同じところにあると思います。
このコマンドで現在のサーバ設定を取得してvpn_server.config.tmp
に保存しています。
その後、diff
コマンドでmasterのファイルと差分があるかを確認しています。
ここではサーバのパスワードxxx
を平文で書いていますが、必要に応じてAnsible Vaultでの暗号化などをしてください。
設定スクリプト
実際にサーバ設定を反映するスクリプトです。
#!/bin/sh
cd `dirname $0`
./vpncmd localhost:8888 /server /PASSWORD:xxx /CMD ConfigSet vpn_server.config.master
先ほどのConfigGet
もそうですが、ConfigSet
は引数に/
を含むパスを取れないようです。
なのであらかじめvpn_server.config.master
が存在するディレクトリにcd
するようにしています。
Ansibleのタスク
最後にAnsibleのタスクです。
- name: send config
copy:
src : "{{ item.src }}"
dest : "{{ item.dest }}"
owner: root
group: root
mode : "{{ item.mode }}"
with_items:
- { src: 'vpn_server.config.master', dest: '/usr/local/vpnserver/vpn_server.config.master', mode: '0600' }
- { src: 'check_config.sh' , dest: '/usr/local/vpnserver/check_config.sh' , mode: '0700' }
- { src: 'set_config.sh' , dest: '/usr/local/vpnserver/set_config.sh' , mode: '0700' }
- name: check config
command: /usr/local/vpnserver/check_config.sh
register: check_config
check_mode: no
failed_when: no
changed_when: 'check_config.rc != 0'
- name: debug config
debug:
var: check_config
when: check_config is changed
- name: set config
command: /usr/local/vpnserver/set_config.sh
when: check_config is changed
send config
で設定ファイルとスクリプトの転送、check config
で設定変更が必要かどうかのチェック、set config
で反映です。また、設定変更があった場合はdebug config
が変更内容をダンプします。
まとめ
最終的なロールの構成は以下のようになりました。
$ tree roles
roles
`-- vpn_config
|-- files
| |-- check_config.sh
| |-- set_config.sh
| `-- vpn_server.config.master
`-- tasks
`-- main.yml