2019年11月6日水曜日

PostgreSQLでIPv6、リンクローカルアドレスにはまる

IPv6、使いたくないという声の方がよく聞きますが、いまさらなので使っていきましょう。
今回はリンクローカルアドレスを使おうとしてはまる。

とある停電でDHCPのIPv4アドレスが振り直されてしまったのでRaspberryPiのIPv6使っておくかというふうに考えてみました。
ということで、RaspberryPiのPostgreSQLにもIPv6使ってみてもいいんじゃない?

IPv6のアドレス

IPv6に限らずですが、使われているアドレスの使われ方は いくつかあります。ローカルかつブロードキャストなど除くと127.0.0.1/8と、192.168.0.0/16 や172.168.0.0/16、10.0.0.0/8、それ以外に知られていないかもしれない169.254.0.0/16、などなどローカルなものもいろいろと。
IPv6でローカル的なアドレスを使おうとすると、ループバックアドレス(::1)、リンクローカルアドレス(fe80::/?)とユニークローカルアドレス(fd00::/8)などなどがあり、IPv4のプライベートIPアドレスのようなものです。
リンクローカルアドレスはルータ越えができず、ユニークローカルアドレスはルータ越えも可能です。
日本でネットに繋いでいればグローバルなIPv6アドレスも振られていると思いますが、外からも見えるので違うアドレスを使おうという今回の計画。

リンクローカルアドレス

今回は同一ネットワーク上にある機器を繋ぐということではじめから振られているリンクローカルアドレスを使ってみようと思ったのですが、PostgreSQLで。
 変更箇所は、postgresql.conf の listen_addressesと pg_hba.conf にIPv6アドレスの接続許可を加えることです。
まずはIPアドレスを確認します。
# ifconfig
でざっくりアドレスなどが出てくるのでinet6でlinkなアドレスを調べます。fe80::ではじまっているはずです。
wlan0: flags=xxxxxxx
          inet: 192.0.2.77
          inet6: fe80::7777:7777:7777:7777  prefixlen: 64  scopeid 0x20<link>
          inet6: 2001:db8:123:4567:89ab:cdef:123:7777 prefixlen 64  scopeid 0x0<global>


lo: とそれ以外があるのでそれ以外の方で fe80::はじまりの <link> のついたものをpostgresql.confのlisten_addressesに追加。

losten_address = '127.0.0.1,192.0.2.77,::1,fe80::7777:7777:7777:7777'

などとしてみます。77は例です。RaspberryPiな環境でPostgreSQLを再起動します。
# systemctl  restart postgresql
待ち受け状態を確認します。
# netstat -ant
tcp6 0 0 ::1:5432  :::* LISTEN

postgresqlのポートは5432ですが、IPv6では::1:5432しか見つかりません。::1なアドレスやグローバルなアドレスはこれで使えているのですが。

解決


リンクローカルアドレスを記述する場合、インターフェースが特定できないと困るので指定しないといけない場合があるようです。Linuxの場合、アドレスの後ろに%wlan0 などとつけます。ZoneIDとかいいます。インターフェースの名前は ifconfigコマンドの頭に出てくるものです。
losten_address = '127.0.0.1,192.168.0.77,::1,fe80::7777:7777:7777:7777%wlan0'

他の場合には%をエスケープする必要があるかもしれません。
これでもう一度再起動したところ接続可能になりました。

参考

URIの場合

古いURL(RFC 1738)ではZoneIDをサポートしていません。URIでも使えませんでしたが、RFC 6874でURIのZoneID拡張が入っています。
  • RFC 6874 ZoneIDをURIで
  • RFC 3986 URI
  • RFC 1738 URL

2019年10月23日水曜日

SQL標準はどこから

SQLはPostgreSQLばかり使っていて標準は少ししか意識していなかったり。
標準化もされていて、SQL99などという名前は聞いたことがあるかもしれないが、今は2003とか2011とかもっと新しいものまである。標準SQLというらしい。
最新版から見ればいいのか、ある程度古いところから差分を追いかけるのがいいのか。
Javaなどのオブジェクト指向に対応したというSQL99あたりから見てみることにしたい。

PostgreSQL 7.3のドキュメントによるとSQLはISO/IEC 9075 Database Language SQLというところが標準らしい。
SQL-92くらいでは実装は最小から大きいところまで分かれていたが大きすぎたので、SQL99ではコアとその他に分けてみたとか。
  • 標準SQL ISO/IEC 9075 Database Language SQL
    • SQL-92
    • SQL99 Javaなどオブジェクト化対応
    • SQL:2003
    • SQL:2011
    • SQL:2016
あまり関係ないがJDBCにオブジェクトを突っ込めそうなライブラリを作ってみた。
JSONでマッピング系を作っていたので流用した結果 Object → JSON → Map → JDBC(SQL) という変換をかけている。未実装だらけなので(仮)。要望等(謎)ないだろうから完成形にするつもりはあまりない。
 GitHub SoftLibD3BIF
動作確認はPostgreSQL 11のみ。
table定義を書かずに主キーなどはアノテーションをクラスに埋めるだけでも可。
そのうちJSONなど中間外して効率化するかもしれない。
EJBとかどうなったんだろか。

2019年10月9日水曜日

ASUS TUF X470 PLUS GAMING + Ryzen 5 2600X にメモリ増設

Ryzen 5 2600Xも快適ながら、早速DDR4メモリ、M.2 NVMeを入手したので増設してみることにしてみたのだけどちょっとエラーも多かったという話。
  • KLeVV CRAS C700 M.2 PCIe 3.0x4 NVMe1.3 480GB
  • KLeVV DDR4-3200 CL16-18-18-38-54 1.350 Vくらい
環境
  • AMD Ryzen 5 2600X
  • ASUS TUF X470-PLUS GAMING
  • キングストン HyperX DDR4-3200 CL16-18-18-36-74 1.350 Vくらい
  • とらんせんど M.2 PCIe 3.0x4 NVMe 1TB
  • GeForce RTX 2070 OC品

KLeVVというメーカーはメモリメーカーのSK Hynixの子会社っぽいところらしいのでほぼSK Hynix純正といえるようなところらしい。
Ryzen 5 2600X といえばメモリはオーバークロックメモリが標準的とも言えるような状態なので、最初からDDR4-3200なオーバークロックメモリを使っていた。というよりDDR4-3200(8GBx2)なメモリを入手したので新PCを組んだ。
今回さらにDDR4-3200(8GBx2)とM.2 Gen.3 x4 480GBを足して試してみることにした。

初回撃退


試用的なメモリなので8GBx2構成。どうせなら8GBx4にして使いたいのでそういうふうに使おうと単純に足してみたところ、起動はするものの、謎のエラーだらけで挫折。
増設して最初はそのまま何の問題もなく起動。
UEFIの設定を開くと設定が一部だけ大きな方向へ変わった。保存して再起動するとしばらくは起動するが不安定に。
2つのメモリ、CPU IDではtRAS、tRCが違うので CL16-18-18-38-54くらいになっているらしい。たぶん。

メモリスロットにうまく刺さっていなかったのか。それでもLEDが点灯するので動いていたとは思うとややコワイ。DDR4-3200 8GB x2構成に戻してしばらく使ってみたが安定した。
M.2を2つめの端子に入れようと思ったがネジとネジの台座がないので挫折。M.2に新しくOSを入れて怖くない環境でテストしてみてからにしよう。
というわけで。

準備。

microSDXCにWindowsイメージを焼き。 メモリを全部抜き、KLEVVのメモリだけを投入。M.2をKLEVVに交換。そのままWindows 10 Proをインストール。
シリアル番号は必須になっていた。が、省略も可能でマザーボードなどの環境情報から引き継がれたようだ。
インストール前に2、3の質問、インストール中にさらに2、3の質問あり。ネットワーク系は前の方にまとめるのは無理なのか。
起動してみると安定している様子。GPUなど各種ドライバなども中途半端に入れてみるが問題ないことを確認。
この段階での予想はメモリ混載がコワイのか? という感じ。

挑戦

KLEVVのメモリ単体では問題なかったのでこれまで使っていたキングストン HyperXと混載してみることに。今度は落ちた状態とは逆の順番で差し。起動してみるもHyperX刺さっていなくて光らず…コワイ。刺し直した。
UEFIの方は後から刺したスロットの方(若い番号の方)のXMP情報に合わせられた。遅い方に合わせるわけではなかったらしい。CL16-18-18-36-74 ということでいいのか?
結果安定しているように見える。何が悪かったのか。
M.2をトランセンドに戻して起動。落ちる様子がないので安定しているらしい。
半日ぐらいしたらエラー吐いた…。

2019年9月12日木曜日

RFC 7230 HTTPのABNF拡張を考えている

最近ABNF界隈のテストでRFCに書かれているABNFをいろいろ実装してみているのですが、ABNFを拡張したものがいくつかあり、RFC 7230 HTTPでは *の他に#というのが追加されていて、ABNFをわかっていないのか、なぜか中途半端なところまでしか書かれていない。
というわけでどうやって実装しようか悩んでみて拡張を投入してみた。

RFC 2373 IPv6
RFC 2396 URI
RFC 3986 URI
RFC 3987 IRI
RFC 6874
RFC 7230 HTTP
RFC 8259 JSON

このあたりのABNFを実装したりしなかったりしてGitHubへ投下してみたり。

NFCからIFTTTのIoTへ繋げるヒント

Google Homeなどで家電の操作ができ、ほとんどリモコンは必要なくなってきていたりしますが、素早く操作したいこともあるのでAndroidで操作画面を開いてアプリを開いてボタンを押す、みたいな長々とした操作をなんとかしたいところ。
というわけで、イベント駆動にNFCタグを使ってIFTTTをつつく方法を探してみたりしていました。IFTTTから先は連携できる機器が沢山あるので省略。
AndroidのIFTTTでもトリガーにNFCタグを読み取るという機能はないので、 NFCタグ側でなんとかしてみたいところです。
部屋の前で電気をつけたり、音楽を再生したり、音声操作が苦手でもNFCタグにタッチでできるようになったりならなかったり。

NFCタグ→URL→IFTTT


NFCに埋め込めるのは、アプリ固有の情報、URLなどいくつかあります。NFCからIFTTTに連携できそうなアプリはないようです。IFTTT側ではURLをトリガーにすることができるようなのでNFCタグにURLを埋め込み、タッチしてAndroidのブラウザで開くとIFTTTが動くという方向で考えてみます。
前提条件(制限事項)
  • FelicaではないのでAndroid画面が使える状態でしかNFCタグには反応しません。たぶん。
  • 数回操作があります。
  • ブラウザで開くので閉じるのが面倒です。

IFTTTのWebhooks

IFTTTをURLからつつくには、Webhooksというのがあるようです。IFTTTの画面が迷路のようなのでどこに何があるのかさっぱり…。

Appletにする

PCだと、IFTTTサイトのCreate でAppletを作ることができます。
If +This then That
  • ThisでWebhooksを探します。基本設定があるかもしれません。(Step 1 of 6)
  • ひとつしかないので Receive a web request を選び、英数で?イベント名を入力します。(Step 2 of 6)
  • Thatで操作対象サービスを選びます (Step 3 of 6)
  • 操作を選びます。(Step 4 of 6)
  • ボタンなどを選択します (Step 5 of 6)
  • できあがった機能に名前をつけて確認してFinish (Step 6 of 6)
追加したWebHooksの基本設定はMy services で確認することができます。
AppletはMy Applets で機能の有効/無効のON/OFFができます。

使う


Webhooksを追加できたらURLを使えるようにします。タグの機能にあわせててきとーに名前っぽいものをつけてON用とかOFF用とか用意します。
Applet? でIoT機器などと連携すればとりあえず完成。

NFCタグを作る

IFTTTで用意したURLをNFCタグに書き込みます。
標準的なURLを埋め込んだNFCタグを作ります。URLは共通仕様なので、書き込みアプリはどれでもいいです。サンワサプライのタグとアプリで書き込んでみました。
URLはIFTTTのMy servicesからWebHooksを選び、右上のDocumentationで書き方を確認できます。個人用のものは公開しないよう注意しましょう。
NFCのデータサイズはURLが入る程度なので小さいものでも問題なく書き込めました。

Androidでタッチ

URLを開きますか? と問われてブラウザが開きます。IFTTTが反応したらとりあえず成功です。あまりさくっと使えるものではないですが、使える場所にNFCタグを張っておくとリモコンがないときに便利かもしれません。

置き換えてみる

NFCタグの他に、QRコードでもURLを開くことはできますね。WindowsやAndroidのショートカットやブラウザのブックマークでもいいのですが、IFTTTのURLがつつければ、何でもできます。

2019年8月19日月曜日

Raspberry PiのTomcat 9にLet's Encryptを

Raspberry Piといえども最近はTLSが必要らしいので早々にTLS化する必要があります。
Let's Encryptを使用してみました。

# apt-get install python-certbot-apache
というのでいろいろインストールされた。
いろいろつついてしまった中で、最初はメールアドレスやライセンスの質問があった気がします。
とりあえず全部rootで実行してしまいましたがtomcatかなにかで使えるのかな?

何度か試してみた後…
# certbot certonly -d siisise.net
How would you like to authenticate with the ACME CA?
(認証方法どないする?)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Apache Web Server plugin (apache)
(Apacheのプラグイン使う)
2: Spin up a temporary webserver (standalone)
(仮の独立Webサーバ立ててサインアップする)
3: Place files in webroot directory (webroot)
(webのrootディレクトリにファイル置いて認証する)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3つの選択肢、サーバを止められるなら2、止められないなら3かな
とりあえず2と3で試してみた。ワイルドカード証明書はこれとは別でDNSを使うと取れるらしいです。

2の場合はポート80を使っているサーバを止めてから実行するだけ。
# service tomcat9 stop を先に実行しておく
仮のサーバが起動し、ドメイン接続確認後、 /etc/letsencrypt/live/siisise.net/ に各種ファイルを作ってくれました。developer.jpも同じように作成。

3の場合は
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for siisise.net
Input the webroot for siisise.net: (Enter 'c' to cancel):
webrootどこにある? と聞かれます。Tomcatの場合は webapps/ROOT/ のことです。
/var/lib/tomcat9/webapps/ROOT/ (マルチドメインにしていない場合)などフルパスで指定すると勝手にファイルを作って勝手に認証され、勝手にファイルを消すか何かで終わってくれます。

証明書とチェーン証明書は
/etc/letsencrypt/live/siisise.net/fullchain.pem
キーファイル(秘密鍵)は
/etc/letsencrypt/live/siisise.net/privkey.pem
2019年11月16日(3カ月くらい)で証明書は切れるよと。
新しい証明書とりたいときはcertbotを走らせるべし。
手動で全証明書更新するなら"certbot renew"を実行するべし。みたいな説明が出て完了。

最近の? Tomcat 9はJKSでもPKCS#11?でもPKCS#12でも使えますが、今回はApacheと同じcertbotが吐き出したPKCS#11かなにか(鍵と証明書が別ファイル)の形式のまま。PKCS12にまとめたりJKSに変換したりはしていないのでお手軽です。ディレクトリと/etc/letsencrypt/archive/ドメイン/privkey.pemのアクセス権をtomcatで利用可能なように調整。
# chgrp tomcat /etc/letsencrypt/archive
他いろいろ
tomcatのconfからシンボリックリンクを張り。使うのは証明書(cert.pemとchain.pem
 かfullchain.pem)と秘密鍵(privkey.pem)

# ln -s /etc/letsencrypt/live/siisise.net/fullchain.pem /etc/tomcat9/siisisenet-rsa-fullchain.pem
# ln -s /etc/letsencrypt/live/siisise.net/privkey.pem /etc/tomcat9/siisisenet-rsa-key.pem

Tomcatの /etc/tomcat9/server.xml を修正、起動。

HTTP/2の使えるport 8443の設定コメントを使ってport 443を設定してみた。(例によって<>括弧は全角)
< Connector port="443" protocol="org.apache.coyote.http11.Http11AprProtocol" maxThreads="150" SSLEnable="true" >
 <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol">
 <SSLHostConfig>
  <Certificate
 certificateKeyFile="conf/siisisenet-rsa-key.pem"
 certificateFile="conf/siisisenet-rsa-fullchain.pem"
 type="RSA" />
 </SSLHostConfig>
 <SSLHostConfig hostName="developer.jp">
  <Certificate
 certificateKeyFile="conf/developerjp-rsa-key.pem"
 certificateFile="conf/developerjp-rsa-fullchain.pem"
 type="RSA" />
 </SSLHostConfig></Connector>

とこんなかんじでマルチドメインでも使えます。SSLHostConfig デフォルト以外はhostNameを付けています。
certificateFileをfullchain.pem  にするとcertificateChainFileは要らないので省略しています。(Apache httpd 2.4.8以上と同じ、らしい)
# service tomcat9 restart かなにかで再起動。
使えないときは /var/log/tomcat9/catalina.2019-08-19.log などでエラーが出ていないかチェックします。
https://siisise.net/ や https://developer.jp/ にアクセスできることを確認。その他ドメインでもアクセスできますがドメインが違うと警告がでます。

Tomcatでサーバ運用は危険といわれていたこともありましたが、今は何が危険なのか。
自動更新までは試していないので、それはまたそのときかな。このまま更新を自動化してもアクセス権が死ぬかもしれない。秘密鍵は更新されない? さてどうでしょう。

2019年8月9日金曜日

Raspberry PiでTomcat 9とPostgreSQLをぐりぐりする

Raspberry Pi Zero WでJava SE 8が使えるようになったところでApache TomcatやPostgreSQLを使いたいのです。アクセス負荷に耐えられるようmicroSDカードは大容量や高耐久のものにしてみたのでした。

Tomcatは9だった

tomcatはパッケージを入れても動くのですが、常時動いてほしいのでaptで取ってくるとどうなるのかというお試し。最新のTomcat 9はJDK 8でも動きます。

# apt-get install tomcat9
で、だいたい入ります。tomcat9-admin も入れてみるといいのでしょうか。
他のパッケージはtomcat9-docs, tomcat9-examples, tomcat9-users とあるようです。
/usr/share/tomcat9 がCATALINA_HOME、/var/lib/tomcat9 がCATALINA_BASE となり、tomcatグループとユーザも作られ、サーバもtomcat権限で動いています。アプリ系のアカウントは基本rootやsudoで作業すればいいのでパスワードを設定してはいけません。
CATALINA_HOMEは基本的に触れません。CATALINA_BASEのconf内をいろいろカスタマイズすることで、いろいろと動いてくれます。/etc/tomcat9 にリンクされています。
初期ポートは8080なので、conf/server.xml でport 80にしたり、複数仮想サーバを作ったりできます。
サービス開始/停止は
# service tomcat9 start
# service tomcat9 stop
でできるようです。どこに設定があるのかよくわからない。 RedHat系で/etc/rc.d/init.d/ にあるようなものは /etc/default/ にあるのかな。
Webはオートデプロイにして、webapps相当のグループをtomcatにして書き込みもできるようにしておくと、管理も楽かもしれませぬ。

PostgreSQLはもう11か

Raspberry Pi Zero WとWH、ふたつあるのでTomcatとは別の方にPostgreSQL入れます。
# apt-get install postgresql だったかもう忘れた。
 rootではpsqlコマンドが使えなくなっているのでpostgresユーザでpsqlコマンドをたたきます。
# su - postgres
$ psql --version
psql (PostgreSQL) 11.4 (Raspbian 11.4-1)
これはrootでもできます。
$ psql
postgres=# \l
 でデータベースの一覧がでてきます。qで終わり? 基本的にいろいろ省略するとユーザ名と同じpostgresというPostgreSQLのユーザで同名のデータベースに繋がっています。
psqlから抜けるのは
postgres=# \q
です。\hでヘルプが出るかもしれません。
外部からのアクセスを許可するには、
/var/lib/postgresql/11/main/ がデータの位置、/etc/postgresql/11/main/ が設定ファイルの位置、らしいです。pg_hba.confで特定IPアドレスからのアクセスを許可します。アカウントも作っておきましょう。postgresql.confの設定も変える必要があるかもしれません。
雑に終了。

公開の際にはIPv4でフィルタリングしていてもIPv6で丸見えになることが予想されるので注意しましょう。

PostgreSQLでIPv6、リンクローカルアドレスにはまる

IPv6、使いたくないという声の方がよく聞きますが、いまさらなので使っていきましょう。 今回はリンクローカルアドレスを使おうとしてはまる。 とある停電でDHCPのIPv4アドレスが振り直されてしまったのでRaspberryPiのIPv6使っておくかというふうに考えてみました...