カテゴリー
OS 社内SE

OpenLiteSpeedでのクライアント認証

最近一部のhttpサーバをApacheからOpenLiteSpeedに変更した。ただ、問題があり、Apacheにはあるクライアント認証の機能がOpenLiteSpeedにはない。

さんざん迷った挙句、Apacheでreverse proxyを使用し、そこでクライアント認証することにした。「全部Apacheで良いじゃないか」という感じもするが、どうもApache+mpm_event+php-fmpの構成では、まれにプチフリするのが気になってしょうがない。設定が悪い気がするが、再現性がなく調査もできない。

案ずるより産むがやすし、動かしてみたら、とても軽快になった。reverse proxy分重くなるかと思ったが、杞憂であった。

以下、OpenLiteSpeedのadmin consoleをクライアント認証に設定する例。

前提

クライアント証明書は以下
 ・CA証明書:/opt/myCA/cacert.pem
 ・証明書失効リスト:/opt/myCA/crl.pem
Admin ConsoleはSSLなしで動作させ、localhost(127.0.0.1)以外は接続させない。(Admin ConsoleをSSLありのデフォルトの状態で動作させたい場合は、Apache設定のコメントを参照のほど。reverse proxyでSSLのエラーを無視させればちゃんとつないでくれる。)
以下はOpenLiteSpeedのAdmin configの設定。設定後、restart。

vi /usr/local/lsws/admin/conf/admin_config.conf
---
enableCoreDump            1
sessionTimeout            3600

errorlog $SERVER_ROOT/admin/logs/error.log {
  useServer               0
  logLevel                INFO
  rollingSize             10M
}

accesslog $SERVER_ROOT/admin/logs/access.log {
  useServer               0
  rollingSize             10M
  keepDays                90
}
# 以下のセクションを追加
accessControl  {
  allow                   127.0.0.1
}
# 以下のセクションを変更
listener adminListener {
  # addressとsecureの2行を変更
  address                 127.0.0.1:7080
  secure                  0
  #keyFile                 $SERVER_ROOT/admin/conf/webadmin.key
  #certFile                $SERVER_ROOT/admin/conf/webadmin.crt
  #clientVerify            0
}
---
systemctl restart lsws

Apach設定

Apacheでhttps://yourdomain.net:8000/にアクセスするとOpenLiteSpeedの管理コンソール(http://127.0.0.1:7080/)にアクセスする設定。ブラウザにクライアント認証の証明書が入っていないとはじかれる。SSLはLetsencryptで取得。
mod_proxy mod_proxy_httpはモジュールで入れること。

# Apacheのバーチャルホストの設定に以下を追加
<IfModule mod_ssl.c>
        <VirtualHost _default_:8000>
                ServerName yourdomain.net
                DocumentRoot /var/www/

                ErrorLog ${APACHE_LOG_DIR}/lsws/proxy_error.log
                CustomLog ${APACHE_LOG_DIR}/lsws/proxy_access.log common

                # Proxy設定
                <Proxy *>
                    Order deny,allow
                    Allow from all
                </Proxy>
                ProxyRequests Off
                ProxyPreserveHost On

                ProxyPass / http://127.0.0.1:7080/
                ProxyPassReverse / http://127.0.0.1:7080/

				# AdminConsoleをデフォルトのまま(SSLで)使用するなら以下
				#SSLProxyEngine On
                #SSLProxyCheckPeerCN off
                #SSLProxyCheckPeerName off
                #ProxyPass / https://127.0.0.1:7080/
                #ProxyPassReverse / https://127.0.0.1:7080/


                # クライアント証明書関係
                SSLEngine on
                SSLCACertificateFile /opt/myCA/cacert.pem
                SSLCARevocationFile /opt/myCA/crl.pem
                SSLCARevocationCheck chain
                SSLVerifyClient require
                SSLVerifyDepth 1

                # SSL
                SSLOptions +StdEnvVars
                Include    /etc/letsencrypt/options-ssl-apache.conf
                SSLCertificateFile /etc/letsencrypt/live/yourdomain.net/fullchain.pem
                SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.net/privkey.pem

        </VirtualHost>
</IfModule>

サイトへのアクセスも楽で、パスコンが盗まれたら失効すれば良いし、クライアント認証の良さは他のセキュリティには代えがたい。Google Authenticatorとかで二段階認証やると、アクセスのたびに入力しなきゃいけなくて面倒だし、フィッシングのリスクもあるし。

カテゴリー
プログラム 社内SE

WordPress twenty- twentyのテーブル変更

WordPress twenty-twentyでこのブログを書いているのだが、付属のテーブルを少しだけおしゃれに外枠をなしにすることにした。

テーブルをブロックで作成した際に、[追加CSSクラス]に[is-style-regular my-style-stripes]とすると以下のような外枠なしの表ができる。

人生項目 内容
プログラム 仕事のために仕方なくやっている
家事 家族のために仕方なくやっている
DIY 家族のために仕方なくやっている
囲碁 ここ数年打っていない。打つ相手もいない。。。
サンプル

やり方は[外観]-[テーマエディター]でstyle.cssを選択し以下のCSSを最後に追加する。(もしくは、[外観]-[カスタマイズ]で左側ペインの[追加CSS]に追加。)

.my-style-stripes table{
	border:none;
}
.my-style-stripes table tr{
	border:none;
}
.my-style-stripes table tbody tr:nth-child(odd) {
	background: #dcd7ca;
}
.my-style-stripes table thead th {
	border-top:none;
	border-right: none;
	border-left: 1px solid #6d6d6d;
	border-bottom: 2px solid #6d6d6d;
}
.my-style-stripes table tbody td{
	border-top:none;
	border-right: none;
	border-left: 1px solid  #6d6d6d;
	border-bottom: 1px solid  #6d6d6d;
}
.my-style-stripes table thead th:first-child, .my-style-stripes tbody td:first-child{
	border-left: none;
}
.my-style-stripes tbody tr:last-child td {
	border-bottom: none;
}
カテゴリー
プログラム 社内SE

Roundcubeに任意のユーザ名とパスワードでログインするプラグイン

レガシーな意見を振り切れず、わずか20人の小売りの会社にメールサーバを一から構築した。その際、メールの自動フォルダ振り分けができるようdovecotにsieveを追加し、その操作のため、初めてRoundcube環境も構築したのだが、これがどうして、通常のメーラーとしてもなかなか良い。

ただ、Roundcubeのログインがメールアドレスとパスワードでしかできないのが自分の環境的に使いにくい。出来れば、自分で設定したユーザ名とパスワードでログインしたいため、ファイルに設定したユーザ名とパスワードでログインできるようなプラグインを作成してみた。また、20人分の設定も面倒なので、CSVにした一覧から設定ファイルを生成するツールも作成した。

インストール方法

  1. RoundcubeのPluginsフォルダーにGithubからソースをダウンロードする
  2. Roundcubeのconfigにvirtuserpassを設定

Linuxなら以下のような感じです。

cd (Roundcubeをインストールしたフォルダ)/plugins
git clone https://github.com/y-toy/virtuserpass virtuserpass

vim ../config/config.inc.php
---
# "virtuserpass" を $config['plugins'] に追加
$config['plugins'] =  array('virtuserpass');
# もしくはファイルの一番下に以下を追加
# $config['plugins'][] =  'virtuserpass';

設定

“(Roundcubeをインストールしたフォルダ)/plugins/virtuserpass/config”の下に”config.inc.php”を作成し、以下のような設定をします。

// 主な設定
$config['virtuserpass'] = array(
	'taro'=>array('967Joe123','taro@biggy.co.jp','emailPass1234'),
	'ziro'=>array('pass1234','ziro@biggy.co.jp','emailPass5678'),
	'saburo'=>array('1234test','saburo@biggy.co.jp','emailPass7777'),
);

// オプション
$config['virtuserpass_scramble']=false;
$config['virtuserpass_email_scramble']=false;
$config['virtuserpass_allow_email_login']=true;

上の設定では、”taro”、”ziro”、”saburo”が設定してあり、”taro”さんはアカウント”taro”とパスワード”967Joe123″でログインできます。(対応するメールアドレスとパスワードは’taro@biggy.co.jp’と’emailPass1234’。)

$config[‘virtuserpass’]

ログインするアカウントの設定をします。ログインするユーザ名とパスワード、内部で変換されるメールアドレスとパスワードを設定します。

$config['virtuserpass'] = array(
	'ユーザ名' => array('パスワード', 'メールアドレス', 'メールのパスワード'),
	// いくつでも設定できます。
);

$config[‘virtuserpass_scramble’]

trueを設定するとconfigファイルのユーザのパスワードがMD5でハッシュされているものとして扱います。パスワードが外部に漏れない用のセキュリティ考慮です。後から説明するツール”makeConfigFileFromCSV.php”で設定できます。

$config[‘virtuserpass_email_scramble’]

trueを設定するとconfigファイルのメールパスワードが暗号化されているものとして扱います。ないよりましでしょの気休めセキュリティです。後から説明するツール”makeConfigFileFromCSV.php”で設定します。

$config[‘virtuserpass_allow_email_login’]

falseを設定するとメールアドレスを使ったログインが出来なくなります。

ツール

CSVファイルから一括でユーザをconifgに設定できるようにツールも作っています。

使い方

php ./makeConfigFileFromCSV.php csv-file-path [1|0] [1|0] [1|0]

引数 1 :CSVファイルのパス
引数 2 : 1を設定するとログイン時のパスワードがハッシュされて設定されます。
引数 3 : 1を設定するとメールアドレスのパスワードが暗号化されて設定されます。
引数 4 : 0を設定するとメールアドレスでのログインが出来なくなります。

Configファイル生成の仕方

  1. CSVファイルを作成します。CSVファイルは以下の4列で作成してください。ログインユーザ名,ログインパスワード, メールアドレス, メールアドレスのパスワード。このプラグインのconfigフォルダーの下にsample.csvファイルがありますので参考ください。
  2. 下のような感じでこのツールを実行します。このプラグイン用のconfigファイルが作成されます。
cd (Roundcubeをインストールしたフォルダ)/plugins/virtuserpass
php ./makeConfigFileFromCSV.php 作ったCSVファイルのパス 1 1 1

3. 作成したCSVファイルは念のため削除するか、公開されていないフォルダに移動します。

カテゴリー
プログラム 社内SE

sshのconfigのhostをリスト表示し、そのままssh

sshコマンドを打つときに.configに設定したホスト名を忘れて躓く方のための補助用のスクリプトです。
Windows Powershell版Linux bash版それぞれあります。

使い方

コマンド:sshfc [ホスト名の一部]

sshfcとだけ打つとconfigファイルに設定した全ホスト名が表示されます。
sshfc sysのように第一引数をつけて打つとホスト名にsysを含むSSH先が表示されます。続けて番号選択でそのままSSH接続です。
コマンド名は”ssh from config” の頭をとってsshfcとしています。以下使用例になります。

C:\> sshfc sys
1) system
2) test_system
3) dev_system
SSHするホストの番号を入力してください。[c]を押すとキャンセルされます。: 3
ssh dev_system
hogehoge@192.168.1.100's password:
....

Linux Bash版 インストール方法

以下の要領で、githubからスクリプトをダウンロードしてPATHが通っているフォルダに置いてください

git clone https://github.com/y-toy/linux_sshfc.git
chmod +x ./linux_sshfc/sshfc
# 以下環境に合わせて実行ください。
mv ./linux_sshfc/sshfc /usr/local/bin/

Windows Powershell版 インストール

以下の要領で、”ユーザフォルダ\bin”をPATHに追加して、githubからファイルをダウンロードします。

New-Item ($HOME + "\bin") -ItemType Directory
[System.Environment]::SetEnvironmentVariable("Path", $env:Path + ";%USERPROFILE%\bin", "User")

git clone https://github.com/y-toy/windows_sshfc.git
cd windows_sshfc
Move-Item ./sshfc.ps1 ($HOME + "\bin")

スクリプト自体が実行できない場合は以下コマンドを実行してみてください。スクリプトの実行制限を緩めます。

Set-ExecutionPolicy Unrestricted -scope CurrentUser

上記は確実ですが、上記をやらなくても、githubからダウンロードしたファイルを、空行を入れるなど意味のない編集をメモ帳などでして、BOM付UTF-8で保存すると実行できるようになるはずです。(普通のUTF-8はNGです。メモ帳の[名前を付けて保存]で UTF-8 BOM付きを選択。)

雑記

最近、WindowsのsshクライアントをMicrosoft謹製の「Windows terminal」に変更しました。 「Windows terminal」 自体は秀逸なのですが、以前使用していたsshクライアントと比べ若干使いずらいのが、SSHの接続先の選択方法。なのでツールを作ってカバーした感じです。

作ったツールが思いのほか便利だったので、bash版も作成しサーバに入った後のSSHも同様にできるようにしました。「.configに設定したホスト名なんだっけ?」と考えることが無くなりました。

Powershell のスクリプトを書くのは初めて。こういった作業効率化のちょっとしたコードを書く分には構文に慣れている分、過去のvbscriptで良いかなあという印象です。bashのスクリプトも簡単な数行ものを除けば、めったに書かないのでいつも構文忘れます。

Powershell版は日英つけていますがps1ファイルは配布が難しいので意味ないです。Bash版は面倒なので英語だけです。

カテゴリー
プログラム 社内SE

Pear Mailで送信したメールを 送信済みフォルダに設置する。

PHPのPear::Mailでシステムからメールを送信し、送信したメールを送信済みフォルダに入れたい事案があった。
解決方法がググっても出てこなかったので、自己解決。

基本的には送信したデータをIMAP関数で送信済みのフォルダに設置するだけ。

以下ソース。

include_once("Mail.php");
include_once("Mail/mime.php");

mb_language("uni");
mb_internal_encoding("UTF-8");

// 宛先とヘッダーとボディを作る。省略。以下mimeの例
$mime = new Mail_mime();
$mime->setHTMLBody('something<br />anything');
$body = $mime->get(array(
  'text_encoding' => '7bit',
  'text_charset' => 'UTF-8',
  'html_charset' => 'UTF-8',
  'head_charset' => 'UTF-8'));
$headers = $mime->headers(array(/*省略*/));
$recipients = array(/*省略*/);

// メール送信
$mailObject = Mail::factory("smtp", Array(/*省略*/)); 
$send = $mailObject->send($recipients, $headers, $body);
if (PEAR::isError($send)){ return 'Mail send error! ' . $send->getMessage(); }

////////////////////////////////////////////////////////////////
// IMAPフォルダに設定。

// 送信済みフォルダに設置するデータ作成
$message = '';
foreach($headers as $key => $value){
  $message .= $key . ': ' . $value . "\r\n";
}
$message .= "\r\n" . $body;
// 設置フォルダー
$folderName = '送信済み'; // 自分のIMAPの送信済みフォルダ
$encodeFolder = mb_convert_encoding($folderName, 'UTF7-IMAP', 'UTF-8'); // エンコード
// imap_openの説明を読んで。SSLならポート以降を:993/imap/ssl
$path = "{imap.hogehoge.com:143/imap/notls}INBOX." . $encodeFolder;
$imapStream = imap_open($path,'username@hogehoge.com','password');
if ($imapStream === FALSE){ die(); }
$result = imap_append($imapStream, $path, $message, "\\Seen");
if ($result === FALSE){ die(); }
imap_close($imapStream);

/* end */

以上