Mac OS X (10.4.11) では apache 1.3.33 がプリインストールされている。
$ httpd -v Server version: Apache/1.3.33 (Darwin) Server built: Jul 1 2006 15:59:38
このapacheの起動停止は [システム環境設定]-[共有] の [サービス] で、パーソナルWeb共有 を選択して「開始」(または「停止」)で起動状態を変更することができる。これを利用しつつ、apacheを新しい2.2系にUpgradeする方法[1]。
$ tar -zxvf httpd-2.2.17.tar.gz
既存のapache1.3に付随するモジュール類は /usr/libexec/httpd
にある。ここに含まれるモジュールには (1)Apacheに付随するもの (2)他のベンダーから提供されたもの(mod_php、mod_perlなど) (3)Apple社が提供するもの(mod_bonjour、mod_hfs_apple) がある。(2) についてはapacheインストール時に一緒にUpgradeしてくれないので別途自身で用意、インストールが必要。(3) についても同様。AppleのHPを見て自身で解決が必要。
以下の例では、全てのモジュールを有効にし、それらのモジュールは可能な限りdynamic objectとする。インストール先ディレクトリの指定がないと、デフォルトの /usr/local/apache2
にインストールされる。
$ ./configure --enable-modules=all --enable-mods-shared=all --enable-static-support
./configure
--enable-modules=all
--enable-mods-shared=all
--enable-static-support
make
を実行。Step 3.でUpdateしていないと「No debug map or DWARF data was found to link」エラーが出る?
sudo make install
を実行。
/usr/local/apache2/conf/httpd.conf
を編集し、apache の実行ユーザ・グループをどちらも「www」にする。Mac OSにプリインストールされているapacheのユーザ・グループがこうなっているので、これに合わせておいた方が、アクセス権限上の問題を避ける上で良いと思われる。
User daemon Group daemon ↓ User www Group www
/usr/local/apache2/conf/httpd.conf
に以下の記述を追記。
PidFile /private/var/run/httpd.pid
/etc/httpd/
に、新たにインストールしたapacheの設定ファイル群はデフォルトの設定では /usr/local/apache2/conf
に置かれている。必要に応じて新apacheの設定へ移行を行う。
[/usr/local/apache2/conf/httpd.conf] CustomLog "logs/access_log" common ErrorLog "logs/error_log" ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/" ↓ CustomLog "/private/var/log/httpd/access_log" common ErrorLog "/private/var/log/httpd/error_log" ScriptAlias /cgi-bin/ "/Library/WebServer/CGI-Executables/"
$ cd /usr/sbin/ $ ls -l apachectl -rwxr-xr-x 1 root wheel 5281 2 23 2008 apachectl $ sudo mv apachectl apachectl-1.3 Password: # ユーザパスワードを入力 $ sudo ln -s /usr/local/apache2/bin/apachectl apachectl $ ls -l apachectl* lrwxr-xr-x 1 root wheel 32 4 13 08:58 apachectl -> /usr/local/apache2/bin/apachectl -rwxr-xr-x 1 root wheel 5281 2 23 2008 apachectl-1.3
Mac OS X 10.4の場合と同様。但し異なる点は以下の通り。
システムによるapache起動で適用されるapacheの設定は 10.6 (snow leopard) の場合 /private/etc/apache2/httpd.conf
。別途インストールしたapacheの設定ファイル(/usr/local/apache2/httpd/conf/httpd.conf
)を適用したければ、/private/etc/apache2/httpd.conf
のバックアップを取った上で、新たにインストールしたapache設定ファイルのシンボリックリンクで上書きする。
$ cd /private/etc/apache2/ $ ls -l httpd.conf -rw-r--r-- 1 root wheel 17817 2 11 09:31 httpd.conf $ sudo cp httpd.conf original/httpd.conf.bak_20100211 $ sudo ln -sf /usr/local/apache2/conf/httpd.conf /private/etc/apache2/httpd.conf $ ls -l httpd.conf lrwxr-xr-x 1 root wheel 34 8 22 09:32 httpd.conf@ -> /usr/local/apache2/conf/httpd.conf
Ubuntu 10.04 LTS で、apache2 を 「Ubuntuソフトウェアセンター」または「Synaptic パッケージ・マネージャ」で apache2 をインストールした場合、ファイルの配置等がソースやRPMパッケージからインストールした場合とは異なる。詳細は設定ファイル参照。
Apache 2.0.64のtarballをダウンロードし、同梱されているhttpd.spec
でrpmbuildするとうまく行かない。以下試行錯誤の記録。
→ある脆弱性対策でUpgradeしようとしていたが、2.0.64「以下」で脆弱性あり。つまり現在(2012/7/27)時点で最新の2.0系にUpgradeしても対策になってないってこと。この努力はあまり意味がなかったかも知れない(^^;
httpd.spec
中に記述されているSerial: 1
をコメントアウト(または削除)。古いタイプの記述で使用不可とのエラーが出るので。
httpd.spec
中に記述されているapr-config
を全てapr-1-config
に、apu-config
を全てapu-1-config
にそれぞれ修正。
httpd-2.0.64/servers/util_md5.c
に以下の記述を追記(変数が未宣言であるというエラーが出るので)[4]。
... #include "util_ebcdic.h" #-- 追記ここから #define APR_MD5_DIGESTSIZE 16 #define MD5_DIGESTSIZE APR_MD5_DIGESTSIZE #-- 追記ここまで AP_DECLARE(char *) ap_md5_binary(apr_pool_t *p, const unsigned char *buf, int length) ...
httpd-2.0.64/servers/config.c
に以下の記述を追記(変数が未宣言であるというエラーが出るので)[5]。
... #include "mpm.h" #-- 追記ここから #define APR_FNM_PERIOD 0x04 #define FNM_PERIOD APR_FNM_PERIOD #-- 追記ここまで AP_DECLARE_DATA const char *ap_server_argv0 = NULL; ...
[$SOURCE/server/rfc1413.c] 100: if ((rv = apr_socket_create(newsock, 101: localsa->family, /* has to match */ 102: SOCK_STREAM, conn->pool)) != APR_SUCCESS) { 102: SOCK_STREAM, APR_PROTO_TCP, conn->pool)) != APR_SUCCESS) { 103: ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, 104: "rfc1413: error creating query socket"); 105: return rv; 106: } [$SOURCE/server/listen.c] 228: if ((sock_rv = apr_socket_create(&tmp_sock, APR_INET6, SOCK_STREAM, p)) 228: if ((sock_rv = apr_socket_create(&tmp_sock, APR_INET6, SOCK_STREAM, APR_PROTO_TCP, p)) 229: == APR_SUCCESS && 230: apr_sockaddr_info_get(&sa, NULL, APR_INET6, 0, 0, p) == APR_SUCCESS && 231: apr_bind(tmp_sock, sa) == APR_SUCCESS) { 232: default_family = APR_INET6; 233: } 299: if ((status = apr_socket_create(&new->sd, 300: new->bind_addr->family, 301: SOCK_STREAM, process->pool)) 301: SOCK_STREAM, APR_PROTO_TCP, process->pool)) 302: != APR_SUCCESS) { 303: ap_log_perror(APLOG_MARK, APLOG_CRIT, status, process->pool, 304: "alloc_listener: failed to get a socket for %s", addr); 305: return "Listen setup failed"; 306: } [$SOURCE/server/mpm_common.c] 548: rv = apr_socket_create(&sock, ap_listeners->bind_addr->family, SOCK_STREAM, p); 548: rv = apr_socket_create(&sock, ap_listeners->bind_addr->family, SOCK_STREAM, APR_PROTO_TCP, p); [$SOURCE/support/ab.c] 1206: 1207: if ((rv = apr_socket_create(&c->aprsock, destsa->family, 1208: SOCK_STREAM, c->ctx)) != APR_SUCCESS) { 1208: SOCK_STREAM, APR_PROTO_TCP, c->ctx)) != APR_SUCCESS) { 1209: apr_err("socket", rv); 1210: } [$SOURCE/modules/proxy/proxy_util.c] 1058 apr_status_t rv; 1059 int connected = 0; 1060 int loglevel; 1061 1062 while (backend_addr && !connected) { 1063 if ((rv = apr_socket_create(newsock, backend_addr->family, 1064 SOCK_STREAM, p)) != APR_SUCCESS) { 1064 SOCK_STREAM, 0, p)) != APR_SUCCESS) { 1065 loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; [$SOURCE/modules/proxy/proxy_ftp.c] 960 /* try each IP address until we connect successfully */ 961 { 962 int failed = 1; 963 while (connect_addr) { 964 965 if ((rv = apr_socket_create(&sock, connect_addr->family, SOCK_STREAM, r->pool)) != APR_SUCCESS) { 965 if ((rv = apr_socket_create(&sock, connect_addr->family, SOCK_STREAM, 0, r->pool)) != APR_SUCCESS) { 966 ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, 1272 "proxy: FTP: EPSV contacting remote host on port %d", 1273 data_port); 1274 1275 if ((rv = apr_socket_create(&data_sock, connect_addr->family, SOCK_STREAM, r->pool)) != APR_SUCCESS) { 1275 if ((rv = apr_socket_create(&data_sock, connect_addr->family, SOCK_STREAM, 0, r->pool)) != APR_SUCCESS) { 1276 ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, 1355 "proxy: FTP: PASV contacting host %d.%d.%d.%d:%d", 1356 h3, h2, h1, h0, pasvport); 1357 1358 if ((rv = apr_socket_create(&data_sock, connect_addr->family, SOCK_STREAM, r->pool)) != APR_SUCCESS) { 1358 if ((rv = apr_socket_create(&data_sock, connect_addr->family, SOCK_STREAM, 0, r->pool)) != APR_SUCCESS) { 1359 ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, 1395 unsigned int h0, h1, h2, h3, p0, p1; 1396 1397 if ((rv = apr_socket_create(&local_sock, connect_addr->family, SOCK_STREAM, r->pool)) ! = APR_SUCCESS) { 1397 if ((rv = apr_socket_create(&local_sock, connect_addr->family, SOCK_STREAM, 0, r->pool)) ! = APR_SUCCESS) { 1398 ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
$SOURCE/server/util_xml.c 27: /* used for reading input blocks */ 28: #define READ_BLOCKSIZE 204828: 29: #define APR_BRIGADE_FOREACH(e, b) APR_RING_FOREACH((e), &(b)->list, apr_bucket, link) $SOURCE/server/core.c 64: #ifndef AP_MAX_INCLUDE_DEPTH 65: #define AP_MAX_INCLUDE_DEPTH (128) 66: #endif 67: 68: #define APR_BRIGADE_FOREACH(e, b) APR_RING_FOREACH((e), &(b)->list, apr_bucket, link) $SOURCE/server/protocol.c 56: #if APR_HAVE_UNISTD_H 57: #include <unistd.h> 58: #endif 59: 60: #define APR_BRIGADE_FOREACH(e, b) APR_RING_FOREACH((e), &(b)->list, apr_bucket, link) 61: 62: APR_HOOK_STRUCT( $SOURCE/modules/http/http_core.c 36: #include "mod_core.h" 37: 38 #define APR_BRIGADE_FOREACH(e, b) APR_RING_FOREACH((e), &(b)->list, apr_bucket, link) 39: 40: /* Handles for core filters */ $SOURCE/modules/http/http_protocol.c 59: #endif 60: 61:#define APR_BRIGADE_FOREACH(e, b) APR_RING_FOREACH((e), &(b)->list, apr_bucket, link) 62: 63: /* New Apache routine to map status codes into array indicies
$SOURCE/server/request.c 51: #endif 52: #define APR_FNM_PATHNAME 0x02 53: #define FNM_PATHNAME APR_FNM_PATHNAME
$SOURCE/include/ap_compat.h 20: /* Drag in apu (and therefore apr) renamed symbols */ 21: /* #include "apu_compat.h" */
/usr/src/redhat/BUILD/httpd-2.0.64/support/ab.c:911: undefined reference to `sqrt'
/usr/src/redhat/BUILD/httpd-2.0.64/support/ab.c:913: undefined reference to `sqrt'
/usr/src/redhat/BUILD/httpd-2.0.64/support/ab.c:912: undefined reference to `sqrt'
/usr/src/redhat/BUILD/httpd-2.0.64/support/ab.c:914: undefined reference to `sqrt'
↓
[httpd.spec]
310 dnl ## Check for library functions
311 #== added from httpd.spec of httpd 2.2.21 line 402-409 Start
312 AC_SEARCH_LIBS(sqrt, m)
313
314 saved_LIBS="$LIBS"
315 LIBS=""
316 AC_SEARCH_LIBS(crypt, crypt)
317 CRYPT_LIBS="$LIBS"
318 APACHE_SUBST(CRYPT_LIBS)
319 LIBS="$saved_LIBS"
320 #== added from httpd.spec of httpd 2.2.21 line 402-409 End
321
322 dnl See Comment #Spoon
modules/aaa/mod_auth_digest.c
にて変数MD5_DIGESTSIZE
が未定義→定義追加[10]
83 #undef APR_HAS_SHARED_MEMORY
84 #define APR_HAS_SHARED_MEMORY 0
85 #define APR_MD5_DIGESTSIZE 16
86 #define MD5_DIGESTSIZE APR_MD5_DIGESTSIZE
87
88 /* struct to hold the configuration info */
apr_proc_other_child_read
関数が未定義→Deprecated、httpd-2.2.21ソース内同名ファイルの内容を参考に関数名変更[11]
[$SOURCE/server/mpm/prefork/prefork.c] 1004 #if APR_HAS_OTHER_CHILD 1005 } 1006 else if (apr_proc_other_child_read(&pid, status) == 0) { 1006 else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH, status) == APR_SUCCE SS) { 1007 1008 /* handled */
apr_lstat
関数が未定義→Deprecated、httpd-2.2.21のソース内同名ファイルの内容を参考に関数定義変更[12]
[$SOURCE/server/config.c] 1544 apr_finfo_t finfo; 1545 1546 if (apr_lstat(&finfo, fname, APR_FINFO_TYPE, p) != APR_SUCCESS) 1546 if (apr_stat(&finfo, fname, APR_FINFO_LINK | APR_FINFO_TYPE, p) != APR_SUCCESS) 1547 return; 1547 return NULL; [$SOURCE/server/util.c] 1924 apr_finfo_t finfo; 1925 1926 if (apr_lstat(&finfo, path, APR_FINFO_TYPE, p) != APR_SUCCESS) 1926 if (apr_stat(&finfo, path, APR_FINFO_TYPE, p) != APR_SUCCESS) 1927 return 0; /* in error condition, just return no */ [$SOURCE/server/request.c] 380 if (!(lfi->valid & APR_FINFO_OWNER)) { 381 if ((res = apr_lstat(&fi, d, lfi->valid | APR_FINFO_OWNER, p)) 381 if ((res = apr_stat(lfi, d, 381.1 lfi->valid | APR_FINFO_LINK | APR_FINFO_OWNER, p)) 382 != APR_SUCCESS) { 940 /* We choose apr_lstat here, rather that apr_stat, so that we 941 * capture this path object rather than its target. We will 942 * replace the info with our target's info below. We especially 943 * want the name of this 'link' object, not the name of its 944 * target, if we are fixing the filename case/resolving aliases. 945 */ 946 rv = apr_lstat(&thisinfo, r->filename, 947 APR_FINFO_MIN | APR_FINFO_NAME, r->pool); 940 /* We choose apr_stat with flag APR_FINFO_LINK here, rather that 941 * plain apr_stat, so that we capture this path object rather than 942 * its target. We will replace the info with our target's info 943 * below. We especially want the name of this 'link' object, not 944 * the name of its target, if we are fixing the filename 944.1 * case/resolving aliases. 945 */ 946 rv = apr_stat(&thisinfo, r->filename, 947 APR_FINFO_MIN | APR_FINFO_NAME | APR_FINFO_LINK, 947.1 r->pool); 948 949 if (APR_STATUS_IS_ENOENT(rv)) { 1695 rnew->finfo.filetype = 0; 1696 } 1697 } 1698 else { 1699 if (((rv = apr_lstat(&rnew->finfo, rnew->filename, 1700 APR_FINFO_MIN, rnew->pool)) != APR_SUCCESS) 1699 if (((rv = apr_stat(&rnew->finfo, rnew->filename, 1700 APR_FINFO_LINK | APR_FINFO_MIN, 1700.1 rnew->pool)) != APR_SUCCESS) 1701 && (rv != APR_INCOMPLETE)) { 1800 rnew->finfo.filetype = 0; 1801 } 1802 } 1803 else { 1804 if (((rv = apr_lstat(&rnew->finfo, rnew->filename, 1805 APR_FINFO_MIN, rnew->pool)) != APR_SUCCESS) 1804 if (((rv = apr_stat(&rnew->finfo, rnew->filename, 1805 APR_FINFO_LINK | APR_FINFO_MIN, 1805.1 rnew->pool)) != APR_SUCCESS) 1806 && (rv != APR_INCOMPLETE)) {
apr_sockaddr_port_get
関数が未定義→Deprecated、httpd-2.2.21のソース内同名ファイルの内容を参考に関数定義変更[6]
[$SOURCE/server/vhost.c] 875 last_s = NULL; 876 877 apr_sockaddr_port_get(&port, r->connection->local_addr); 877 port = r->connection->local_addr->port; 878 879 /* Recall that the name_chain is a list of server_addr_recs, some of 931 apr_port_t port; 932 933 apr_sockaddr_port_get(&port, r->connection->local_addr); 933 port = r->connection->local_addr->port; 934 935 /* 936 * This is in conjunction with the ServerPath code in http_core, so we 1057 * matching this port 1058 */ 1059 apr_sockaddr_port_get(&port, conn->local_addr); 1059 port = conn->local_addr->port; 1060 1061 trav = find_default_server(port); [$SOURCE/server/listen.c] 251 apr_port_t oldport; 252 apr_sockaddr_t *sa; 252.1 int found_listener = 0; 271 /* see if we've got an old listener for this address:port */ 272 for (walk = &old_listeners; *walk; walk = &(*walk)->next) { 272 for (walk = &old_listeners; *walk;) { 273 sa = (*walk)->bind_addr; 274 /* Some listeners are not real so they will not have a bind_addr. */ 275 if (sa) { 276 apr_sockaddr_port_get(&oldport, sa); 276 ap_listen_rec *new; 276.1 apr_port_t oldport; 276.2 276.3 oldport = sa->port; 276.4 /* If both ports are equivalent, then if their names are equivalent, 276.5 * then we will re-use the existing record. 276.6 */ 277 if (!strcmp(sa->hostname, addr) && port == oldport) { 278 /* re-use existing record */ 277 if (port == oldport && 278 ((!addr && !sa->hostname) || 278.1 ((addr && sa->hostname) && !strcmp(sa->hostname, addr)))) { 279 new = *walk; 280 *walk = new->next; 281 new->next = ap_listeners; 282 ap_listeners = new; 282.1 found_listener = 1; 283 return NULL; 283 continue; 284 } 285 } 285.1 walk = &(*walk)->next; 286 } 286.1 286.2 if (found_listener) 286.3 return NULL; 286.4 } [$SOURCE/server/util_script.c] 240 apr_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */ 241 242 apr_sockaddr_port_get(&rport, c->remote_addr); 242 rport = c->remote_addr->port; 243 apr_table_addn(e, "REMOTE_PORT", apr_itoa(r->pool, rport)); [$SOURCE/server/rfc1413.c] 153 apr_size_t buflen; 154 155 apr_sockaddr_port_get(&sav_our_port, conn->local_addr); 155 sav_our_port = conn->local_addr->port; 156 apr_sockaddr_port_get(&sav_rmt_port, conn->remote_addr); 156 sav_rmt_port = conn->remote_addr->port; 157 158 /* send the data */
APR_STATUS_IS_SUCCESS
未定義→定義追加[13]
[$SOURCE/server/util_time.c] 17 #include "util_time.h" 18 19 #define APR_STATUS_IS_SUCCESS(s) ((s) == APR_SUCCESS) 20 /* Cache for exploded values of recent timestamps [$SOURCE/server/util_script.c] 54 #define MALFORMED_HEADER_LENGTH_TO_SHOW 30 54.1 #define APR_STATUS_IS_SUCCESS(s) ((s) == APR_SUCCESS) 55 56 static char *http2env(apr_pool_t *a, const char *w)
apr_shutdown
、apr_recv
関数が未定義→Deprecated、httpd-2.2.21のhttpd.specを参考に関数定義変更[6]
[$SOURCE/server/connection.c] 98 AP_DECLARE(void) ap_lingering_close(conn_rec *c) 99 { 100 char dummybuf[512]; 101 apr_size_t nbytes = sizeof(dummybuf); 102 apr_status_t rc; 103 apr_int32_t timeout; 133 * to the peer. 134 */ 135 if (apr_shutdown(csd, APR_SHUTDOWN_WRITE) != APR_SUCCESS 135 if (apr_socket_shutdown(csd, APR_SHUTDOWN_WRITE) != APR_SUCCESS 136 || c->aborted) { 150 nbytes = sizeof(dummybuf); 151 rc = apr_recv(csd, dummybuf, &nbytes); 152 if (rc != APR_SUCCESS || nbytes == 0) 151 if (apr_socket_recv(csd, dummybuf, &nbytes) || nbytes == 0) 153 break;
apr_bind
、apr_listen
、apr_connect
、apr_sendv
、apr_sendfile
、apr_send
、apr_accept
、apr_recv
→Deprecated、apr_socket_bind
、apr_socket_listen
、apr_socket_connect
、apr_socket_sendv
、apr_socket_sendfile
、apr_socket_send
、apr_socket_accept
、apr_socket_recv
にそれぞれ関数名を変更[6]
[$SOURCE/support/ab.c] 724: #endif 725: e = (e>aprsock, r to `apr_send' + c->rwrote, &l); 725: e = (e>aprsock, r to `apr_socket_send' + c->rwrote, &l); 726: 727: /* 728: * Bail early on the most common case 729: */ 1215: c->start = apr_time_now(); 1216: if ((rv = apr_connect(c->aprsock, destsa)) != APR_SUCCESS) { 1216: if ((rv = apr_socket_connect(c->aprsock, destsa)) != APR_SUCCESS) { 1217: if (APR_STATUS_IS_EINPROGRESS(rv)) { 1235: if (bad++ > 10) { 1236: fprintf(stderr, 1237: "\nTest aborted after 10 failures\n\n"); 1238: apr_err("apr_connect()", rv); 1238: apr_err("apr_socket_connect()", rv); 1239: } 1710: if (c->state == STATE_CONNECTING) { 1711: apr_pollfd_t remove_pollfd; 1712: rv = apr_connect(c->aprsock, destsa); 1712: rv = apr_socket_connect(c->aprsock, destsa); 1713: remove_pollfd.desc_type = APR_POLL_SOCKET; 1719: if (bad++ > 10) { 1720: fprintf(stderr, 1721: "\nTest aborted after 10 failures\n\n"); 1722: apr_err("apr_connect()", rv); 1722: apr_err("apr_socket_connect()", rv); 1723: } 1724: c->state = STATE_UNCONNECTED; 1337: #endif 1338: status = apr_recv(c->aprsock, buffer, &r); 1338: status = apr_socket_recv(c->aprsock, buffer, &r); 1339: if (APR_STATUS_IS_EAGAIN(status)) 1350: * certain number of them before completely failing? -aaron */ 1351: apr_err("apr_recv", status); 1351: apr_err("apr_connect_recv", status); 1352: } [$SOURCE/server/listen.c] 135 #endif 136 137 if ((stat = apr_bind(s, server->bind_addr)) != APR_SUCCESS) { 137 if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) { 138 ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, 230 apr_sockaddr_info_get(&sa, NULL, APR_INET6, 0, 0, p) == APR_SUCCESS && 231 apr_bind(tmp_sock, sa) == APR_SUCCESS) { 231 apr_socket_bind(tmp_sock, sa) == APR_SUCCESS) { 232 default_family = APR_INET6; 142 return stat; 143 } 144 145 if ((stat = apr_listen(s, ap_listenbacklog)) != APR_SUCCESS) { 145 if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) { 146 ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, [$SOURCE/server/mpm_common.c] 566 return rv; 567 } 568 569 rv = apr_connect(sock, ap_listeners->bind_addr); 569 rv = apr_socket_connect(sock, ap_listeners->bind_addr); 570 if (rv != APR_SUCCESS) { [$SOURCE/server/core.c] 2929 while (bytes_written != len) { 2930 rv = apr_sendv(s, vec + i, nvec - i, &n); 2930 rv = apr_socket_sendv(s, vec + i, nvec - i, &n); 2931 bytes_written += n; 2991 apr_size_t tmplen = file_bytes_left; 2992 2993 rv = apr_sendfile(c->client_socket, fd, hdtr, &file_offset, &tmplen, 2993 rv = apr_socket_sendfile(c->client_socket, fd, hdtr, &file_offset, &tmplen, 2994 flags); 3103 bytes_sent = sendlen; 3104 rv = apr_send(c->client_socket, &buffer[o], &bytes_sent); 3104 rv = apr_socket_send(c->client_socket, &buffer[o], &bytes_sent); 3105 if (rv == APR_SUCCESS) { [$SOURCE/server/rfc1413.c] 124 125 if ((rv = apr_bind(*newsock, localsa)) != APR_SUCCESS) { 125 if ((rv = apr_socket_bind(*newsock, localsa)) != APR_SUCCESS) { 126 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv, 127 "rfc1413: Error binding query socket to local port"); 136 if ((rv = apr_connect(*newsock, destsa)) != APR_SUCCESS) { 136 if ((rv = apr_socket_connect(*newsock, destsa)) != APR_SUCCESS) { 137 apr_socket_close(*newsock); [$SOURCE/server/rfc1413.c] 167 apr_status_t status; 168 status = apr_send(sock, buffer+i, &j); 168 status = apr_socket_send(sock, buffer+i, &j); 169 if (status != APR_SUCCESS) { 193 apr_status_t status; 194 status = apr_recv(sock, buffer+i, &j); 194 status = apr_socket_recv(sock, buffer+i, &j); 195 if (status != APR_SUCCESS) { [$SOURCE/os/unix/unixd.c] 467 *accepted = NULL; 468 status = apr_accept(&csd, lr->sd, ptrans); 468 status = apr_socket_accept(&csd, lr->sd, ptrans); 469 if (status == APR_SUCCESS) { [$SOURCE/modules/proxy/proxy_connect.c] apr_send → apr_socket_send(6箇所) apr_recv → apr_socket_recv(1箇所) [$SOURCE/modules/proxy/proxy_http.c] apr_recv → apr_socket_recv(1箇所)
$SOURCE/modules/proxy/proxy_connect.c
のapr_poll_setup
、apr_poll_socket_add
、apr_poll_revents_get
→ Deprecated。httpd-2.2.21の$SOURCE/modules/proxy/mod_proxy_connect.c
を参考に修正。apr_poll
で第1引数に互換性がない書式が使われているエラーが出るので、同じくhttpd-2.2.21を参考に修正。[19]
[$SOURCE/modules/proxy/proxy_connect.c] 26 int ap_proxy_connect_canon(request_rec *r, char *url) 27 int ap_proxy_connect_handler(request_rec *r, proxy_server_conf *conf, 28 char *url, const char *proxyname, 29 apr_port_t proxyport); 67 /* canonicalise CONNECT URLs. */ 68 int ap_proxy_connect_canon(request_rec *r, char *url) 68 static int proxy_connect_canon(request_rec *r, char *url) 69 int ap_proxy_connect_canon(request_rec *r, char *url) 75 /* CONNECT handler */ 76 int ap_proxy_connect_handler(request_rec *r, proxy_server_conf *conf, 77 char *url, const char *proxyname, 78 apr_port_t proxyport) 76 static int proxy_connect_handler(request_rec *r, 76 proxy_server_conf *conf, 77 char *url, const char *proxyname, 78 apr_port_t proxyport) 91 int failed; 92 apr_pollfd_t *pollfd; 92 apr_pollset_t *pollset; 92.1 apr_pollfd_t pollfd; 92.2 const apr_pollfd_t *signalled; 93 apr_int32_t pollcnt, pi; 94 apr_int16_t pollevent; 95 apr_sockaddr_t *uri_addr, *connect_addr; 123 /* do a DNS lookup for the destination host */ 124 err = apr_sockaddr_info_get(&uri_addr, uri.hostname, APR_UNSPEC, uri.port, 0, p); 124.1 if (APR_SUCCESS != err) { 124.2 return ap_proxyerror(r, HTTP_BAD_GATEWAY, 124.3 apr_pstrcat(p, "DNS lookup failure for: ", 124.4 uri.hostname, NULL)); 124.5 } 125 126 /* are we connecting directly, or via a proxy? */ 258 /* 259 * Step Four: Handle Data Transfer 260 * 261 * Handle two way transfer of data over the socket (this is a tunnel). 262 */ 263 264 /* r->sent_bodyct = 1;*/ 265 266 if((rv = apr_poll_setup(&pollfd, 2, r->pool)) != APR_SUCCESS) 267 { 266 if ((rv = apr_pollset_create(&pollset, 2, r->pool, 0)) != APR_SUCCESS) { 268 apr_socket_close(sock); 269 ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, 270 "proxy: CONNECT: error apr_poll_setup()"); 271 return HTTP_INTERNAL_SERVER_ERROR; 272 } 273 274 /* Add client side to the poll */ 275 apr_poll_socket_add(pollfd, client_socket, APR_POLLIN); 275 pollfd.p = r->pool; 275.1 pollfd.desc_type = APR_POLL_SOCKET; 275.2 pollfd.reqevents = APR_POLLIN; 275.3 pollfd.desc.s = client_socket; 275.4 pollfd.client_data = NULL; 275.5 apr_pollset_add(pollset, &pollfd); 276 277 /* Add the server side to the poll */ 278 apr_poll_socket_add(pollfd, sock, APR_POLLIN); 278 pollfd.desc.s = sock; 278.1 apr_pollset_add(pollset, &pollfd); 281 /* ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: CONNECT: going to sleep (pol l)");*/ 282 if ((rv = apr_poll(pollfd, 2, &pollcnt, -1)) != APR_SUCCESS) 282 if ((rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled)) != APR_SUCCESS) { 282.1 if (APR_STATUS_IS_EINTR(rv)) { 282.2 continue; 282.3 } 283 { 284 apr_socket_close(sock); 285 ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy: CONNECT: error apr_poll()"); 286 return HTTP_INTERNAL_SERVER_ERROR; 287 } 288 /* ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, ... 346 break; 347 } 349 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, 350 "proxy: CONNECT: finished with poll() - cleaning up"); 351 352 /* 353 * Step Five: Clean Up 292 /* ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, 293 "proxy: CONNECT: woke from select(), i=%d", pollcnt);*/ 294 295 if (pollcnt) { 296 apr_poll_revents_get(&pollevent, sock, pollfd); 297 if (pollevent & APR_POLLIN) { 454 static void ap_proxy_connect_register_hook(apr_pool_t *p) 455 { 456 proxy_hook_scheme_handler(ap_proxy_connect_handler, NULL, NULL, APR_HOOK_MIDDLE); 457 proxy_hook_canon_handler(ap_proxy_connect_canon, NULL, NULL, APR_HOOK_MIDDLE); 458 }
apr_file_unset_inherit
→Deprecated、apr_file_inherit_unset
に関数名を変更[14]
[$SOURCE/server/apr_file_unset_inherit.c] 473 /* close these before exec. */ 474 apr_file_unset_inherit((*pod)->pod_in); 474 apr_file_inherit_unset((*pod)->pod_in); 475 apr_file_unset_inherit((*pod)->pod_out); 475 apr_file_inherit_unset((*pod)->pod_out); 476 477 return APR_SUCCESS;
apr_proc_other_child_check
→Deprecated、httpd-2.2.21のソース内同名ファイルの内容を参考にapr_proc_other_child_refresh_all
に関数名、引数等を変更[11]
[$SOURCE/server/apr_file_unset_inherit.c] 259 #if APR_HAS_OTHER_CHILD 260 apr_proc_other_child_check(); 260 apr_proc_other_child_refresh_all(APR_OC_REASON_RESTART); 261 #endif
apr_compare_users
→Deprecated、httpd-2.2.21のソース内同名ファイルの内容を参考にapr_uid_compare
を使った記述に修正[15]
[$SOURCE/server/request.c] 392 393 if (apr_compare_users(fi.user, lfi->user) != APR_SUCCESS) { 393 if (apr_uid_compare(fi.user, lfi->user) != APR_SUCCESS) { 394 return HTTP_FORBIDDEN; 395 } 396 397 /* Give back the target */
apr_filename_of_pathname
→Deprecated、apr_filepath_name_get
に関数名を修正[16]
[$SOURCE/server/util_script.c] 432 "Premature end of script headers: %s", 433 apr_filename_of_pathname(r->filename)); 433 apr_filepath_name_get(r->filename)); 434 return HTTP_INTERNAL_SERVER_ERROR; 535 ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, 536 "%s: %s", malformed, 537 apr_filename_of_pathname(r->filename)); 537 apr_filepath_name_get(r->filename)); 538 return HTTP_INTERNAL_SERVER_ERROR; [$SOURCE/modules/generators/mod_cgi.c] 同上
apr_mmap_dup
→引数多すぎ、第4引数はDeprecated。第4引数「0」を削除[16]
[$SOURCE/modules/cache/mod_file_cache.c] 277 apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc); 278 279 apr_mmap_dup(&mm, file->mm, r->pool, 0); 279 apr_mmap_dup(&mm, file->mm, r->pool); 280 b = apr_bucket_mmap_create(mm, 0, (apr_size_t)file->finfo.size,
$SOURCE/modules/experimental/cache_storage.c
でincludeしている$SOURCE/modules/experimental/mod_cache.h
中で、apr_atomic_t
より前にspecifier-qualifier-listが来ないとだめ、と言われる。httpd-2.2.21の$SOURCE/modules/cache/mod_cache.h
を参考に修正。
エラーメッセージ In file included from /usr/src/redhat/BUILD/httpd-2.0.64/modules/experimental/cache_storage.c:19: /usr/src/redhat/BUILD/httpd-2.0.64/modules/experimental/mod_cache.h:182: error: expected specifier-qualifier-list before 'apr_atomic_t' [$SOURCE/modules/experimental/mod_cache.h] 174 typedef struct cache_object cache_object_t; 175 struct cache_object { 176 char *key; 176 const char *key; 177 cache_object_t *next; 178 cache_info info; 179 void *vobj; /* Opaque portion (specific to the cache implementation) of the cache ob ject */ 179 /* Opaque portion (specific to the implementation) of the cache object */ 179.1 void *vobj; 179.2 /* FIXME: These are only required for mod_mem_cache. */ 180 apr_size_t count; /* Number of body bytes written to the cache so far */ 181 int complete; 182 apr_atomic_t refcount; 183 apr_size_t cleanup; 182 apr_uint32_t refcount; /* refcount and bit flag to cleanup object */ 184 };
[$SOURCE/modules/experimental/util_ldap.c] 130 int util_ldap_handler(request_rec *r) 131 { 132 util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module); 132 util_ldap_state_t *st = (util_ldap_state_t *) 132.1 ap_get_module_config(r->server->module_config, &ldap_module); 133 134 r->allowed |= (1 << M_GET); 159 /* 160 * Closes an LDAP connection by unlocking it. The next time 161 * util_ldap_connection_find() is called this connection will be 162 * available for reuse. 163 */ 164 LDAP_DECLARE(void) util_ldap_connection_close(util_ldap_connection_t *ldc) 164 static void util_ldap_connection_close(util_ldap_connection_t *ldc) 165 { 186 /* 187 * Destroys an LDAP connection by unbinding and closing the connection to 188 * the LDAP server. It is used to bring the connection back to a known 189 * state after an error, and during pool cleanup. 190 */ 191 LDAP_DECLARE_NONSTD(apr_status_t) util_ldap_connection_unbind(void *param) 191 static apr_status_t util_ldap_connection_unbind(void *param) 192 { 207 /* 208 * Clean up an LDAP connection by unbinding and unlocking the connection. 209 * This function is registered with the pool cleanup function - causing 210 * the LDAP connections to be shut down cleanly on graceful restart. 211 */ 212 LDAP_DECLARE_NONSTD(apr_status_t) util_ldap_connection_cleanup(void *param) 212 static apr_status_t util_ldap_connection_cleanup(void *param) 213 { 238 /* 239 * Connect to the LDAP server and binds. Does not connect if already 240 * connected (i.e. ldc->ldap is non-NULL.) Does not bind if already bound. 241 * 242 * Returns LDAP_SUCCESS on success; and an error code on failure 243 */ 244 LDAP_DECLARE(int) util_ldap_connection_open(request_rec *r, 244 static int util_ldap_connection_open(request_rec *r, 245 util_ldap_connection_t *ldc) 377 /* 378 * Find an existing ldap connection struct that matches the 379 * provided ldap connection parameters. 380 * 381 * If not found in the cache, a new ldc structure will be allocated from st->pool 382 * and returned to the caller. If found in the cache, a pointer to the existing 383 * ldc structure will be returned. 384 */ 385 LDAP_DECLARE(util_ldap_connection_t *)util_ldap_connection_find(request_rec *r, const char *host, int port, 386 const char *binddn, const char *bindpw, deref_options deref, 387 int secure ) 385 static util_ldap_connection_t * 386 uldap_connection_find(request_rec *r, 387 const char *host, int port, 387.1 const char *binddn, const char *bindpw, 387.2 deref_options deref, int secure) 388 { 505 /* 506 * Compares two DNs to see if they're equal. The only way to do this correctly is to 507 * search for the dn and then do ldap_get_dn() on the result. This should match the 508 * initial dn, since it would have been also retrieved with ldap_get_dn(). This is 509 * expensive, so if the configuration value compare_dn_on_server is 510 * false, just does an ordinary strcmp. 511 * 512 * The lock for the ldap cache should already be acquired. 513 */ 514 LDAP_DECLARE(int) util_ldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc, 515 const char *url, const char *dn, const char *reqdn, 516 int compare_dn_on_server) 514 static int uldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc, 515 const char *url, const char *dn, 516 const char *reqdn, int compare_dn_on_server) 517 { 629 /* 630 * Does an generic ldap_compare operation. It accepts a cache that it will use 631 * to lookup the compare in the cache. We cache two kinds of compares 632 * (require group compares) and (require user compares). Each compare has a different 633 * cache node: require group includes the DN; require user does not because the 634 * require user cache is owned by the 635 * 636 */ 637 LDAP_DECLARE(int) util_ldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, 638 const char *url, const char *dn, 639 const char *attrib, const char *value) 637 static int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, 638 const char *url, const char *dn, 639 const char *attrib, const char *value) 640 { 766 LDAP_DECLARE(int) util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc, 767 const char *url, const char *basedn, int scope, char **attrs, 768 const char *filter, const char *bindpw, const char **binddn, 769 const char ***retvals) 766 static int uldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc, 767 const char *url, const char *basedn, 768 int scope, char **attrs, const char *filter, 769 const char *bindpw, const char **binddn, 769.1 const char ***retvals) 770 { 995 /* 996 * This function will return the DN of the entry matching userid. 997 * It is used to get the DN in case some other module than mod_auth_ldap 998 * has authenticated the user. 999 * The function is basically a copy of util_ldap_cache_checkuserid 1000 * with password checking removed. 1001 */ 1002 LDAP_DECLARE(int) util_ldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc, 1003 const char *url, const char *basedn, int scope, char **attrs, 1004 const char *filter, const char **binddn, 1005 const char ***retvals) 1002 static int uldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc, 1003 const char *url, const char *basedn, 1004 int scope, char **attrs, const char *filter, 1005 const char **binddn, const char ***retvals) 1006 { 1179 /* 1180 * Reports if ssl support is enabled 1181 * 1182 * 1 = enabled, 0 = not enabled 1183 */ 1184 LDAP_DECLARE(int) util_ldap_ssl_supported(request_rec *r) 1184 static int uldap_ssl_supported(request_rec *r) 1185 { 1186 util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config( 1187 r->server->module_config, &ldap_module); 1188 1189 return(st->ssl_support); 1189 return(st->ssl_supported); 1190 }
httpd.spec
中のconfigureオプションで、ldap関係の指定を外す。
[httpd.spec]
112 ../configure -C \
113 --prefix=%{_sysconfdir}/httpd \
114 --with-apr=/usr/bin/apr-1-config \
115 --with-apr-util=/usr/bin/apu-1-config \
...
132 --with-devrandom \
133 --with-ldap --enable-ldap --enable-auth-ldap \
134 --enable-cache --enable-disk-cache --enable-mem-cache --enable-file-cache \
135 --enable-ssl --with-ssl \
136 --enable-deflate --enable-cgid \
137 --enable-proxy --enable-proxy-connect \
138 --enable-proxy-http --enable-proxy-ftp \
139 $*
[$SOURCE/modules/filters/mod_deflate.c] 692 if (rv != APR_SUCCESS) { 693 /* What about APR_EAGAIN errors? */ 694 inflateEnd(&ctx->stream); 695 return rv; 696 } 697 698 APR_BRIGADE_FOREACH(bkt, ctx->bb) { 698 for (bkt = APR_BRIGADE_FIRST(ctx->bb); 698.1 bkt != APR_BRIGADE_SENTINEL(ctx->bb); 698.2 bkt = APR_BUCKET_NEXT(bkt)) 698.3 { 699 const char *data; 700 apr_size_t len; 701 702 /* If we actually see the EOS, that means we screwed up! */ [$SOURCE/modules/filters/mod_ext_filter.c] 746 dc = ctx->dc; 747 748 APR_BRIGADE_FOREACH(b, bb) { 748 for (b = APR_BRIGADE_FIRST(bb); 748.1 b != APR_BRIGADE_SENTINEL(bb); 748.2 b = APR_BUCKET_NEXT(b)) 748.3 { 749 750 if (APR_BUCKET_IS_EOS(b)) { 858 rv = ap_get_brigade(f->next, bb, mode, block, readbytes); 859 if (rv != APR_SUCCESS) { 860 return rv; 861 } 862 863 APR_BRIGADE_FOREACH(b, bb) { 863 for (b = APR_BRIGADE_FIRST(bb); 863.1 b != APR_BRIGADE_SENTINEL(bb); 863.2 b = APR_BUCKET_NEXT(b)) 863.3 { 864 if (!APR_BUCKET_IS_EOS(b)) { [$SOURCE/modules/generators/mod_cgi.c] 同上2箇所 [$SOURCE/modules/generators/mod_cgid.c] 同上2箇所
rpmbuild時のエラーメッセージ /usr/src/redhat/BUILD/httpd-2.0.64/modules/proxy/proxy_connect.c: In function 'proxy_connect_handler': /usr/src/redhat/BUILD/httpd-2.0.64/modules/proxy/proxy_connect.c:455: error: invalid storage class for function 'ap_proxy_connect_register_hook' /usr/src/redhat/BUILD/httpd-2.0.64/modules/proxy/proxy_connect.c:468: error: expected declaration or statement at end of input 134 --enable-ssl --with-ssl \ 135 --enable-deflate --enable-cgid \ 136 --enable-proxy --enable-proxy-connect \ 137 --enable-proxy-http --enable-proxy-ftp \ 138 $*
[$SOURCE/modules/generators/mod_autoindex.c] FNM_NOESCAPE→APR_FNM_NOESCAPE(2箇所) FNM_PERIOD→APR_FNM_PERIOD(2箇所)
2.2.22の32bit版rpmをビルドする時の試行錯誤の記録(実際には64bit版rpmをビルドする際合わせて作ったソースパッケージsrpmを元にビルド)。
$ rpmbuild -bc httpd.spec (前略) checking for distcache/dc_client.h... no configure: error: distcache support failed: can't include distcache headers エラー: /var/tmp/rpm-tmp.97546 の不正な終了ステータス (%build) RPM ビルドエラー: /var/tmp/rpm-tmp.97546 の不正な終了ステータス (%build)
distcache,distcache-develがinstallされている必要ありとのこと[20]。distcacheはinstall済みだったが、distcache-develはinstallされていなかっので入れる。
# yum list distcache* Loaded plugins: fastestmirror Installed Packages distcache.i386 1.4.5-14.1 installed Available Packages distcache-devel.i386 1.4.5-14.1 base # yum list distcache-devel
再度ビルド。別のエラーがわらわらと出る。
# rpmbuild -bb httpd.conf /usr/bin/ld: skipping incompatible /usr/lib/libm.so when searching for -lm /usr/bin/ld: skipping incompatible /usr/lib/libm.a when searching for -lm /usr/lib/libdb-4.3.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status /usr/bin/ld: skipping incompatible //usr/lib/libm.so whenusr/bin /ld: skippingsearching incompatible /usr/lib/libm.so when searching for -lm /usr/bin/ld: skipping incompatible /usr/lib/libm.a when searching for -lm /usr/lib/libdb-4.3.so: could not read symbols: File in wrong format for -lm /usr/bin/ld: skipping incompatible /usr/collect2: lib/libm.a when searching for -lm /ld returned 1 exit statususr/ lib/libdb-4.3.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status make[2]: *** [logresolve] Error 1 make[2]: *** Waiting for unfinished jobs.... make[2]: *** [httxt2dbm] Error 1 make[2]: *** [rotatelogs] Error 1 /usr/bin/ld: skipping incompatible /usr/lib/libm.so when searching for -lm /usr/bin/ld: skipping incompatible /usr/lib/libm.a when searching for -lm /usr/lib/libdb-4.3.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status /usr/bin/ld: skipping incompatible /usr/lib/libm.so when searching for -lm /usr/bin/ld: skipping incompatible /usr/lib/libm.a when searching for -lm /usr/lib/libdb-4.3.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status /usr/bin/ld:make[2]: *** [htpasswd] Error 1 skipping incompatible /usr/lib/libm.so when searching for make[2]: *** [htdigest] Error 1 -lm /usr/bin/ld: skipping incompatible /usr/lib/libm.a when searching for -lm /usr/lib/libdb-4.3.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status make[2]: *** [htdbm] Error 1 /usr/bin/ld: skipping incompatible /usr/lib/libm.so when searching for -lm /usr/bin/ld: skipping incompatible /usr/lib/libm.a when searching for -lm /usr/lib/libdb-4.3.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status make[2]: *** [htcacheclean] Error 1 /usr/bin/ld: skipping incompatible /usr/lib/libm.so when searching for -lm /usr/bin/ld: skipping incompatible /usr/lib/libm.a when searching for -lm /usr/lib/libdb-4.3.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status make[2]: *** [checkgid] Error 1 make[2]: Leaving directory `/tmp/redhat/BUILD/httpd-2.2.22/prefork/support' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/tmp/redhat/BUILD/httpd-2.2.22/prefork/support' make: *** [all-recursive] Error 1 エラー: /var/tmp/rpm-tmp.16866 の不正な終了ステータス (%build) RPM ビルドエラー: /var/tmp/rpm-tmp.16866 の不正な終了ステータス (%build) #
/usr/lib/libdb-4.3.so: could not read symbols: File in wrong format
の対処法として、i386版db4をeraseすればいいみたい[21]。やってみて再ビルド。
# yum list db4 (前略) Installed Packages db4.i386 4.3.29-10.el5_5.2 installed db4.x86_64 4.3.29-10.el5_5.2 installed # yum erase db4.i386 (前略) Dependencies Resolved ==================================================================================================== Package Arch Version Repository Size ==================================================================================================== Removing: db4 i386 4.3.29-10.el5_5.2 installed 2.0 M Removing for dependencies: control-center i386 1:2.16.0-16.el5 installed 8.1 M db4-devel i386 4.3.29-10.el5_5.2 installed 7.3 M evolution-data-server i386 1.12.3-18.el5 installed 11 M evolution-data-server-devel i386 1.12.3-18.el5 installed 1.4 M gnome-panel i386 2.16.1-7.el5 installed 10 M gnome-panel-devel i386 2.16.1-7.el5 installed 170 k gnome-utils i386 1:2.16.0-5.el5 installed 8.5 M kdesdk i386 3.5.4-3.el5 installed 16 M kdewebdev i386 6:3.5.4-2.fc6 installed 31 M pam_ccreds i386 3-5 installed 32 k Transaction Summary ==================================================================================================== Remove 11 Package(s) Reinstall 0 Package(s) Downgrade 0 Package(s) Is this ok [y/N]: y (中略) Removed: db4.i386 0:4.3.29-10.el5_5.2 Dependency Removed: control-center.i386 1:2.16.0-16.el5 db4-devel.i386 0:4.3.29-10.el5_5.2 evolution-data-server.i386 0:1.12.3-18.el5 evolution-data-server-devel.i386 0:1.12.3-18.el5 gnome-panel.i386 0:2.16.1-7.el5 gnome-panel-devel.i386 0:2.16.1-7.el5 gnome-utils.i386 1:2.16.0-5.el5 kdesdk.i386 0:3.5.4-3.el5 kdewebdev.i386 6:3.5.4-2.fc6 pam_ccreds.i386 0:3-5 Complete! # rpmbuild -bb --target i686 httpd.spec (前略) /usr/bin/ld: skipping incompatible /usr/lib/libm.so when searching for -lm /usr/bin/ld: skipping incompatible /usr/lib/libm.a when searching for -lm /usr/lib/libexpat.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status make[2]: *** [rotatelogs] Error 1 make[2]: *** Waiting for unfinished jobs.... /usr/bin/ld: skipping incompatible /usr/lib/libm.so when searching for -lm /usr/bin/ld: skipping incompatible /usr/lib/libm.a when searching for -lm /usr/lib/libexpat.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status /usr/bin/ld: skipping incompatible /usr/lib/libm.so when searching for -lm /usr/bin/ld: skipping incompatible /usr/lib/libm.a when searching for -lm /usr/lib/libexpat.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status make[2]: *** [httxt2dbm] Error 1 make[2]: *** [htdigest] Error 1 /usr/bin/ld: skipping incompatible /usr/lib/libm.so when searching for -lm /usr/bin/ld: skipping incompatible /usr/lib/libm.a when searching for -lm /usr/lib/libexpat.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status make[2]: *** [logresolve] Error 1 /usr/bin/ld: skipping incompatible /usr/lib/libm.so when searching for -lm /usr/bin/ld: skipping incompatible /usr/lib/libm.a when searching for -lm /usr/lib/libexpat.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status make[2]: *** [htpasswd] Error 1 /usr/bin/ld: skipping incompatible /usr/lib/libm.so when searching for -lm /usr/bin/ld: skipping incompatible /usr/lib/libm.a when searching for -lm /usr/lib/libexpat.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status make[2]: *** [htcacheclean] Error 1 /usr/bin/ld: skipping incompatible /usr/lib/libm.so when searching for -lm /usr/bin/ld: skipping incompatible /usr/lib/libm.a when searching for -lm /usr/lib/libexpat.so: could not read symbols: File in wrong format collect2: ld returned 1 exit status make[2]: *** [htdbm] Error 1 make[2]: Leaving directory `/tmp/redhat/BUILD/httpd-2.2.22/prefork/support' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/tmp/redhat/BUILD/httpd-2.2.22/prefork/support' make: *** [all-recursive] Error 1 エラー: /var/tmp/rpm-tmp.618 の不正な終了ステータス (%build) RPM ビルドエラー: /var/tmp/rpm-tmp.618 の不正な終了ステータス (%build)
今度はlibexpat.so
に関するエラー。./configure
のオプションに--with-expat=builtin
を付加すればよいらしい(このオプションはソースルートのconfigureにはなく、scrlib/apr-util/configure
のオプションにあった)[22]。ただ、httpd.spec
には強制的にビルトインのapr,apr-util,pcreを使えなくするよう、ビルドの初期段階でソースからコンテンツを削除する手順が入っていたのでコメントアウト。
[httpd.spec] 80 %build 81 # forcibly prevent use of bundled apr, apr-util, pcre 82 rm -rf srclib/{apr,apr-util,pcre} 82 #rm -rf srclib/{apr,apr-util,pcre} 120 --enable-reqtimeout=shared \ 120.1 --with-expat=builtin \ 121 $*
状況は変わらず。64bit環境で32bit版rpmをビルドするのは断念、32bit環境でビルドする方針に転換。
改めて32bit環境で実施。
# rpmbuild -bb httpd.spec modules/http/.libs/libmod_http.a(byterange_filter.o): In function `ap_set_byterange': byterange_filter.c:(.text+0x12cd): undefined reference to `apr_array_clear' collect2: ld returned 1 exit status make[1]: *** [httpd] Error 1 make[1]: Leaving directory `/home/user/redhat/BUILD/httpd-2.2.22/prefork' make: *** [all-recursive] Error 1 エラー: /var/tmp/rpm-tmp.32267 の不正な終了ステータス (%build) RPM ビルドエラー: /var/tmp/rpm-tmp.32267 の不正な終了ステータス (%build)
(1)builtinのaprを参照するようconfigure option追加、(2)builtin環境を消す設定をコメントアウト、の変更を行ってrpmbuild。
[httpd.spec] 80 %build 81 # forcibly prevent use of bundled apr, apr-util, pcre 82 rm -rf srclib/{apr,apr-util,pcre} 82 #rm -rf srclib/{apr,apr-util,pcre} 120 --enable-reqtimeout=shared \ 120.1 --with-included-apr \ 121 $* # rpmbuild -bb httpd.spec (前略) ../configure: line 5679: ../srclib/apr/apr-1-config: No such file or directory ../configure: line 5700: ../srclib/apr-util/apu-1-config: No such file or directory (中略) You need APR random support to use mod_auth_digest. Look at APR configure options --with-egd and --with-devrandom. checking whether to enable mod_auth_digest... configure: error: mod_auth_digest has been requested but can not be built due to prerequisite failures エラー: /var/tmp/rpm-tmp.27354 の不正な終了ステータス (%build) RPM ビルドエラー: /var/tmp/rpm-tmp.27354 の不正な終了ステータス (%build)
configure optionでapr, apr-utilの指定を除外。--with-pcreの指定が重複していたので、一方をコメントアウト。そして再ビルド。
[httpd.spec] 88 function mpmbuild() 89 { 90 mpm=$1; shift 91 mkdir $mpm; pushd $mpm 92 ../configure \ 93 --prefix=%{_sysconfdir}/httpd \ 94 --with-apr=/usr/bin/apr-1-config \ 94 # --with-apr=/usr/bin/apr-1-config \ 95 --with-apr-util=/usr/bin/apu-1-config \ 95 # --with-apr-util=/usr/bin/apu-1-config \ 96 --with-pcre=/usr/bin/pcre-config \ 114 --enable-pie \ 115 --with-pcre \ 115 # --with-pcre \ 116 --enable-file_cache=shared \ # rpmbuild -bb httpd.spec (前略) config.status: executing default commands + --with-pcre=/usr/bin/pcre-config --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --mandir=/usr/share/man --libdir=/usr/lib --sysconfdir=/etc/httpd/conf --includedir=/usr/include/httpd --libexecdir=/usr/lib/httpd/modules --datadir=/var/www --with-installbuilddir=/usr/lib/httpd/build --with-mpm=prefork --enable-suexec --with-suexec --with-suexec-caller=pdbj --with-suexec-docroot=/var/www --with-suexec-logfile=/var/log/httpd/suexec.log --with-suexec-bin=/usr/sbin/suexec --with-suexec-uidmin=500 --with-suexec-gidmin=500 --enable-pie /var/tmp/rpm-tmp.22157: line 46: --with-pcre=/usr/bin/pcre-config: No such file or directory エラー: /var/tmp/rpm-tmp.22157 の不正な終了ステータス (%build) RPM ビルドエラー: /var/tmp/rpm-tmp.22157 の不正な終了ステータス (%build)
結局、2.2.21ならビルドできたけど、2.2.22はビルドできないことが判明。とりあえず2.2.21のrpmを作って署名し、yum localinstall。
yum コマンドが実行できなかったので問題を解消しリトライ。apr、apr-utilなど依存性問題でinstall NG。apr-utilをビルドするにはfreetds-devel、unixODBC-develが必要とされるので入れる(yum install freetds-devel unixODBC-devel
)。apr、apr-utilのrpmをlocalinstall→まだ依存性問題解消しきれず。mod_ssl(localupdateでも既存をupdateするものと認識してくれない)、httpd_suexecなどhttpd関連のものが主のよう。
--> Finished Dependency Resolution Error: Missing Dependency: libaprutil-0.so.0 is needed by package mod_perl Error: Missing Dependency: libldap-2.3.so.0 is needed by package httpd Error: Missing Dependency: httpd-mmn = 20020903 is needed by package mod_python Error: Missing Dependency: pcre >= 5.0 is needed by package httpd Error: Missing Dependency: httpd-mmn = 20020903 is needed by package mod_ssl Error: Missing Dependency: libc.so.6(GLIBC_2.4) is needed by package apr-util Error: Missing Dependency: libpthread.so.0(GLIBC_2.4) is needed by package apr Error: Missing Dependency: httpd = 2.0.52-49.ent.centos4 is needed by package mod_ssl Error: Missing Dependency: libdb-4.3.so is needed by package httpd Error: Missing Dependency: liblber-2.3.so.0 is needed by package httpd Error: Missing Dependency: httpd-mmn = 20020903 is needed by package mod_perl Error: Missing Dependency: libc.so.6(GLIBC_2.4) is needed by package apr Error: Missing Dependency: libssl.so.6 is needed by package httpd Error: Missing Dependency: httpd-mmn = 20020903 is needed by package php Error: Missing Dependency: rtld(GNU_HASH) is needed by package apr Error: Missing Dependency: libiconv.so.2 is needed by package apr-util Error: Missing Dependency: rtld(GNU_HASH) is needed by package httpd Error: Missing Dependency: rtld(GNU_HASH) is needed by package apr-util Error: Missing Dependency: libapr-0.so.0 is needed by package mod_perl Error: Missing Dependency: libcrypto.so.6 is needed by package httpd Error: Missing Dependency: httpd = 2.0.52-49.ent.centos4 is needed by package httpd-suexec
Macにapache2をインストールの最終ステップに記した通り。[システム環境設定]-[共有] の [サービス]タブで画面左の「パーソナルWeb共有]を選択し、「開始」ボタンをクリックすればサービスが開始される。
↓「開始」をクリック
Apacheの設定変更はhttpd.conf
を編集して行う。このファイルの標準的な場所は以下の通り。
OS | 場所 | 備考 |
---|---|---|
CentOS 5、RHEL 5 | /etc/httpd/conf |
RPMでインストールした場合 |
Mac OS X 10.4 (tiger) | /etc/httpd |
|
Mac OS X 10.6 (snow leopard) | /etc/apache2 |
|
Windows |
|
|
Ubuntu 10.04 LTS |
|
パッケージマネージャ等からインストールした場合 |
ソースからのインストール | /usr/local/apache2/conf |
なお、設定は/etc/httpd/conf.d
ディレクトリ配下に*.conf
というファイル名を置くことで、httpd.conf
とは分けて記述指定可能。どちらに記述しても効果は同じだが、共通の設定は/etc/httpd/conf/httpd.conf
に記述しておき、モジュールやディレクトリに固有の設定は/etc/httpd/conf.d
配下のファイルに記述するなどして管理上使い分けることができる。
設定を反映するにははApacheを再起動する。CentOS5、RHEL5などの場合、/etc/init.d/httpd restart
。設定内容によっては /etc/rc.d/init.d/httpd graceful
でサービスを停止せず設定を反映できるらしい。
OS | 場所 | 備考 |
---|---|---|
CentOS 5、RHEL 5 | /etc/init.d/httpd |
RPMでインストールした場合 |
Mac OS X 10.4 (tiger) |
|
|
Mac OS X 10.6 (snow leopard) |
|
|
Windows |
|
|
Ubuntu 10.04 LTS | /etc/init.d/apache2 |
パッケージマネージャ等からインストールした場合 |
ソースからのインストール |
|
ディレクトリの設定ごとの設定を指定するには、Directory
ディレクティブを用いる。この設定内容はサブディレクトリにも適用される。
【書式】 <Directory "ローカルパス"> (指定内容) </Directory> 【使用可能場所】 サーバ設定ファイル、バーチャルホスト 【モジュール】 core
ローカルパスは絶対パスにて指定。この設定はシンボリックリンクをたどって別のパスからアクセスした場合には適用されない。
【例】
<Directory "/var/www/html">
(指定内容)
</Directory>
ディレクトリの指定を正規表現を使って行うには、表現の前に「~」を付加するか、あるいはDirectoryMatch
ディレクティブを用いる。
【書式】 <Directory ~ "ローカルパスの正規表現表記"> (指定内容) </Directory>
【書式】 <DirectoryMatch "ローカルパスの正規表現表記"> (指定内容) </DirectoryMatch> 【使用可能場所】 サーバ設定ファイル、バーチャルホスト 【モジュール】 core
【例】/www/ 以下にある数字 3 文字のディレクトリにマッチ <Directory ~ "^/www/(.+/)?[0-9]{3}"> (指定内容) </Directory> <DirectoryMatch "^/www/(.+/)?[0-9]{3}"> (指定内容) </DirectoryMatch>
指定内容の記述に用いるディレクティブには以下のようなものがある。詳細はタイトルリンク先を参照のこと。
Options
Order
Allow
Deny
AllowOverride
.htaccess
ファイルによるディレクトリ別設定の上書きを許可するかどうか設定する。
ファイルの設定を指定するには、Files
ディレクティブやFilesMatch
を用いる。
使用可能場所:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
【書式】 <Files "ファイル名"> (指定内容) </Files> <FilesMatch "正規表現"> (指定内容) </FilesMatch>
アクセス先ファイル名を指定しなかった場合、何を返すかの設定。
DirectoryIndex ファイル名 ...
ファイル名は空白で区切って複数列挙可能。前から順にファイルを探し、あればそのファイルを表示。いずれも見つからなかった場合の挙動は次項の設定による。
<Directory "/var/www/html"> Options Indexes </Directory>
Options
の引数にIndexes
を指定した場合、DirectoryIndex
に指定したファイルがなければファイルリストを表示する。そうでなければ、Forbiddenエラーページを表示する。
AllowOverride
を記すことにより、各ディレクトリに.htaccess
ファイル(既定名)を置いて個々に設定を上書きできるかどうかの設定を行うことができる。<Directory>
ディレクティブ内に記せばそのディレクトリ以下のみ、そうでなければサイト全体に設定が反映される。
【書式1】全て上書き許可
AllowOverride All
【書式2】全て上書き拒否
AllowOverride None
【書式3】上書き内容を指定
AllowOverride 指定
【例】"/var/www/html" ディレクトリに関する設定は全て .htaccess ファイルの内容で上書き
<httpd.conf>
<Directory "/var/www/html">
AllowOverride All
</Directory>
指定は空白で区切って複数併記可能。
指定値 | 内容 | 含まれるもの |
---|---|---|
AuthConfig |
認証関係 | AuthType, AuthName |
FileInfo |
文書関係 | |
Indexes |
ディレクトリインデックス関係 | |
Limit |
アクセス元制御関係 | |
Options=オプション,オプション... |
Options |
Directory(Match)
中や、.htaccess
中の、Options
ディレクティブ中に「FollowSymLinks
」と記せば、シンボリックファイルへのアクセスが許可される。「+FollowSymLinks
」と記せば、他のオプションは変更せず、シンボリックファイルへのアクセス許可だけが上書きされる。
<Directory "/var/www/html"> Options FollowSymLinks </Directory>
基本認証、ダイジェスト認証を要求するよう設定するには、以下のいずれかの設定ファイルに指示を記述する。
httpd.conf
).htaccess
ファイル(.htaccess
ファイルによる上書きが有効となるようApache設定ファイルの AllowOverrideを設定しておく必要あり)設定記述箇所は以下の通り。
.htaccess
についてはそのままトップレベルで記述する。
.htaccess
ファイルに記述する。
Basic認証、Digest認証それぞれの設定方法は以下の通り。
htpasswd
コマンドを用いてパスワードファイルを作成・更新する。詳細は使用方法は認証情報ファイルを生成(htpasswd)を参照のこと。
【例】新たにパスワードファイルを作成し、ユーザ hoge のパスワード情報を追加する。 $ htpasswd -c .passwd hoge New password: Re-type new password: Adding password for user hoge
認証型の指定(AuthType)、認証要求ダイアログの表示内容の指定(AuthName)、認証情報ファイルの指定(AuthUserFile)、許可ユーザの指定(Require)の設定をApache設定ファイルなどに追記する。
【例】Apache設定ファイルで /var/www/html/internal 配下にBasic認証を設定 <Directory /var/www/html/internal> # 認証タイプの指定(Basic) AuthType Basic # 認証要求ダイアログに表示内容の指定 AuthName "関係者以外立ち入り禁止! 関係者は認証してお入りください。" # パスワードファイルの指定 AuthUserFile /var/www/.passwd # 全ての認証されたユーザにアクセスを許可 Require valid-user </Directory>
Basic認証とは異なり、htdigest
コマンドを用いてパスワードファイルを作成・更新を行う。詳細はDigest認証用認証情報ファイルを生成(htdigest)はを参照のこと。
【例】新たにパスワードファイルを作成し、ユーザ hoge のパスワード情報を追加する。 $ htdigest -c .passwd '関係者以外立ち入り禁止! 関係者は認証してお入りください。' hoge Adding password for hoge in realm 関係者以外立ち入り禁止! 関係者は認証してお入りください。 New password: Re-type new password: $ cat .passwd hoge:関係者以外立ち入り禁止! 関係者は認証してお入りください。:9c6a0dff5e3d51fd7cc640b19ffa4d1e
認証型の指定(AuthType)、認証要求ダイアログの表示内容の指定(AuthName)、認証情報ファイルの指定(AuthUserFile)、許可ユーザの指定(Require)の設定をApache設定ファイルなどに追記する。AuthNameに設定する値は単に認証ダイアログに表示する値というだけではなく、htdigestでユーザ情報を作成した時に指定したレルム名と一致させておく必要がある。
【例】Apache設定ファイルで /var/www/html/internal 配下にBasic認証を設定 <Directory /var/www/html/internal> # 認証タイプの指定(Digest) AuthType Digest # 認証要求ダイアログに表示内容の指定。htdigestで指定したレルム名と同じ値を設定すること。 AuthName "関係者以外立ち入り禁止! 関係者は認証してお入りください。" # パスワードファイルの指定 AuthUserFile /var/www/.passwd # 全ての認証されたユーザにアクセスを許可 Require valid-user </Directory>
AuthType
は Directory
ディレクティブ内にて認証型を指定する。
【書式】
AuthType 認証型
【例】
AuthType Basic
Basic
または Digest
。
AuthName
は Directory
ディレクティブ内にて認証要求ダイアログの表示内容を指定する。
【書式】
AuthName 文字列
【例】
AuthName "Welcome to Internal Site!"
【書式】 htpasswd [-c] [-m] [-D] パスワードファイル名 ユーザ名 htpasswd -b [-c] [-m | -d | -p | -s] [-D] パスワードファイル名 ユーザ名 パスワード htpasswd -n [-m | -d | -p | -s] ユーザ名 htpasswd -nb [-m | -d | -p | -s] ユーザ名 パスワード
-b
【例】 $ htpasswd -c .passwd hoge New password: Re-type new password: Adding password for user hoge $ cat .passwd hoge:$apr1$8lgp457k$XBBFLgCy2REBJ.l34KrY/. ←パスワードのハッシュ値が記録されている $ htpasswd .passwd hoge2 New password: Re-type new password: Adding password for user hoge2 $ cat .passwd hoge:$apr1$8lgp457k$XBBFLgCy2REBJ.l34KrY/. hoge2:$apr1$NCY3HPF8$2QOjf39rCEjyKiV0xUh7F0 ← -c オプションがないと既存情報は残し追記される $ htpasswd -c .passwd hoge3 New password: Re-type new password: Adding password for user hoge3 $ cat .passwd hoge3:$apr1$kfPlfW4B$F.eXdxiPiQFeSGzhEdy5/. ← -c オプションがあると既存情報は消去され新規にファイルが作成される パスワードファイルがまだ存在しない場合 -c オプションは必要。-c オプションがないとエラーになる。 $ htpasswd .passwd hoge htpasswd: cannot modify file .passwd; use '-c' to create it
-d
htpasswd
は恐らく全ての環境で動作しますが、Windows、Netware、TPF上のhttpdは対象外です。【例】 $ htpasswd -c .passwd hoge New password: Re-type new password: Adding password for user hoge $ cat .passwd hoge:$apr1$8lgp457k$XBBFLgCy2REBJ.l34KrY/. ←パスワードのハッシュ値が記録されている $ htpasswd .passwd hoge2 New password: Re-type new password: Adding password for user hoge2 $ cat .passwd hoge:$apr1$8lgp457k$XBBFLgCy2REBJ.l34KrY/. hoge2:$apr1$NCY3HPF8$2QOjf39rCEjyKiV0xUh7F0 ← -c オプションがないと既存情報は残し追記される $ htpasswd -D .passwd hoge Deleting password for user hoge $ cat .passwd hoge2:$apr1$NbMEZkSu$RRXax8qGSpRFpQKBAHSMm1 ← 指定したユーザの情報だけ消去された
-m
-n
-c
オプションと一緒に使うことはできない。-p
htpasswd
は恐らく全ての環境で動作しますが、Windows、Netware、TPF上のhttpdデーモンは平文パスワードしか受け付けません。-s
【例】 $ htpasswd -c .passwd hoge New password: Re-type new password: Adding password for user hoge $ htpasswd -v .passwd hoge Enter password: Password for user hoge correct. ← パスワードが合っていた場合 $ htpasswd -v .passwd hoge Enter password: password verification failed ← パスワードが間違っていた場合
htdigestはDigest認証で用いるユーザ情報ファイルを作成・更新する。
【書式】 htpasswd [-c] パスワードファイル名 レルム名 ユーザ名
作成されるファイルの書式は以下の通り。
ユーザ名:レルム:パスワードダイジェスト
user:関係者以外立ち入り禁止! 関係者は認証してお入りください。:5d7f4a1d592002507b1a7824927a311f
AuthUserFile
は Directory
ディレクティブ内にて認証ユーザ情報を収めたテキストファイルを指定する。
AuthGroupFile
は Directory
ディレクティブ内にて認証ユーザグループの情報を収めたテキストファイルを指定する。いずれも絶対パスでなければServerRoot
からの相対パスとみなされる。
【書式】 AuthUserFile ユーザ情報ファイル名 AuthGroupFile ユーザグループ情報ファイル名 【例】 AuthUserFile /var/www/.htpasswd
ユーザファイルについて。
/sbin/nologin
に設定されている→ユーザ管理 - UNIX関係参照)と、NFSマウントされた領域のファイルが参照できない。この場合、ローカル領域にファイルをコピーして利用。ユーザ情報ファイル名の各行にはユーザ名、コロン、暗号化したパスワードを記述する。同一ユーザ ID が複数回登録された時は、最初に見つかったパスワードを使用して認証する。
【ユーザ情報ファイル名の例】 hoge:eF87dxcl foo:Sau0Xlki
パスワードの生成はsrc/support
にあるhtpasswd
コマンドを使う。詳細は認証情報管理(htpasswd)を参照。
認証方式(→AuthType)にダイジェスト認証を選択した場合はhtdigest
を用いる。
Require
は Directory
ディレクティブ内にてアクセスを許可する対象を指定する。
以下の構文はmod_authz_user, mod_authz_host, mod_authz_groupfileを必要とするものを含む
Requireと2番目の値との間に「not」を記すと条件を反転したものとすることができる(例: Require not ip 192.168.0)
アクセスの許可や拒否はAllow
およびDeny
ディレクティブで行う。またAllow
とDeny
のどちらを先に適用するかはOrder
ディレクティブで指示する。
なおこのディレクティブはApache 2.4では廃止予定となり使用は非推奨となっている。代わりにRequireなどを使うことが推奨されている[21]。
Allow from アクセス元 Deny from アクセス元アクセス元は、ホスト名・ドメイン名、完全なIPアドレス、IP アドレスの一部、ネットワークセグメントで指定できます。IPv4およびIPv6どちらも使えます。指定は空白区切りで複数列挙できます。
# ドメイン名指定 Allow from apache.org Allow from .net example.edu Allow from localhost # IPv4の個別指定 Allow from 10.1.2.3 Allow from 192.168.1.104 192.168.1.205 # IPv4の前部指定 Allow from 10.1 Allow from 10 172.20 192.168.2 # セグメント指定 Allow from 10.1.0.0/255.255.0.0 Allow from 10.1.0.0/16 # IPv6個別、セグメント Allow from 2001:db8::a00:20ff:fea7:ccea Allow from 2001:db8::a00:20ff:fea7:ccea/10更に、クライアントのUser-Agent(OSやブラウザの種類)など環境変数によるアクセス許可の設定も行うことができます。
【例】「KnockKnock/2.0」で始まるUser-Agentからのアクセスを許可する SetEnvIf User-Agent ^KnockKnock/2\.0 let_me_in <Directory /docroot> Order Deny,Allow Deny from all Allow from env=let_me_in </Directory>
all
を引数に指定すれば全てを許可することになります。
<Directory>ディレクティブ
、.htaccess
Deny
Allowと同様。許可が拒否に変わるだけ。
Order
Allow
とDeny
のどちらを優先して適用するかを設定する。# 先にDenyを評価しマッチすれば拒否、その他は許可(デフォルト許可) Order Deny,Allow # 先にAllowを評価しマッチすれば許可、その他は拒否(デフォルト拒否) Order Allow,Denyアクセス元は、ホスト名・ドメイン名、完全なIPアドレス、IP アドレスの一部、ネットワークセグメントで指定できます。IPv4およびIPv6どちらも使えます。指定は空白区切りで複数列挙できます。
# ドメイン名指定 Allow from apache.org Allow from .net example.edu # IPv4の個別指定 Allow from 10.1.2.3 Allow from 192.168.1.104 192.168.1.205 # IPv4の前部指定 Allow from 10.1 Allow from 10 172.20 192.168.2 # セグメント指定 Allow from 10.1.0.0/255.255.0.0 Allow from 10.1.0.0/16 # IPv6個別、セグメント Allow from 2001:db8::a00:20ff:fea7:ccea Allow from 2001:db8::a00:20ff:fea7:ccea/10更に、クライアントのUser-Agent(OSやブラウザの種類)など環境変数によるアクセス許可の設定も行うことができます。
【例】「KnockKnock/2.0」で始まるUser-Agentからのアクセスを許可する SetEnvIf User-Agent ^KnockKnock/2\.0 let_me_in <Directory /docroot> Order Deny,Allow Deny from all Allow from env=let_me_in </Directory>
all
を引数に指定すれば全てを許可することになります。
<Directory>ディレクティブ
、.htaccess
Require[22]
【書式】アクセスを許可するホストを指定 Require host ホスト名 Require ip IPアドレス Require local Require all granted
【例】アクセスを許可するホストを指定 Require host example.org Require host .net example.edu Require ip 10.1.2.3 Require ip 192.168.1.104 192.168.1.205 Require ip 10.1 Require ip 10 172.20 192.168.2 Require ip 10.1.0.0/255.255.0.0 Require ip 10.1.0.0/16 Require ip 2001:db8::a00:20ff:fea7:ccea Require ip 2001:db8:1:1::a Require ip 2001:db8:2:1::/64 Require ip 2001:db8:3::/48
not を使って指定を否定(反転)できる
【例】192.168.205.xxx 以外からのアクセスを許可 Require not ip 192.168.205
複数の条件をandでつなぐ(全ての条件を満たした時のみアクセスを許可する)には<RequireAll> ... </RequireAll>を用いる
【例】アクセス元がexample.orgドメインでかつ、IPが1.2.3.xxx でないものにアクセスを許可 <RequireAll> Require example.org Require not ip 1.2.3 </RequireAll>
複数の条件をorでつなぐ(1つ以上の条件を満たした時にアクセスを許可する)には<RequireAny> ... </RequireAny>を用いる
【例】アクセス元がexample.orgドメインまたは、IPが1.2.3.xxx であるものにアクセスを許可 <RequireAny> Require example.org Require ip 1.2.3 </RequireAny>
【例1】"/var/www/html/internal" 以下へのアクセスには認証を要求するよう設定する。 アクセスを許可するユーザは AuthUserFile で指定したパスワードファイルに登録された全てのユーザ <Directory "/var/www/html/internal"> AuthType Basic AuthName "Welcome to Internal Site!" AuthUserFile "/var/www/work/.passwd" Require valid-user </Directory> 【例2】例1でアクセス許可ユーザを hoge のみに限定する場合 <Directory "/var/www/html/internal"> AuthType Basic AuthName "Welcome to Internal Site!" AuthUserFile "/var/www/work/.passwd" Require user hoge </Directory>
Directory
ディレクティブ内で、Satisfy
ディレクティブを記述して、Allow
とRequire
の両方が設定されている場合の挙動を指定することで実現可能。アクセス元の指定にはホスト名またはその一部(例:host.hoge.com、.foo.org)、IPアドレスまたはその一部(例:192.168.0.10、192.168.1.)、ネットワークセグメント(例:192.168.0.0/255.255.255.0、192.168.0.0/24)、
SatisfyディレクティブはApache2.4でなくなった?
【例】192.168.1.xxx ネットワークからは認証なし、それ以外は認証要求。認証ユーザのみアクセス許可。 <Directory "/var/www/html"> Require valid-user Order allow,deny Allow from 192.168.1. Satisfy Any </Directory>
なお、Satisfy
の書式は以下の通り
【書式1】「アクセス元が許可ネットワーク」でかつ「要認証」(他ネットワークからのアクセスは無条件拒否) Satisfy All 【書式2】「アクセス元が許可ネットワーク」なら無認証、それ以外は「要認証」 Satisfy Any
【書式1の例】アクセス元が192.168.1.xxx ネットワークで認証されたユーザのみアクセス許可。 <Directory "/var/www/html"> Require valid-user Order allow,deny Allow from 192.168.1 Satisfy All </Directory>
NISユーザ情報を使って認証にするは、AuthenNIS本体の他、付随していくつかのモジュール類が必要[1]。
Apacheのperlモジュールmod_perl
をmod_perlのサイトからダウンロードしてインストール。またはyumでインストール。以下はソースをダウンロードしてRPMパッケージをビルドしてインストールする場合の手順。
# ダウンロードする場所に移動 [root@server ~]# cd /usr/src/redhat/SOURCES # ダウンロード実行 [root@server SOURCES]# wget http://perl.apache.org/dist/mod_perl-2.0-current.tar.gz --2013-02-27 12:38:23-- http://perl.apache.org/dist/mod_perl-2.0-current.tar.gz perl.apache.org をDNSに問いあわせています... 140.211.11.131, 192.87.106.229, 2001:610:1:80bc:192:87:106:229 perl.apache.org|140.211.11.131|:80 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 3784950 (3.6M) [application/x-gzip] `mod_perl-2.0-current.tar.gz' に保存中 100%[==========================================================>] 3,784,950 851K/s 時間 4.8s 2013-02-27 12:38:29 (772 KB/s) - `mod_perl-2.0-current.tar.gz' へ保存完了 [3784950/3784950] # 解凍展開 [root@server SOURCES]# tar -zxvf mod_perl-2.0-current.tar.gz mod_perl-2.0.7/ mod_perl-2.0.7/Apache-Reload/ mod_perl-2.0.7/Apache-SizeLimit/ mod_perl-2.0.7/Apache-Test/ ... mod_perl-2.0.7/Apache-Reload/lib/Apache2/ mod_perl-2.0.7/Apache-Reload/lib/Apache2/Reload.pm mod_perl-2.0.7/Apache-Reload/lib/Apache/Reload.pm # RPM仕様ファイル(specファイル)をSPECSディレクトリにコピー [root@server SOURCES]# cp mod_perl-2.0.7/mod_perl.spec ../SPECS/ # 元のtarballをrename(specでの指定との整合性のため) [root@server SOURCES]# mv mod_perl-2.0-current.tar.gz mod_perl-2.0.7.tar.gz # specファイルディレクトリに移動 [root@server SOURCES]# cd ../SPECS # 同梱されているspecのバージョン指定などを修正 [root@server SPECS]# vim mod_perl.spec ... [root@server SPECS]# diff mod_perl.spec ../SOURCE/mod_perl-2.0.7/mod_perl.spec 1,4c1,4 < %define _version 2.0.6 < %define _release < %define _source http://perl.apache.org/dist/mod_perl-2.0.6-rc1.tar.gz < %define _dirname mod_perl-2.0.6-rc1 --- > %define _version 2.0.7 > %define _release 1 > %define _source http://perl.apache.org/dist/mod_perl-2.0.7.tar.gz > %define _dirname mod_perl-2.0.7 # RPMパッケージのビルド実行 [root@server SPECS]# rpmbuild -ba mod_perl.spec ... # RPMパッケージへの署名→RPMパッケージの署名方法についてを参照。 # yum localinstall あるいは RPMレポジトリに配置してInstall (Update)
perl-Sort-VersionsはExtUtils-AutoInstallのインストールでrpmビルドに必要となるので未インストールであればインストールしておく。Dag RPM RepositoryからrpmパッケージおよびGPGキーをダウンロードし、GPGキーをインポート(rpm --import キーファイル名
)、rpmパッケージをインストールして、rpmforgeをyum repositoryに追加されていれば見つかる。
# yum install perl-Sort-Versions
次項のperl-CPANPLUSのインストールでperl-DBD-SQLiteなどいくつかの追加パッケージもインストールする必要があるが、これらをインストールするため、epelレポジトリを参照先レポジトリに追加しておく。RepoView: "Fedora EPEL 5 - i386"などからレポジトリを追加するためのRPMパッケージをインストールする。
【例】epelレポジトリのgpgkeyをimport # wget http://ftp.tsukuba.wide.ad.jp/Linux/fedora/epel/5/i386/epel-release-5-4.noarch.rpm # yum localinstall epel-release-5-4.noarch.rpm Loaded plugins: rhnplugin, security This system is receiving updates from RHN Classic or RHN Satellite. Excluding Packages in global exclude list Finished Excluding Packages from Red Hat Enterprise Linux (v. 5 for 64-bit x86_64) Finished Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package epel-release.noarch 0:5-4 set to be updated --> Finished Dependency Resolution Dependencies Resolved ==================================================================================================== Package Arch Version Repository Size ==================================================================================================== Installing: epel-release noarch 5-4 myrepoh 12 k Transaction Summary ==================================================================================================== Install 1 Package(s) Upgrade 0 Package(s) Total size: 12 k Is this ok [y/N]: y Downloading Packages: Running rpm_check_debug Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction Installing : epel-release 1/1 Installed: epel-release.noarch 0:5-4 Complete!
なおrpmパッケージをインストールする際、gpgkeyのインポートも必要かもしれない。
【例】epelパッケージインストールに失敗したのでレポジトリのgpgkeyをimport # yum localinstall epel-release-5-4.noarch.rpm Loaded plugins: rhnplugin, security This system is receiving updates from RHN Classic or RHN Satellite. Excluding Packages in global exclude list Finished Excluding Packages from Red Hat Enterprise Linux (v. 5 for 64-bit x86_64) Finished Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package epel-release.noarch 0:5-4 set to be updated --> Finished Dependency Resolution Dependencies Resolved ==================================================================================================== Package Arch Version Repository Size ==================================================================================================== Installing: epel-release noarch 5-4 myrepo 12 k Transaction Summary ==================================================================================================== Install 1 Package(s) Upgrade 0 Package(s) Total download size: 12 k Is this ok [y/N]: y Downloading Packages: epel-release-5-4.noarch.rpm | 12 kB 00:00 警告: rpmts_HdrFromFdno: ヘッダ V3 DSA signature: NOKEY, key ID 217521f6 ksys-noarch/gpgkey | 1.7 kB 00:00 Public key for epel-release-5-4.noarch.rpm is not installed # rpm --import http://ftp.jaist.ac.jp/pub/Linux/Fedora/epel//RPM-GPG-KEY-EPEL
perl-CPANPLUSはExtUtils-AutoInstallのインストールでrpmビルドに必要となるので未インストールであればインストールしておく。perl-CPANPLUSのサイトには、ソースバイナリしかないみたい。古いバージョン用のSPECファイルがDAG: perl-CPANPLUSにあったので、それを改造し、バイナリソースからrpmパッケージを作成しインストール。
[root@server ~]# cd /usr/src/redhat/SOURCES/ [root@server SOURCES]# wget http://search.cpan.org/CPAN/authors/id/B/BI/BINGOS/CPANPLUS-0.9001.tar.gz ※名前を「perl-CPANPLUS」に変えておかないと、SPECファイルとの整合性がとれないので一旦解凍し、リネームして再圧縮 [root@server SOURCES]# tar -zxvf CPANPLUS-0.9001.tar.gz [root@server SOURCES]# mv CPANPLUS-0.9001.tar.gz perl-CPANPLUS-0.9001 [root@server SOURCES]# tar -zcvf perl-CPANPLUS-0.9001.tar.gz [root@server SOURCES]# rm CPANPLUS-0.9001.tar.gz [root@server SOURCES]# cd ../SPECS [root@server SPECS]# wget http://dag.wieers.com/rpm/packages/perl-CPANPLUS/perl-CPANPLUS.spec [root@server SPECS]# vi perl-CPANPLUS.spec 以下の点を修正 ---- ・Version: 0.82 → 0.9001 ・%{real_name} を参照しているところは %{name} に変更 ---- [root@server SPECS]# rpmbuild -ba perl-CPANPLUS.spec [root@server SPECS]# rpm --resign /usr/src/redhat/RPMS/noarch/perl-CPANPLUS-0.9001-1.noarch.rpm パスフレーズの入力: [root@server SPECS]# yum install perl-CPANPLUS
なお、依存関係により合わせて必要となるパッケージ群を同時にインストールするため、epelレポジトリを先に追加しておく必要あり。レポジトリの追加については前節や参照先rpmレポジトリの編集を参照。
「ExtUtils-AutoInstall」はDag RPMのperl-ExtUtils-AutoInstallから適当なものをダウンロードしてインストールすればよいとのこと。インストール先OS(RHEL5)用のものがないので、rpmソースパッケージ(perl-ExtUtils-AutoInstall-0.63-1.test.src.rpm)をダウンロードし、rpmをビルド。
# cd /usr/src/redhat/SRPMS/ # wget http://dag.wieers.com/rpm/packages/perl-ExtUtils-AutoInstall/perl-ExtUtils-AutoInstall-0.63-1.test.src.rpm ※バイナリパッケージをビルド # rpm -ivh perl-ExtUtils-AutoInstall-0.63-1.test.src.rpm # cd ../SPECS # rpmbuild -bb perl-ExtUtils-AutoInstall-0.63-1.spec 署名追加(→rpmパッケージへ署名する方法参照) # cd ~ ←署名マクロ(.rpmmacro)のある場所へ移動 # rpm --resign /usr/src/redhat/RPMS/noarch/perl-ExtUtils-AutoInstall-0.63-1.rf.noarch.rpm ※バイナリパッケージをインストール # yum install /usr/src/redhat/RPMS/noarch/perl-ExtUtils-AutoInstall-0.63-1.rf.noarch.rpm
参考文献・サイト
rpmforge-release package をインストールして、yum repositoryにrpmforgeを追加しておけばyumで簡単にインストールできる。
# yum install perl-Net-NIS
次項のApache(2)-AuthenNISのインストールで、README記載通りの手順を踏もうとすると「Invalid command 'PerlAuthenHandler'」というエラーが発生。perl-Module-Build のRPMパッケージをrpmforgeよりインストールしたらエラーは出なくなった。なお、依存関係により追加で2パッケージもインストールされるが前述のepelレポジトリも登録必要。
[root@server Apache2-AuthenNIS-0.15]# /etc/init.d/httpd configtest Syntax error on line xxx of /etc/httpd/conf/httpd.conf: Invalid command 'PerlAuthenHandler', perhaps misspelled or defined by a module not included in the server configuration [root@server Apache2-AuthenNIS-0.15]# perl Build.PL Can't locate Module/Build.pm in @INC (@INC contains: /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8 .) at Build.PL line 3. BEGIN failed--compilation aborted at Build.PL line 3. [root@server Apache2-AuthenNIS-0.15]# yum install perl-Module-Build Loaded plugins: rhnplugin, security This system is receiving updates from RHN Classic or RHN Satellite. Excluding Packages in global exclude list Finished Excluding Packages from Red Hat Enterprise Linux (v. 5 for 64-bit x86_64) Finished Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package perl-Module-Build.noarch 1:0.3607-1.el5.rf set to be updated --> Processing Dependency: perl(ExtUtils::CBuilder) >= 0.27 for package: perl-Module-Build --> Processing Dependency: perl(ExtUtils::ParseXS) >= 2.21 for package: perl-Module-Build --> Running transaction check ---> Package perl-ExtUtils-CBuilder.noarch 0:0.2603.01-1.el5.rf set to be updated ---> Package perl-ExtUtils-ParseXS.noarch 0:2.2206-1.el5 set to be updated --> Finished Dependency Resolution Dependencies Resolved ==================================================================================================== Package Arch Version Repository Size ==================================================================================================== Installing: perl-Module-Build noarch 1:0.3607-1.el5.rf rpmforge 298 k Installing for dependencies: perl-ExtUtils-CBuilder noarch 0.2603.01-1.el5.rf rpmforge 36 k perl-ExtUtils-ParseXS noarch 2.2206-1.el5 epel 33 k Transaction Summary ==================================================================================================== Install 3 Package(s) Upgrade 0 Package(s) Total download size: 367 k Is this ok [y/N]: y Downloading Packages: (1/3): perl-ExtUtils-ParseXS-2.2206-1.el5.noarch.rpm | 33 kB 00:00 (2/3): perl-ExtUtils-CBuilder-0.2603.01-1.el5.rf.noarch.rpm | 36 kB 00:00 (3/3): perl-Module-Build-0.3607-1.el5.rf.noarch.rpm | 298 kB 00:01 ---------------------------------------------------------------------------------------------------- Total 116 kB/s | 367 kB 00:03 Running rpm_check_debug Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction Installing : perl-ExtUtils-CBuilder 1/3 Installing : perl-ExtUtils-ParseXS 2/3 Installing : perl-Module-Build 3/3 Installed: perl-Module-Build.noarch 1:0.3607-1.el5.rf Dependency Installed: perl-ExtUtils-CBuilder.noarch 0:0.2603.01-1.el5.rf perl-ExtUtils-ParseXS.noarch 0:2.2206-1.el5 Complete!
Apache2::AuthenNIS(NIS認証モジュールmod_perl2)をインストール(Apache2.2の場合、Apache2.0の場合はApache::AuthenNIS)。rpmパッケージにするのは面倒なのでやってない。
[root@server ~]# wget http://search.cpan.org/CPAN/authors/id/I/IT/ITEAHAUS/Apache2-AuthenNIS-0.15.tar.gz [root@server ~]# tar -zxvf Apache2-AuthenNIS-0.15.tar.gz [root@server ~]# cd Apache2-AuthenNIS-0.15 [root@server Apache2-AuthenNIS-0.15]# perl Makefile.PL Checking if your kit is complete... Looks good Writing Makefile for Apache2::AuthenNIS [root@server Apache2-AuthenNIS-0.15]# make cp lib/Apache2/AuthenNIS.pm blib/lib/Apache2/AuthenNIS.pm Manifying blib/man3/Apache2::AuthenNIS.3pm [root@server Apache2-AuthenNIS-0.15]# make install Installing /usr/lib/perl5/site_perl/5.8.8/Apache2/AuthenNIS.pm Installing /usr/share/man/man3/Apache2::AuthenNIS.3pm Writing /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/auto/Apache2/AuthenNIS/.packlist Appending installation info to /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/perllocal.pod
NISグループ単位でアクセス許可をしたい場合は、Apache2:AuthzNISもインストール(Apache2.2の場合、Apache2.0の場合はApache::AuthzNIS)。手順は同上。
[root@server ~]# wget http://search.cpan.org/CPAN/authors/id/I/IT/ITEAHAUS/Apache2-AuthzNIS-0.13.tar.gz [root@server ~]# tar -zxvf Apache2-AuthzNIS-0.13.tar.gz [root@server ~]# cd Apache2-AuthzNIS-0.13 [root@server Apache2-AuthzNIS-0.13]# perl Makefile.PL Checking if your kit is complete... Looks good Writing Makefile for Apache2::AuthzNIS [root@server Apache2-AuthzNIS-0.13]# make cp lib/Apache2/AuthzNIS.pm blib/lib/Apache2/AuthzNIS.pm Manifying blib/man3/Apache2::AuthzNIS.3pm [root@server Apache2-AuthzNIS-0.13]# make install Installing /usr/lib/perl5/site_perl/5.8.8/Apache2/AuthzNIS.pm Installing /usr/share/man/man3/Apache2::AuthzNIS.3pm Writing /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/auto/Apache2/AuthzNIS/.packlist Appending installation info to /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/perllocal.pod
【書式】 <Directory "ディレクトリ名"> AuthType 認証方式 AuthName 認証名 PerlAuthenHandler Apache2::AuthenNIS PerlAuthzHandler Apache2::AuthzNIS PerlSetVar AllowAlternateAuth no require 許可ユーザ </Directory> 【例】 <Directory "/var/www/html/internal"> AuthType Basic AuthName "Internal site (input your id and password)" PerlAuthenHandler Apache2::AuthenNIS PerlAuthzHandler Apache2::AuthzNIS PerlSetVar AllowAlternateAuth no require valid-user </Directory>
通常はcgiの実行もApacheデーモンの実行ユーザで実行されるが、suExecを有効にするとcgiの実行は別ユーザで行われる。Apache設定ファイルで、SuexecUserGroup
ディレクティブの指定を行うとsuExecが適用される?(有効になるようにオプションしてインストールしておく必要がある?)
設定ファイル(メイン) | 設定ファイル(バーチャルホスト) | .htaccess |
---|---|---|
○ | ○ | × |
【書式】 SuexecUserGroup ユーザ名 グループ名 【例】 SuexecUserGroup nobody nogroup
参考文献・サイト
ScriptAliasディレクトリ(cgi-bin
など)配下のファイルは何でも実行ファイルとして扱われてしまうため、このようなディレクトリ配下に置いた画像を表示しようとしても、表示できずエラーになる。回避方法としては(1)ScriptAliasディレクトリの外に画像ファイルを置く(2)ScriptAliasディレクトリの設定に以下のような設定を追加する、がある。
<Directory "/var/www/cgi-bin"> AddHandler image/gif .gif AddHandler image/jpg .jpg AddHandler image/png .png </Directory>
参考文献・サイト
SetHandlerはファイルの種類を指定する。
使用できる場所(コンテキスト):サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き:FileInfo
【書式】
SetHandler ハンドラ名
【例】"help" をCGIスクリプトとして処理する
<Files "help">
SetHandler cgi-script help
</Files>
AddType
ディレクティブは、拡張子とファイル種別の対応情報を追加する。MIMEタイプファイルにない対応を追加するのに利用できる。
書式 |
AddType MIMEタイプ 拡張子 拡張子 ...
|
---|---|
設定可能箇所 |
|
htmlコード内にPHPコードで他のファイルに記されたhtmlコードを差し込むのに .html ファイルをPHPコードファイルとして登録が必要。
$ cat main.html <html> <body> <!-- ここからinclude --> <?php include 'sub.html'; ?> <!-- ここまでinclude --> </body> </html> $ cat sub.html ほげほげ 既定の設定では .html 内のPHPコードは PHPコードとして処理されずそのまま出力される $ grep AddType httpd.conf $ $ wget -q -O - http://localhost/main.html ※wgetコマンドについてはUNIX関係を参照 <html> <body> <!-- ここからinclude --> <?php include 'sub.html'; ?> <!-- ここまでinclude --> </body> </html> .html もPHPコードとしてタイプを追加しておく $ grep AddType httpd.conf AddType application/x-httpd-php .php .html $ echo `wget -q -O - http://localhost/main.html <html> <body> <!-- ここからinclude --> ほげほげ <!-- ここまでinclude --> </body> </html>
DocumentRootからの物理的パスとは異なる場所にあるコンテンツを返す方法として、Alias、Redirect、Rewriteがある。それぞれの特徴などを以下にまとめる。
ディレクティブ名 | エイリアス | リダイレクト | リライト |
---|---|---|---|
概要 | URL とファイルシステムのパスを対応づける。DocumentRoot配下にないコンテンツにウェブサイトへのアクセスで参照できるようにすることもできる。 | クライアントに別のURLに新たなリクエストを送るように指示する。 | アクセスリクエストの内容を都度変更した上で応答する。Redirectより複雑な制御が可能。 |
適用可能範囲 | ローカルのみ | 別サイトへ向けることも可能 | 別サイトへ向けることも可能 |
使用するモジュール | mod_alias | mod_alias | mod_rewrite |
設定可能場所 | サーバ設定ファイル、バーチャルホス | サーバ設定ファイル、バーチャルホスト、ディレクトリ、.htaccess | (ディレクティブによって異なる) |
AliasはURL とファイルシステムのパスを対応づける指定を行う。正規表現を使った指定を行うにはAliasMatchを用いる。正規表現はPCRE(Perl互換)。詳細は各正規表現の比較 - 正規表現・ワイルドカード参照。
【必要モジュール】mod_alias 【使用可能場所(コンテキスト)】サーバ設定ファイル(httpd.conf)、バーチャルホスト(<VirtualHost>) 【書式】 Alias URLパス ローカルパス AliasMatch URL正規表現 ローカルパス 【例】/image 配下へのアクセスに対し /ftp/pub/image 配下のコンテンツを返すようにする Alias /image /ftp/pub/image 【例】/icons で始まるパスへのアクセスに対し /usr/local/apache2/icons 配下のコンテンツを返すようにする Alias ^/icons(.*) /usr/local/apache2/icons$1
Redirectは古いURLを新しいURLと対応づけて、クライアントに新しい場所を訪れるように指し示す。対象の指定に正規表現を使いたい場合はRedirectMatchを用いる。正規表現はPCRE(Perl互換)。詳細は各正規表現の比較 - 正規表現・ワイルドカード参照。
【必要モジュール】mod_alias 【使用可能場所(コンテキスト)】サーバ設定ファイル(httpd.conf)、バーチャルホスト(<VirtualHost>)、 ディレクトリ(<Directory>)、ディレクトリ別設定(.htaccess) 【書式】 Redirect ステータス 処理対象URLパス リダイレクト先URL RedirectMatch ステータス 処理対象URL正規表現 リダイレクト先URL 【例】index_ja.cgi または index_en.cgi は 別サイトへ一時リダイレクト RedirectMatch (index_)(ja|en)(\.cgi) http://www.hoge.com/$1$2$3 (ja|en) → ja または en (\.cgi) → 正規表現で.(ピリオド)は任意の1文字を意味するため、 ピリオドそのものを指定したい場合は直前にバックスラッシュを置いてエスケープ $1 → 1番目の( )の内容 【例】ドキュメントルートへのアクセスは /hoge/ にリダイレクト Redirect / /hoge/
値 | コード | 意味 |
---|---|---|
permanent | 301 | 永久リダイレクト(リソースが永久に移動したということを意味する)。 |
temp | 302 | 一時リダイレクト(デフォルト)。 |
seeother | 303 | See Other ステータス(リソースが他のもので置き換えられたことを意味する)。 |
gone | 410 | Gone ステータス(リソースが永久に 削除されたことを意味する)。このステータスの場合リダイレクト先URLは指定しない。 |
mod_rewrite
モジュールはルールを定義し、そのルールに記載された正規表現をリライトエンジンが解釈して動作する。ルールの定義数には制限がなく、柔軟で強力なURLの操作ができる。条件にはサーバ変数、環境変数、HTTPヘッダ、タイムスタンプなどを利用することもできる。様々な書式で外部データベースを参照し、非常に詳細なURLマッチングを行うこともできる。
RewriteEngineはリライト機能を有効にするかどうかを設定する。
【書式】
RewriteEngine スイッチ
【設定できる場所(コンテキスト)】
/etc/httpd/conf/httpd.conf
など)<VirtualHost>
ディレクティブ内)<VirtualHost>
ディレクティブ内)RewriteCond(2.2 / 2.4)はRewriteRuleを適用するための条件を指定する。
【書式】 RewriteCond 評価対象 条件 フラグ
通常の文字列および以下の拡張指定が利用可能。
RewriteRule(2.2 / 2.4)はURL書き換えのルールを定義する。1つのRewriteRuleに記載できるルールは1つだけだが、RewriteRuleを複数個記載することにより複数のルールを記載できる。ルールは登場順に適用される。
【書式】 RewriteRule 対象URLパターン 書き換え後URL [フラグ]
パターンはPerl互換正規表現(PCRE)で記す。リクエストされたURLがこのパターンに適合した場合、URL書き換え対象となる。
通常、VirtualHost内ではホスト名、ポート部分とクエリ文字列を除いた部分(例:/app1/index.html)が照合対象となる。これら除いた部分も参照したい場合は %{HTTP_HOST}、%{SERVER_PORT}、%{QUERY_STRING} の変数を参照する必要がある。Directoryや.htaccessではデフォルトの対象がprefix部分を除いたファイルシステムパスとなる(例:app1/index.html)。
フラグとその書式 | 内容 |
---|---|
B | 書き換えを適用する前に非アルファベット文字のエスケープ処理を行う。 |
BNP | 後方参照表現にエスケープ処理が適用されているとき、空白は + ではなく %20 でエスケープすべき。URLをクエリ文字列としてではなく、パス構成要素として扱う時にこのオプションは有用。 |
backrefnoplus | |
C | 後続のルールも続いて適用する。ルールに適合しなかった場合、そのルールは適用されず後続のルール判定に移る。 |
chain | |
CO=キー名:値 |
クライアントのブラウザにクッキーを設定する。完全な書式は以下の通り:CO=キー名:値:ドメイン:有効期限:パス:Secure:httponly
【例】URLの書き換えは行わない(リダイレクト先 "-")が、キーと値が(frontdoor:yes)のクッキーを設定する。クッキーは .example.com ドメイン配下のあらゆるホストで有効。有効期限は 1440分(=24時間)。有効ホスト内にあるすべてのURLでクッキーが送られる。 RewriteEngine On RewriteRule "^/index\.html" "-" [CO=frontdoor:yes:.example.com:1440:/] |
cookie=キー名:値 | |
L | Rewrite処理を終了し、以降のルールは適用しない。ディレクトリ別設定や.htaccessにおける設定の際には特に注意が必要 |
last | |
N | 書き換え後のURLに対して、再び最初のルールから書き換えチェックを行う。 |
next | |
PT | 他のURL書き換えに関係するルール(Alias、Redirect、ScriptAlias)も適用できるようにする。この指定がないと、書き換え後のパスは(プロトコル・ドメイン部分の指定がなければ)DocumentRootからのパスと見なされ、Aliasなどの設定は適用されない。 |
passthrough | |
R=httpコード | 外部へ強制的にリダイレクトする。プロトコル・ドメイン部分を省略すると、自己ドメインのもの(例:http://somedomain)を書き換え後URLの前に付加する。その際に返すhttpコードを指定することもできる。httpコードを指定しない場合、既定値として302(Found)がセットされる。恒久的なリダイレクトなら301を指定する。 |
redirect | |
【設定できる場所(コンテキスト)】
/etc/httpd/conf/httpd.conf
など)<VirtualHost>
ディレクティブ内)<VirtualHost>
ディレクティブ内).htaccess
)
ホスト名ベースでのバーチャルホスト(異なるホスト名でアクセスしてくると別のコンテンツを返す仕組み)の設定を行うにはサーバ設定ファイル(httpd.conf
)に以下の記述を行う。
【書式】 NameVirtualHost IPアドレス:ポート番号 【例】192.168.0.1 の 8080 ポートでバーチャルホストリクエストを受け付ける NameVirtualHost 192.168.0.1:8080 【例】全インタフェースへのリクエストを受け取る NameVirtualHost *
なお「NameVirtualHost」ディレクティブを記述すると、メインのホスト設定(ServerNameなどの設定)は無効になるので、メインホストも含めVirtualHost設定を記述する必要がある[17]。
また各NameVirtualHostの指定に対し、同じ引数を持った<VirtualHost>要素を1つ以上定義する必要がある。そうでないとApache起動時(またはconfigtest時)「VirtualHost *:80 -- mixing * ports and non-* ports with a NameVirtualHost address is not supported, proceeding with undefined results」のようなエラーが出る。
【OKな例】 1) NameVirtualHost * <VirtualHost *> ServerName www.hoge.com </VirtualHost *> 2) NameVirtualHost *:80 <VirtualHost *:80> ServerName www.hoge.com </VirtualHost *> 【NGな例】 1) <VirtualHost *> がない NameVirtualHost * <VirtualHost *:80> ServerName www.hoge.com </VirtualHost *> 2) <VirtualHost *:80> がない NameVirtualHost *:80 <VirtualHost *> ServerName www.hoge.com </VirtualHost *>
【書式】 <VirtualHost アドレス:ポート番号アドレス:ポート番号> ServerName スキーム名://完全修飾ホスト名:ポート番号 DocumentRoot ローカルディレクトリパス </VirtualHost>
【例】 <VirtualHost *:80> ←http://www.hoge.com/ へのアクセスには /var/www/html を見せる ServerName www.hoge.com DocumentRoot /var/www/html </VirtualHost> <VirtualHost *:80> ←http://doc.hoge.com/ へのアクセスには /var/www/doc を見せる ServerName doc.hoge.com DocumentRoot /var/www/doc </VirtualHost>
バーチャルホストに関するアクセスの処理フローを以下に示す。
参考文献・サイト
HTTP TRACEメソッドは、クライアントのHTTPリクエストをそのままTRACEレスポンスとして返す。Webサイトにクロスサイトスクリプティングの脆弱性が存在し、Webブラウザにクロスドメインの脆弱性がある場合、このメソッドを使ってcookie情報や認証情報を含む機密情報を取得されてしまう可能性がある。コネクションのデバッグには有用だが、必要ない場合は許可しないよう設定するべき。Apacheの場合以下の記述を設定ファイル(httpd.conf
)に追加するとTRACEメソッドの使用が許可されなくなる(古いApacheではmod_rewriteモジュールの組み込みと、Rewriteディレクティブの記述も必要らしい)。
TraceEnable off
参考文献・サイト
Alias
はサーバ内でのコンテンツファイルを別名でも呼び出せるようにするもの。
Redirect
はアクセスに対し、新URLを通知し、新URLに再アクセスを促すもの。サイト移転などに使う。
Rewrite
はサーバ側でURLを変換して返してしまうので、クライアント側から見るとアクセス先URLが存在するかのように振る舞う。
参考文献・サイト
ウェブページにアクセスする際、htmlファイルに続きファイル内で指定されている画像ファイルなども取得しに行くことが一般的だが、このように連続したアクセスにおいてファイルごとに通信セッションを張り直していると効率が悪いので、一定の間セッションを維持することが行われる。その仕組みは「KeepAlive」と呼ばれ、ApacheはデフォルトでONになっているが、KeepAliveディレクティブで指定することができる。また最大同時接続数は「MaxKeepAliveRequests」ディレクティブ、リクエストが来なくなってからセッションを切るまでの秒数は「KeepAliveTimeout」ディレクティブで設定できる[7]。
また接続クライアント数などの状況をリアルタイムで知るには以下の方法を使う[7]。
<Location /server-status> SetHandler server-status Order deny,allow # 拒否設定が先に適用され、許可設定が後で上書き Deny from all # まず全てからのアクセスを拒否 Allow from 192.168.0 # アクセスを許可するアクセス元IP(前方一致) Allow from 127.0.0.1 </Location> # 詳細出力をOnにする場合、以下の1行も追記。 ExtendedStatus On
http://サーバ名/server-status
にアクセスする。?auto
をURLの末尾に付加すればスクリプト処理に使いやすい書式で出力される。
/etc/init.d/httpd configtest
で設定ファイル(httpd.conf
など)に文法エラーがないかチェックできる。
# /etc/init.d/httpd configtest Syntax OK
同時接続最大数の設定は、Apache設定ファイル中のMaxClientsにて行う。この設定はMPM(Multi-Processing Module)[13][14]の動作モード別に設定できるようになっていて、Preforkモード(スレッドを使わず先行してforkするモード、互換性重視、UNIXではこれが既定値)で動作している場合と、Worker(マルチスレッドとマルチプロセスのハイブリッド型動作モード)それぞれ別に値を設定可能。MaxClients値はServerLimit値を越えないよう動作するので、必要に応じServerLimit値も変更する。設定値の目安は「使用可能なメモリ量/Apacheの1プロセスが使用するメモリ量」らしい[12]
参考:httpd - Apache Hypertext Transfer Protocol Server - Apache HTTP Server
httpd
はApacheハイパーテキスト転送プロトコル(HTTP)サーバプログラムです。単独のデーモンプロセスとして動作するよう設計されています。動作する際、子プロセスやスレッドを用意しておいてリクエストを制御できるようにします。
通常、UNIXベースのシステムやWindowsNT、2000、XPのサービス、Windows 9xやMeのコンソールアプリケーションにおいてhttpd
は直接実行すべきではなく、apachectl
を通して実行すべきです。
【書式】
httpd オプション
-d serverroot
-f config
-C ディレクティブ
-c ディレクティブ
-D パラメータ
-e レベル
-E ファイル
-R ディレクトリ
-h
-k
-L
-l
-M
-n
-S
【例】 # httpd -S VirtualHost configuration: wildcard NameVirtualHosts and _default_ servers: *:443 hoge.org (/etc/httpd/conf.d/newweb_ssl.conf:3) _default_:8443 www.hoge.org (/etc/httpd/conf.d/nss.conf:84) *:80 is a NameVirtualHost default server hoge.org (/etc/httpd/conf/httpd.conf:1) port 80 namevhost www.hoge.org (/etc/httpd/conf.d/legacy.conf:20) Syntax OK
-T
-t
-V
-v
【例】 $ httpd -v Server version: Apache/2.2.25 (Unix) Server built: Jul 25 2013 13:57:30
-w
-X
WebDAV(Web-base Distributed Authoring and Versioning)サービスを使うと、httpでファイルのやりとりができる。Apache 2.2での実装手順は以下の通り[11]
[/etc/httpd/conf/httpd.conf] ... LoadModule mime_module modules/mod_mime.so LoadModule dav_module modules/mod_dav.so LoadModule status_module modules/mod_status.so LoadModule autoindex_module modules/mod_autoindex.so LoadModule info_module modules/mod_info.so LoadModule dav_fs_module modules/mod_dav_fs.so LoadModule vhost_alias_module modules/mod_vhost_alias.so ...
/var/www/webdav
をWebDAV用ディレクトリとして作成。
# mkdir /var/www/webdav
Apache実行ユーザを所有者にしておく。以下はapache:apacheが実行ユーザである場合。
# chown apache:apache /var/www/webdav
/etc/httpd/conf.d/webdav.conf
を作成し以下の内容を記述。
# エイリアス設定 Alias /webdav/ "/var/www/webdav/" <IfModule mod_dav.c> DAVMinTimeout 600 <Location /webdav> DAV On Order deny,allow Deny from all Allow from all </Location> </IfModule> # 認証を設ける場合の例 <Directory "/var/www/webdav"> Options +Indexes AuthType Basic AuthName "Welcome to WebDAV service" AuthUserFile /var/www/.htpasswd Require valid-user </Directory>
ログ(access_log, error_log ) |
/var/log/httpd/ |
設定(httpd.conf ) |
/private/etc/apache2/httpd.conf |
モジュール(*.so ) |
/usr/libexec/httpd/ |
tomcatのコンソールログ catalina.out をrotateするには、Tomcat起動スクリプト catalina.sh を改造し、Apache付属の rotatelogs コマンドを使うようにすればいいらしい[14]
Webログ解析ツールの一つwebalizerについて。このツールはApacheのアクセスログを解析したレポートをWebコンテンツとして出力してくれるもの。
RHEL5では既に入っていた(業者が気を利かせて入れてくれたのかも知れない)。ただ、既定ではローカルホストからのアクセスしか許可しない設定になっている。設定は、/etc/httpd/conf.d/webalizer.conf
に記述されているが、アクセスを許可するにはこのファイルを編集する。
【例】192.168.0.0/24 ネットワークからのアクセスは許可(赤字部追記) Alias /usage /var/www/usage <Location /usage> Order deny,allow Deny from all Allow from 127.0.0.1 Allow from ::1 # Allow from .example.com Allow from 192.168.0 </Location>
参考文献・サイト
Apache設定ファイル(/etc/httpd/conf/httpd.conf
など)にLogFormatディレクティブを用いて指定する。
【書式】 LogFormat 書式指示またはニックネーム ニックネーム 【既定値】 LogFormat "%h %l %u %t \"%r\" %>s %b" 【設定可能箇所】 サーバ設定ファイル(httpd.confなど)、バーチャルホスト設定内 【使用モジュール】 mod_log_config
指示子 | 内容 | 出力例 |
---|---|---|
%% | % の文字そのもの | % |
%a | リクエスト元となるクライアントのIPアドレスとポート番号 | |
%A | ローカルIPアドレス | |
%B | 応答で返したデータ量をバイト単位で示したもの。HTTPヘッダ部分はこの量には含まない。 | 12345 |
%b | 応答で返したデータ量をバイト単位で示したもの。HTTPヘッダ部分はこの量には含まない。CLFフォーマットでは、何も返答されなかった場合、0ではなく-が記録される。 | 12345 |
%h | リモートホスト名。名前解決をoffにする設定(HostnameLookups Off)になっていれば アクセス元IPアドレスが、そうでなければホスト名が記録される。 | 133.1.158.151 |
%{指定子}i |
サーバに送られて来たリクエストのヘッダの中から指定子で指定した内容を記録する。
|
%{User-Agent}i → Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) |
%l | リモートログ名(identdが動作していればそこから得られる値)。mod_identモジュールがloadされており、かつIdentityCheckがONになっている(認証が行われた)でない限り、ダッシュ(-)がセットされる。 | - |
%r | リクエストの先頭行 | |
%s | HTTPステータス。内部でリダイレクトが行われた場合、リダイレクト前のステータスを記録する。%>s と記せば転送後の最終的なステータスが記録される。 | 200 |
%t | アクセスリクエストを受けた時刻。書式は英語の標準書式 | |
%v | サーバがリクエストに対して応答した完全なServerName | |
%u | リクエストが認証済みのものであった場合、リモートユーザ名が記載される。但し、HTTPステータスが401(認証失敗)であった場合、有効なユーザ名ではない可能性がある。 |
修飾子
% と指示子の間にHTTPステータスを示す3桁の数値(コンマ区切りで複数併記可能)を記すと、指定したHTTPステータスのアクセスのみ当該指示子に対応する情報が記録され、それ以外のHTTPステータスであった場合はハイフン(-)が記録される。例:%400,500{User-Agent}i→HTTPステータスが400または500であった場合はUser-Agent情報が記録され、その他のステータスであった場合は-が記録される。
また数値の前に ! を記すと指定した値にマッチ「しなかった」HTTPステータスであった場合に情報の記録が行われ、マッチした場合に-が記録される。
PHPスクリプトによるウェブページへのアクセスで発生したエラーは基本的にはApacheに渡され、Apacheのエラーログに記録されるが、これを別のログに分離する方法を以下に記す[18][19]。
/etc/php.ini
など)あるいはApache設定ファイル(/etc/httpd/conf/httpd.conf
など)で
【PHP設定ファイルの場合】下記1行を追加 error_log = 'ログファイル名' 例: error_log = '/var/log/php.log' 【Apache設定ファイルによるPHP設定上書き】 PHP_Value error_log = 'ログファイル名'
touch
で空のログファイルを作成し、アクセス権を変更しておくといった方法がある。
# ls -l /var/log/php.log ls: /var/log/php.log: そのようなファイルやディレクトリはありません # touch /var/log/php.log # ls -l /var/log/php.log -rw-r--r-- 1 root root 0 4月 16 10:32 /var/log/php.log # ↑このアクセス権では、非rootのapache実行ユーザは書き込むことができない # chmod 666 /var/log/php.log # ls -l /var/log/php.log -rw-rw-rw- 1 root root 0 4月 16 10:32 /var/log/php.log
logrotateにより新たに生成されたログが書き込めなくなることを防ぐよう設定しておく。
例:/etc/logrotate.d/php /var/log/php.log { missingok notifempty size 1M rotate 12 create 0666 root root }
httpsサイト運営時に必要となるサーバ証明書には有効期限がある。certwatchを動作させた時、期限までの日数が一定値(既定値は30日)を切るとrootに警告メールが飛ぶようになる。これを解消するには証明書の更新が必要。
サーバ証明書の有効期限は以下の方法で確認できる[20]。
# certutil -d /etc/httpd/alias -L -n Server-Cert Certificate: Data: Version: 3 (0x2) Serial Number: 3 (0x3) Signature Algorithm: PKCS #1 SHA-1 With RSA Encryption ... Validity: Not Before: Wed Nov 04 15:17:06 2009 Not After : Mon Nov 04 15:17:06 2013 ...
【例】 #!/usr/local/bin/perl →正しくは"/usr/bin/perl" →1. "/usr/bin/perl"と修正する →2. "/usr/local/bin/perl" へのシンボリックリンクファイルを作る (ln -s /usr/bin/perl /usr/local/bin/perl)
【例】 shell> sudo less /var/log/httpd/error_log Apacheのエラーログには以下の出力 Compile Error: failed to link "qdbm" dynamically: /usr/lib/gauche/site/0.8.14/i686-pc-linux-gnu/qdbm.so: cannot restore segment prot after reloc: Permission denied shell> ls -Z /usr/lib/gauche/site/0.8.14/i686-pc-linux-gnu/ ←-Z オプションは --context を指定したのと同じらしい -r-xr-xr-x root root user_u:object_r:lib_t dbd_mysql.so -r-xr-xr-x root root system_u:object_r:default_t qdbm.so shell> sudo chcon -v -u user_u -t textrel_shlib_t /usr/lib/gauche/site/0.8.14/i686-pc-linux-gnu/qdbm.so shell> ls -Z /usr/lib/gauche/site/0.8.14/i686-pc-linux-gnu/ -r-xr-xr-x root root user_u:object_r:lib_t dbd_mysql.so -r-xr-xr-x root root user_u:object_r:textrel_shlib_t qdbm.so ↑Gaucheでqdbmを使うためのこれはtextrel_shlib_tのコンテキストでないと動かないらしい
[root@server ~]# /etc/init.d/httpd start httpd を起動中: (98)Address already in use: make_sock: could not bind to address [::]:80 (98)Address already in use: make_sock: could not bind to address 0.0.0.0:80 no listening sockets available, shutting down Unable to open logs [失敗] [root@server ~]# /usr/sbin/lsof -i | grep http httpd 32028 root 4u IPv6 80010903 TCP *:http (LISTEN) httpd 32028 root 6u IPv6 80010908 TCP *:pcsync-https (LISTEN) httpd 32028 root 8u IPv6 80010913 TCP *:https (LISTEN) ... [root@pdbjkw2 conf]# kill 32028 [root@pdbjkw2 conf]# /etc/init.d/httpd start httpd を起動中: [ OK ]
【例】 [root@server ~]# /etc/init.d/httpd start httpd を起動中: httpd: Syntax error on line 198 of /etc/httpd/conf/httpd.conf: Cannot load /etc/httpd/modules/mod_file_cache.so into server: /etc/httpd/modules/mod_file_cache.so: cannot open shared object file: No such file or directory [失敗] 以下の2行をコメントアウト [/etc/httpd/conf/httpd.conf] LoadModule file_cache_module modules/mod_file_cache.so LoadModule mem_cache_module modules/mod_mem_cache.so ↓ #LoadModule file_cache_module modules/mod_file_cache.so #LoadModule mem_cache_module modules/mod_mem_cache.so(2)該当モジュールを有効化するようconfigure時のオプション引数に指定する。
【例】file_cacheモジュールをsharedオブジェクトとして有効化する
./configure
↓
./configure --enable-file_cache=shared
共通設置 /etc/httpd/conf/httpd.conf 内だけではなく、個別設定 /etc/httpd/conf.d/*.conf も含めた全体の中で重複した設定がある。
【例】エラーログ [/var/log/httpd/error_log] [Mon May 23 09:51:17 2011] [error] NSS_Initialize failed. Certificate database: /etc/httpd/alias. [Mon May 23 09:51:17 2011] [error] SSL Library Error: -8038 SEC_ERROR_NOT_INITIALIZED
/etc/httpd/conf/httpd.conf
)の「Group」で指定した値に一致させる。
【例】 # grep '^Group' /etc/httpd/conf/httpd.conf Group hoge # ls -ld /etc/httpd/alias/*.db -rw-r----- 1 root apache 65536 11月 6 2009 /etc/httpd/alias/cert8.db -rw-r----- 1 root apache 16384 11月 6 2009 /etc/httpd/alias/key3.db -rw-r----- 1 root apache 16384 11月 6 2009 /etc/httpd/alias/secmod.db # chown root:hoge /etc/httpd/alias/*.db
apacheをコンパイルし直して再インストールするしかない?[6]
以下の原因が考えられる。
httpd.conf
)中のUserディレクティブで指定されている。
/sbin/nologin
)になっている場合、実コンテンツがローカルにない(=NFSマウントされた領域にある)パスワードファイルをAuthUserFileディレクティブで指定している。→ファイルをローカル領域(=ローカルディスクからマウントした領域)にコピーしてそちらを利用する。
apache実行ユーザが読み込み可能で、apache設定ファイル(httpd.conf、でディレクトリごとの設定上書きを許可している場合は .htaccessの設定が優先)でもアクセス許可しているにも関わらず、ブラウザでアクセスできない場合、SELinuxでウェブコンテンツとして許可されていないコンテキストになっていることが考えられる。
【例】ドキュメントルートが/var/www/html/、ルートURLが http://www.test.org/ コンテキスト設定が以下のようになっている場合 # ls -l --context /var/www/html/ -rw-rw-r-- apache apache user_u:object_r:httpd_sys_content_t index.html -rw-rw-r-- apache apache user_u:object_r:httpd_sys_content_t fig_ok.jpg -rw-rw-r-- apache apache user_u:object_r:user_home_t fig_ng.jpg http://www.test.org/fig_ok.jpg → アクセスOK(200) http://www.test.org/fig_ng.jpg → アクセスNG(403 Permission Denied) ファイルのコンテキストを httpd_sys_content_t に修正すればアクセスできるようになる。 ファイルコンテキストの変更はchconコマンドで行う。 # chcon -v --type=httpd_sys_content_t fig_ng.jpg context of fig_ng.jpg changed to user_u:object_r:httpd_sys_content_t # ls -l --context /var/www/html/ -rw-rw-r-- apache apache user_u:object_r:httpd_sys_content_t index.html -rw-rw-r-- apache apache user_u:object_r:httpd_sys_content_t fig_ok.jpg -rw-rw-r-- apache apache user_u:object_r:httpd_sys_content_t fig_ng.jpg
また、親ディレクトリのアクセス権設定が問題という場合もあった。
# cat /etc/httpd/conf.d/myportal.conf Alias /myportal /home/user/Dropbox/myportal <Directory "/home/user/Dropbox/myportal"> Options Indexes MultiViews FollowSymLinks AllowOverride None Require all granted </Directory> # ls -ld /home/user/Dropbox/myportal drwxr-xr-x 4 user user 4096 8月 17 14:06 /home/user/Dropbox/myportal →上記状態で 403 Forbidden。親ディレクトリのアクセス権を見ると700だった。 # ls -ld /home/user/Dropbox drwxr----- 24 user user 4096 8月 11 23:55 /home/user/Dropbox →755に変更したらアクセスできるようになった # chmod 755 /home/user/Dropbox # ls -ld /home/user/Dropbox drwxr----- 24 user user 4096 8月 11 23:55 /home/user/Dropbox
/etc/httpd/alias/*.db
の所有グループが、設定ファイル(httpd.conf
)で指定されたapache実行グループと異なる場合、このエラーが出る。/etc/httpd/alias/*.db
の所有グループをapache実行グループに変更すれば良い。
# tail /var/log/httpd/error_log ... [Fri May 11 15:32:30 2012] [error] NSS_Initialize failed. Certificate database: /etc/httpd/alias. [Fri May 11 15:32:30 2012] [error] SSL Library Error: -8038 SEC_ERROR_NOT_INITIALIZED # ls -l /etc/httpd/alias/*.db -rw-r----- 1 root apache 65536 1月 6 17:56 /etc/httpd/alias/cert8.db -rw-r----- 1 root apache 16384 1月 6 17:56 /etc/httpd/alias/key3.db -rw-r----- 1 root apache 16384 1月 6 17:56 /etc/httpd/alias/secmod.db # grep '^Group' /etc/httpd/conf/httpd.conf Group hoge # chgrp hoge /etc/httpd/alias/*.db # ls -l /etc/httpd/alias/*.db -rw-r----- 1 root hoge 65536 1月 6 17:56 /etc/httpd/alias/cert8.db -rw-r----- 1 root hoge 16384 1月 6 17:56 /etc/httpd/alias/key3.db -rw-r----- 1 root hoge 16384 1月 6 17:56 /etc/httpd/alias/secmod.db
/etc/nsswitch.conf
などに記載されている。
# 下記事例の場合、(1)ローカルのホスト情報ファイル(/etc/hosts
)、(2)NISサーバ、(3)DNSサーバ の順に参照
$ cat /etc/nsswitch.conf
...
hosts: files nis dns
...
Mac OS X 10.6ではデフォルトでapache 2.2.14 がインストールされている。これをOS起動時に自動起動するよう設定するには[システム環境設定]-[共有]で「Web共有」をONにすればいいが、別途上位バージョンのapache2.2をインストールした後、ある時から起動しなくなった(sudo /usr/local/apache2/bin/apachectl start
で起動)。ソフトウェア・アップデートしたことで発生した?
まずは /System/Library/LaunchDaemons/org.apache.httpd.plist
を編集してみる7。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Disabled</key> <true/> <key>Label</key> <string>org.apache.httpd</string> <key>ProgramArguments</key> <array> <string>/usr/sbin/httpd</string> <string>/usr/local/apache2/bin/httpd</string> <string>-D</string> <string>FOREGROUND</string> </array> <key>OnDemand</key> <false/> <key>SHAuthorizationRight</key> <string>system.preferences</string> </dict> </plist>
これで動くようになった。
[システム環境設定]-[共有]で「Web共有」OFFの状態 $ ps -ef | grep httpd 501 2443 238 0 0:00.00 ttys000 0:00.00 grep httpd ONにする $ ps -ef | grep httpd 0 2446 1 0 0:00.01 ?? 0:00.02 /usr/local/apache2/bin/httpd -D FOREGROUND 70 2450 2446 0 0:00.00 ?? 0:00.00 /usr/local/apache2/bin/httpd -D FOREGROUND 70 2451 2446 0 0:00.00 ?? 0:00.00 /usr/local/apache2/bin/httpd -D FOREGROUND 70 2452 2446 0 0:00.00 ?? 0:00.00 /usr/local/apache2/bin/httpd -D FOREGROUND 70 2453 2446 0 0:00.00 ?? 0:00.00 /usr/local/apache2/bin/httpd -D FOREGROUND 70 2454 2446 0 0:00.00 ?? 0:00.00 /usr/local/apache2/bin/httpd -D FOREGROUND 501 2456 238 0 0:00.00 ttys000 0:00.00 grep httpd
Apache HTTPサーバは子プロセスを管理する際、新たな接続を待ち受けるプロセスを起動する方法が必要となる。これを行うため、サーバは自分自身に対するHTTPリクエストを発行する。このリクエストに対応するアクセスがアクセスログに記録される。アクセス元IPアドレスはループバック(127.0.0.1または::1、後者はIPv6が有効であった場合)として記録される。ユーザエージェント情報を記録する設定にしていた場合、その部分には「(internal dummy connection)」という文字列が記載されます(非SSLサーバの場合)。ある一定期間、各httpd子プロセスごとにそのような記録が行われます。このリクエストは全く正常なものですが、この情報は一般的に出力する必要はありません。[9]
/etc/httpd/conf.d/wsgi.conf
中のwsgiモジュールをロードする指定がコメントアウトされていたらコメントアウトを解除する[10]。
# vi /etc/httpd/conf.d/wsgi.conf ... # LoadModule wsgi_module modules/mod_wsgi.so ↓ LoadModule wsgi_module modules/mod_wsgi.so
httpdの再起動を繰り返すと、セマフォを使い切ってしまい、新たにhttpdが起動できなくなることがある。その場合、「[Mon Mar 10 10:00:00 2014] [emerg] (28)No space left on device: Couldn't create accept lock (/etc/httpd/logs/accept.lock.12345) (5)」のような記録がエラーログに残る。対処するには2つの方法がある。対処法と合わせて以下に記す[11]。
# ipcs -s | awk '{ if ( $3 ~ /apache/ && $1 ~ /[0-9]/ ) system("ipcrm -s "$2) }' ※apacheにはApache実行ユーザ名を指定。 ※ipcs -sの出力3列目(所有者)にapacheがあり、しかも1列目(キー)が数字であった場合、 出力2列目(セマフォid)の値を引数にしてipcrm -sを実行し、指定したidを持つセマフォを消去する
/proc/sys/kernel/sem
の値を修正する。4列目の値がセマフォの最大数。
【例】最大値を128から256に増やす # cat /proc/sys/kernel/sem 250 32000 32 128 # echo "250 32000 32 256" > /proc/sys/kernel/sem # cat /proc/sys/kernel/sem 250 32000 32 256
Apache 2.4でバージョンを確認したとき「httpd: symbol lookup error: httpd: undefined symbol: apr_crypto_init」というメッセージが出たら、apr-util 1.4以上が入っているかを確認する[13]。
# httpd -v httpd: symbol lookup error: httpd: undefined symbol: apr_crypto_init # yum --enablerepo=myrepo list apr ... インストール済みパッケージ apr.x86_64 1.3.9-5.el6_2 @anaconda-CentOS-201508042137.x86_64/6.7 利用可能なパッケージ apr.i686 1.3.9-5.el6_2 base apr.x86_64 1.5.2-1 myrepo-base # yum --enablerepo=myrepo update apr ... トランザクションを実行しています 更新 : apr-1.5.2-1.x86_64 1/2 整理中 : apr-1.3.9-5.el6_2.x86_64 2/2 Verifying : apr-1.5.2-1.x86_64 1/2 Verifying : apr-1.3.9-5.el6_2.x86_64 2/2 更新: apr.x86_64 0:1.5.2-1 完了しました! # httpd -v Server version: Apache/2.4.25 (Unix) Server built: Jan 10 2017 11:27:14
WebアクセスクライアントからWebサーバへアクセスする際、ブラウザ、OS、許容言語などのユーザAgent情報がサーバへと通知される。MultiViewにはこの許容言語情報が利用される。PHPでは $_SERVER['HTTP_ACCEPT_LANGUAGE'] にて通知された許容情報が参照可能(→詳細はPHP関係 - 定義済み変数参照。)。
日本語を示す情報として、「ja」と「ja-jp」(またはja-JP)がある。最近のブラウザは後者を通知している場合が増えているよう。少なくともSafari 4.05、IE8はそのよう。逆にFirefox3.5.8は「ja」。PHPでMultiViewを実現する際、日本語は「ja」だけと思っていて問題になかなか気づかなかった。参考:IE7でコンテント・ネゴシエーションが残念なことになる件 | 水無月ばけらのえび日記
.htaccess
)で設定を上書きするかどうかや、上書き対象範囲を設定