highlight.xcode

2021年6月7日月曜日

Debian stretch で zswap を有効化



運用中の Debian stretch が、たまにスワップアウトを起こし、動作が遅くなってしまう事があるのですが、事情が有ってメモリを増やす事も出来ないので、zswap を試してみる事にしました。

zswap とは、実メモリの一部をスワップ領域として使用する機能です。また、メモリ上のスワップ領域は圧縮されるので、圧縮に使用される CPU パワーと引き換えに、スワップアウトしづらくなる、といった機能です。

Debian stretch ではカーネルパラメータとして指定する事で、zswap 機能が有効となったカーネルイメージを使用するようになります。


"/etc/default/grub"ファイルを編集し、"zswap.enabled=1"というパラメータを追加します。
(省略)
GRUB_CMDLINE_LINUX_DEFAULT="quiet zswap.enabled=1"
(省略)

パラメータを追加したら保存し、grub を更新します。
# update-grub
(省略)

これで再起動を行うと、zswap 機能が有効となったカーネルイメージが使用される様になります。


再起動したら、一応確認します。
# dmesg | grep zswap
[    0.000000] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-4.9.0-15-686-pae root=UUID=69f4b940-3ffc-43b8-91d7-0ea0d831470f ro quiet ipv6.disable=1 zswap.enabled=1
[    1.191044] zswap: loaded using pool lzo/zbud

無事 zswap がロードされている様です。

2021年5月31日月曜日

nginx の「Too many open files」エラーの対処



Debian buster 上の nginx の設定を煮詰め直すのに色々と調べた時のメモ。

nginx と言えばC10K問題の解決、を目的の 1つとして開発された I/O 特化型の Web サーバーです。しかし、当然の事ですが OS 等による制約は超えられない訳で、その制約の内の 1つが、ファイルディスクリプタの制限(扱えるファイル数の上限)です。

そしてそのファイルディスクリプタの制限についての設定は、nginx をユーザプロセスとして実行しているか、デーモンプロセスとして実行しているかにより異なります。今回、色々と調べていたら、その辺を混同して解説している情報が多かったので、整理の上メモっておきます。


まずは結論から。
  1. OS(Debian buster)自体の制限を設定。
  2. ユーザープロセスとして実行している場合は、実行ユーザーの制限を設定。
  3. デーモンプロセスとして実行している場合は、デーモンの制限を設定。
  4. nginx の制限を設定。
至極当たり前の事しか書いてない気もしますが、整理が目的なので…。ユーザープロセスとして実行する場合は 2を、デーモンプロセスとして実行する場合は 3を行います。


OS(Debian buster)自体の制限値を確認するには、以下のコマンドを実行します。
# cat /proc/sys/fs/file-max
9223372036854775807
なかなか恐ろしい数値が返ってきましたが、多分、全開って事なんだと思います。

OS(Debian buster)自体の制限を設定する方法は、"/etc/sysctl.conf"に設定を追加するだけ。ファイルを開き、最終行の下へ以下を追加します。
(省略)
# Limit of file descriptor
fs.file-max = 2147483647
再起動で反映されます。


ユーザープロセスとして実行する場合の設定です。

ユーザープロセスの制限値を確認するには、以下のコマンドを実行します。
$ ulimit -n
1024
ソフトリミット(ユーザーが設定可能な値の現在値)を確認するには、以下のコマンドを実行します。
$ ulimit -Sn
1024
ソフトリミットを設定するには、以下のコマンドを実行します。この値はハードリミットの値までが設定可能です。
$ ulimit -Sn 2048
$ ulimit -Sn
2048
ハードリミット(ユーザーが設定可能な値の上限値)を確認するには、以下のコマンドを実行します。
$ ulimit -Hn
1048576
ハードリミットを設定するには、以下のコマンドを実行します。が、一般ユーザは減らす事しか出来ないので、実際には実行してはいけません。ハードリミットの上限を増やしたい場合は、スーパーユーザーで設定を行います。
$ ulimit -Hn 2048
$ ulimit -Hn
2048
各ユーザーのハードリミット(ソフトリミットも)を設定するには、スーパーユーザーで"/etc/security/limits.conf"ファイルを開き、ファイル下部に以下の様に記述します。"item"の"nofile"がファイルディスクリプタの上限です。
(省略)
#<domain>      <type>  <item>         <value>
user            hard   nofile         32768
user            soft   nofile         1024
ユーザーのログイン時に適用される為、設定したユーザーをログインし直せば反映されます。


デーモンプロセスとして実行する場合の設定です。

デーモンプロセスの制限値を確認するには、以下のコマンドを実行します(nginx の場合)。
# grep "open files" /proc/`pidof -s nginx`/limits
Max open files            1024                 524288               files
デーモンプロセスの制限値を設定するには、systemd の設定ファイルへ記述します。Debian buster の場合は"/etc/systemd/system/nginx.service.d"ディレクトリ以下の"*.conf"ファイルです。ディレクトリ、及び設定ファイルが既存する場合は、その内容を確認して下さい。ディレクトリや設定ファイルが存在しない場合は、新規に作成します。
# mkdir /etc/systemd/system/nginx.service.d
# touch /etc/systemd/system/nginx.service.d/override.conf
"/etc/systemd/system/nginx.service.d/override.conf"を開き、以下の様に記述します。
[Service]
LimitNOFILE=65536


nginx 側の設定を行います。"/etc/nginx/nginx.conf"を開き、以下の様に追加します。追加箇所はトップレベルです。ここではワーカープロセスの数を 2つ、ワーカープロセス当たりの制限値に 32768 を指定しています。
worker_processes 2;
worker_rlimit_nofile 32768;
nginx を再起動し、設定を確認します。
# systemctl daemon-reload
# systemctl restart nginx
# grep "open files" /proc/`pidof -s nginx`/limits
Max open files            32768                32768                files
# ps aux | grep nginx | grep -v grep
root      8515  0.0  0.0  68724  1764 ?        Ss   15:59   0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data  8516  0.0  0.2  69384  5900 ?        S    15:59   0:00 nginx: worker process
www-data  8517  0.0  0.2  69384  5900 ?        S    15:59   0:00 nginx: worker process
ワーカープロセスの制限値が 32768、マスタープロセスが 1つ、ワーカープロセスが 2つ実行されている事が確認できます。

2018年11月11日日曜日

Debian stretch もしかして腐ってる? 代理マシン編 その2 (x11vnc)



以前TOSHIBA dynabook EX/35LWHKS」というラップトップ PC に、Debian stretch をインストールしたんですが、ラップトップ PC を広げっぱなしにしておくのも邪魔なので、VNC サーバーをインストールし、メイン PC から遠隔操作する事にしました。

普通に Linux に VNC サーバーをインストールすると、VNC クライアントから接続する度に新たなセッションが作られる様になります。それはそれで Linux らしい仕様で良いんですが、今回は既存のセッションを利用する形で運用できないかと思い、色々調べたてみました。どうやら可能みたいです。

x11vnc という VNC サーバーを使用すると、既存のセッションに対して接続出来る様です。x11vnc の基本的な情報は「DebianでX11VNCをインストールする – OSS情報システム研究会」を参考にさせてもらいました。


x11vnc をインストール、パスワードの設定、起動してみます。
# aptitude install x11vnc
(省略)

# x11vnc -storepasswd

Enter VNC password:[パスワード]
Verify password:[パスワード]
Write password to /root/.vnc/passwd? [y]/n
Password written to: /root/.vnc/passwd

# x11vnc -rfbauth /root/.vnc/passwd
VNC クライアントとしては Windows 版 UltraVNC Viewer を使用し、色々試してみました。

が…、またしても腐っていた訳です…。
Debian stretch の x11vnc が…。

イントールされたバージョンは "0.9.13-2" でした。主な問題は次の様なものです。
  1. たまにクラッシュする。
  2. 一部のキーが無限にリピートする。
  3. Shift + TAB入力時に Shift が無視され、TAB のみ入力される。
他にも問題は有るかもしれません…。


取り合えずネットで検索した所「新しいバージョンを使え」という事の様で…。 ご丁寧にスクリプトも公開されていたので、それを参考に、ダウンロード、ビルドを行いました。インストールしたバージョンは "0.9.14" です。

Debian の場合、libxtst-dev、libssl-dev、libjpeg-dev が必要みたいですが、私の環境では libxtst-dev はインストール済みだったので下記では省略しています。
# aptitude install libssl-dev
(省略)
# aptitude install libjpeg-dev
(省略)
# cd /usr/src

# wget http://x11vnc.sourceforge.net/dev/x11vnc-0.9.14-dev.tar.gz
(省略)
# gzip -dc x11vnc-0.9.14-dev.tar.gz | tar -xvf -
(省略)
# cd x11vnc-0.9.14

# ./configure --prefix=/usr/local CFLAGS='-g -O2 -fno-stack-protector -Wall'
(省略)
# make
(省略)
# make install
(省略)
# /usr/local/bin/x11vnc -auth /var/run/lightdm/root/:0 -display :0 -xkb -forever -shared -rfbport 5900 -repeat
しばらく使ってみたんですが、少なくともクラッシュする事はなくなりました。ただし、「キーの無限リピート」や「Shift + TAB が使えない」といった症状はそのままでした。


APT でのパッケージの更新を止めて置かないと、自ビルドしたバイナリを上書きされてしまいますので、このまま使い続ける場合は、x11vnc の更新を停止しておきます。

パッケージの更新停止。
# aptitude hold x11vnc
# aptitude hold x11vnc-dat
パッケージの更新停止を解除する場合。
# aptitude unhold x11vnc
# aptitude unhold x11vnc-dat


「Shift + TAB が使えない」については、解決方法が見つかったので、対処しました。
# vi /usr/share/X11/xkb/symbols/pc
変更前。
key   {  [ Tab,  ISO_Left_Tab    ]   };
変更後。
key   {  [ Tab                   ]   };
これで X の再起動、または PC の再起動で改善されるはずです。


次に、サービス化です。VNC サーバーをサービス化する事により、グラフィカルログイン画面に対しても接続可能とする方法が「debian - Creating x11vnc system service - Unix & Linux Stack Exchange」に、そのままズバリ載っていたので、これも設定します。

vnc.service ファイルを編集(作成)。
# vi /lib/systemd/system/vnc.service
vnc.service ファイルの内容。
[Unit]
Description=Start x11vnc at startup.
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/local/bin/x11vnc -auth guess -forever -loop -noxdamage -repeat -rfbauth /root/.vnc/passwd -rfbport 5900 -shared -remap Zenkaku-Zenkaku_Hankaku,Hankaku-Zenkaku_Hankaku

[Install]
WantedBy=multi-user.target
サービスの有効化、およびリロード。
sudo systemctl enable vnc.service
sudo systemctl daemon-reload
これで、PC を起動直後のグラフィカルログイン画面の状態に対し、VNC ビューワーから接続出来る様になります。

注意が必要なのは、vnc.service ファイルの内容のうち、x11vnc のオプションについては環境により調整が必要だと思います。特にキー関連のイベントの扱いが、使用する VNC ビューワーにより異なるので、思わぬ挙動をする場合もあるようです。


最後に「キーの無限リピート」の対処方、というより誤魔化し方です。

無限リピートが始まったら他のキーを押す事で、リピート自体は止められます。今の所、解決策が見つかっていないので、こんな使い方で誤魔化すしかないでしょう。

私の環境では「半角/全角」キーが 100% リピートするので、「半角/全角」キーを押したら、すぐに「Esc」を押すことでリピートを止めています。

2018年10月26日金曜日

Java 6 の TLS 1.2 対応



いまだに Java 6 使ってます、はい…。
移行しなければならないのは重々承知しています、はい…。

そんな中、HTTPS のセキュリティプロトコルを TLS 1.2 に移行するサイトが増え、TLS 1.2 に未対応の Java 6 ではスクレイピング出来なくなって困っていました。色々と検索した所、暗号化ライブラリを導入すると Java 6 でも TLS 1.2 に対応する事が可能な様です。

また、Let's Encrypt といった新しめの認証局のサーバー証明書も、 Java 6 では対応出来ていないので、それらも導入します。

お品書き。
  1. Bouncy Castle という暗号化ライブラリを導入します。
    ライセンスは Apache Software License, Version 1.1. の様です。
  2. Bouncy Castle を利用して SSL 通信を行う SSLSocketFactory の実装クラス TLSSocketFactory、および関連クラスを導入します。
    ライセンスは MIT X11 License の様です。
  3. 有志作成のスクリプトを参考にし、Let's Encrypt のサーバー証明書を導入します。
    Windows 版 bat ファイル(証明書ファイル付き)、Linux 版 sh ファイル(証明書ファイルダウンロード)を参考にしました。
  4. Let's Encrypt の中間認証局のサーバー証明書を導入します。
    IdenTrust DST Root および、ISRG Root です。
「2.」の Bouncy Castle を利用するクラスについては、別のクラスについて日本語で発信している方が何人かいらっしゃったのですが、私の環境ではことごとく機能しませんでした。細かくは検証していないので原因は不明ですが…。

「4.」の中間認証局のサーバー証明書については、ネットの情報ではどうしてもうまく機能せず、最終手段として Java 8 のキーストアからサーバー証明書を抜いてきて、java 6 のキーストアに突っ込む、とい強引な方法をとっています。

まあ、自己責任ですね…。


Bouncy Castle をプロジェクトへ導入します。
  1. Bouncy Castle の jar ファイルをダウンロードします。
    Latest Releases からダウンロードできます。
    今回私が使用したのは bcprov-jdk15on-160.jar です。
  2. 上記 jar ファイルをプロジェクトのライブラリとして追加します。
  3. また、実行環境のクラスパスにも上記 jar ファイルを追加します。


SSLSocketFactory の実装クラス TLSSocketFactory、および関連クラスを導入します。

TLSSocketFactory からダウンロードするなり、クローンするなり、コピペするなりし、プロジェクトへ 5つのクラスを追加します。
  1. メインとなるクラス TLSSocketFactory
    javax.net.ssl.SSLSocketFactory 抽象クラスの実装クラスです。
  2. 関連クラスTLSAuthentication
    org.bouncycastle.crypto.tls.TlsAuthentication インターフェイスの実装クラスです。
  3. 関連クラス TLSClient
    org.bouncycastle.crypto.tls.DefaultTlsClient 抽象クラスの実装クラスです。
  4. 関連クラス TLSSession
    javax.net.ssl.SSLSession インターフェイスの実装クラスです。
  5. こっちの方がメインとなるクラスとも言える TLSSocket
    javax.net.ssl.SSLSocket 抽象クラスの実装クラスです。
基本的にコードの質は良くないです…。インデントがタブ、スペース混じりだったり、コメントが英語だったり、日本語だったり、無かったり…。API コメントはほぼ無い…。

とりあえずインデントが崩れてるのは、スペース 4つをタブ 1つに置換するか、逆にタブ 1つをスペース 4つに置換すれば揃います…。

あと、1 箇所問題が有って、仮対応として修正しました。

TLSSession クラスのオーバーライドメソッド getLocalPrincipal() が未実装なんですが、このメソッドが呼ばれた場合に、未実装であることを表す UnsupportedOperationException をスローしているので、例外でコケてしまいます。

これを null を返す様にすると、一応は動作する様になります。ただし、これは仮対応なので、本来は正しく実装しないと問題が起きる場合が有ると思います。調査が追いついていませんが、Google が化けるのはこれが原因かなぁ…。

TLSSession # getLocalPrincipal() メソッド。
 @Override
 public Principal getLocalPrincipal()
 {
//	throw new UnsupportedOperationException();
	return null;
 }


Let's Encrypt のサーバー証明書を導入します。

サーバー証明書へのリンクや、サーバー証明書についての説明は Let's Encrypt Chain of Trust に有るんですが、Java のキーストアへインポート出来る der ファイルへのリンクが無いっていうね…。

私は有志作成のスクリプト import-letsencrypt-java.sh を参考にし、Let's Encrypt のサーバー証明書 4つのみインポートするスクリプトを書きました。

私の場合は Java 開発環境をインストールしない派(置いておくだけ)、環境変数 JAVA_HOME を使わない派(パスはスクリプト等で自己管理)なので、実際には、ディレクトリ等を直に指定したり、ダウンロードしたファイルを残しておいたり、ログファイルを出力する等、大幅に書き直しました。が、そんなスクリプトは参考にならないと思うので、オリジナルの一部をコメントアウトしたコードを参考までに載せておきます。

オリジナル からの変更点は、letsencryptauthorityx1.der および、letsencryptauthorityx2.der をダウンロード、インポート、削除しない様にコメントアウトしただけです。

Let's Encrypt のサーバー証明書をインポートする参考コード。
#!/bin/bash -e
# JAVA_HOME can be passed as argument if not set
if [ ! -d $JAVA_HOME ]; then
 JAVA_HOME=${1}
fi

KEYSTORE=$JAVA_HOME/jre/lib/security/cacerts
if [ ! -f "$KEYSTORE" ]; then
 echo "Keystore not found in '$KEYSTORE'"
 exit 1
fi
cp $KEYSTORE $KEYSTORE.`date +"%Y%m%d%H%m%S"`

#wget https://letsencrypt.org/certs/letsencryptauthorityx1.der
#wget https://letsencrypt.org/certs/letsencryptauthorityx2.der
wget https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.der
wget https://letsencrypt.org/certs/lets-encrypt-x2-cross-signed.der
wget https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.der
wget https://letsencrypt.org/certs/lets-encrypt-x4-cross-signed.der

# to be idempotent
#keytool -delete -alias isrgrootx1 -keystore $KEYSTORE -storepass changeit 2> /dev/null || true
#keytool -delete -alias isrgrootx2 -keystore $KEYSTORE -storepass changeit 2> /dev/null || true
keytool -delete -alias letsencryptauthorityx1 -keystore $KEYSTORE -storepass changeit 2> /dev/null || true
keytool -delete -alias letsencryptauthorityx2 -keystore $KEYSTORE -storepass changeit 2> /dev/null || true
keytool -delete -alias letsencryptauthorityx3 -keystore $KEYSTORE -storepass changeit 2> /dev/null || true
keytool -delete -alias letsencryptauthorityx4 -keystore $KEYSTORE -storepass changeit 2> /dev/null || true

#keytool -trustcacerts -keystore $KEYSTORE -storepass changeit -noprompt -importcert -alias isrgrootx1 -file letsencryptauthorityx1.der
#keytool -trustcacerts -keystore $KEYSTORE -storepass changeit -noprompt -importcert -alias isrgrootx2 -file letsencryptauthorityx2.der
keytool -trustcacerts -keystore $KEYSTORE -storepass changeit -noprompt -importcert -alias letsencryptauthorityx1 -file lets-encrypt-x1-cross-signed.der
keytool -trustcacerts -keystore $KEYSTORE -storepass changeit -noprompt -importcert -alias letsencryptauthorityx2 -file lets-encrypt-x2-cross-signed.der
keytool -trustcacerts -keystore $KEYSTORE -storepass changeit -noprompt -importcert -alias letsencryptauthorityx3 -file lets-encrypt-x3-cross-signed.der
keytool -trustcacerts -keystore $KEYSTORE -storepass changeit -noprompt -importcert -alias letsencryptauthorityx4 -file lets-encrypt-x4-cross-signed.der

#rm -f letsencryptauthorityx1.der letsencryptauthorityx2.der lets-encrypt-x1-cross-signed.der lets-encrypt-x2-cross-signed.der lets-encrypt-x3-cross-signed.der lets-encrypt-x4-cross-signed.der
rm -f lets-encrypt-x1-cross-signed.der lets-encrypt-x2-cross-signed.der lets-encrypt-x3-cross-signed.der lets-encrypt-x4-cross-signed.der

キーストア内の一覧を表示する参考コード。
keytool -list -keystore $KEYSTORE -storepass changeit

キーストア内の詳細を表示する参考コード。
keytool -v -list -keystore $KEYSTORE -storepass changeit


Let's Encrypt の中間認証局のサーバー証明書を導入します。

IdenTrust DST Root および、ISRG Root です。

これについてネットで検索すると、特に英語のサイトでは色々なやり方が紹介されているんですが、ことごとく機能しませんでした…。得に IdenTrust DST Root のサーバー証明書には手こずって手こずって、諦めてしまいました…。

で、Java 8 のキーストアからサーバー証明書をぶっこ抜いて、java6 のキーストアへ突っ込む、という強引な方法にたどり着いた訳です…。邪道です…。

これも参考コードを載せておきます。が、あくまで自己責任で…。

あと、パスを直接指定しているので、全てのパスを変更しないと動きません。

Java 8 のキーストアから、Java 6 のキーストアへサーバー証明書をコピーする参考コード。
#! /bin/sh

# Java 8 のキーツールのパス
J8KEYTOOL=/hogehoge/jdk1.8.0/jre/bin/keytool

# Java 8 のキーストアのパス
J8KEYSTORE=/hogehoge/jdk1.8.0/jre/lib/security/cacerts

# Java 6 のキーツールのパス
J6KEYTOOL=/hogehoge/jdk1.6.0/jre/bin/keytool

# Java 6 のキーストアのパス
J6KEYSTORE=/hogehoge/jdk1.6.0/jre/lib/security/cacerts

# 作業ディレクトリ
WORKDIR=/hogehoge
cd ${WORKDIR}

# Java 8 から証明書をエクスポート
${J8KEYTOOL} -exportcert -alias letsencryptisrgx1\ [jdk] -keystore ${J8KEYSTORE} -storepass changeit -file ${WORKDIR}/jdk8_letsencryptisrgx1.cer
${J8KEYTOOL} -exportcert -alias identrustdstx3\ [jdk] -keystore ${J8KEYSTORE} -storepass changeit -file ${WORKDIR}/jsk8_identrustdstx3.cer

# Java 6 のキーストアから既存を削除
${J6KEYTOOL} -delete -alias letsencryptisrgx1 -keystore ${J6KEYSTORE} -storepass changeit
${J6KEYTOOL} -delete -alias identrustdstx3 -keystore ${J6KEYSTORE} -storepass changeit

# Java 6 のキーストアへ追加
${J6KEYTOOL} -trustcacerts -keystore ${J6KEYSTORE} -storepass changeit -noprompt -importcert -alias letsencryptisrgx1 -file ${WORKDIR}/jdk8_letsencryptisrgx1.cer
${J6KEYTOOL} -trustcacerts -keystore ${J6KEYSTORE} -storepass changeit -noprompt -importcert -alias identrustdstx3 -file ${WORKDIR}/jsk8_identrustdstx3.cer

# 証明書ファイルの削除
rm -f ${WORKDIR}/jdk8_letsencryptisrgx1.cer ${WORKDIR}/jsk8_identrustdstx3.cer


おまけ。

Apache HTTPClient で HttpClientBuilder を使用して、素の HttpClient のインスタンスを生成する場合は簡単なんですが、ConnectionManager を使用する場合は工夫が必要なので、参考コードを載せておきます。

素の HttpClient の参考コード。
SSLConnectionSocketFactory sockFctr = new SSLConnectionSocketFactory
(
	new TLSSocketFactory()
	, new String[]{"TLSv1.2"}
	, null
	, new DefaultHostnameVerifier()
);

HttpClient client = HttpClientBuilder
	.create()
	.setSSLSocketFactory(sockFctr)
	.build();

ConnectionManager を指定する HttpClient のダメな参考コード。
PoolingHttpClientConnectionManager connMngr = new PoolingHttpClientConnectionManager();

SSLConnectionSocketFactory sockFctr = new SSLConnectionSocketFactory
(
	new TLSSocketFactory()
	, new String[]{"TLSv1.2"}
	, null
	, new DefaultHostnameVerifier()
);

HttpClient client = HttpClientBuilder
	.create()
	.setConnectionManager(connMngr)
	.setSSLSocketFactory(sockFctr)
	.build();

上記コードの場合、setConnectionManager メソッドで指定した ConnectionManager の SocketFactory でオーバーライドされてしまい、setSSLSocketFactory メソッドで指定した SocketFactory は使用されません。

ConnectionManager を指定する HttpClient の参考コード。
Registry sockFctrReg = RegistryBuilder
	.create()
	.register
	(
		"https"
		, new SSLConnectionSocketFactory
		(
			new TLSSocketFactory()
			, new String[]{"TLSv1.2"}
			, null
			, new DefaultHostnameVerifier()
		)
	)
	.register
	(
		"http"
		, PlainConnectionSocketFactory.getSocketFactory()
	)
	.build();

PoolingHttpClientConnectionManager connMngr = new PoolingHttpClientConnectionManager
(
	sockFctrReg
);

HttpClient client = HttpClientBuilder
	.create()
	.setConnectionManager(connMngr)
	.build();

org.apache.http.config.Registry へ HTTPS 用の SocketFactory と、HTTP 用の SocketFactory を登録し、その Registry を ConnectionManager のコンストラクタへ渡すという、かなり回りくどい方法です。他の方法も有るかとは思いますが、まあ参考まで。

2018年4月30日月曜日

テキストエディタ「SciTE」の設定見直し



以前、エディタを「SciTE」に乗り換えた時に「User Options」の設定例を載せたんですが、バージョンが変わった為、それに合わせて設定を見直しました。デスクトップ環境を「MATE」に変更したせいかな?

特に困っていたのが、等幅フォントがズレる様になってしまった事で、その原因が設定方法に変更が加わった事に有り、以前の設定のままだと問題が出る、というものでした。

あと、検索ウィンドウ、置換ウィンドウが、ダイアログではなくなり、エディタ下部にドッキングされた形式に変わったんですが、設定でダイアログに戻せるので、それも変更しています。

メニュー「Options」->「Open User Options File」を開き、設定を変更します。
変更した所は赤字の部分です。
# 行番号の表示
line.margin.visible=1
line.margin.width=1+
margin.width=4

# 矩形選択時 改行より右にカーソルがいけるようにする
virtual.space=1

# 文字コード
character.set=128
code.page=65001
if PLAT_GTK
 LC_CTYPE=ja_JP.UTF-8
 output.code.page=65001

# フォント
technology=0
font.base=$(font.monospace)
font.small=$(font.monospace)
font.comment=$(font.monospace)
font.text=$(font.monospace)
font.text.comment=$(font.monospace)
font.embedded.base=$(font.monospace)
font.embedded.comment=$(font.monospace)
font.vbs=$(font.monospace)

# タブの幅
tabsize=8
indent.size=8

# 空白文字の表示
view.whitespace=1

# 選択部分の色
selection.fore=#000000;
selection.back=#ffd700
selection.alpha=256
find.mark.indicator=style:roundbox,colour:#0080FF,under,outlinealpha:140,fillalpha:80

# 出力ウィンドウを横分割にする
split.vertical=0

# 終了時に折りたたみを保存する
session.folds=1

# 検索・置換はストリップでなくダイアログ
find.use.strip=false
replace.use.strip=false

ただし、すべてのオプションを見直した訳では無いので、上記の設定にもまだ間違いが存在する可能性が有ります。

2018年4月11日水曜日

Debian stretch もしかして腐ってる? 代理マシン編 その1



以前「GA-MA78GPM-DS2H」+「AMD Athlon X2 5050e」にインストールした Debian stretch の調子が悪い…。

症状としては、突然再起動がかかる、気が付くと電源が落ちている、といった感じなのだが、一番の問題はログが残らないので、原因の特定が困難な事…。症状から察するにハードウェア関係、またはドライバ関係の問題っぽいのだが、マイナートラブルなのか、アップデートで問題が解消される訳でもなく、ネットで検索してみても話題にすらなって無いっぽい…。

という事で、余ってるマシンを代理マシンにする事にした。

今回のターゲットPCは「TOSHIBA dynabook EX/35LWHKS」というラップトップ PC。 構成としては「インテル Celeron プロセッサー 900」+「モバイル インテル GL40 Expressチップセット」、グラフィックは「モバイル インテル GMA 4500M」という感じ。

例によって Debian stretch は32bit(i386)版です。

で、タイトルの「Debian stretch もしかして腐ってる?」についてなんですが、今回のインストール中にも、突然ハングアップする、突然再起動する、といった症状が出てしまい、結局何回もインストールし直したり、設定を変えてみたりを繰り返すはめになった為、この様なタイトルになってしまいました…。

以下、素人なりの分析。
  1. 前回の「GA-MA78GPM-DS2H」+「AMD Athlon X2 5050e」が Debian stretch インストール直後から調子が悪い。が、その直前までは Debian wheezy で問題無く使用出来ていた為、ハードウェアの不具合は考えにくい。
  2. ログも吐かずに突然再起動する、電源が切れるといった症状から、ハードウェア周りか、ドライバ周りの問題の可能性が高い。
  3. 今回の「TOSHIBA dynabook EX/35LWHKS」に Debian stretch をインストールしても、ハングアップする、突然再起動する、といった症状が出てしまったが、主にドライバの設定で回避できた。
結果、Debian stretch のドライバ周りは腐ってるっ!(※個人の感想です)


それと、前回のインストールではデスクトップ環境として「CINNAMON」を選択したんですが、今回は結局ハードウェアレンダリングを無効化しなければならなくなった為、デスクトップ環境とし「MATE」を選択する事にしました。ちなみに「メイト」と読むものだと思っていたら、「マテ」と読むのが正解でした…。

以下、インストールログです。
  1. PC に CD をセットして起動、インストールを開始する。
  2. 最初のメニューでグラフィカルインストールを選択。無事インストール開始。
  3. 言語は日本語、インストール対象は「Debian デスクトップ環境」、「MATE」、「標準システムユーティリティ」のみ。インストールが始まるのでしばらく待つ。
  4. インストールが完了すると CD が排出され、再起動するかと聞かれるので CD を回収し再起動。
  5. 再起動すると GRUB のメニューが表示され、デフォルトで先ほどインストールしたシステムが起動される。
  6. 起動ログが流れていき、ログイン画面が出るか、というタイミングでクラッシュ!
    画面が虹色モザイクというか何というか、表示が完全に崩れ、しかも何の操作も受け付けなくなりました。
    Ctrl + Alt + F1 等で他のコンソールに切り替える事も出来ません。
  7. 電源ボタンの長押しで再起動する…。
で、ここからの試行錯誤が非常に長かったんですが、先に結果だけ書き留めておきます。
  1. "/etc/X11/xorg.conf" ファイルを作り、グラフィックドライバの設定を変更する。
  2. グラフィックドライバは "intel" を指定。
  3. グラフィックドライバのオプション "NoAccel" を指定し、ハードウェアアクセラレーションをオフる。
  4. "/etc/default/grub" ファイルへカーネルパラメーターを追加し、"execlist" を無効化する。
これでやっとまともにログインし、デスクトップにたどり着けました…。

"xorg.conf" の作り方については「debian squeeze で xorg.conf が無い場合の対処法 | ラムダ算法書店」を参考にさせてもらいました。"intel" グラフィックドライバの設定等に関しては「Intel Graphics - ArchWiki」を参考にさせてもらいました。

特に「Intel Graphics - ArchWiki」は、"intel" グラフィックドライバに関して、色々な環境、いろいろなトラブルについて詳細に書かれており、大変参考になりました。その反面、膨大な情報の中から自分の環境に合った正解に辿り着くまでに、大変な時間を要しました。もちろん私の場合は解決に至ったので、大変感謝しています!


以下、個別の作業メモです。

通常通り起動してしまうとグラフィカルログイン前、またはログイン後に、クラッシュやフリーズをしてしまうので、"GRUB" メニューの "Advanced options for Debian GNU/Linux" -> "recovery mode" から、リカバリーモードに "root" でログインして作業を行います。
  1. コンソールが日本語に対応していない為、日本語メッセージが化けてしまうので、言語設定を英語にする。
  2. "Xorg -configure" コマンドで "/root/xorg.conf.new" ファイルを作成。
  3. "/root/xorg.conf.new" ファイルを、"/etc/X11/xorg.conf" へと移動、改名。
  4. "/etc/X11/xorg.conf" ファイルを編集し、グラフィックドライバの設定を変更。
  5. "/etc/default/grub" ファイルを編集し、カーネルパラメーターを追加。
  6. "update-grub2" コマンドで GRUB を更新。
  7. 再起動。
"/etc/X11/xorg.conf" ファイル編集までのコマンドです。
# export LANG=C
# Xorg -configure
# mv /root/xorg.conf.new /etc/X11/xorg.conf
# vi /etc/X11/xorg.conf
"/etc/X11/xorg.conf" ファイルの内容です。Identifier "Card0"、"Card1" と 2モード分のグラフィックデバイスの設定が有るので、ここに "NoAccel" オプションを追加します。
 (省略)
Section "Device"
 (省略)
 Identifier  "Card0"
 Driver      "intel"
 Option      "NoAccel" "True"
 BusID       "PCI:0:2:0"
 (省略)
EndSection

Section "Device"
 (省略)
 Identifier  "Card1"
 Driver      "intel"
 Option      "NoAccel" "True"
 BusID       "PCI:0:2:1"
 (省略)
EndSection
 (省略)
"/etc/default/grub" ファイルを編集します。
# vi /etc/default/grub
"/etc/default/grub" ファイルの内容です。"GRUB_CMDLINE_DEFAULT" へ "i915.enable_execlists=0" を追加し、"execlist" を無効化します。
(省略)
GRUB_CMDLINE_DEFAULT="quiet i915.enable_execlists=0"
(省略)
"update-grub2" コマンドで GRUB を更新し、再起動します。
# update-grub2
# reboot
無事、グラフィカルログインも成功し、デスクトップが表示されました!


今回の環境「TOSHIBA dynabook EX/35LWHKS」では、ハードウェアアクセラレーションの無効化、"execlist" の無効化で、なんとか使える環境まで持っていけました。その他ソフトウェアのインストールや、システムの移行が完了したら、「GA-MA78GPM-DS2H」+「AMD Athlon X2 5050e」にも再挑戦しようと思っています。やっぱグラフィックドライバ周りが原因なのかなぁ…。

2017年11月1日水曜日

Gedit が使いづらいのでエディタを SciTE に乗り換える



※この記事の設定はその後見直しました。

何回使っても Gedit が使いづらい。特に検索が酷い。あと、プラグインが微妙…。純正プラグインはまあ良いとして、それだけでは機能が足りないので野良プラグインで補完しようとするも、バージョン間の互換性が低いせいで、上手く動かなかったりする事が多い気がする…。

で、割とまともなエディタ「SciTE」に乗り換えます。まあ、毎度のパターン。

SciTE をインストールします。
# aptitude install scite

メニューの「プログラミング」に登録されるみたいです。


SciTE を起動し、設定を整えていきます。
メニュー「Options」->「Open User Options File」を開き、設定を変更します。
とりあえず個人的な定番設定を書き込み、保存します。
# 行番号の表示
line.margin.visible=1
line.margin.width=1+
margin.width=4

# 矩形選択時 改行より右にカーソルがいけるようにする
virtual.space=1

# 文字コード
character.set=128
code.page=65001
if PLAT_GTK
 LC_CTYPE=ja_JP.UTF-8
 output.code.page=65001

# フォント
technology=0
font.base=font:!Monospace Regular,size:9
font.small=font:!Monospace Regular,size:8
font.comment=$(font.base)
font.code.comment.box=$(font.comment)
font.code.comment.line=$(font.comment)
font.code.comment.doc=$(font.comment)
font.code.comment.nested=$(font.comment)
font.text=$(font.base)
font.text.comment=$(font.base)
font.embedded.base=$(font.base)
font.embedded.comment=$(font.base)
font.monospace=$(font.base)
font.vbs=$(font.base)
font.js=$(font.base)

# タブの幅
tabsize=8
indent.size=8

# 空白文字の表示
view.whitespace=1

# 選択部分の色
selection.fore=#000000;
selection.back=#ffd700
selection.alpha=256
find.mark.indicator=style:roundbox,colour:#0080FF,under,outlinealpha:140,fillalpha:80

# 出力ウィンドウを横分割にする
split.vertical=0

# 終了時に折りたたみを保存する
session.folds=1

設定方法は「SciTE Documentation」に有るんですが、英語なので正直メンドイんですよねぇ…。