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で丸見えになることが予想されるので注意しましょう。

2019年8月7日水曜日

RazpberryPi Zero WでJavaを使おう

というわけでRaspberryPiどころか家でPCにも触ってなかったのですが最近Ryzen 5 2600XなPCを組んでからプログラミングやらいろいろ再開中で、RaspberryPiでWebサーバでもと思ったら2Bが行方不明なのでZero Wを買って挑戦してみることに。
いろいろ罠にはまります。
  • RaspberryPi Zero WとWHをスイッチサイエンスで1つずつ購入
  • microSDXCカード 128GBを2枚購入していた(危険 class 10、UHS-Ⅰ Speed Class 1、A1対応)
  • microSDHC 8~32GBが推奨
  • USBキーボードがなかった(Logiのワイヤレスドングルので可。SANWAのキーボードもあった)
  • てきとーなmicroUSBで繋がる電源
  • PuTTYとWinSCPでリモート接続

本体の選択

まずは本体の選択、初心者はできれば3B+かな。Zeroは2台目以降でもいいのかもしれない。
フルサイズUSB端子がある、有線LANがある、無線LANもある、HDMIがフルサイズ、などの理由です。変換ケーブル類も高いので予備がないなら3B+です。
Zero Wは、シングルコアARMv6、microUSB OTGがある、有線LANがない、無線LANがある、HDMIがminiサイズ、といろいろと不便です。Zeroになると無線LANまでないので別途用意しないといけません。
Javaを動かしたいならARMv7以降のCPUのものを選ぼう。NOOBSにはARMv7対応のJava11くらいが入っていた。Zero WはARMv6です。あとで対応したJavaを探します。

メモリーカード、OSの選択

メモリーカードの設定から入ります。microSDHC、microSDXCが使えますが、推奨は8GB以上のようです。microSDXCはフォーマットがFAT32ではないという理由で初心者にはおすすめしません。というわけで、初心者向けの容量は8GBから32GBの間で選びます。挑戦したい人はmicroSDXCも今は512GBくらいまであるので選び放題です。
速度など容量以外の選択基準では、class10、UHS不要、A1かA2対応のスマホ用に最適化されているようなものや、書き換えに高耐久なもの、がおすすめです。PCで最初に書き込むのが速い方がいいという理由でUHSスピードクラスの速いものを選んでも全然かまいません。

次にOS(インストーラ)ですが、NOOBSにしてみます。ファイルをコピーするだけで簡単です。OSは、Raspbianなども選択できます。

書き込んでみる(microSDXCで難儀)

64GB以上のmicroSDXCは特殊事情により標準のフォーマットがexFATです。RaspberryPiではこれをFAT32にする必要があります。
http://www.ridgecrop.demon.co.uk/index.htm?guiformat.htm
RasPiサイトでおすすめのフォーマッタはこれなのでこれでFAT32にフォーマットしてみました。
次にNOOBSのファイルをダウンロード、解凍して入れるだけ。Torrentも利用できるようです。とりあえずインストーラは完成。

繋ぐ+トラブル

RaspberryPi Zero WにmicroSDXCカード、miniHDMI、microUSB電源、キーボードを繋ぎ起動、インストーラ選択画面まで表示、操作できません。
原因は電源不足電源とデータの接続が逆。USBとPWRの刻印があるので注意しましょ。電源が外側の端子のようです。また、データ側のUSBを抜き差ししても再起動してしまうことがよくあるのでインストール用にUSB HUBなどをあらかじめ繋いでおきます。
無線LANを設定、OSを選んでインストールでなんとか進みます。インストーラの言語を日本語にしたりもできます。

OS入れた

インストールが進むと再起動、何かのOSがGUIで起動しました。このあとWi-Fi(選択するだけ、パスワードは設定済み?)など少し設定を進めます。言語のダウンロードなどがなぜか失敗。とりあえず完了のようなのでsshで繋ぐのとCUIで起動するくらいに少し設定を触ってみたりで再起動。
# java うごかない openjdk-11-jdkが入っていてARMv7以降に対応していました。RaspberryPi Zero WはARMv6のようですよ。なぜ。

設定が終わればキーボードマウスは使わないのではずしてしまっても安全です。
というわけで、いろいろ設定できるものを探してみるところからまたはじめようかと思います。
Bluetoothが繋がるタイミングも調べてみないとわかりませんね。

Javaを探す

Raspberry Pi Zero Wではopenjdk11が入っていても動かないのでバージョンを下げる対策が必要なようです。

# java -version
Error occurred during initialization of VM
Server VM is only supported on ARMv7+ VFP
javaコマンドを叩いてみるも、JDKが動きません。 server VMがARMv7用だとか。
何が入っているのか探してみます。
# which java
コマンドの位置を調べるコマンド which
 /usr/bin/java
# dpkg -S /usr/bin/java
ファイルのパッケージを調べるコマンド dpkg
反応がない…リンクされているのでその先をたどります。
# ls -l /usr/bin/java
最終的にたどりついたのは /usr/lib/jvm/java-11-openjdk-armhf/bin/java のようです
# dpkg -S /usr/lib/jvm/java-11-openjdk-armhf/bin/java
openjdk-11-jre-headless というパッケージに当たったので消し去ります。
openjdk-10-jre-headlessやopenjdk-9-jre-headlessも入っていたら消します。
# apt-get remove openjdk-11-jre-headless
openjdkとopenjreが消えてくれます。
# apt-get install openjdk-8-jdk
openjdk 8をインストール
# java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-8u212-b01-1+rpi1-b01)
OpenJDK Client VM (build 25.212-b01, mixed mode)
動いてくれました。

ここまでくれば、あとはてきとーに楽しめます。