計算機メモ目次 (目的のページと内容が一致しない場合, 目次から探してください)

Solaris 8 上で Apache 2.2.24 + OpenSSL を構築する


必要なもの
  httpd-2.2.24.tar.gz
  OpenSSL (mod_ssl 用)

ソース修正
  modules/proxy/proxy_ftp.c の次のような仕様を下記のパッチで修正
  (mod_proxy_ftp モジュールを使用しないのなら修正の必要なし)
  ・空白を含むファイル名やディレクトリ名を正しくパースしてくれない.
  ・TYPE I (バイナリモード) で SIZE の返り値が 0 になると Content-Length: 0
    というヘッダを作成してしまう.
  ・ファイル名やディレクトリ名に ASCII コードしか許してくれない.
  ・ProxyPass にて FTP アカウントを明示していても(たとえば匿名FTP),
    それは読み込まずに無視され, 実際の FTP ログインには反映されない.
    また, 読み込んでも, Apache の認証確認ダイアログでの入力を優先してしまい,
    HTTP 用と FTP 用のアカウントを分けることができない.

*** modules/proxy/mod_proxy_ftp.c.orig	Tue Feb 19 01:52:21 2013
--- modules/proxy/mod_proxy_ftp.c	Wed May  8 15:44:02 2013
***************
*** 155,162 ****
--- 155,166 ----
          return HTTP_BAD_REQUEST;
      if (user != NULL && !ftp_check_string(user))
          return HTTP_BAD_REQUEST;
+     else if (user != NULL)
+         r->parsed_uri.user = user;
      if (password != NULL && !ftp_check_string(password))
          return HTTP_BAD_REQUEST;
+     else if (password != NULL)
+         r->parsed_uri.password = password;
  
      /* now parse path/parameters args, according to rfc1738 */
      /*
***************
*** 178,185 ****
--- 182,191 ----
      path = ap_proxy_canonenc(p, url, strlen(url), enc_path, 0, r->proxyreq);
      if (path == NULL)
          return HTTP_BAD_REQUEST;
+ /*
      if (!ftp_check_string(path))
          return HTTP_BAD_REQUEST;
+ */
  
      if (r->proxyreq && r->args != NULL) {
          if (strp != NULL) {
***************
*** 516,524 ****
  
          /* a directory/file? */
          else if (ctx->buffer[0] == 'd' || ctx->buffer[0] == '-' || ctx->buffer[0] == 'l' || apr_isdigit(ctx->buffer[0])) {
!             int searchidx = 0;
              char *searchptr = NULL;
!             int firstfile = 1;
              if (apr_isdigit(ctx->buffer[0])) {  /* handle DOS dir */
                  searchptr = strchr(ctx->buffer, '<');
                  if (searchptr != NULL)
--- 522,530 ----
  
          /* a directory/file? */
          else if (ctx->buffer[0] == 'd' || ctx->buffer[0] == '-' || ctx->buffer[0] == 'l' || apr_isdigit(ctx->buffer[0])) {
!             static int searchidx = 0;
              char *searchptr = NULL;
!             static int firstfile = 1;
              if (apr_isdigit(ctx->buffer[0])) {  /* handle DOS dir */
                  searchptr = strchr(ctx->buffer, '<');
                  if (searchptr != NULL)
***************
*** 911,917 ****
       * Basic Auth simply uuencodes the plain text password. But chances are
       * still smaller that the URL is logged regularly.
       */
!     if ((password = apr_table_get(r->headers_in, "Authorization")) != NULL
          && strcasecmp(ap_getword(r->pool, &password, ' '), "Basic") == 0
          && (password = ap_pbase64decode(r->pool, password))[0] != ':') {
          /* Check the decoded string for special characters. */
--- 917,933 ----
       * Basic Auth simply uuencodes the plain text password. But chances are
       * still smaller that the URL is logged regularly.
       */
!     /* URL-coded user [ & password ] will be checked first (OCG Server) */
!     if ((user = r->parsed_uri.user) != NULL) {
!         user = apr_pstrdup(p, user);
!         decodeenc(user);
!         if ((password = r->parsed_uri.password) != NULL) {
!             char *tmp = apr_pstrdup(p, password);
!             decodeenc(tmp);
!             password = tmp;
!         }
!     }
!     else if ((password = apr_table_get(r->headers_in, "Authorization")) != NULL
          && strcasecmp(ap_getword(r->pool, &password, ' '), "Basic") == 0
          && (password = ap_pbase64decode(r->pool, password))[0] != ':') {
          /* Check the decoded string for special characters. */
***************
*** 928,933 ****
--- 944,950 ----
          r->ap_auth_type = "Basic";
          r->user = r->parsed_uri.user = user;
      }
+ /*
      else if ((user = r->parsed_uri.user) != NULL) {
          user = apr_pstrdup(p, user);
          decodeenc(user);
***************
*** 937,942 ****
--- 954,960 ----
              password = tmp;
          }
      }
+ */
      else {
          user = "anonymous";
          password = "apache-proxy@";
***************
*** 1514,1520 ****
              for (j = 0; apr_isdigit(ftpmessage[j]); j++)
                  ;
              ftpmessage[j] = '\0';
!             if (ftpmessage[0] != '\0')
                   size = ftpmessage; /* already pstrdup'ed: no copy necessary */
          }
          else if (rc == 550) {    /* Not a regular file */
--- 1532,1538 ----
              for (j = 0; apr_isdigit(ftpmessage[j]); j++)
                  ;
              ftpmessage[j] = '\0';
!             if (ftpmessage[0] != '\0' && ! (ftpmessage[0] == '0' && ftpmessage[1] == '\0'))
                   size = ftpmessage; /* already pstrdup'ed: no copy necessary */
          }
          else if (rc == 550) {    /* Not a regular file */

コンフィグレーション
  ./configure --prefix=/home/public/apache2 \
    --enable-mods-shared=all --enable-ssl --with-ssl=/usr/local \
    --enable-proxy --enable-proxy-connect --enable-proxy-ftp --enable-proxy-http \
    --enable-cache --enable-disk-cache --enable-mem-cache \
    --enable-suexec --with-suexec-safepath=/usr/local/bin:/usr/bin 

ビルド
  make

  注意: シンボリックリンクを張ったディレクトリ上でビルドを行なってはいけない

インストール
  make install

設定
  httpd.conf と ssl.conf をサイトにあわせて変更する.
  httpd.conf において変更するべき主なディレクティブ:
    User
    Group
    ServerAdmin
    ServerName
    DocumentRoot
    <Directory "$DocumentRoot"> の Options (Indexes を外して MultiViews 追加)
    DirectoryIndex (MultiViews を使うので index のみとする)
    ScriptAlias
    AddDefaultCharset (HTML ヘッダの meta タグで文字セットを指定したいので Off にする)

注意
  SSL 用のキャッシュファイルの書き込みが User で設定されたユーザの権限で
  行われるようになっている. そのため, そのユーザが書き込めるよう, ログ用
  ディレクトリ (logs) の書き込み属性を設定しておくか, あるいは空のファイル
  logs/ssl_scache.dir および logs/ssl_scache.pag [dbmの場合] を作っておいて
  当該ユーザに書き込み権限を与えておくか, どちらかしないと httpd が起動しない.

備考
  Forte 6 のコンパイラで作ったバイナリはうまく起動しない.


計算機メモ目次 (目的のページと内容が一致しない場合, 目次から探してください)
海洋大循環分野
daigo@ocg.aori.u-tokyo.ac.jp