SoftEther VPN Serverのsystemd用*.serviceファイルを書いた
Ubuntu 16.04 LTSのリリースが目前に迫りつつある今日この頃(ちょいと気が早いか?)。何かにつけてそろそろsystemdと仲良くしないといけないようなので、initスクリプトではなくて、systemd用の*.serviceファイルについてごにょごにょし始めました。
第一弾として、個人的にとっつき易かった、SoftErther VPN Server用の.serviceファイルを書いてみました。
vpnserver.service
動作検証環境
メモ
- KillMode=control-groupはデフォルトらしいが一応書いておく。KillMode=processにするときれいに消えてくれないので注意。
- 一応ネットワーク関係がオンラインになってから立ち上がるようにしてみた。
SoftErther VPN Serverで使うSSL証明書をLet's Encryptで取得して設定するとこまで自動化してみた。
Let's Encryptの活用方法シリーズ!?第二弾です。今回は、SoftErther VPN Serverの証明書をLet's Encryptで取得して設定するところまでを自動でできるようにしてみました。
↓第一弾↓ kitaeng.hateblo.jp
内容的には、第一弾の自動で更新のスクリプトにSoftErther VPNのコマンドラインツールでの証明書設定変更を追加しただけです。
softerthervpn_letsencrypt_cert_autoupdate.sh
動作検証環境
- Ubuntu Server 14.04 LTS, Ubuntu Server 15.10
- SoftEther VPN Server (64 bit) Version 4.19 Build 9599 (Japanese)
レポートメールのサンプル
Subject: [Soft Erther VPN Server Cert Auto Update] Update Report for exsample.com
Date: Sat, 20 Feb 2016 00:00:00 +0900 (JST)
From: root <root@exsample.com>
To: root@exsample.com
# Let's Encrypt Cert autopudate Start: 2016-02-20-Sat-00:00:00
# Update Log START ---------------------------------------------------------#
Updating letsencrypt and virtual environment dependencies......
Requesting root privileges to run with virtualenv: /root/.local/share/letsencrypt/bin/letsencrypt certonly --renew-by-default --webroot -w /var/www/html -d exsample.com
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/exsample.com/fullchain.pem. Your cert will
expire on 2016-05-20. To obtain a new version of the certificate in
the future, simply run Let's Encrypt again.
- If you like Let's Encrypt, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
# SoftErther VPN SERVER CERT CHANGE LOG START ------------------------------#
vpncmd コマンド - SoftEther VPN コマンドライン管理ユーティリティ
SoftEther VPN コマンドライン管理ユーティリティ (vpncmd コマンド)
Version 4.19 Build 9599 (Japanese)
Compiled 2015/10/19 20:28:20 by yagi at pc30
Copyright (c) SoftEther VPN Project. All Rights Reserved.
VPN Server "localhost" (ポート 5555) に接続しました。
VPN Server 全体の管理権限があります。
VPN Server>ServerCertSet /LOADCERT:/etc/letsencrypt/live/exsample.com/fullchain.pem /LOADKEY:/etc/letsencrypt/live/exsample.com/privkey.pem
ServerCertSet コマンド - VPN Server の SSL 証明書と秘密鍵の設定
コマンドは正常に終了しました。
#---------------------------- SoftErther VPN SERVER CERT CHANGE LOG END ---#
#------------------------------------------------------------- Update Log END ---#
# Let's Encrypt Cert autopudate End: 2016-02-20-Sat-00:00:00
諸注意
うまく証明書が発行されなかったときや、SoftErther VPN Serverのパスワードが違うなどがあると、SoftErther VPNのコマンドラインツールが入力待ちの状態になってしまうので、そこでもれなく止まって進まなくなります……。設定値には十分ご注意を。
あとがき
実験で何回か実行したら、Lets's Encryptのエラーで処理が止まってしまった。リクエストしすぎだよ!って怒られました。ごめんなさい。
UbuntuでPostgreSQLのストリーミングレプリケーションをするときの微妙にはまる!?落とし穴
PostgreSQL 9.5でストリーミングレプリケーションの構築を試してみました。いわゆるDBのマスター&スレーブ構成ってやつでしょうか。 これ→25.2. ログシッピングスタンバイサーバ
その作業の中で、普通ははまらないであろう落とし穴に落ちたので記録しておきます。
僕の落ちた落とし穴に落ちる可能姓のある人
僕が落ちた落とし穴に落ちる可能姓があるのは、以下の様な状況の人です。
- OSがUbuntu
- PostgreSQLをパッケージでインストールしている
- 複数のバージョンのPostgreSQLがインストールされている
(しかもマスタースレーブ構成を構築するPostgreSQLが一番最初にインストールしたバージョンじゃない) /etc/postgresql-common/user_clusters
で使用するPostgreSQLのバージョンを指定していない
ということが重なると今回の落とし穴に落ちる可能姓が大きいです。
はまった落とし穴
PostgreSQL 9.4での情報ですが、以下の方法の通り進めていきました。 hkou.hatenablog.com
ちなみに、Let's Postgresのページでも同様のやり方説明がありました。 lets.postgresql.jp
マスター側の設定は何事もなく終了し、「ベースバックアップをスレーブに転送する」をしようと、
user@localhost:~$ sudo su - postgres
postgres@localhost:~$ pg_basebackup -h exsample.com -U replicationuser -D /var/lib/pgsql/9.5/main/ -P -v --xlog
Password:
pg_basebackup: incompatible server version 9.5.1
という挙動を示してくれました。 pg_basebackup: incompatible server version 9.5.1
何事ぞ。
どうやらバージョンが違うといっているようですが、マスター側のDBは9.5.1だし、スレーブ側でも、
postgres@localhost:~$ psql --version
psql (PostgreSQL) 9.5.1
といわれます。 スレーブDB側の環境では確かに9.4、9.5の二つが動いていますが・・・。一応、Google先生に問い合わせてみるもそれらしい回答がない・・・。困ったなぁと思ったときに、そういえばUbuntuのPostgrSQLってなんだか特殊なんだったということを思い出しました。
上にあるように複数バージョンのPostgreSQLを運用しやすいように?なんかうまいことやってくれているらしいのですが、これが時にやっかいごとを招くようです。
落とし穴からの飛び出し方
落とし穴に入っているかは、このコマンドを叩いてみれば一発です。pg_basebackupのバージョンを確認してみます。pg_basebackupの説明ページでほとんど使うことはないだろうけどみたいに紹介されているオプション-vが役立つときです。
postgres@localhost:~$ pg_basebackup -v
pg_basebackup (PostgreSQL) 9.4.6
なんで9.4.6なの!?
理由はちょっと置いといて、Ubuntu で PostgreSQL を使ってみよう(続編) — Let's Postgresが言うには、
/usr/lib/postgresql/version/bin
にそれぞれのオリジナルの実行ファイルがあるようなので、
postgres@localhost:~$ /usr/lib/postgresql/9.5/bin/pg_basebackup -h exsample.com -U replicationuser -D /var/lib/pgsql/9.5/main/ -P -v --xlog
Password:
transaction log start point: 0/7000028 on timeline 1
151435/151435 kB (100%), 1/1 tablespace
transaction log end point: 0/7000130
pg_basebackup: base backup completed
ということでうまくいきました。
ちなみに、/etc/postgresql-common/user_clusters
で使用するPostgreSQLのバージョンを指定していれば、問題ないようです。
その後の作業は上のリンク先の通りにやったら無事完了でした。めでたしめでたし。
グローバルIPアドレス国別割り当てのデータを生成するスクリプトが書き上がるまでの道のりは険しかった…(解決編)
RIRsが提供してくれている、RIR statistics exchange formatになっているIPアドレスの割り当て状況のデータを加工するスクリプトを書きました。思考、試行過程をちょっと備忘録的に記録しておきますの第二弾です。
RIR statistics exchange formatを扱う時の問題点
詳細は第一弾で書いたとおりですが、一応ざっくりだけ。 kitaeng.hateblo.jp
RIR statistics exchange formatのレコードの中には、1レコードに対して一つの「ネットワークアドレス/CIDRブロック」の形で表せないレコードが存在しています。
例えばこんなレコードがあります。value
というのがIPアドレスの個数です。
registry | cc | start | value | date | status |
---|---|---|---|---|---|
ripencc | CH | 195.242.163.0 | 768 | 20080617 | assigned |
768個って、上の表では出てきません。768 = 256 * 3
なので、なるべくブロックが細かくならないように分けるとすると、/23と/24で分割してあげないといけません。
registry | cc | start | value | date | status |
---|---|---|---|---|---|
ripencc | CH | 195.242.163.0 | 256 | 20080617 | assigned |
ripencc | CH | 195.242.164.0 | 512 | 20080617 | assigned |
解決策1~まず始めに考えた方法
問題点としてあげたようなレコードは全レコードの中の大半を占めているという程の量ではなくて、普通に1レコードが一つの「ネットワークアドレス/CIDRブロック」の形で表せるものが大半なので、
- 一つの「ネットワークアドレス/CIDRブロック」で表せるもの
- 複数の「ネットワークアドレス/CIDRブロック」で表さなければならないもの
でレコードの処理方法を分ける事にしました。
一つの「ネットワークアドレス/CIDRブロック」で表せるものについては、CIDRブロックとホスト数の対応表を作って置いて、ホスト数(value)に基づいて、開始アドレス(=ネットワークアドレス)に対応するCIDRブロックを結合して出力することにしました。
複数の「ネットワークアドレス/CIDRブロック」で表さなければならないものについては、ホスト数(value)の値をうまく分割できるようなCIDRブロック表に現れるホスト数を見つけるために、valueの値を、CIDRブロック表にあるホスト数の少ない方から順に割っていって、割り切れなくなる(余りが0ではなくなる)ものの一つ前のCIDRブロックで分割することにしました。
一応コードとしては書き上がって、エラーもなく出力が得られたので、ウキウキしたのですが、PostgreSQLに読み込ませてからいろいろとSELECTをしてみていたら、なんだかデータがおかしいような気がしてきました。。。。
なんてこった!!
賢明な方は、すでに自分が陥った失態に気がついていることでしょう。
「RIR statistics exchange formatを扱う時の問題点」の説明のところを見直して見てください。分割すべきCIDRブロックは必ずしも同じ大きさのもので等分するのではなくて、複数の大きさのブロックをつかって分けた方が、効率的な分割になるのです。
等分するとなると結構小さなブロックが選ばれる事が多くて、/10とかは選ばれにくいわけです。そうなると、ある程度多い数のホスト数の部分を分割するときには、分割数が等分だと100個とかになることがありました。後々検索に書けるデータとして使うのには、レコード数はむやみにやたらと増えない方がベターな気がします。
ということで、この解決策1はボツになりました。
解決策2~別にホスト数とCIDRブロックの対応表なんていらないじゃん!
解決策1がボツになったことで、どうしたものかと考え直していたら、そもそも、ホスト数とCIDRブロックの対応表からマッチさせる必要などないのではないかと気がつきました。
ホスト数が分かれば、CIDRブロックなんて数値計算で導出できるではないかと。
計算方法はいくつかあるのでしょうが、科学計算分野でもよく使われるというPythonらしい感じで(!?)いくと、
Python 3.4.3
>>> import math
>>> cidr = 32 - math.log(value,2)
ホスト数(value)の底が2の対数を取って、32から引けば、そのホスト数をぴったり入れるCIDRブロックが分かります。一つのCIDRブロックで表現できないようなホスト数の場合は、この計算の結果が、整数にならないので、そこで判別ができます。
で、整数にならなかったものはどうするの??
例えば、このレコードの場合は、上の計算結果が小数になります。
registry | cc | start | value | date | status |
---|---|---|---|---|---|
ripencc | CH | 195.242.163.0 | 768 | 20080617 | assigned |
Python 3.4.3
>>> import math
>>> cidr = 32 - math.log(768,2)
22.415037499278846
常に切り上げてあげれば、最大のCIDRブロックは出そうです。あとは、ブロックの大きさを一つずつ小さくしながら、ホスト数が0になるまで減らしていけばいいと思うのですが…。
この処理を書こうとしたら、for、while、if地獄に落ちいって、どうもいい書き方が生み出せませんでした。
ということで、解決策2もボツです。
解決策3~3度目の正直!Pythonには、ipaddressという便利なモジュールがあった!
うーん。困ったとうなりながら、最後の出力の部分で使えそうだなと思って目星をつけていたipaddressというPythonのモジュールのドキュメントを読んでいると…。
21.28. ipaddress — IPv4/IPv6 操作ライブラリ — Python 3.5.1 ドキュメントの、「21.28.5. その他のモジュールレベル関数」という項目で、
ipaddress.summarize_address_range(first, last)(原文)
first と last で指定された IPアドレス帯に対するイテレーターを返します。 first はアドレス帯の中の最初の IPv4Address か IPv6Address で、 last はアドレス帯の中の最後の IPv4Address か IPv6Address です。 first か last がIPアドレスでない場合や、2つの型が揃っていない場合に、 TypeError を発生させます。 last が first より大きくない場合や、 first アドレスのバージョンが 4 でも 6 でもない場合は ValueError を発生させます。
という関数があるという紹介がありました。
自分の欲していた機能ではないか!!しかもこれを使えば、別に、
- 一つの「ネットワークアドレス/CIDRブロック」で表せるもの
- 複数の「ネットワークアドレス/CIDRブロック」で表さなければならないもの
で処理を分けなくてもいい(=コードが短くなる)ではないか!と感激したのでした。
ipaddressモジュールのおかげで、随分と楽に出来上がりました。Python3.x系からの標準ライブラリのようなのが、難点ですが、Ubuntuとかだと、次の16.04とかではPython3.xがメインのほうになるとかならないとかってのを見たような気がしないでもないので…。
ということで、完成したのが、 kitaeng.hateblo.jp
で紹介しているスクリプトです。
グローバルIPアドレス国別割り当てのデータを生成するスクリプトが書き上がるまでの道のりは険しかった…(原因編)
RIRsが提供してくれている、RIR statistics exchange formatになっているIPアドレスの割り当て状況のデータを加工するスクリプトを書きました。思考、試行過程をちょっと備忘録的に記録しておきます。
RIR statistics exchange formatについて
このフォーマットの仕様が道のりを険しくする最大の要因です。
普段IPアドレスの一覧を作るときや、iptablesとかの設定に入れるときは、
- "192.168.2.1" <-- 個別のIPそれぞれ
- "192.0.2.0/24" <--ブロックでまとめて
と表現することが多いと思います。IPアドレスの国別IPアドレス割り当てなんて話になれば、膨大な数のIPアドレスを扱うことになるので、個別のIPを列挙していくというよりも、ブロックでまとめての表現をつかうのがベターと思うのですが……。
RIR statistics exchange formatでは、割り当て開始のIPアドレスと、そこから何個分を割り当てているかという形で表現されています。そこから何個分を割り当てているかというところが鬼門です。
CIDR表記で扱う時の各CIDRに対応するIPアドレスの個数は、2 ^ (32 - CIDR)
で表せて、
CIDR | IPアドレス数 | CIDR | IPアドレス数 | |
---|---|---|---|---|
/32 | 1 | /16 | 65,536 | |
/31 | 2 | /15 | 131,072 | |
/30 | 4 | /14 | 262,144 | |
/29 | 8 | /13 | 524,288 | |
/28 | 16 | /12 | 1,048,576 | |
/27 | 32 | /11 | 2,097,152 | |
/26 | 64 | /10 | 4,194,304 | |
/25 | 128 | /9 | 8,388,608 | |
/24 | 256 | /8 | 16,777,216 | |
/23 | 512 | /7 | 33,554,432 | |
/22 | 1,024 | /6 | 67,108,864 | |
/21 | 2,048 | /5 | 134,217,728 | |
/20 | 4,096 | /4 | 268,435,456 | |
/19 | 8,192 | /3 | 536,870,912 | |
/18 | 16,384 | /2 | 1,073,741,824 | |
/17 | 32,768 | /1 | 2,147,483,648 | |
/0 | 4,294,967,296 |
という具合になるわけですが、RIR statistics exchange formatでは、この表に出てくるIPアドレス数以外の個数が現れます。
「えっ!?」ってなりますよね?
例えばこんなレコードがあります。value
というのがIPアドレスの個数です。
registry | cc | start | value | date | status |
---|---|---|---|---|---|
ripencc | CH | 195.242.163.0 | 768 | 20080617 | assigned |
768個って、上の表では出てきません。768 = 256 * 3
なので、なるべくブロックが細かくならないように分けるとすると、/24と/23で分割してあげないといけません。
registry | cc | start | value | date | status |
---|---|---|---|---|---|
ripencc | CH | 195.242.163.0 | 256 | 20080617 | assigned |
ripencc | CH | 195.242.164.0 | 512 | 20080617 | assigned |
こんな具合に書いていてくれればいいんですけど、そうじゃない……。
上のCIDR一覧に出てくるような数字だけが、valueに入っているなら、単純にvalueの部分を対応するCIDRに置換していって、開始IPアドレスのstart
と結合してあげれば、"192.0.2.0/24"の形になってくれるので、簡単だったんですが…。
手作業で例外部分だけ直すなんてのはちょっと美しくないのでどうしたものかとなったわけです。
皆さんならばどう解決しますか??
つづく...