2014年12月17日水曜日

(AWS編 RHEL6) ルートパーティションのluks暗号化 - sshでパスフレーズ入力

前2回分の連載で、SoftLayer 用に行った luks 暗号化操作を AWS でやるとどうなるかまとめてみました。元記事もご参照ください。手順自体に漏れはないですが、元記事の方が詳しいです。
SoftLayer 版との違いは、dhcp 対応させたことです。設定ファイルに直接 IP アドレスを埋め込まない分だけ、可搬性が高くなっています。


ルートパーティションの暗号化を行います。

AWS の EBS は暗号化がサポートされていますが、1台目の Root デバイスについては暗号化がサポートされていません。また、EBS の暗号化では鍵を AWS が管理しているため、セキュリティポリシー的に許容されない場合もあるかと思われます。

本稿では、ルートパーティションを luks という仕組みで暗号化し、通常は OS 起動時にコンソールにて入力する必要があるパスフレーズを、ssh でリモートから接続して、コンソールに割り込んで送り込む方法を説明します。AWS ではコンソール操作ができませんが、コンソールを操作できなくても暗号化されたルートパーティションから OS を起動することができます。

まず初めに、できないことを述べます。
BIOS が対応していないので、/boot パーティションは暗号化できません。swap 用パーティションは暗号化します。
HVM タイプでの操作のみ紹介します。PV タイプだと PV-Grub が読み込む設定ファイルの位置の関係で、起動カーネルを変更する必要があると思いますが試していません。

では、RHEL6 の仮想マシンを作成するところから説明を始めます。


Tokyo Region で [Launch Instance] を開始します。
最小要件で例示します。


Step 1: Choose an Amazon Machine Image (AMI)

Community AMIs から
RHEL-6.6_HVM_GA-20141017-x86_64-1-Hourly2-GP2 - ami-a15666a0 
を Select します。


Step 2: Choose an Instance Type

t2.micro を選択します。


Step 3: Configure Instance Details

RHEL6 のインストーラ iso イメージをマウントして公開しているリポジトリと接続可能な
ネットワーク設定とします。
プライベート・リポジトリを想定していますが、CentOS6 の公開リポジトリでも良いです。
ここでは、http://ftp.iij.ad.jp/pub/linux/centos/6.6/os/x86_64/ を使って例示します。
Rescue モードでの起動時に images/install.img をダウンロードできれば良いです。


Step 4: Add Storage

EBS を1つ追加します。
暗号化にあたり、一時的にルートパーティションにあるファイルを置くためのものです。
ルートパーティションのファイルは 2GB ほどありますが、圧縮すると 800MB を切ります。
1GB の EBS を /dev/sdb として追加すれば十分です。


Step 5: Tag Instance

Name: サーバ名


Step 6: Configure Security Group

以下のルールが許可されているセキュリティグループを選択します。
・インバウンド 22/tcp (操作端末より)
・インバウンド 222/tcp (操作端末より。OS 起動時のみ必要)
・アウトバウンド 80/tcp (リポジトリへ。Rescue モードでの起動時のみ必要)


Step 7: Review Instance Launch

内容を確認します。


Select an existing key pair or create a new key pair

適切な公開鍵を選択します。


gcc が使える端末で、補助プログラムをビルドします。


cat << 'EOF' | tee to_console.c
// gcc -std=gnu99 -O2 -Wl,-s -Wall to_console.c -o to_console
#include <sys/ioctl.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main (int argc, const char * argv[]) {
  int fd = open("/dev/console", O_RDONLY);
  if (fd < 0) {
    perror("open");
    return 1;
  }
  for (const char* str = argv[1]; *str; ++str) {
    int rv = ioctl(fd, TIOCSTI, str);
    if (rv < 0) {
      perror("ioctl(TIOCSTI)");
      return 2;
    }
  }
  close(fd);
  return 0;
}
EOF
gcc -std=gnu99 -O2 -Wl,-s -Wall to_console.c -o to_console


出来上がったバイナリを圧縮して base64 でテキスト化し、以下の実行結果 (赤字部分) を後述の構築手順に組み込みます。


gzip to_console
echo "base64 -di << 'EOF' | sudo tee /usr/share/dracut/modules.d/40earlyssh/to_console.gz > /dev/null"; \
base64 to_console.gz; \
echo EOF; \
echo sudo gunzip /usr/share/dracut/modules.d/40earlyssh/to_console.gz
base64 -di << 'EOF' | sudo tee /usr/share/dracut/modules.d/40earlyssh/to_console.gz > /dev/null
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
EOF
sudo gunzip /usr/share/dracut/modules.d/40earlyssh/to_console.gz


ec2-user にて、ルートパーティションを暗号化したいサーバに ssh でログインします。


ssh ec2-user@<サーバの IP アドレス>


ssh サーバをインストールします。OpenSSH ではなく、dropbear を使います。
ダウンロードして、ec2-user のホームディレクトリに保存し、インストールします。
ここでは、curl コマンドで直接ダウンロードしていますが、適宜読み替えてください。


curl -O http://ftp.iij.ad.jp/pub/linux/fedora/epel/6Server/x86_64/dropbear-2014.65-1.el6.x86_64.rpm
curl -O http://ftp.iij.ad.jp/pub/linux/fedora/epel/6Server/x86_64/libtomcrypt-1.17-21.el6.x86_64.rpm
curl -O http://ftp.iij.ad.jp/pub/linux/fedora/epel/6Server/x86_64/libtommath-0.42.0-3.el6.x86_64.rpm
file *.rpm
dropbear-2014.65-1.el6.x86_64.rpm:  RPM v3.0 bin i386/x86_64 dropbear-2014.65-1.el6
libtomcrypt-1.17-21.el6.x86_64.rpm: RPM v3.0 bin i386/x86_64 libtomcrypt-1.17-21.el6
libtommath-0.42.0-3.el6.x86_64.rpm: RPM v3.0 bin i386/x86_64 libtommath-0.42.0-3.el6

sudo rpm -ivh dropbear-*.rpm libtomcrypt-*.rpm libtommath-*.rpm
rm -f dropbear-*.rpm libtomcrypt-*.rpm libtommath-*.rpm


ssh サーバを初期 RAM ディスクに組み込む設定を入れます。


sudo rm -rf /usr/share/dracut/modules.d/40earlyssh
sudo mkdir -p /usr/share/dracut/modules.d/40earlyssh
cd /usr/share/dracut/modules.d/40earlyssh

base64 -di << 'EOF' | sudo tee /usr/share/dracut/modules.d/40earlyssh/to_console.gz > /dev/null
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
EOF
sudo gunzip /usr/share/dracut/modules.d/40earlyssh/to_console.gz

cat << 'EOF' | sudo tee /usr/share/dracut/modules.d/40earlyssh/luks
#!/bin/bash
read -sp "luks password: " pass
to_console $(echo -ne "$pass\r")
echo
/bin/sleep 3
/bin/cat /dev/vcs1
EOF

sudo dropbearkey -t dss -f /usr/share/dracut/modules.d/40earlyssh/dropbear_dss_host_key
sudo dropbearkey -t rsa -f /usr/share/dracut/modules.d/40earlyssh/dropbear_rsa_host_key

cat << 'EOF' | sudo tee /usr/share/dracut/modules.d/40earlyssh/hosts
127.0.0.1   localhost
::1         localhost
EOF

echo 'multi on' | sudo tee /usr/share/dracut/modules.d/40earlyssh/host.conf

echo 'root:x:0:0:root:/home/root:/bin/bash' | sudo tee /usr/share/dracut/modules.d/40earlyssh/passwd

echo '/bin/bash' | sudo tee /usr/share/dracut/modules.d/40earlyssh/shells

cat << 'EOF_' | sudo tee /usr/share/dracut/modules.d/40earlyssh/install
#!/bin/bash

inst_dir "/etc/dropbear"
inst "${moddir}/dropbear_dss_host_key" "/etc/dropbear/dropbear_dss_host_key"
inst "${moddir}/dropbear_rsa_host_key" "/etc/dropbear/dropbear_rsa_host_key"

inst_dir "/home"
inst_dir "/home/root"
inst_dir "/home/root/.ssh"
inst "${moddir}/authorized_keys" "/home/root/.ssh/authorized_keys"

grep ^root: /etc/shadow > /root/.shadow
chmod 000 /root/.shadow
inst_simple "/root/.shadow" "/etc/shadow"

inst "/etc/localtime"
inst "${moddir}/nsswitch.conf" "/etc/nsswitch.conf"
inst "/etc/resolv.conf"
inst "${moddir}/host.conf" "/etc/host.conf"
inst "${moddir}/hosts" "/etc/hosts"
inst "${moddir}/passwd" "/etc/passwd"
inst "${moddir}/shells" "/etc/shells"
inst "${moddir}/local.conf" "/etc/modprobe.d/local.conf"
inst "${moddir}/luks" "/bin/luks"

cat << 'EOF' | tee /usr/share/dracut/modules.d/40earlyssh/remote-ssh.sh > /dev/null
#!/bin/sh

/sbin/ip link set dev lo up
/sbin/modprobe eth0
/sbin/ip addr flush dev eth0
/sbin/ip link set dev eth0 up

/sbin/dhclient -d -w eth0 -lf /dev/null -lf /tmp/leases &
while /bin/true;
do
  if [ -e /tmp/leases ]; then
    IP=$(/bin/sed -n 's/^.*fixed-address \(.*\);$/\1/p' /tmp/leases)
    MASK=$(/bin/sed -n 's/^.*subnet-mask \(.*\);$/\1/p' /tmp/leases)
    GW=$(/bin/sed -n 's/^.*routers \(.*\);$/\1/p' /tmp/leases)
    [ "$GW" ] && break
  fi
  /bin/sleep 1
done
/usr/bin/pkill dhclient

/sbin/ip addr add $IP/$MASK dev eth0
/sbin/ip route add default via $GW
/bin/mkdir -p /var/log
/bin/touch /var/log/lastlog
/usr/sbin/dropbear -E -m -j -p 222 -K 600 -P /tmp/dropbear.pid
EOF

cat << 'EOF' | tee /usr/share/dracut/modules.d/40earlyssh/remote-ssh-delete.sh > /dev/null
#!/bin/sh
read main_pid </tmp/dropbear.pid
/bin/kill -KILL $main_pid 2>/dev/null
/usr/bin/pkill -KILL dropbear
/sbin/ip link set dev lo down
/sbin/ip link set dev eth0 down
IP=$(/bin/sed -n 's/^.*fixed-address \(.*\);$/\1/p' /tmp/leases)
MASK=$(/bin/sed -n 's/^.*subnet-mask \(.*\);$/\1/p' /tmp/leases)
GW=$(/bin/sed -n 's/^.*routers \(.*\);$/\1/p' /tmp/leases)
/sbin/ip addr delete $IP/$MASK dev eth0
/sbin/ip route del default via $GW
EOF

chmod 755 /usr/share/dracut/modules.d/40earlyssh/{remote-ssh.sh,remote-ssh-delete.sh}

inst_hook pre-trigger 01 "$moddir/remote-ssh.sh"
inst_hook pre-pivot 01 "$moddir/remote-ssh-delete.sh"

inst_binary "${moddir}/to_console" "/bin/to_console"

dracut_install -o ps find grep egrep sed less more cat tac head tail true false mkdir rmdir rm touch vi ip ping ssh scp pkill kill sleep bash dropbear dhclient
EOF_

cat << 'EOF' | sudo tee /usr/share/dracut/modules.d/40earlyssh/check
#!/bin/bash
exit 0
EOF

cat << 'EOF' | sudo tee /usr/share/dracut/modules.d/40earlyssh/installkernel
#!/bin/bash
instmods eth0
instmods xen_netfront
EOF

cat << 'EOF' | sudo tee /usr/share/dracut/modules.d/40earlyssh/local.conf
alias eth0 xen_netfront
EOF

cat << 'EOF' | sudo tee /usr/share/dracut/modules.d/40earlyssh/nsswitch.conf
passwd:     files
shadow:     files
group:      files
initgroups: files
hosts:      files dns
bootparams: files
ethers:     files
netmasks:   files
networks:   files
protocols:  files
rpc:        files
services:   files
automount:  files
aliases:    files
EOF

sudo touch /usr/share/dracut/modules.d/40earlyssh/authorized_keys

sudo chmod 755 /usr/share/dracut/modules.d/40earlyssh/{check,install,installkernel,luks,to_console}
sudo chmod 600 /usr/share/dracut/modules.d/40earlyssh/authorized_keys
cd


公開鍵認証でログインしたい場合は、/usr/share/dracut/modules.d/40earlyssh/authorized_keys に入れておきます。
ここでは、ec2-user と同じものを入れています。適宜読み替えてください。


cat ~/.ssh/authorized_keys | sudo tee -a /usr/share/dracut/modules.d/40earlyssh/authorized_keys


Rescue モードで起動する準備をします。


sudo curl -o /boot/vmlinuz http://ftp.iij.ad.jp/pub/linux/centos/6.6/os/x86_64/isolinux/vmlinuz
sudo curl -o /boot/initrd.img http://ftp.iij.ad.jp/pub/linux/centos/6.6/os/x86_64/isolinux/initrd.img
file /boot/{vmlinuz,initrd.img}
/boot/vmlinuz:    Linux kernel x86 boot executable bzImage, version 2.6.32-504.el6.x86_64 (mockbuil, RO-rootFS, swap_dev 0x3, Normal VGA
/boot/initrd.img: LZMA compressed data, streamed

cat << 'EOF' | sudo tee /boot/grub/grub.conf
default=0
timeout=1
serial --unit=0 --speed=115200
terminal --timeout=1 serial console
title Rescue
        root (hd0,0)
        kernel /boot/vmlinuz rescue repo=http://ftp.iij.ad.jp/pub/linux/centos/6.6/os/x86_64/ nomount sshd=1 lang=en_US keymap=us selinux=0 biosdevname=0 ksdevice=eth0 ip=dhcp
        initrd /boot/initrd.img
EOF

cat << 'EOF' | sudo tee /boot/grub/device.map
(hd0)     /dev/xvda
EOF


OS を再起動します。
OS 再起動後、2分ほど経過すると Rescue モードで起動するので、ssh でログインします。
root アカウントにてパスワードなしでログインします。


sudo reboot

ssh root@<サーバの IP アドレス>


パスワードなしでログインできる状態は危険なので、sshd デーモンを停止します。


kill -KILL $(ps -ef | grep [/]sbin/sshd | awk '{print $2}')


OS バックアップ保存領域を初期化します。


dd if=/dev/zero of=/dev/xvdb bs=1M count=1
fdisk -H 64 -S 32 /dev/xvdb << 'EOF'
o
n
p
1


p
w
EOF
sleep 3
mkfs.ext4 /dev/xvdb1
mkdir /backup
mount /dev/xvdb1 /backup


暗号化後に変更が必要となる設定を入れ、SELinux を無効化し、OS イメージをバックアップします。


mkdir /mnt/sysimage
mount /dev/xvda1 /mnt/sysimage

cat << 'EOF' | tee /mnt/sysimage/etc/crypttab
luks-0e144deb-0180-42a1-a2ad-6404d83d9eda UUID=0e144deb-0180-42a1-a2ad-6404d83d9eda
luks-1a528f04-c266-4b17-b3f7-a32b01670818 UUID=1a528f04-c266-4b17-b3f7-a32b01670818
EOF

cat << 'EOF' | tee /mnt/sysimage/etc/fstab
/dev/mapper/luks-0e144deb-0180-42a1-a2ad-6404d83d9eda / ext4 defaults   1 1
UUID=7e70ca17-3016-4b92-8542-615d909115f9 /boot ext4    defaults        1 2
/dev/mapper/luks-1a528f04-c266-4b17-b3f7-a32b01670818 swap swap pri=1,defaults 0 0
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
EOF

cat << 'EOF' | tee /mnt/sysimage/boot/grub/grub.conf
default=0
fallback=1
timeout=1
serial --unit=0 --speed=115200
terminal --timeout=1 serial console
title Red Hat Enterprise Linux 6 (2.6.32-504.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-504.el6.x86_64 ro root=/dev/mapper/luks-0e144deb-0180-42a1-a2ad-6404d83d9eda rd_NO_LVM rd_NO_MD rd_NO_DM xen_blkfront.sda_is_xvda=1 crashkernel=auto SYSFONT=latarcyrheb-sun16 LANG=en_US.UTF-8 KEYBOARDTYPE=pc KEYTABLE=us console=ttyS0,115200n8 console=tty0 selinux=0
        initrd /initramfs-2.6.32-504.el6.x86_64.img
title Rescue
        root (hd0,0)
        kernel /vmlinuz rescue repo=http://ftp.iij.ad.jp/pub/linux/centos/6.6/os/x86_64/ nomount sshd=1 lang=en_US keymap=us selinux=0 biosdevname=0 ksdevice=eth0 ip=dhcp
        initrd /initrd.img
EOF

sed -i -e 's/^SELINUX=.*$/SELINUX=disabled/' /mnt/sysimage/etc/sysconfig/selinux

cd /mnt/sysimage
tar czvf /backup/os.tgz .
cd /
umount /mnt/sysimage


HDD を初期化して、パーティショニングします。


# /boot 250MB
# swap  2GB
# /     残り

parted /dev/xvda mklabel msdos
Warning: The existing disk label on /dev/xvda will be destroyed and all data on this disk will be
lost. Do you want to continue?
Yes/No? y
Information: You may need to update /etc/fstab.

dd if=/dev/zero of=/dev/xvda bs=1M count=1
fdisk -H 64 -S 32 /dev/xvda << 'EOF'
o
n
p
1

+250M
n
p
2

+2049M
n
p
3


t
2
82
p
w
EOF


暗号化対象のパーティションに対し、ランダムな書き込みを行います。


dd if=/dev/urandom of=/dev/xvda2 bs=1M
dd if=/dev/urandom of=/dev/xvda3 bs=1M


パーティションを暗号化します。
データを上書きしてよいかどうか聞かれるので大文字で 「YES」 と入力してください。
パスフレーズを2回入力する必要があります。


cryptsetup luksFormat -c aes-xts-plain64 -s 512 --uuid=1a528f04-c266-4b17-b3f7-a32b01670818 /dev/xvda2

WARNING!
========
This will overwrite data on /dev/xvda3 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: ******** ******** ******** ********
Verify passphrase: ******** ******** ******** ********

cryptsetup luksFormat -c aes-xts-plain64 -s 512 --uuid=0e144deb-0180-42a1-a2ad-6404d83d9eda /dev/xvda3

WARNING!
========
This will overwrite data on /dev/xvda2 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: ******** ******** ******** ********
Verify passphrase: ******** ******** ******** ********


暗号化したパーティションをオープンします。パスフレーズを入力する必要があります。


cryptsetup luksOpen /dev/xvda2 luks-1a528f04-c266-4b17-b3f7-a32b01670818
Enter passphrase for /dev/xvda2: ******** ******** ******** ********

cryptsetup luksOpen /dev/xvda3 luks-0e144deb-0180-42a1-a2ad-6404d83d9eda
Enter passphrase for /dev/xvda3: ******** ******** ******** ********


暗号化されていない最初のパーティションに /boot 領域のためのファイルシステムを作成します。


mkfs.ext4 -L /boot -U 7e70ca17-3016-4b92-8542-615d909115f9 /dev/xvda1
tune2fs -c 0 -i 0 /dev/xvda1


暗号化されたパーティション上にファイルシステムを作成します。swap 領域も作成します。


mkfs.ext4 -L / -U 4bf120f5-6da0-4cb8-9540-bec49fff57a1 /dev/mapper/luks-0e144deb-0180-42a1-a2ad-6404d83d9eda
tune2fs -c 0 -i 0 /dev/mapper/luks-0e144deb-0180-42a1-a2ad-6404d83d9eda
mkswap -L SWAP -U 299ff4da-8897-405b-ae8e-5648a14fc81e /dev/mapper/luks-1a528f04-c266-4b17-b3f7-a32b01670818


OS イメージを展開できるように、マウントします。


mount /dev/mapper/luks-0e144deb-0180-42a1-a2ad-6404d83d9eda /mnt/sysimage
mkdir /mnt/sysimage/boot
chmod 555 /mnt/sysimage/boot
mount /dev/xvda1 /mnt/sysimage/boot


OS イメージを展開します。


cd /mnt/sysimage
tar xzvf /backup/os.tgz


chroot して grub をインストールします。


mount -t proc /proc /mnt/sysimage/proc
mount -t sysfs /sys /mnt/sysimage/sys
mount --bind /dev /mnt/sysimage/dev
chroot /mnt/sysimage

\cp /proc/mounts /etc/mtab

grub-install /dev/xvda || :
grub << 'EOF'
device (hd0) /dev/xvda
root (hd0,0)
setup (hd0)
quit
EOF


初期 RAM ディスクを作成し、暗号化対応、ssh サーバ起動設定を組み込みます。


cd /boot
mkinitrd --force initramfs-2.6.32-504.el6.x86_64.img 2.6.32-504.el6.x86_64


再起動し、ssh でログインします。ポート番号に222を指定している点に注意してください。


exit
umount /mnt/sysimage/dev
umount /mnt/sysimage/sys
umount /mnt/sysimage/proc
cd /
umount /mnt/sysimage/boot
umount /mnt/sysimage
cryptsetup luksClose luks-0e144deb-0180-42a1-a2ad-6404d83d9eda
cryptsetup luksClose luks-1a528f04-c266-4b17-b3f7-a32b01670818
reboot

ssh -p 222 root@<server の IP アドレス>


コンソールに表示されている内容を確認します。


cat /dev/vcs1
lo: Disabled Privacy Extensions                                                 
[97] Dec 08 02:44:16 Running in background                                      
dracut: Starting plymouth daemon                                                
dracut: rd_NO_DM: removing DM RAID activation                                   
dracut: rd_NO_MD: removing MD RAID activation                                   
Refined TSC clocksource calibration: 2499.998 MHz.                              
Switching to clocksource tsc                                                    
scsi0 : ata_piix                                                                
scsi1 : ata_piix                                                                
ata1: PATA max MWDMA2 cmd 0x1f0 ctl 0x3f6 bmdma 0xc100 irq 14                   
ata2: PATA max MWDMA2 cmd 0x170 ctl 0x376 bmdma 0xc108 irq 15                   
input: ImExPS/2 Generic Explorer Mouse as /devices/platform/i8042/serio1/input/i
nput4                                                                           
xlblk_init: register_blkdev major: 202                                          
blkfront: xvda: barriers disabled                                               
 xvda: xvda1 xvda2 xvda3                                                        
blkfront: xvdb: barriers disabled                                               
 xvdb: xvdb1                                                                    
dracut: luksOpen /dev/xvda2 luks-0e144deb-0180-42a1-a2ad-6404d83d9eda           
                                                                                
Password (/dev/xvda2):[242] Dec 08 02:44:30 Child connection from ***.***.***.**
*:54756                                                                         
[242] Dec 08 02:44:33 Pubkey auth succeeded for 'root' with key md5 b9:d9:3a:0b:
c0:2f:07:f0:d4:0e:1e:be:9e:78:61:5c from ***.***.***.***:54756                  
                                                                                


パスフレーズを入力します。


luks
luks password: ********


後は、通常通り OS が起動します。
一時的なバックアップ置き場として用意したボリュームは、削除してもよいし、暗号化して /etc/crypttab に組み込んでもよいです。

次回は、このパスフレーズ入力を自動化します。

0 件のコメント:

コメントを投稿