sslでエラーが出るのは,SSL証明書の発行元のせいだったよ!

背景

StartSSLで発行した証明書を使用しているサーバ(この鯖でした)へのアクセス時,たまにchromeで証明書エラーが出ていた.
特定のマシンでしかエラーが出ないので,放置していたんだけれども,最近になってfirefoxでもエラーが出るようになり本格的に怪しいと感じるようになったので証明書の発行元について調べてみた.

StartSSL(StartCom)のSSL証明書がiPhoneなどで認識されない問題 | カニとモモンガと愉快なユウ

ダメぢゃん…

はい,発行元,乗り換えるよ!

SSL証明書の発行

乗り換え先として名前がいくつかのサイトで挙がっていた Certbot へ移行することにした.
無料でSSL証明書を発行できるのはメリットだね!

発行手順(debianの場合のみ)

  1. backportsをsources.listに追加して,apt-getでbackportsからインストールできるようにする.
    ここは,どっかのサイトを調べてできるようにしてね.
  2. certbotをインストールする.
    python関連の他の用途では使わないパッケージが色々と入れられるので,可能なら他のホストで実行することをオススメする.
    私の場合,別のVMを立ててポートフォワードを設定変更して(証明書の設定の手順に関係)証明書の発行だけした.

    sudo apt-get install certbot -t jessie-backports
    
  3. 既存のkeyからcsrを作成する.
    注意は,既存サーバと同じホストで実行する場合,既存サーバの443ポートと競合するので,既存サーバを落としておくこと.

    openssl genrsa -aes256 2048 > server.key  # <- 未だ秘密鍵がない場合
    openssl req -new -sha256 -key server.key -out server.csr  # <- 未だ証明書署名要求がない場合
    sudo certbot certonly --standalone --csr server.csr --config-dir . --logs-dir . --work-dir . -d DOMAINNAME
    
  4. dhパラメタの生成.
    openssl dhparam 2048 -out dhparam.pem
    
  5. 証明書を設定する.
    まず,0000_cert.pemが証明書本体.
    0000_chain.pemが中間証明書かルート証明書か,ともかく証明書を連結して使う最近のトレンドで証明書本体と連結すべきやつ.trusted_certificateにも,これを指定する.
    0001_chain.pem上2つの連結証明書.nginxとかはこれを使う.

    ssl_certificate /path/to/0001_chain.pem;
    ssl_certificate_key /path/to/server.key;
    ssl_dhparam /home/hada/sslfiles/dhparam.pem;
    ssl_trusted_certificate /path/to/0000_chain.pem;
    
  6. 鯖を再起動して完了

dovecotを入れてメールのローカル配信をする

インストール

sudo apt-get install dovecot-pop3d dovecot-lmtpd heirloom-mailx postfix
maildirmake.dovecot /var/mail/USERNAME  # Maildir形式の場合

設定

  • /etc/dovecot
    • dovecot.conf
    • conf.d/10-mail.conf
    • conf.d/10-master.conf
    • conf.d/10-ssl.conf
  • /etc/postfix
    • main.cf
  • /etc/aliases
    • 書いたら newaliases を走らせる./etc/aliases のオーナーが /etc/aliases.db と一緒でないとエラーを吐く
  • /etc/mailname

テスト

送信テスト
行中に「.」のみの行が末尾のしるし.

mail USERNAME@HOSTNAME
Subject: Test
this is test
.

受信テスト

mail

nginx のメモ

よく忘れるので,メモ.

設定について

add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains;';
HSTS 設定.SSLでアクセスするようブラウザに指示するHTTPヘッダを追加する.
sendfile
ファイルI/Oにカーネルキャッシュを利用する…らしい
tcp_nopush
ヘッダとデータをチャンクして送信するようになるらしい
tcp_nodelay
パケット転送時に他にまとめられるものがないか,ちょっと待つのを止めさせるらしい
types_hash_max_size
typesのハッシュテーブルの最大サイズ
server_token
レスポンスヘッダに含むサーバの情報について制御する

インストールについて

debianの場合,jessie-backportsで入れれば1.10.3が入る(2017.3時点)ので,自分でコンパイルするのをやめた.
WebDAVをまともに使おうと思った場合,libnginx-mod-http-dav-extを一緒に入れると良い.

起動スクリプトについて

systemctl start nginx.service で PID ファイルに関するエラーが出る場合は,起動スクリプトを修正すると良い.

@@ -20,6 +20,7 @@
 PIDFile=/run/nginx.pid
 ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
 ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
+ExecStartPost=/bin/sleep 0.1
 ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
 ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
 TimeoutStopSec=5

jupyter notebook tips

色々とtipsを書くエントリ.

ブラウザを起動しない
jupyter notebook --no-browser
他のホストからアクセスさせる
デフォルト設定をファイル出力させる.

jupyter notebook --generate-config

設定ファイルを編集する.

c.NotebookApp.ip = '*'
c.NotebookApp.port = 8888
c.NotebookApp.password = 'sha1:********'

パスワードの生成は

from notebook.auth import passwd; passwd()

2回パスワードを入力すると,ハッシュが返ってくるので,上のpasswordの値として代入する.

mfiler4の導入 for ubuntu

結構簡単になってたよ

手順

  • lv
    • sudo apt-get install lv
  • ncurses
    • 入ってた
  • oniguruma
    • sudo apt-get install libonig-dev
  • cmigemo
    • sudo apt-get install cmigemo libmigemo-dev
  • ライブラリの再読み込みなど
    • sudo ldconfig; rehash
  • xyzsh
    • ダウンロード from http://sourceforge.jp/projects/xyzsh/
    • ./configure --with-migemo; make; sudo make install
  • ライブラリの再読み込みなど
    • sudo ldconfig; rehash
  • mfiler4
    • ダウンロード from https://ja.osdn.net/projects/mfiler4/ または https://github.com/ab25cq/mfiler4
    • ./configure --with-migemo; make; sudo make install

マウスのミドルクリックの割り当てをrdesktopでもxmonadでも変更したい

結論

xmodmap が駄目なら xinput を使えばいいじゃない.

前提

私の場合はマウスのミドルクリックを頻繁に使うので,使い易い場所に配置したくなる.
今まで,Ubuntu上でremminaやVMを使っている場合にリモートやVM内でミドルクリックを入力する場合には,.Xmodmapでpointerを設定すれば良かった.
例えばKensingtonのEM-7でボタン8(右上のボタン)にミドルクリックを割り当てる場合は

pointer = 1 8 3 4 5 6 7 2 9 10 11 12

あとはX起動時にこのファイルを読み込めばよく,xmonadの場合はStartHookに

spawn "xmodmap ~/.Xmodmap"

とかでも良いし,.xprofileも読み込まれるので,こっちでも良い

xmodmap ~/.Xmodmap

課題

しかしながら,この記事→ HHKBをHHKモードでWindowsでもLinuxでも使う - hadacchi blog のキーボードマッピングのために RDP クライアントを remmina から rdesktop に変更したところ,xmodmap の設定が反映されず元のボタン配置での入力がリモートホストに届くようになってしまった.

対策

これではまずいので対処を調べたところ,xmodmap ではなく xinput を使う方法でもマウスの設定が可能なことが分かった.
設定はこんな感じ.

  • まずデバイス名を調べる.
    xinput --list --name-only | grep Kensington
    

    ID を表示させて ID 番号で指定することも可能であるが,起動する度に変更される可能性があるのか不明なこと,ならばとコマンドで ID を抽出するともっと長くなることから,今回は名前でデバイス指定することにする.
    ちなみに ID でどうしてもやりたかったら,ID の抽出はこんな感じ.

    $ xinput --list | grep Kensington | cut -d= -f2 | cut -d'	' -f1    # スペースではなくタブ文字
    
  • 現在の設定を表示させてみる.
    ちなみに,EM-7はデバイス名にタブとかスペースが連続して幾つも入っていて,ちゃんと調べるのが面倒だったのでコマンドでそのまま送ることにした.

    $ xinput get-button-map "$(xinput --list --name-only | grep Kensington)"
    1 2 3 4 5 6 7 8 9 10 11 12
    

    どうやら,うちの環境では xmodmap を適用していても xinput からは変更がないように認識されているようだった.

  • 設定を変更してみる.
    xmodmap の設定を消して再起動(再ログイン)するのを忘れずに.

    $ xinput set-button-map "$(xinput --list --name-only | grep Kensington)" 1 8 3 4 5 6 7 2 9 10 11 12
    

    VM でも rdesktop でも,もちろんホスト OS でも正しく動作したので,これで行くことにする.

  • xmonad の設定 xmonad.hs に書くことにした.xmodmap の時みたく xprofile でも良いかも.
    main = do
        (略)
        xmonad $ ewmh defaultConfig
          { (略)
          , startupHook    = myStartupHook
          }
    myStartupHook = do
        (略)
        spawn "xinput set-button-map \"$(xinput --list --name-only | grep Kensington)\" 1 8 3 4 5 6 7 2 9 10 11 12"
    

異なる環境で共通の.vimrcを使う

前提

gitなどで設定ファイルを管理していて,どのマシンでも同じ設定をgit cloneですぐに引っ張れるようにしている.
こうするとスタートアップは用意であるものの,環境依存の設定のためエラーを吐いたり最悪の場合は動作しないことがある.
今回はその中でも vim の場合.

対処法

vimの設定は.vimrcや.gvimrc(vim.gtkなど)などで設定する.
.vimrcなどの中では条件分岐が使える.
1を返す関数がTrueを,0を返す関数がFalseを意味する.
has('feature')が便利で,OSによる分岐や:versionで出力されるfeatureの有無(+/-)による分岐が可能.

例えば,pluginのsingletonはclientserverを必要とするが,cygwinでコンソールでのみvimを使う場合にエラーを吐く.
これを防ぐためには

if has('clientserver')
    call singleton#enable()
endif

などとすればどちらにも対応できる.

nginx で StartSSL のクライアント証明書を使ったクライアント認証をやる

毎回,認証が表示されるのが面倒臭いので,クライアント認証を導入する.

環境

nginxのバージョンを上げるか,opensslのバージョンを上げるかしないとエラーを吐くので,nginxを1.9.12以降に上げるか(#901 (Changes in openssl master wrt SSL_shutdown()) – nginx),opensslを1.1.0以降に上げる(SSL error NginX 1.9.10

本記事では,試験鯖でnginx公式リポジトリ(Debian 8 (Jessie) - Web サーバ Nginx 構築(Nginx 公式リポジトリ使用)! - mk-mode BLOG)を使用して入れた1.10.2-1と,
jessie-backportsを使用して入れた1.0.2k-1により動作確認することとする.

ちなみに,この鯖はそれらとは環境がまた違います.

nginxのアップデート

ownCloudを入れていてnginxを使っている時にnginx-commonを消すとapache2が入ってしまい,/etc/systemd/system/nginx.service/dev/nullを指すようになってしまったので,/lib/systemd/systemにnginx.serviceを書いて(NGINX systemd service file | NGINX),おまじないを唱える.

sudo systemctl unmask nginx.service

そうすると,systemdで制御できるようになるようなので,service nginx startとかが効く.
nginx.serviceに書いてあるバイナリーのバージョンを確認して,問題なければnginxの設定に入る.

nginxの設定

startsslのログインにクライアント証明書を使ったクライアント認証が必要(最近はメールアドレスへのワンタイムパスがサポートされたけど,昔は証明書を失くしたら二度とログインできなかった)なので,当然インストール済だとして,その証明書を使うことにする.
証明書のsubjectは以下とする.

/description=For login authentication only/CN=mail@address.com/emailAddress=mail@address.com

subjectを確認する方法は

openssl pkcs12 -nokeys -info -in CERTIFICATIONFILE.pfx

とかやる.pkcs12の部分は証明書の形式に応じて変更する.

あとはnginxのserverあたりに設定を書く.
基本的な設定は,この辺を流用すると楽チン.Generate Mozilla Security Recommended Web Server Configuration Files

server {
    listen 443 http2;
    server_name YOURDOMAIN;

    ssl on;
    ssl_verify_client on; # クライアント認証を有効化
    ssl_verify_depth 2;   # 認証局を辿る数

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /path/to/crt/of/your/server.crt;
    ssl_certificate_key /path/to/key/of/your/server.key;
    ssl_client_certificate /path/to/crt/of/your/CA.crt;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;


    # modern configuration. tweak to your needs.
    ssl_protocols TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    # Add headers to serve security related headers
    # Before enabling Strict-Transport-Security headers please read into this topic first.
    #add_header Strict-Transport-Security "max-age=15552000; includeSubDomains";
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;

    # Path to the root of your installation
    root /path/to/your/document/root;
    index index.php index.htm;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    if ($ssl_client_s_dn !~ "/CN=mail@address.com/emailAddress=mail@address.com")
    {
           return 401;
    }

    # あとは普通の設定と同様
}

ね,簡単でしょ?

キー入力イベントの可視化

キー入力のトラブル

PCを使っていると,キー入力が思い通りにいかないことがある.
違うキーが入力されるのは,目で見て分かるのでまだマシな方で,何か入力されているのか否かも分からない場合もある.
その場合,キーイベントを拾って出力させるのが良い.

具体的には,HHKBをHHKモードでWindowsでもLinuxでも使う - hadacchi blogという記事のようなことをしていて,
かつremminaでRDP接続をしている時に,hhk上のALT(◇と入れ替えている)を押しても,スタートメニューが開かない(Winキー入力になってない)場合.

Windows側で確認

KT Software - Keymill がシンプルで良い.
ただし,画面の上側にタスクバーを表示させていると,ウィンドウがタスクバーの後ろに起動して,移動できなくなる.

Linux側で確認

xevコマンドを叩く.
起動したウィンドウを閉じようと思うとマウスを動かすとマウスイベントも拾ってしまうので,コンソールのログが流されてしまうのが欠点.

debian jessie に owncloud 8.1 を導入する

方法

owncloudの入れ方には,大きく分けて2種類

  • apt-getで入れる
    • 普通に入れる
    • backportsから入れる
  • ソースからコンパイル

ついでに,owncloudはwebdavが必要になるので,httpdも入れる.

  • apache2
  • nginx

で,本記事では

  • apt-get で backportsから owncloudを入れる (apache2を使いたくないから)
  • nginx で運用する

手順

  1. nginxと,mysql or mariadbは使える前提
  2. owncloudを入れてみる
    1. sudo apt-get install owncloud
    2. なんか apache2 が入ってきたものの,nginx で十分なので backports で入れることにする
      echo 'deb http://ftp.jp.debian.org/debian/ jessie-backports main contrib non-free' | sudo tee -a /etc/apt/sources.list
      sudo apt-get update; sudo apt-get upgrade
      sudo apt-get -t jessie-backports install owncloud
  3. apache2とかを消す
    1. 普通に消そうとすると,php5-cgiが入ろうとする.これも要らない.php5-cgiも消そうとしたら,php5-fpmが入ろうとする.これは使う.
      sudo apt-get remove apache2 php5-cgi
    2. 他に一緒に入ったものをまとめて消す
      sudo apt-get autoremove
    3. spdyでも良ければ,これでOK
      http2を使う場合は,nginxとopensslもbackportsで入れる
  4. mysqlの設定
    • DB作成.owncloudにログインする時に初期設定するので,何でもOK.ユーザも別で作って良い.
  5. nginxの設定
    • 基本はnginx Example Configurations — ownCloud 9.2 Server Administration Manual 9.2 documentationに従いつつ,Generate Mozilla Security Recommended Web Server Configuration Filesあたりを参照して,自分の環境に直す.
      私の場合,

      -upstream php-handler {
      -    server 127.0.0.1:9000;
      -    #server unix:/var/run/php5-fpm.sock;
      -}
      -
       server {
           listen 80;
      -    server_name cloud.example.com;
           # enforce https
           return 301 https://$server_name$request_uri;
       }
      
       server {
      -    listen 443 ssl;
      -    server_name cloud.example.com;
      +    listen 443 http2;
      +    server_name YOURDOMAINNAME;
      
      -    ssl_certificate /etc/ssl/nginx/cloud.example.com.crt;
      -    ssl_certificate_key /etc/ssl/nginx/cloud.example.com.key;
      +    ssl on;
      +
      +    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
      +    ssl_certificate /path/to/certificate/file;
      +    ssl_certificate_key /path/to/certificate/key/file;
      +    ssl_session_timeout 1d;
      +    ssl_session_cache shared:SSL:50m;
      +    ssl_session_tickets off;
      +
      +
      +    # modern configuration. tweak to your needs.
      +    ssl_protocols TLSv1.2;
      +    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
      +    ssl_prefer_server_ciphers on;
      +
      +    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
      +    add_header Strict-Transport-Security max-age=15768000;
      +
      +    # OCSP Stapling ---
      +    # fetch OCSP records from URL in ssl_certificate and cache them
      +    ssl_stapling on;
      +    ssl_stapling_verify on;
      
           # Add headers to serve security related headers
           # Before enabling Strict-Transport-Security headers please read into this topic first.
      @@ -83,7 +97,9 @@
               fastcgi_param HTTPS on;
               fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
               fastcgi_param front_controller_active true;
      -        fastcgi_pass php-handler;
      +        fastcgi_pass unix:/var/run/php5-fpm.sock;
      +        fastcgi_index index.php;
               fastcgi_intercept_errors on;
               fastcgi_request_buffering off; #Available since nginx 1.7.11
           }
      
  6. あと,この辺も設定しておかないとwebdavで大容量ファイルの転送に失敗すると思われる. nginx + php-fpmでphpを動かす - Qiita
    要するにファイルサイズの上限解除.