プロジェクト

全般

プロフィール

Apache mod autoindex » 履歴 » バージョン 5

sylow castle, 2019/11/13 22:09

1 5 sylow castle
# Apache mod autoindex
2 1 sylow castle
3
## 概要
4
5
あったことを適当に書いてく
6
7
## クライアント認証とOption Index
8
9
### やりたい事
10
11
- 特定ディレクトリにクライアント認証をかけたい
12 4 sylow castle
- https://example.com/ でアクセスしたときにapacheのインデックスページを出したい
13 1 sylow castle
14
### 設定状況
15
16
こんなディレクトリを持っていたとする:
17
18
- DocumentRoot
19
  - ClientVerifyDir
20
  - FooDir
21
  - BarDir
22
23
こんな設定だったりする:
24
25
- ディレクトリClientVerifyDirにクライアント認証をかけている
26
- ディレクトリDocumentRootにはクライアント認証をかけていない
27
- DocumentRootにOption +Indexがついている
28
- index.htmlとかはない
29
30
### 何が起きた
31
32 4 sylow castle
https://example.com/ でアクセスしたときにSSLのネゴシエーションに失敗する
33 1 sylow castle
34
エラーログはこんな感じ
35
36
```
37
SSL Library Error: error:140890C7:SSL routines:ssl3_get_client_certificate:peer did not return a certificate -- No CAs known to server for verification?
38
AH02261: Re-negotiation handshake failed
39
```
40
41
結構悩んだのでメモしとく
42
43
### 原因(推測)
44
45 2 sylow castle
1. https://example.com/にアクセス
46
1. インデックスページを生成しようとする
47
1. DocumentRootのエントリ「ClientVerifyDir」を読もうとする
48
1. 一方ClientVerifyDirを読むにはクライアント認証が必要
49 1 sylow castle
   アクセスしているDocumentRootはクライアント認証の提示をブラウザに要求していない
50 2 sylow castle
1. クライアント認証は失敗する
51 1 sylow castle
52
って感じなんだろうか。うーん、ディレクトリのread権限がなくて403 Forbidden的なしょぼいエラーと似ている気がする
53
54
### 対処
55
56
まず、ディレクトリ構造を変更
57
58
- DocumentRoot
59
  - SecretsDir
60
      - ClientVerifyDir
61
  - FooDir
62
  - BarDir
63
64
クライアント認証かけるディレクトリをSecretsDirより下のものたちに。
65
66
```
67 3 sylow castle
<Directory "DocumentRoot/SecretsDir/*">
68 1 sylow castle
    SSLVerifyClient require
69
</Directory>
70
```
71 4 sylow castle
72
-------
73
74
### ソースを読んでみた
75
76
もやもやを解消したくせっかくだしソースを読んでみた。
77
https://github.com/apache/httpd/blob/trunk/modules/generators/mod_autoindex.c
78
79
たぶんこの辺。「make_autoindex_entry」とかいういかにもディレクトリエントリのリンク作り出しそうな関数
80
81
82
```c
83
if ((autoindex_opts & SHOW_FORBIDDEN)
84
    && (rr->status == HTTP_UNAUTHORIZED || rr->status == HTTP_FORBIDDEN)) {
85
    show_forbidden = 1;
86
}
87
88
if ((rr->finfo.filetype != APR_DIR && rr->finfo.filetype != APR_REG)
89
    || !(rr->status == OK || ap_is_HTTP_SUCCESS(rr->status)
90
    || ap_is_HTTP_REDIRECT(rr->status)
91
    || show_forbidden == 1)) {
92
    ap_destroy_sub_req(rr);
93
    return (NULL);
94
}
95
```
96
97
以下、頭の中垂れ流し:
98
99
最初のifでたぶん、IndexOptionディレクティブのShowFobbidenのあたりを処理している。
100
if文の式を読むと「SHOW_FOBIDDENが立っていて、サブリクエストのステータスがUNAUTHORIZEDやFORBIDDENのとき」、フラグを立ててる。
101
このフラグが立っていると、下のif内の式第二項がfalseになると。なのでif文の中に突入するには、「ディレクトリでない かつ 通常のファイルでない」が成立すると。
102
で、このときNULL返してる、本来の返却値はentへのポインタなのでたぶん、エントリを作らなかった時にこのreturnなんだろう。
103
104
ここから逆に考えて、通常のファイルやディレクトリを表示しようとするときは第二項がfalseになる。
105
これはつまりサブリクエストがOKでないし、HTTPに成功もしてないし、リダイレクトでもないし、show_forbiddenが立ってない。
106
まぁ特に設定してない限りSHOW_FORBIDDENは0なのでいいや。
107
108
### 結論
109
110
うーん、つまりディレクトリエントリへのサブリクエストが成功しないと表示しないのね。
111
BASIC認証必要なディレクトリが出てきたり、出てこなかったりするのもこれでひとまず納得できる。
112
やっぱ表示していいディレクトリだけ出すようにmod_autoindexさんが辺制御してるということか。
113
114
ちゃんと読んでないけどたぶん合ってるだろう
115
116
## 参考
117
118
- mod_autoindex.c https://github.com/apache/httpd/blob/trunk/modules/generators/mod_autoindex.c
119
- mod_autoindexのディレクティブ https://httpd.apache.org/docs/2.4/en/mod/mod_autoindex.html#indexoptions
120
- サブリクエスト http://koseki.hatenablog.com/entry/20090921/ModDirRewrite