Apache と NameVirtualHost と HTTPS

Apache には NameVirtualHost という、HTTP Header の Hostの値によって、 返すコンテンツを変えることができる機能があります。

使い方は例えば

<VirtualHost *:80>
ServerName  test1.localhost:80
DocumentRoot /var/www/test1/
</VirtualHost>

<VirtualHost *:80>
ServerName  test2.localhost:80
DocumentRoot /var/www/test2/
</VirtualHost>

こんな風に。

HTTPS対応したいときは

<VirtualHost *:443>
ServerName  test1.localhost:443
SSLCertificateFile /etc/httpd/conf/server1.crt
SSLCertificateKeyFile /etc/httpd/conf/server1.key
DocumentRoot /var/www/test1/
</VirtualHost>

<VirtualHost *:443>
ServerName  test2.localhost:443
SSLCertificateFile /etc/httpd/conf/server2.crt
SSLCertificateKeyFile /etc/httpd/conf/server2.key
DocumentRoot /var/www/test2/
</VirtualHost>

こう。

コンテンツを試しに

cat /var/www/test1/index.html
test1
cat /var/www/test2/index.html
test2

おいてみます。

早速curl と opensslでアクセスしてみましょう。

> curl http://127.0.0.1/
test1

> curl http://127.0.0.1/ -H"Host: test1.localhost"
test1

> curl http://127.0.0.1/ -H"Host: test2.localhost"
test2
> curl http://test1.localhost/
test1

> curl http://test1.localhost/ -H"Host: test1.localhost"
test1

> curl http://test1.localhost/ -H"Host: test2.localhost"
test2
> curl http://test2.localhost/
test2

> curl http://test2.localhost/ -H"Host: test1.localhost"
test1

> curl http://test2.localhost/ -H"Host: test2.localhost"
test2
  • Host に応じてコンテンツが返ってきます。
  • Host が一致しないと、最初に見つかったVirtualHostのコンテンツが返ってきます。

curl はHostヘッダを追加しないと、URLのホスト名をHostヘッダに入れます。

> openssl s_client -connect test1.localhost:443 
<test1のCertification>
GET / HTTP/1.1

HTTP/1.1 400 Bad Request

> openssl s_client -connect test2.localhost:443 
<test1のCertification>
GET / HTTP/1.1

HTTP/1.1 400 Bad Request
> openssl s_client -connect 127.0.0.1:443 
<test1のCertification>
GET / HTTP/1.1

HTTP/1.1 400 Bad Request

> openssl s_client -connect 127.0.0.1:443 
<test1のCertification>
GET / HTTP/1.1
Host: test1.localhost

HTTP/1.1 200 OK
test1

> openssl s_client -connect 127.0.0.1:443 
<test1のCertification>
GET / HTTP/1.1
Host: test2.localhost

HTTP/1.1 200 OK
test2
> openssl s_client -connect 127.0.0.1:443 -servername test1.localhost
<test1のCertification>
GET / HTTP/1.1

HTTP/1.1 400 Bad Request

> openssl s_client -connect 127.0.0.1:443 -servername test1.localhost
<test1のCertification>
GET / HTTP/1.1
Host: test1.localhost

HTTP/1.1 200 OK
test1

> openssl s_client -connect 127.0.0.1:443 -servername test1.localhost
<test1のCertification>
GET / HTTP/1.1
Host: test2.localhost

HTTP/1.1 400 Bad Request
> openssl s_client -connect 127.0.0.1:443 -servername test2.localhost
<test2のCertification>
GET / HTTP/1.1

HTTP/1.1 400 Bad Request

> openssl s_client -connect 127.0.0.1:443 -servername test2.localhost
<test2のCertification>
GET / HTTP/1.1
Host: test1.localhost

HTTP/1.1 400 Bad Request

> openssl s_client -connect 127.0.0.1:443 -servername test2.localhost
<test2のCertification>
GET / HTTP/1.1
Host: test2.localhost

HTTP/1.1 200 OK
test2
  • servername を与えないと、最初に見つかったtset1.localhostの証明書を渡されますが、 Host ヘッダに応じて、帰ってくるコンテンツが変わります。
  • servername を与えると、Hostヘッダが一致しないとBad Requestが返ってきます。
  • そもそもHostヘッダがないとBad Requestが帰ってきます。

注 openssl はconnect でホスト名を指定しても servernameには使いません。

prometheus と remote_write と logging と

prometheus でデータ収集しつつ、 remote_write で influxdb にデータを貯めるという実験を行っています。

マシンのディスク容量が小さいこともあるのですが、短期間で予想以上のディスク容量を消費していたので確認して見たところ、 ログファイルが肥大していました。

そこで、ログの出力元を確認したところ、いくつかの原因が判明しました。

  • prometheus

コマンドライン引数でログレベルが設定できますが、何も設定しないと infoになっている。 --log.level=warn に変えて様子見

  • remote_storage_adapter

main.goファイルを見るとわかるのですが、ログレベルがdebugに指定されている。 info に変えて go build

  • influxdb

コンフィグファイルを見ると書いてあるのですが HTTP requestは標準で enable # Determines whether HTTP request logging is enabled.なので

[http]
log-enabled = false

へ変更。

とりあえずこれで出力されるログの量がぐっと減ります。

トラブル時には一時的に変更する必要が有るかと思いますが、普段はこのくらいで良いのではないかと思います。 もちろん、出力を減らさず、ログをきちんと運用するようにすれば良いのですが。

まだ遊んでいる段階なので頑張りは適度に。

CentOS7 rsyslogとelasticsearch output plugin でエラーが出た

rsyslogにはelasticsearchへそのまま出力するプラグイン用意されています。

用意されているのですが、CentOS7(1708)標準のリポジトリにあるものは 8.24.0と若干古く、Elasticsearch側のバージョンが新しい(6以上)と、正常に出力できません。

デバッグ出力をonにしてみるとわかるのですが、 プラグイン

Content-type: text/json

でElasticsearchへ向けて出力しており、

Content-type: application/json

でないと受け付けてくれないからです。

Merge pull request #1698 from wdauchy/es_contenttype · rsyslog/rsyslog@a25573f · GitHub

Merge pull request #1743 from wdauchy/es_contenttype_bulk · rsyslog/rsyslog@9cb5c17 · GitHub

このあたりでContent-typeに関する修正がなされています。

ですので 8.29.0もしくは8.30.0以上でないと正常に出力できないと思われます。

最新のrsyslogをインストールする方法はオフィシャルサイト に記載がありますが、

repoファイル を /etc/yum.repos.d/ へ配置し、 yum install rsyslog-elasticsearch によってインストールできます。