2019/08/16(金)少なくとも Passenger Ver 5 以降は、FreeBSD11.3 ではコンパイル不能

2019/08/16 21:57 サーバ運営・管理
発端は、ruby を2.4系から 2.5系にアップデートしたことに始まります。
redmime を一部のプロジェクトで運用していますが、これを Apache で動作させるために、Passenger という連携モジュールが必要。

今回はこれにハマりました。現状の最新版 Passenger-6.0.2 でも同様です。

先ず、 redmine の動作に必要な ruby ライブラリをインストール後、最後にこのモジュールのインストール作業を行います。
通常、redmine をインストールしたディレクトリにて、
# gem install passenger
# passenger-install-apache2-module
とやるんですが、これがどうも上手く行かない。調べると、上記手順を実施する前に、
# setenv APXS2 '/usr/local/apache2/bin/apxs'
# setenv PATH '/bin:/usr/local/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/pgsql/bin:/usr/local/apache2/bin'
といった、環境変数の設定が必要な模様。
ソースコードから Apache をインストールした場合、passenger インストーラがApache を確認できないらしい。
これで、
# gem install passenger
は、上手く行きます。しかし、
# passenger-install-apache2-module
は、途中でコンパイルエラーになります。こんな感じ:
/usr/include/c++/v1/string_view:771:37: note: 'Passenger::ApiAccountUtils::string_view' declared here
typedef basic_string_view string_view;
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
1 warning and 20 errors generated.
rake aborted!
Command failed with status (1): [c++ -o buildout/support-binaries/WatchdogMain.o -Isrc/agent -Isrc/cxx_supportlib -Isrc/cxx_supportlib/vendor-copy -Isrc/cxx_supportlib/vendor-modified -Isrc/cxx_supportlib/vendor-modified/libev -Wno-ambiguous-member-template -Isrc/cxx_supportlib/vendor-copy/libuv/include -Isrc/cxx_supportlib/vendor-copy/websocketpp -I/usr/local/include -DHAS_CURL_EASY_RESET -D_REENTRANT -I/usr/local/include -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-long-long -Wno-missing-field-initializers -Wno-ambiguous-member-template -fvisibility=hidden -DVISIBILITY_ATTRIBUTE_SUPPORTED -DHAVE_ACCEPT4 -DHAS_SFENCE -DHAS_LFENCE -DPASSENGER_DEBUG -DBOOST_DISABLE_ASSERTS -g -fno-limit-debug-info -Wno-unused-local-typedefs -Wno-format-nonliteral -DHAS_UNORDERED_MAP -c src/agent/Watchdog/WatchdogMain.cpp]

Tasks: TOP => apache2 => buildout/support-binaries/PassengerAgent => buildout/support-binaries/WatchdogMain.o
調べると、どうも C++17 からでないと、サポートしていない構文を使っている模様。
C++17 をコンパイラに強制させて解決するには、こうします:
# setenv EXTRA_CXXFLAGS '-std=c++17'
要するに、上記の環境変数にて、追加のコンパイラオプションを設定し、再度
# passenger-install-apache2-module
と、するのです。ですが、これで解決するはずが、別の場所でエラーが出ました。こんな感じ:
pedefs -Wno-format-nonliteral -DHAS_UNORDERED_MAP -std=c++17 -c src/cxx_supportlib/IOTools/IOUtils.cpp
src/cxx_supportlib/IOTools/IOUtils.cpp:288:3: error: use of undeclared identifier 'random_shuffle'
random_shuffle(result.begin(), result.end());
^
1 error generated.
rake aborted!
Command failed with status (1): [c++ -o buildout/apache2/module_libpassenger_common/IOTools/IOUtils.o -Isrc/cxx_supportlib -Isrc/cxx_supportlib/vendor-copy -Isrc/cxx_supportlib/vendor-modified -Isrc/cxx_supportlib/vendor-modified/libev -Wno-ambiguous-member-template -Isrc/cxx_supportlib/vendor-copy/libuv/include -O -fPIC -I/usr/local/apache2/include -I/usr/local/apache2/include -I/usr/local/apache2/include -D_REENTRANT -I/usr/local/include -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-long-long -Wno-missing-field-initializers -Wno-ambiguous-member-template -fvisibility=hidden -DVISIBILITY_ATTRIBUTE_SUPPORTED -DHAVE_ACCEPT4 -DHAS_SFENCE -DHAS_LFENCE -DPASSENGER_DEBUG -DBOOST_DISABLE_ASSERTS -g -fno-limit-debug-info -Wno-unused-local-typedefs -Wno-format-nonliteral -DHAS_UNORDERED_MAP -std=c++17 -c src/cxx_supportlib/IOTools/IOUtils.cpp]

Tasks: TOP => apache2 => buildout/apache2/mod_passenger.so => buildout/apache2/module_libpassenger_common/IOTools/IOUtils.o
ん~、、調べると、この random_shuffle という関数は C++17では「廃止」されたらしい。
なのでエラーになるのです。これには困った・・・というか、バグの類でしょう。。

結局、3箇所修正することで、コンパイルできます。
/usr/local/lib/ruby/gems/2.5/gems/passenger-6.0.2/src/cxx_supportlib/IOTools/IOUtils.cpp
   37 #include <algorithm>
   38 #include <string>
   39 #include <vector>
+  40 #include <random>
   41 #include <sys/socket.h>
   42 #include <sys/types.h>

  287         freeaddrinfo(res);
  288         if (shuffle) {
  289 //              random_shuffle(result.begin(), result.end());
+ 290                 std::shuffle(result.begin(), result.end(),std::mt19937());
  291         }
  292         return result;
  293 }
/usr/local/lib/ruby/gems/2.5/gems/passenger-6.0.2/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/memory.hpp
 65 #ifdef _WEBSOCKETPP_CPP11_MEMORY_
 66     using std::shared_ptr;
 67     using std::weak_ptr;
 68 //    using std::auto_ptr;
 69     using std::enable_shared_from_this;
 70     using std::static_pointer_cast;
 71     using std::make_shared;
 72     using std::unique_ptr;
ソースコード修正後、
# setenv EXTRA_CXXFLAGS '-std=c++17'
# passenger-install-apache2-module
とすることで、使用できるモジュールが出来上がるようです。

2019/07/12(金)FreeBSD11/FreeBSD12 にて無償利用可能なサーバ証明書 Let's Encrypt を使う

2019/07/12 17:39 サーバ運営・管理
他のFreeBSD バージョンでも恐らく使用可能です。
Let's Encrypt は、有効期間90日(自動延長可能)な無償サーバ証明書です。
FreeBSD におけるやり方について、余り情報が書かれていないので、ここで提示しておきます。

これを使うには、先ずは使用するサーバにて、管理ツールのようなものをインストールします:
FreeBSD Ports においては、 securiry/py-certbot をインストールします。
#Python を使用したスクリプトなので、依存関係で Python 本体と、動作に必要な python モジュールが
#インストールされます。

インストールが終わったら、Apache や nginx を一旦停止して、
# certbot certonly --standalone -d 《FQDN名》-m 《通知電子メールアドレス》
のようにコマンドを入力します。
#このスクリプトが一時的に http サーバになるため、ポート番号が競合するからのようです。

《FQDN名》は、証明書発行申請するときのコモン名。例えば https://server.example.com/ のサーバ証明書が欲しければ、 ここに server.example.com と記述します。

《通知電子メールアドレス》は、何かある場合に連絡が入る電子メールアドレスを指定します。
実在する電子メールアドレスを指定します。
証明書の期限が間近になった場合などに連絡が入るようです。

コマンドの実行が始まると、先ず、下記のメッセージが表示されます:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A
使用条件・契約条件を許諾するか否かの問いです。Agree のA を入力します。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
次に、各種の連絡を電子メールで送るけれど、本当に良いか? という趣旨の問いです。
これも Yes の Y を入力します。
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for server.example.com
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/usr/local/etc/letsencrypt/live/server.example.com/fullchain.pem
Your key file has been saved at:
/usr/local/etc/letsencrypt/live/server.example.com/privkey.pem
Your cert will expire on 2019-10-10. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- Your account credentials have been saved in your Certbot
configuration directory at /usr/local/etc/letsencrypt. You should
make a secure backup of this folder now. This configuration
directory will also contain certificates and private keys obtained
by Certbot so making regular backups of this folder is ideal.
- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
上記で、'Congratulation' のメッセージが含まれていたら、作成は成功です。
正直なところ、少し判り難いです。
上記例では有効期限は 2019/10/10 だと言っています。

失敗しているような場合は、再度、
# certbot certonly --standalone -d 《FQDN名》-m 《通知電子メールアドレス》
上記のコマンドを入力してみましょう。
但し、FQDN名がDNSで正引き出来ないと、上手く行かないみたいです。

Apache には以下の要領で設定します (要所を抜粋):
SSLCACertificateFile /usr/local/etc/letsencrypt/live/server.example.com/chain.pem
SSLCertificateFile /usr/local/etc/letsencrypt/live/server.example.com/cert.pem
SSLCertificateKeyFile /usr/local/etc/letsencrypt/live/server.example.com/privkey.pem
 'server.example.com' の部分を、使用するFQDN に合わせて変更します。

最後に自動更新させるには、以下を、crontab に追加します:
0 6,21 * * * /usr/local/bin/certbot renew --agree-tos --webroot -w
/home/webroot/server.example.com/public --renew-by-default
&& /usr/local/etc/rc.d/apache2 restart
#表示の便宜上3行に分けているが、実際に適用の際は半角スペースで区切って1行にすること。
 -w のあとのフルパスは、該当 FQDN におけるドキュメントルート絶対パスを指定します。

1日2回の更新チェックが推奨されているようです。

URL変更のお知らせ

2018/12/20 4:29 雑多なトピック
はんかくさい日報のURLを https://www.basekernel.jp/cgi-bin/adiary/adiary.cgi/basekrnl/ 配下に変更しました。
旧URLからは、上記の新URL配下へ自動転送されます。

ブックマークやリンクされている場合は、お手数おかけしますが上記URLへの変更をお願いします。
尚、サブドメイン hankakusai.basekernel.co.jp は、 2019/07/15 に廃止します。

2019/06/05(水)Postfix にて Cyrus SASL 認証のセットアップ

2019/06/05 17:31 サーバ運営・管理
自分メモ。
以前は管理の都合上、ソースコードから構築していたが、最近はFreeBSD でも Ports から導入する方が確実。
最近の FreeBSD では、素の Cyrus-SASL ソースコードでは色々面倒なことのほうが多い。

security/cyrus-sasl-2.1.27
security/cyrus-sasl-saslauthd-2.1.27_1

の2つを Ports からインストールします。
その後で、SMTP 認証にCyrus SASL を使えるように Postfix をセットアップします。
Postfix は、Ports ではなく、ソースコードから構築しないと、管理上却って面倒。

root で先ずはこんな感じで環境設定:
# setenv CPPFLAGS '-I/usr/local/include -I/usr/local/include/db5 -I/usr/include -I/usr/local/include/sasl'
# setenv LDFLAGS '-L/usr/local/lib -L/usr/local/lib/db5 -L/usr/lib'
# setenv LD_LIBRARY_PATH '/usr/local/lib /usr/local/lib/db5 /usr/lib'
これやらないと、当方の環境ではコンパイル自体が上手く行かないんです。

続いて root で make ファイル生成
(画面上では見やすいように複数行にしているが、実際は半角スペースで区切って1行にしてください):
# make -f Makefile.init makefiles
  'CCARGS=-DUSE_TLS -DUSE_SASL_AUTH -DUSE_CYRUS_SASL
             -I/usr/local/include -I/usr/local/include/sasl -I/usr/include/openssl'
  'AUXLIBS=-L/usr/lib -lssl -lcrypto
       -L/usr/local/lib -lsasl2 -licudata -licui18n -licuio -licutest -licutu -licuuc
       -L/usr/local/lib/db5 -ldb'
これが上手く出来れば、あとは普通に
# make
# make install
# rehash
とすれば、Cyrus SASL 認証サポート対応の Postfix が出来るはず。

続いて設定:
下記の内容で、 /usr/local/lib/saal2/smtpd.conf のテキストファイルを作成:
pwcheck_method: auxprop
この設定は、cyrus SASL 独自で認証ユーザを管理することを意味します。
サーバ自身にユーザアカウントを追加せずに済むので、このメールアドレス管理方法はお勧めです。
以下でメールアドレスを設定・管理できます:
# saslpasswd2 -c -u example.com xxxxuser (ユーザ新規追加)
# saslpasswd2 -d -u example.com xxxxuser (ユーザの削除)
# sasldblistusers2            (登録ユーザの確認)
ここで、example.com は実際に使用するドメイン名、 xxxxuser は、メールアドレスの@マークの左側を指定します。
ユーザ新規追加の際のみ、設定するパスワード入力を促されます。2回同じパスワードを入力するようになります。
/usr/local/etc/sasldb2 に登録されます。このファイルのパーミッションは 644 にしておきます。

更に、/etc/postfix/main.cf に下記の設定追加:
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = cyrus
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $mydomain

smtpd_relay_restrictions = permit_mynetworks,
                           permit_sasl_authenticated,
                           defer_unauth_destination

smtpd_recipient_restrictions = permit_mynetworks,
                               permit_sasl_authenticated,
                               reject_unauth_destination

smtpd_helo_restrictions = permit_mynetworks,
                          permit_sasl_authenticated,
                          reject_unauth_destination
最後に自動起動の設定です。/etc/rc.conf に
saslauthd_enable="YES"
saslauthd_flags="-a pam"
の2行を追加しておきましょう。
最後に、サーバを再起動するか、 /usr/local/etc/rc.d/saslauthd start で、認証デーモンをスタート出来たら設定完了。

2019/05/11(土)帯域不足が明らか・・・〔車載動画〕

2019/05/11 19:11 雑多なトピック
今日の未明、6本の車載動画をアップしたのですが、下記はそのうちの2本。
 

所々、画質劣化が起きるのは既知の問題なのですが、この2つはそれが酷い。
原因はハッキリしていて、小枝が沢山あるような細かい画になると、Youtube の配信ビットレートでは情報量が過多になるので、その分画質落として削るのです。

なので、オリジナルを用意しました。(※ Chrome でしか再生出来ません。)
ただ、動画のビットレート見ると 25Mbps 程度になっていて、スムーズな再生は困難な環境が多そうです。逆に言うと mp4 では、25Mbps 必要なんですよ。。。
〔手稲山往還 上り〕https://www.asahi-net.or.jp/~nz7k-tkhs/20190504_teine_up.html
〔手稲山往還 下り〕https://www.asahi-net.or.jp/~nz7k-tkhs/20190504_teine_down.html

あと、上記2つは、
合法的にダウンロード再生してもよいように、クリエイティブコモンズライセンスにしました。2次加工もご自由にどーぞ。


ほんと、ユーザサイドではどうしようもできないので、改善して欲しい。

2019/04/17(水)新元号の対応

弊社の現在公開しているページ( https://www.basekernel.co.jp/ )にて確認作業していたので、ひょっとしたら見た人がいたかもしれませんが・・・
#限りなくゼロに近いと思っているが。。

20190417_1.png

20190417_2.png

20190417_3.png

20190417_4.png

20190417_5.png


ま、こんな感じにしました。西暦2019年は、4/30,5/2 も祝日法に基づくと、
西暦2019年限定で休日になります。

ちなみに今年と来年は、オリンピックもあり、特例の祝日が結構あるんです。

2019/03/16(土)CPU マイクロコードのアップデート

2019/03/16 6:36 サーバ運営・管理
昨年、CPU自体の脆弱性として、「Meltdown」(メルトダウン)と「Spectre」(スペクトル)というものが知られるようになり、対処するためにCPU製造メーカでは、「マイクロコードの修正・更新」という手法を使って居ます。

聞いたことはあっても、『マイクロコードって何?』的な方々が殆どだと思います。
これはCPUの基本的な仕組みを知らない方々に対して言葉で説明するのも難しい代物ですが、
できるだけ簡単に述べると、CPUに対する命令コード(いわゆる昔は「機械語」と言っていた)の解析・実行処理を司る部分の一部を、内部の配線を変更するかの如くに書き換えるのです。

実際に配線を変更するのではなく、同等の効果を得るようにファームウェアを書き換えるようなイメージが最も近いでしょうか。しかし、実際はCPU内部にファームウェアを持っているわけではありません。やはり、CPUの仕組みを習得してもらわないと的確な説明は難しいです、はい。

FreeBSD においては、Ports の中の sysutils/devcpu-data をインストールすることで可能です。
# cd /usr/ports/sysutils/devcpu-data
# make install
インストール完了時にこのようなメッセージが出ます:
The first method ensures that any CPU features introduced by a microcode
update are visible to the kernel.  In other words, the update is loaded
before the kernel performs CPU feature detection.

To enable updates using the first method, add the following lines to
the system's /boot/loader.conf:

cpu_microcode_load="YES"
cpu_microcode_name="/boot/firmware/intel-ucode.bin"

This method will not load the microcode update until the system is
rebooted.

To enable updates using the second method, add the following line to
the system's /etc/rc.conf:

microcode_update_enable="YES"


Updating CPU Microcode...
/usr/local/share/cpucontrol/m32306c3_00000022.fw: updating cpu /dev/cpuctl0 from rev 0x17 to rev 0x22... done.
/usr/local/share/cpucontrol/m32306c3_00000022.fw: updating cpu /dev/cpuctl2 from rev 0x17 to rev 0x22... done.
/usr/local/share/cpucontrol/m32306c3_00000022.fw: updating cpu /dev/cpuctl4 from rev 0x17 to rev 0x22... done.
/usr/local/share/cpucontrol/m32306c3_00000022.fw: updating cpu /dev/cpuctl6 from rev 0x17 to rev 0x22... done.
Done.
インストール時にマイクロコードの更新は出来ているようですが、上記の英文見ると、どうやら自動更新させるために更に設定が必要なようです。
自分も含めて英語が苦手な方々向けに説明を残します。

1つ目:
/boot/loader.conf に下記の行を追記:
cpu_microcode_load="YES"
cpu_microcode_name="/boot/firmware/intel-ucode.bin"
再起動で必要に応じ、マイクロコードの更新がされる模様。

2つ目;
/etc/rc.conf に下記の行を追記:
microcode_update_enable="YES"
OSブート時に必要に応じ、マイクロコードの更新がされる模様。

どちらか1つで良さそう(後者だけを指示しているブログ等も見かける)ですが、よくわからないので、とりあえず一応両方入れています。

2019/03/01(金)ディジタル証明書の形式 pem と der

https:// 接続などでサーバ証明書を扱ったことがある方は、下記フォーマットを見たことがあると思います。
※現在、実運用で使っていませんが念のため一部端折っています。
-----BEGIN CERTIFICATE-----
MIIC4TCCAkqgAwIBAgIBADANBgkqhkiG9w0BAQUFADB4MQswCQYDVQQGEwJKUDER
MA8GA1UECBMISG9ra2FpZG8xGzAZBgNVBAoTEkJhc2UgS2VybmVsIENvIEx0ZDEg
MB4GA1UECxMXTmV0d29yayBPcHJhdGlvbiBDZW50ZXIxFzAVBgNVBAMTDkJhc2Ug
S2VybmVsIENBMB4XDTA4MDcxMzEzMTU0NVoXDTI4MDcxMzEzMTU0NVoweDELMAkG

・・・・一部省略・・・・

A1UEBhMCSlAxETAPBgNVBAgTCEhva2thaWRvMRswGQYDVQQKExJCYXNlIEtlcm5l
+6EEruiOlNKYnViRTdjEoAPRYfgM+eqjnfbVOxB0wEV7w5GjcqbGe9ePrEUs1wYS
ktnZC7H0p5H01z92udKE3BaCEACQ
-----END CERTIFICATE-----
これは、pem 形式と呼ばれるディジタル証明書で、通常はこの形式で管理します。
ところが、時々、 der 形式しか受け付けないディジタル証明書アプリケーションがあるのです。

今回、コントロールパネルのサーバ設定部分の一部が時代に合わなくなっていて、この部分の改良を施しているところで、その一環でサーバ証明書をある程度自力管理できるようにしているのですが、その過程でディジタル証明書の内容を解析する Perl モジュールに Crypt::X509 という便利なものがあってそれを使おうとしたら、このモジュールが der 形式しか対応していないのです。

もっと便利そうなものに Crypt::OpenSSL::X509 というのがあるが、今のところ、OpenSSL 1.x 系への対応があまり芳しくなく、避けざるを得ない状況。

der 形式はバイナリファイルなので扱いにくいのです。ただ、具体的中身まではよく知りません。
調べると、 pem 形式ファイルの -----BEGIN CERTIFICATE----- 行と、-----END CERTIFICATE----- 行を取っ払った残りの部分を、Base64 デコードしてあげればいいだけであることが判りました。

つまり、pem 形式は、der 形式で生成したディジタル証明書のデータ構造を Base64 エンコードして、-----BEGIN CERTIFICATE----- 行と、-----END CERTIFICATE----- 行を付け足しただけなのです。

ここまで判れば、ディジタル証明書の内容確認は、Perl でやる場合は以下の要領で出来ます:
#!/usr/local/bin/perl

use MIME::Base64 ;                                     # Base64ライブラリ使用宣言
use Crypt::X509 ;                                      # 証明書内容参照ライブラリ使用宣言

$csr_pem = "" ;
$status  = open (CSRPEM,"hoge.pem") ;
if ($status) {
  local $/ = undef ; $csr_pem = <CSRPEM> ; close(CSRPEM) ;
}

$csr_pem =~ /\-\-\-\-\-BEGIN\s+CERTIFICATE\-\-\-\-\-(.+)\-\-\-\-\-END\s+CERTIFICATE\-\-\-\-\-/s ;
$x509_tmp = $1 ;
%outstr   = {} ;

$x509_decode = Crypt::X509->new(cert => decode_base64($x509_tmp)) ;
@nb = localtime($x509_decode->not_before) ;
@na = localtime($x509_decode->not_after) ;
@jw = ('日','月','火','水','木','金','土') ;
$outstr{'not_before'}     = sprintf("%d/%02d/%02d(%s) %02d:%02d:%02d",$nb[5] + 1900,$nb[4] + 1,$nb[3],$jw[$nb[6]],$nb[2],$nb[1],$nb[0]) ;
$outstr{'not_after'}      = sprintf("%d/%02d/%02d(%s) %02d:%02d:%02d",$na[5] + 1900,$na[4] + 1,$na[3],$jw[$na[6]],$na[2],$na[1],$na[0]) ;

$outstr{'subj_country'}   = $x509_decode->subject_country ;
$outstr{'subj_state'}     = $x509_decode->subject_state ;
$outstr{'subj_local'}     = $x509_decode->subject_locality ;
$outstr{'subj_org'}       = $x509_decode->subject_org ;
$outstr{'subj_ou'}        = $x509_decode->subject_ou ;
$outstr{'subj_cn'}        = $x509_decode->subject_cn ;

$outstr{'issuer_cn'}      = $x509_decode->issuer_cn ;
$serial16 = sprintf("%X",$x509_decode->serial) ;
$serial16 =  '0' . $serial16 if (length($serial16) % 2) ;
1 while $serial16 =~ s/^([\da-fA-F]+)([\da-fA-F][\da-fA-F])/$1\:$2/ ;
$outstr{'issuer_serial'}  = $serial16 ;
$outstr{'issuer_country'} = $x509_decode->issuer_country ;
$outstr{'issuer_state'}   = $x509_decode->issuer_state ;
$outstr{'issuer_local'}   = $x509_decode->issuer_locality ;
$outstr{'issuer_org'}     = $x509_decode->issuer_org ;
$outstr{'sigalgo'}        = $x509_decode->sig_algorithm ;
上記サンプルにて、連想配列 %outstr に表示可能な文字列にて解析内容が入ります。
参考:https://metacpan.org/pod/Crypt::X509

2019/02/13(水)perl にて IPv4 と IPv6 のデュアルスタックサーバを作る

Perl において、この用途には IO::Socket::INET というコアモジュールが広く使われていて、
ちまたにはこれを、IO::Socket::IP に変えるだけで IPv4/IPv6 デュアルスタックが実現するかのような話が広く知られているようだが、実際はどうも違う模様。。

今まで IPv4 で動作していたこのコード:
#!/usr/local/bin/perl
#
use utf8 ; binmode(STDOUT, ":utf8") ;
use IO::Socket::INET ;                     # ソケットインタフェース使用宣言

$comm_queue  = 5 ;                         # コネクション待ち受けキューの数
$port        = 9999 ;                      # port no.

### 通信ソケット生成
# ソケットオープン
$reqsock = IO::Socket::INET->new (LocalPort => $port,
                                  Listen    => $comm_queue,
                                  Proto     => 'tcp',
                                  Reuse     => 1,
                                 ) ;
if (not $reqsock) {
  err_trap("通信ソケットが作成できません。",$!) ;
  exit ;
}

### サーバメインルーチン
for (;;) {
  $sock = $reqsock->accept() ;
  if (not $sock) {
    err_trap("クライアントの要求受け付けに失敗しました。(accept error)",$!) ;
    exit ;
  }

  if ($child = fork()) {
  # 親プロセスの実行コード
    $sock->close() ;
    waitpid($child,0) ;
    next ;                                 # 次のコネクション要求を待つ

  } elsif (defined($child)) {
  # 子プロセスの実行コード(メインルーチン)
    $reqsock->close() ;
    select($sock) ; $| = 1;                # 常に flash するようにする
    select(STDOUT) ;
    binmode $sock ,':encoding(UTF-8)' ;

  以下、サーバの処理プログラム・・・・
  }
}
IO::Socket:INET の部分を、IO::Socket::IP に書き換えても、IPv6 しか受け付けない状態になります。
もしかしたら、IPv4射影アドレスを使えばいいのかもしれないですが、現状環境には全く合わない。

試行錯誤の結果、以下で動作する模様:
#!/usr/local/bin/perl
#
use utf8 ; binmode(STDOUT, ":utf8") ;
use IO::Socket::INET ;                     # IPv4 Socket インタフェースライブラリ使用宣言
use IO::Socket::INET6 ;                    # IPv6 Socket インタフェースライブラリ使用宣言
use IO::Select ;

$comm_queue  = 5 ;                         # コネクション待ち受けキューの数
$port        = 9999 ;                      # port no.

### 通信ソケット生成
$select = IO::Select->new ;

# ソケットオープン[IPv6]
$psock6 = IO::Socket::INET6->new (LocalPort => $port,
                                  Listen    => $comm_queue,
                                  Type      => SOCK_STREAM,
                                  Reuse     => 1,
                                  Proto     => "tcp"
                                 ) ;
if (not $psock6) {
  err_trap("通信ソケットが作成できません。[IPv6]",$!) ;
  exit ;
} else {
  $select->add($psock6) ;
}

# ソケットオープン[IPv4]
$psock4 = IO::Socket::INET->new (LocalPort => $port,
                                 Listen    => $comm_queue,
                                 Type      => SOCK_STREAM,
                                 Reuse     => 1,
                                 Proto     => "tcp"
                                ) ;
if (not $psock4) {
  err_trap("通信ソケットが作成できません。[IPv4]",$!) ;
  exit ;
} else {
  $select->add($psock4) ;
}

### サーバメインルーチン
for (;;) {
  while (my @ready = $select->can_read) {
    foreach my $reqsock (@ready) {
      $sock = $reqsock->accept() ;
      if (not $sock) {
        err_trap("クライアントの要求受け付けに失敗しました。(accept error)",$!) ;
        exit ;
      }

      if ($child = fork()) {
      # 親プロセスの実行コード
        $sock->close() ;
        waitpid($child,0) ;
        next ;                                 # 次のコネクション要求を待つ

      } elsif (defined($child)) {
      # 子プロセスの実行コード(メインルーチン)
        select($sock) ; $| = 1;                # 常に flash するようにする
        select(STDOUT) ;
        binmode $sock ,':encoding(UTF-8)' ;

      以下、サーバの処理プログラム・・・・
      }
    }
  }
}
参考になったのは、これ → How best to support IPv4/v6 in Perl server

2019/02/07(木)FreeBSD の portupgrade

2019/02/07 18:47 サーバ運営・管理
FreeBSDを10 から11にしたあと、portupgrade で ports 導入の各ソフトウェアを更新したりすると、
===>  Cleaning for ImageMagick7-nox11-7.0.8.22
--->  Cleaning out obsolete shared libraries
No such file or directory @ realpath_rec - /usr/local/lib/compat/pkg/db5
No such file or directory @ realpath_rec - /usr/local/lib/compat/pkg/db5
No such file or directory @ realpath_rec - /usr/local/lib/compat/pkg/db5
No such file or directory @ realpath_rec - /usr/local/lib/compat/pkg/db5
No such file or directory @ realpath_rec - /usr/local/lib/compat/pkg/db5
No such file or directory @ realpath_rec - /usr/local/lib/compat/pkg/db5
のようなメッセージが毎回出るようにになります。実害は無いのでほったらかし状態だったが、気になるものは気になるので、対策を。。
# cd /usr/local/lib/compat/pkg
# ls -al
lrwxr-xr-x  1 root  wheel        22  7月  4  2018 libdb_cxx-5.3.so.0@ -> db5/libdb_cxx-5.3.so.0
lrwxr-xr-x  1 root  wheel        18  7月  4  2018 libdb_cxx-5.so.0@ -> libdb_cxx-5.3.so.0
lrwxr-xr-x  1 root  wheel        22  7月  4  2018 libdb_stl-5.3.so.0@ -> db5/libdb_stl-5.3.so.0
lrwxr-xr-x  1 root  wheel        18  7月  4  2018 libdb_stl-5.so.0@ -> libdb_stl-5.3.so.0
lrwxr-xr-x  1 root  wheel        18  7月  4  2018 libdb-5.3.so.0@ -> db5/libdb-5.3.so.0
lrwxr-xr-x  1 root  wheel        14  7月  4  2018 libdb-5.so.0@ -> libdb-5.3.so.0
実に簡単。上記6つのシンボリックリンクを削除するだけ。これで解決しました。
OSをメジャーバージョンアップデートしたら、依存ライブラリは変更されていることが殆どなので、できるだけ早めに各ソフトウェアは再コンパイルするのが無難。

FreeBSD は、後方互換機能で何事もなく動作することが多いです。
しかしそれに頼り切っていると経験上、ある日突然、不可解な障害に悩むことになるのです。
OK キャンセル 確認 その他