8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

rsyslogでのTLS(SSL)によるセキュアな送受信(暗号化のみ)

Last updated at Posted at 2020-03-10

はじめに

 この記事は、rsyslogでのTLS(SSL)によるセキュアな送受信 の関連記事になります。

 ここではsyslog通信の暗号化のみをしていきたいと思います。端末の認証はしません。そのため盗聴防止は出来るものの、成りすましは防げないという状態になります。

 検証環境は引き続き CentOS8 と Ubuntu(18.04)です。
 syslog送信側(クライアント):CentOS(rsyslog version 8.37.0), IP=192.168.0.15
 syslog受信側(サーバー):Ubuntu(rsyslog version 8.32.0), IP=192.168.0.13

#プライベートCA(認証局)の証明書の作成
 本来ならば正規のCAから発行された証明書を使用すべきですが、検証環境であることと、syslog転送という特定のホストから通信しか利用しないということから、プライベート認証局(CA)の証明書を利用することとします。いわゆるオレオレ証明書です。サーバー担当のUbuntuが認証局(CA)を兼ねる構成です。

 今回は、certtoolを使って証明書を作成していくためインストールします。
###Ubuntuの場合

$ sudo apt-get install gnutls-utils

###CentOSの場合

$ sudo yum install gnutls-utils

 certtoolのドキュメントはこちらになります。:4.2.6 Invoking certtool
 helpやmanコマンドも可能ですが英語なので、上記をGoogle翻訳した方が手っ取り早いんじゃないかなと思います。

$ certtool --help
$ man certtool

プライベートCAの秘密鍵の作成

 サーバー担当のUbuntu端末で、cert というフォルダを作り、そこにプライベートCAの秘密鍵を作成します。
 秘密鍵や証明書は重要情報なため、root でしか扱えないよう sudo コマンドで作っていきます。(sudo を付けずに作成して、あとで chown で変更をかけてもいいとは思いますが)

$ sudo certtool --generate-privkey --outfile ca-key.pem

image.png

プライベートCAの証明書の作成

 次に作成した秘密鍵を使って、証明書を作成していきます。

$ sudo certtool --generate-self-signed --load-privkey ca-key.pem --outfile ca.pem

 このコマンドを実行すると、組織名やサーバー名などが要求されます。
 本来であれば正式な情報を入力すべきですが、プライベートCAということもあり、こちらのドキュメントを参考に適当に入力していきます。:Setting up the CA

 今回、使用した入力値は次の通りです。

Common name: SomeName
Organization unit name: SomeOU
Organization name: SomeOrg
Locality name: Chiyoda-ku
State or province name: Tokyo
Country name(2 chars): JP
   # 途中は全て未入力Enterで進めていく
The certificate will expire in(days): 3650
   # 有効期限はおよそ10年くらいでいいでしょう。

image.png

 Extentions. の項目は、[Does the certificate belong to an authority?]だけ y にしてあとは全部デフォルト設定で実施していきます。
ca-pemEx.png

 「Is the above information ok? (y/N):」と最終確認されるので、y と入力して証明書を生成します。
ca-pemOK.png

 ca-key.pem と ca.pem が作成されていることを確認します。
ca-files.png

#サーバーの秘密鍵、CSR、そして証明書の作成
 ここからはサーバーの証明書を作成してきます。手順は次の通りです。

1. 端末上で秘密鍵を作成する
2. 秘密鍵を元に証明書署名要求:CSRを作成し、認証局(CA)に送る
3. 認証局(CA)はCSRから証明書を作成し、端末に送り返す

 この検証環境においては、サーバーと認証局(CA)が同じ端末になるので、連続して処理を行っていきます。

##秘密鍵の作成

$ sudo certtool --generate-privkey --outfile server-key.pem

image.png

##CSRの作成
 秘密鍵を使って、証明書署名要求:CSR(Certificate Signing Request)を作成します。

$ sudo certtool --generate-request --load-privkey server-key.pem --outfile server-request.pem

 今回も様々な情報を求められますが、これもこちらのドキュメントを参考にして作成していきます。:Generating the machine certificate

 ここで重要なのはCommon name です。ホストがDNS登録されている場合はそちらを使用します。使用していない場合でも FQDN形式のホスト名を使用する必要があるようです。

Common name: server.example.jp
Organization unit name: SomeOU
Organization name: SomeOrg
Locality name: Chiyoda-ku
State or province name: Tokyo
Country name(2 chars): JP
   # 途中はすべてデフォルト値
Is this a TLS web client certificate? (y/N): y
Is this also a TLS web server certificate? (y/N): y

image.png

##証明書の作成
 ここからは認証局(CA)のパートです。
 CSRが出来たので(本来ならば送られてくるものだが)、サーバーの証明書を作成していきます。
 実行前に、次のファイルが揃っていることを確認してください。

  • server-request.pem
  • ca.pem
  • ca-key.pem
$ sudo certtool --generate-certificate --load-request server-request.pem --outfile server-cert.pem --load-ca-certificate ca.pem --load-ca-privkey ca-key.pem

期限を聞かれるので3600日としておきます。
(CAの期限を3650日としたので、それより少ない日が良かろうという意味)

The certificate will expire in (days): 3600

image.png

 拡張の箇所は、今回は次の通りにします。DNS Nameの設定には、サーバーのCSRの作成時のCommon name で使用したのと同じ値を入力します。検証環境にはDNSはないので自分のIPアドレスも設定しておきました。(参考にしたドキュメントにはここは設定されていませんが、正確な情報はあった方がいいかなと思って) 今回の検証環境の場合は 192.168.0.13 です。

Does the certificate belong to an authority?(y/N): n
Is this a TLS web client certificate? (y/N): y
(略)
Is this a TLS web server certificate? (y/N): y
Enter the dnsName of the subject of the certificate: server.example.jp
Enter the IP address of the subject of the certificate: [自身のIPアドレス]

image.png

 「Is the above information ok? (y/N):」と最終確認されるので、y と入力します。
 これでサーバー証明書が作成されます。

server-certOK.png

 server-cert.pemが存在していたら成功です。
server-files.png

#各端末への証明書の送付
 認証局(CA)で作成した証明書は、各端末に送らなければなりません。
 ただ今回はサーバーと認証局は同じ端末ですので、クライアント端末のみへの送付になります。
 送付するファイルはca.pemだけです。

  • 受信側(サーバー)&認証局(CA)の方:Ubuntu

  • ca-key.pem

  • ca.pem

  • server-cert.pem

  • server-key.pem

  • 送信側(クライアント)の方:CentOS

  • ca.pem

鍵と証明書用のディレクトリ作成と移動

 サーバー側、クライアント側の両方で、root権限にてrsyslog.dの配下に tls というフォルダを作成して、そこに鍵と証明書を移動させます。

サーバー側の設定

受信側(サーバー)
$ sudo mkdir /etc/rsyslog.d/tls

$ sudo mv ca.pem /etc/rsyslog.d/tls
$ sudo mv server-cert.pem /etc/rsyslog.d/tls
$ sudo mv server-key.pem /etc/rsyslog.d/tls

 権限の確認を行います。
image.png

クライアント側の設定

 送信側(クライアント)に移動した直後のファイルは、移動したアカウントの権限になっているので、これをroot権限に変更してから移動します。

移動したばかりの ca.pemの権限:
image.png

送信側(クライアント)
$ sudo chown root:root ca.pem
$ sudo chmod 644 ca.pem
$ sudo mkdir /etc/rsyslog.d/tls
$ sudo mv ca.pem /etc/rsyslog.d/tls

image.png

 権限の確認を行います。
image.png

lmnsd_gtlsモジュールのインストール

 rsyslogのTLS転送を行うためには、拡張モジュールlmnsd_gtls が必要になりますので、双方の端末でインストールします。
###Ubuntuの場合

$ sudo apt-get install rsyslog-gnutls

###CentOSの場合

$ sudo yum install rsyslog-gnutls

rsyslogの設定

サーバー側のrsyslogの設定

 imtcpのmodule についてTLS化を使用するための設定を追加します。
 前項で移動させた鍵や証明書を参照できるようにしておきます。ここではAuthmode="anon"として、クライアント認証を行わないモードとします。

module(
 load="imtcp"
 StreamDriver.Name="gtls"
 StreamDriver.Mode="1"
 StreamDriver.Authmode="anon"
)

input(type="imtcp" port="514")

global(
 DefaultNetstreamDriver="gtls"
 DefaultNetstreamDriverCAFile="/etc/rsyslog.d/tls/ca.pem"
 DefaultNetstreamDriverCertFile="/etc/rsyslog.d/tls/server-cert.pem"
 DefaultNetstreamDriverKeyFile="/etc/rsyslog.d/tls/server-key.pem"
)

image.png
image.png

 再起動を行い、問題が発生していないか確認しておきましょう。

$ sudo systemctl restart rsyslog.service
$ sudo systemctl status rsyslog.service

 参考までに、問題が発生していると、たとえば次のようなエラーが出ています。
 これは40行目の前にエラーがあるよ、という意味です。
image.png

クライアント側のrsyslogの設定

 クライアント側についても設定変更していきます。サーバー側の設定と合わせるように、Port番号やクライアント認証の設定を行います。
 変更箇所は認証ファイルの設定と転送設定です。前回の転送設定が残っていたらば削除しておきましょう。


global(DefaultNetstreamDriverCAFile="/etc/rsyslog.d/tls/ca.pem")

action(type="omfwd" protocol="tcp" port="514"
       Target="192.168.0.13"
       StreamDriver="gtls"
       StreamDriverMode="1"
       StreamDriverAuthMode="anon")

# *.*    @@192.168.0.13 ←この設定が残っていたならば削除

image.png

image.png

2020年04月01日追記
 ここで転送の書き方を Basic からAdvanced に変えています。書き方が異なるのはそのためです。
 $(ドル)記号で始まって一行で書く設定方法もありますが、それは obsolete legacy ということで非推奨です。
 また、Advanced で、ファシリティとシビアリティを指定するには、action の前で指定します。

ファシリティがmail、.シビアリティは全ての指定の場合
mail.* action(type="omfwd" protocol="tcp" port="514"
       Target="192.168.0.13"
       StreamDriver="gtls"
       StreamDriverMode="1"
       StreamDriverAuthMode="anon")

詳しくはこちらをご覧ください。
Configuration Formats
https://www.rsyslog.com/doc/v8-stable/configuration/conf_formats.html


 再起動を行い、問題が発生していないか確認しておきましょう。

$ sudo systemctl restart rsyslog.service
$ sudo systemctl status rsyslog.service

送信側のエラー発生と是正措置

 これで問題ないはずなのですが、私の検証環境では ca.pemに対しての Permission denied が発生して上手く行きませんでした。

image.png

 権限も問題ないはず。
image.png

 ログを見ると、SELinuxがブロックしている。

$ tail /var/log/messages | grep rsyslogd

image.png

 はい。オフ。
(本当はちゃんと許可してあげるべきですが検証環境なので…)
image.png

サーバー側のエラー発生と是正措置

 ここで送信側(クライアント)から syslog 転送を行ってみます。logger で発生させてもいいですし、全ログ転送になっていた場合、少し待てば発生するでしょう。
 サーバー側のrsyslogのステータスを確認するとエラーを吐いていました。server-key.pem を読み込めなかった。権限がないとのこと。
image.png

 今回はSELinuxは邪魔していません。
 確かに、server-key.pem には root 以外に読み取り権限はありませんが、
image.png

 rsyslogってrootで動いているんじゃないの?と確認したところ、Ubuntuでは syslog ユーザーで動いているとのこと。
image.png
 所有者をsyslog にするか読み取り権限を追加するかのどちらかをする必要がありますが、出来ればよりセキュアな方がいいので、ここでは『最小権限の原則』に従ってsyslogユーザーに変更しておきます。

$ sudo chown syslog:syslog server-key.pem

image.png

 これで再起動してステータスを確認したところ問題はなくなりました。

Syslogの中身が見れないことの確認

 クライアント側からデータを送ってみましょう。
image.png

 無事に受信できていることが確認できました。
image.png
 
 パケットを確認しても中身が確認できないことが分かります。
image.png

 これでsyslogの転送がよりセキュアになりました。

参考

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?