Linuxのセミナーに参加してSELinuxとOpenSSH、https化を勉強しました

LPI主催のLinuxセキュリティに関するセミナーへ参加しました。

LPIC level2も合格し、ある程度サーバーの構築ができるようになったので、次はセキュリティとSSL証明書関連をマスターしようという思惑があります。

セミナーは2時間程度の座学でしたが、家で実際に作業してみましたので、その内容をまとめます。

セミナーの内訳

  • SELinuxの設定方法
  • OpenSSHの設定方法
  • WebサーバーのSSL設定方法

SELinuxの設定方法と実際の挙動。OpenSSHの鍵認証の設定方法、SSL/TLSを当ててhttps化する方法を学びました。

以下、記載したコマンドはCentOS7で私が投入したものになります。Ubuntuなど他のOSでも流れは同じですが、適宜自分の環境に置き換えて実行してください。

30分で分かった気になれるSELinux

SELinuxはSecurity-Enhanced Linuxの略称で、Linuxのカーネルに組み込まれているアクセス制御を行うためのモジュールです。有効にすると強固な壁を作ってくれます。ユーザーはその壁に穴を通すように、「このアプリケーションのこの動作を許可する。この動作は許可しない。」と言った具合に細かく挙動を制御することで、必要な動作のみ許可するような環境を構築できます。頑張ればroot権限でも回避できない強制的なアクセス制御も実現可能です。

SELinuxの有効化

/etc/selinux/config
上記configファイルの「SELINUX=xxx」の項目を下記のように編集します。

SELINUX=enforcing
or
SELINUX=permissive

編集後はSELINUXを再起動します。

getenforceコマンドでステータスを確認できます。

SELinuxを有効にするといくつかのコマンドの出力結果にコンテキストが付与されます。試しに下記コマンドを実行してみます。
ls -laZ, id, ps -axZ

lsではsystem_u:ob~~~
idではcontext=hogehoge
psではLABELのカラムに変化が見られます。

 

semanageコマンドの利用

SELinuxを設定するには「semanage」コマンドを利用します。semanageはpolicycoreutils-pythonの一部なので、それをインストールします。

sudo yum -y install policycoreutils-python

インストール後、semanageコマンドで実際に設定されているセキュリティ項目のブーリアン値をみてみます。例えば、Apacheのセキュリティ項目で許可されている項目を見たい時。

sudo semanage boolean -l | grep httpd | grep Allow

ブーリアン値をオン/オフ(許可/不許可)することでアクセス制御を設定するようです。

OpenSSHでエレガントにsshしてみた

OpenSSHはSSH接続を行うためのLinuxのソフトウェアです。SSHは全ての通信を暗号化しつつ、リモートのクライアントからサーバへアクセスする仕組みのこと。暗号化しているので、誰かに通信が盗聴された場合でも、複合するためのパスワードを知らない限り、盗聴者には通信内容がバレません。これで安心してリモート作業を行えます。

公開鍵認証

公開鍵と秘密鍵のペアを作成し、公開鍵で通信を暗号化、秘密鍵で複合します。公開鍵で暗号化された情報は秘密鍵でしか複合できません。秘密鍵を失くすと接続できなくなるので管理には気をつけます。

公開鍵認証の設定

sshを公開鍵認証で接続できるように設定します。クライアント側で公開鍵と秘密鍵のペアを作成し、SSH接続したいサーバーに、作成した公開鍵のコピーを置きます。

前準備

私はVagrantで構築した仮想環境で試験しました。vagrantとvirtualboxをインストールし、仮想マシンを二つ作成。各マシンのvagrantfileに下記1文を追記し、お互い疎通できる状態にしておきます。

ホストA
config.vm.network “private_network”, ip: “192.168.33.15”, virtualbox__intnet: “intnet”

ホストB
config.vm.network “private_network”, ip: “192.168.33.19”, virtualbox__intnet: “intnet”

 

クライアント側の設定

クライアント側で下記コマンドを投入し、公開鍵と秘密鍵を作成します。

ssh-keygen -t dsa

 

id_dsaが秘密鍵、id_dsa.pubが公開鍵です。ユーザーディレクトリの.sshディレクトリ内に置かれます。

 

SSH接続先の設定

ssh接続先のサーバーに潜り、クライアント側で作成した公開鍵を~/.ssh/authorized_keysに追加します。.sshフォルダが無い場合は作成します。作成する場合はroot権限でしか操作できないようにパーミッションを設定します。

mkdir ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

 

authorized_keysにid_dsa.pubの内容を追記します。スマートなやり方ではないですが、vimで開いて最終行にコピペしました。

vim ~/.ssh/authorized_keys

 

クライアントからサーバーへssh

sshしてみます。
ssh hostname

ユーザー指定してssh
ssh user@hostname

 

OpenSSHサーバーの設定

PermitRootLoginの設定をしてrootでのログインを制限したり
PasswordAuthenticationの設定をしてパスワード認証の制限しました。

セキュアなssh接続を行うなら、rootでのログインはNo。パスワード認証もNoにするべき。
さらにGoogle Authenticatorを使ってワンタイムパスワード認証の設定もすれば、ガッチガチに強固な接続にできます。

WebサーバーのSSL設定〜頑張ってhttps化してみた

SSLを介したhttpをhttpsと呼びます。通信が暗号化されるので、ユーザーはより安心してサイトを閲覧できます。ChromeやFirefoxでは、https化されていないWebサイトにアクセスしたユーザーに対し、下記のようなメッセージを表示するようになりました。https化はすでに当たり前の時代が到来しています。

httpsの3つの役割

https化すると、主に下記の3つのメリットがあります。

1)サーバーのなりすまし防止
2)送受信されるデータの盗聴防止
3)データの改ざん防止

1)について
認証局が電子署名したサーバー証明書でサーバー自体の信頼性を保証

2)について
共通鍵暗号で通信内容を暗号化

3)について
メッセージ認証コードでデータが改ざんされていないことを確認

https化に必要なもの

・WebサーバーにApacheを利用する場合はApacheのSSLモジュール
・サーバーの公開鍵(CSR)と秘密鍵(Key)
・認証局(CA)が電子署名したサイト証明書(CRT)

通常、信頼のおける認証局にて署名してもらう必要がありますが、今回、認証局を自分で構築しました。

セミナーで配布された資料の方法ではChrome58に対応しておらず、うまくhttps化できなかったため、下記ページを参考に証明書を発行しました。

Fixing Chrome 58+ [missing_subjectAltName] with openssl when using self signed certificates

 

前準備:ApacheとOpenSSLのインストール、hostsの設定

下記コマンドでApacheとsslモジュールをインストールします。OpenSSLがない場合はそれもインストールします。

yum -y install httpd mod_ssl
yum -y install openssl

 

証明書のコモンネームに任意のドメインを使用する場合は、/etc/hostsファイルの設定も済ませておきます。

 

サーバー秘密鍵(Key)の作成

mkdir ~/crt/
openssl genrsa -aes128 -out ~/crt/server.key 2048

genrsa
RSA形式の秘密鍵を作成するサブコマンド。

-aes128
128ビットAES暗号方式で暗号化する。

-out 秘密鍵ファイル名
秘密鍵のファイル名を指定する。

2048
2048ビットの秘密鍵にする。ビット数は最後に書く。

コマンドを実行するとパスフレーズの入力を求められるので、任意のパスフレーズを入力します。

 

CSR (Certificate Signing Request)の作成

CSRファイルは証明書を発行するために必要な情報を記述します。このファイルの内容を基に、認証局は証明書を発行することができます。

openssl req -new -key ~/crt/server.key -sha256 -out ~/crt/server.csr

req
CSRファイルを作成する。

-new
新規にCSRを作成する。

-key 秘密鍵ファイル
秘密鍵のファイル名を指定する。

-sha256
署名アルゴリズムとして SHA-2 を利用する。(SHA-1 にする場合は、このオプションを付けない。)

-out CSRファイル名
作成する CSR のファイル名を指定する。

コマンド実行後、秘密鍵のパスフレーズを要求されます。続いて国や会社の情報、コモンネーム(ドメイン名)の設定をします。

 

認証局(CA : Certification Authority)の構築

認証局を構築し、認証局の証明書(公開鍵)を発行します。

mkdir ~/ssl/
openssl genrsa -des3 -out ~/ssl/rootCA.key 2048
openssl req -x509 -new -nodes -key ~/ssl/rootCA.key -sha256 -days 1024 -out ~/ssl/rootCA.pem

 

コマンドが長いので、シェルスクリプトにして実行すると楽かなと思います。

 

サイト証明書の発行

CSRを認証局に送りつけて、サーバー証明書を発行します。

sudo openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout server.key -config <( cat ~/crt/server.csr.cnf )
sudo openssl x509 -req -in ~/crt/server.csr -CA ~/ssl/rootCA.pem -CAkey ~/ssl/rootCA.key -CAcreateserial -out ~/crt/server.crt -days 500 -sha256 -extfile ~/crt/v3.ext

 

あらかじめ下記内容でopensslのコンフィグファイルを作っておき、上記1行目のopensslコマンドで参照します。

[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[dn]
C=JP
ST=Hodaland
L=Hodacity
O=Hodacaompany
OU=Testing Domain
emailAddress=hodaland@gmail.com
CN = mycentos

 

さらにv3.extファイルを用意します(2行目のコマンドで参照)。v3.extファイルではsubjectAltName、通称SANSと呼ばれる項目を設定しています。これが特に重要で、chrome58以降は証明書にSANSが設定されていないとエラーが表示されます。

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = mycentos

 

このコマンドも非常に長いので、シェルスクリプトとして実行するのが楽です。下記は実行結果になりますが、いくつかエラーが発生しています。このエラーは無視しても問題ないですが、こちらのページ(C.2. Creating an SSL Certificate)を参考に解消できるので、試してみると良いかと。

 

サーバー秘密鍵とサイト証明書設置

サーバー秘密鍵とサイト証明書を適当な場所へ設置し、パーミッションの設定をします。

sudo mkdir /etc/httpd/conf/ssl.key
sudo chmod 700 /etc/httpd/conf/ssl.key
sudo cp ~/crt/server.key /etc/httpd/conf/ssl.key
sudo chmod 600 /etc/httpd/conf/ssl.key
sudo mkdir /etc/httpd/conf/ssl.crt
sudo cp ~/crt/server.crt /etc/httpd/conf/ssl.crt/server.crt

 

Apacheの設定と接続確認

ssl.confを編集し、ドキュメントルートの設定をコメントインします。

sudo vim /etc/httpd/conf.d/ssl.conf

さらに下記文を追記し、もともと設定されていた行はコメントアウトします。
SSLCertificateFile /etc/httpd/conf/ssl.crt/server.crt
SSLCertificateKeyFile /etc/httpd/conf/ssl.key/server.key

 

動作確認

これまでの設定が完了したらApacheを再起動してブラウザで確認します。

sudo systemctl restart httpd

 

正しく設定されていればパスフレーズの入力指示があります。

 

ブラウザで確認すると下図のようになります。

 

これは、自分で構築した認証局の情報がPCに登録されていないためです。認証局の公開鍵(ルート証明書Root certificate)をインポートすると、下図のようにアドレス欄が緑色になり、正常にページが表示されます。

 

検証ツールで確認すると、正常に証明書が当てられていることを確認できます。

 

 

 

まとめ

SELinuxとOpenSSH、https化の基本的な設定方法を学びました。自己認証によるhttps化はかなり手こずりましたが、無事解決できて良かったです。証明書に関しては、今後はLet’s encryptを利用して、実際に運営しているサイトに適用したいと考えています。

以上です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください