Showing posts with label configuration. Show all posts
Showing posts with label configuration. Show all posts

Apache: mod_proxy, mod_proxy_html 사용하기 edit

mod_proxy모듈로 내부 백엔드 서버에 Apache를 통해 접속할 수 있고 mod_proxy_html모듈로 그 서버의 내부 소스들(HTML, Javascript, etc)에서 링크된 상대/절대 경로들을 원하는 경로로 바꿀 수 있다.

데비안 Stable 패키지를 설치하거나 소스에서 빌드하여 바로 설치하거나 빌드된 바이너리를 패키징하여 설치할 수 있다.

Download & Build from source for Apache2 using apxs2

$ apt-get install apx2 libxml2-dev

mod_xml2enc

mod_xml2enc모듈은 지원하지 않는 인코딩들을 지원하게 해준다.

$ ./apxs -c -I/usr/include/libxml2 /usr/local/src/mod_xml2enc/mod_xml2enc.c

mod_proxy_html

$ ./apxs -c -I/usr/include/libxml2 -I/usr/local/src/mod_xml2enc /usr/local/src/mod_proxy_html/mod_proxy_html.c

Debian Packaging

각 디렉토리에 .libs라는 디렉토리가 생성되었을 것이다. 필요한것은 .so파일이다.

  1. libapache2-mod-proxy-html_3.1.2_i386디렉토리를 만들고 하위에 DEBIAN디렉토리를 생성한다.
  2. 생성한 DEBIAN디렉토리 안에 control파일을 만든다. 이 파일은 데비안 공식 패키지에서 추출하여 수정해도 된다.

    control:

    Package: libapache2-mod-proxy-html
    Source: mod-proxy-html
    Version: 3.1.2
    Architecture: i386
    Maintainer: me <me@localhost>
    Depends: libc6 (>= 2.7-1), apache2, apache2.2-common, libxml2 (>> 2.5.10)
    Section: web
    Priority: optional
    Description: Apache2 filter module for HTML links rewriting
     mod_proxy_html is an output filter to rewrite HTML links in a proxy
     situation, to ensure that links work for users outside the proxy. It
     serves the same purpose as Apache's ProxyPassReverse directive does for
     HTTP headers, and is an essential component of a reverse proxy.
    
  3. libapache2-mod-proxy-html_3.1.2_i386/usr/lib/apache2/modules/디렉토리들을 생성한다음 컴파일된 mod_proxy_html.so파일을 넣는다.
  4. libapache2-mod-proxy-html_3.1.2_i386/etc/apache2/mods-available/디렉토리들을 생성한다음 생성된 proxy_html.conf파일을 넣어주고 proxy_html.load파일을 만든다.

    proxy_html.load:

    LoadFile /usr/lib/libxml2.so.2
    LoadModule proxy_html_module /usr/lib/apache2/modules/mod_proxy_html.so
    
  5. 상위 디렉토리(../libapache2-mod-proxy-html_3.1.2_i386)에서 패키징한다.
    $ dpkg-deb --build libapache2-mod-proxy-html_3.1.2_i386
  6. 패키징한 libapache2-mod-proxy-html_3.1.2_i386.deb파일을 설치한다.
  7. $ sudo dpkg -i libapache2-mod-proxy-html_3.1.2_i386.deb
  8. mod_xml2enc모듈도 위와같이 패키징하면 된다.

Configuration

모듈 설치 이후 /etc/apache2/mods-enabled/../mods-availalbe/하위에 필요한 모듈과 설정파일들을 심볼링 링크한다.

/etc/apache2/mods-enabled$ sudo ln -s ../mods-available/proxy.load
/etc/apache2/mods-enabled$ sudo ln -s ../mods-available/proxy.conf
/etc/apache2/mods-enabled$ sudo ln -s ../mods-available/proxy_http.load
/etc/apache2/mods-enabled$ sudo ln -s ../mods-available/proxy_html.load
/etc/apache2/mods-enabled$ sudo ln -s ../mods-available/proxy_html.conf
/etc/apache2/mods-enabled$ sudo ln -s ../mods-available/xml2enc.load

데비안 Stable 패키지를 설치하였다면 xml2enc는 현재 squeeze배포판에서 지원하지 않는다.

  • 3.1 이전 버전의 mod_proxy_html에는 SetOutputFilter proxy-html를 사용하며 3.1 버전부터 ProxyHTMLEnable On를 사용한다.
  • 프락시 설정시 끝에 붙는 '/'(슬래시)에 주의.
  • mod_proxy_html모듈은 페이지를 필터링할때 모두 UTF-8로 변경하여 필터링하고 출력 인코딩의 기본값도 UTF-8이며 이것을 변경하려면 ProxyHTMLCharsetOut옵션을 사용해야 하지만 이 옵션을 사용하면 UTF-8 출력을 설정된 인코딩으로 다시 인코딩하기 때문에 오버헤드가 발생한다.
  • ProxyRequests옵션은 포워드 프록시를 켜는 옵션이며 이 옵션을 인증과정없이 켠다면 자신의 서버가 공개프락시가 되는셈이다.
  • RequestHeader unset Accept-Encoding옵션으로 압축되지 않은 응답을 백엔드 서버로부터 전송받아야 mod_proxy_html모듈이 필터링을 할 수 있다.
  • 백엔드 서버의 프로토콜이 HTTPS라면 SSLProxyEngine On옵션을 설정해야 한다.
  • mod_headers 모듈을 추가한다음 RequestHeader옵션으로 Authorization헤더를 추가함으로써 내부 백엔드 서버에 자동으로 로그인 할 수 있다. 혹은 백엔드 서버의 인증 아이디와 비밀번호가 웹서버와 같아도 헤더가 포워딩되서 자동으로 인증된다.
    • RequestHeader set Authorization "Basic BASE64(ID:PASSWORD)"
  • 설정에 대한 더 자세한 사항은 아파치 사이트모듈 사이트를 참고.

ZNC

ProxyRequests off
<Proxy *>
    Order Allow,Deny
    Allow from all
</Proxy>

Redirect /znc https://server.domain/znc/
ProxyPass /znc/ http://localhost:port/
ProxyHTMLURLMap http://localhost:port/ /znc/
<Location /znc>
    ProxyPassReverse /
    SetOutputFilter proxy-html
    ProxyHTMLURLMap / /znc/
    RequestHeader unset Accept-Encoding
    RequestHeader set Authorization "Basic BASE64(ID:PASSWORD)"
</Location>

최신버전의 mod_proxy_html과 mod_xml2enc모듈을 사용하였더니 인코딩이 부분적으로 깨져서 데비안 squeeze의 기본 패키지로 다운그레이드 하였다.

ZNC는 HTTPSock.cpp의 다음과 같은 소스에 의해 Authorization 헤더가 요청으로 들어온다면, 자동으로 아이디와 비밀번호를 BASE64로부터 산출하여 로그인한다. 이로인해 프록시를 설정한 루트도메인에서 다른 아이디와 비밀번호를 설정하였다면 ZNC Webadmin 페이지 접속시 다른 아이디와 비밀번호로 인해 Login Invalid라는 오류메시지가 출력된다.

HTTPSock.cpp:

} else if (sName.Equals("Authorization:")) {
    CString sUnhashed;
    sLine.Token(2).Base64Decode(sUnhashed);
    m_sUser = sUnhashed.Token(0, false, ":");
    m_sPass = sUnhashed.Token(1, true, ":");
    m_bLoggedIn = OnLogin(m_sUser, m_sPass);

Transmission

ProxyRequests off
<Proxy *>
    Order Allow,Deny
    Allow from all
</Proxy>

Redirect /transmission https://server.domain/transmission/web/
ProxyPass /transmission/ http://localhost:port/transmission/
<Location /transmission>
    ProxyPassReverse /
    RequestHeader set Authorization "Basic BASE64(ID:PASSWORD)"
</Location>

IPTIME 공유기

IPTIME 공유기 웹어드민 페이지를 프록시로 아파치를 통해 HTTPS로 접속하여 사용하려고 하였으나, mod_proxy_html사용시 한글 인코딩이 모두 깨지고 페이지가 자바스크립트로 매우 복잡하게 되어있어서 이를 위한 도메인을 따로 독립적으로 사용하여 mod_proxy_html의 필터링 없이 mod_proxy만 사용하여 도메인의 루트경로에서 사용하였다.

인코딩이 깨지는 원인이 공유기 웹어드민 페이지가 응답을 chunked로 주어서 여기에 버그가 있기때문인줄 알았으나 설치된 Apache 데비안 패키지의 버전과 소스를 보니 이미 해당 버그가 패치된 Apache를 사용하고 있었다.(http://grokbase.com/t/apache/dev/074bj0x0kr/mod-proxy-buffering-small-chunks)

특히 mod_proxy_html모듈이 공유기 웹어드민 최상위 경로 접속시 자동으로 /login/login.cgi로 리다이렉션 하는데 이는 HTML의 META태그에 의한것이며 이를 필터링하는데 실패하였다.

독립된 도메인을 사용하면서 크로스 도메인으로 본래의 도메인과 인증없이 연동하여 사용하려고 HTTP Digest Authentication 인증 메쏘드를 사용해 보았지만 대부분의 거의 모든 브라우저가 이를 지원하지 않는다.

Most browsers do not respect the Digest "domain" directive and will not resend credentials for other URIs. As far as I know, Opera is the only browser that honors it. For Opera, the server(s) must respond with the same "realm" string for each URI in the domain list. In other words, if domain="/test /example", the server needs to send "Test Realm - example.com" in the WWW-Authenticate header for both of those URIs. I assume Opera does this because it stores H(A1) instead of the actual password for security. Read into RFC2617 for more on this. Here's my cross-browser solution to this problem: http://travisce.com/arest/

HTTP Digest Authentication 인증 메쏘드에 대한 설정법은 따로 포스팅 한다.

References

apache2 + php5 환경에서 큰 파일 업로드하기 edit

Apache2 + PHP5 환경에서 큰파일을 업로드할때 들어온 POST 데이터들을 모두 메모리에 넣은 뒤 tmp에 저장시킨다음 지정된 디렉토리로 이동하는줄 알고 큰파일을 업로드 시킬경우 메모리가 터져나가 안되는줄 알고있었는데, 다시해보니 잘못알고 있었다.

php.iniupload_max_filesizepost_max_size를 각각 2G씩 설정했을땐 아예 모든크기의 파일이 업로드되지 않았다.(큰 파일은 끝에서 멈춰버렸고 작은파일은 아예 진행이 안됨) 이유는 모르겠으나 추측하건데 POST 최대 크기값이 각 파일들의 크기값과 같거나 작아서(post_max_size <= upload_max_filesize) 그랬거나 단순히 2GG심볼을 이해하지 못해서 그랬을지도 모른다.(php 공식사이트엔 이해한다고 되어있다.)
http://php.net/manual/en/ini.core.php

PHP allows shortcuts for bit values, including K (kilo), M (mega) and G (giga). PHP will do the conversions automatically if you use any of these. Be careful not to exceed the 32 bit signed integer limit (if you're using 32bit versions) as it will cause your script to fail.

Myth of 'memory_size'


이건 거의 미신수준이다.(하지만 구버전에선 어떤지 모르겠다.)

http://stackoverflow.com/questions/2854283/writing-direct-to-disk-with-php

I don't believe the myth that 'memory_size' should be the size of the uploaded file. The files are definitely not kept in memory... instead uploaded chunks of 1MB each are stored under /var/tmp and later on rebuild under /tmp before moving to the web/user space.

I'm running a linux-box with only 64MB RAM, setting the memory_limit to 16MB and uploading files of sizes about 100MB is no problem at all! (http://php.net/manual/en/features.file-upload.php)

PHP settings that related to file upload


php.ini:
; Whether to allow HTTP file uploads.
file_uploads = On

; Temporary directory for HTTP uploaded files (will use system default if not
; specified).
upload_tmp_dir = /home/tmp

; Maximum allowed size for uploaded files.
upload_max_filesize = 2000000000  ; about 1.86G

; Maximum size of POST data that PHP will accept.
post_max_size = 2147483648  ; 2G

max_execution_time = 30     ; Maximum execution time of each script, in seconds
max_input_time = 60 ; Maximum amount of time each script may spend parsing request data

upload_tmp_dir


시스템 환경에 맞게 설정.

upload_max_filesize and post_max_size


업로드되는 각 파일의 최대 크기이며 post_max_size는 HTTP POST Request의 최대 크기이므로 post_max_size사이즈를 좀더 크게 설정.('multipart/form-data' is also POST Request)

max_execution_time and max_input_time


테스트해보진 않았지만 업로드할 파일의 크기가 매우 큰경우 timeout되어 업로드가 안될경우 늘려주면 될듯.

http://www.radinks.com/upload/config.php

These settings define the maximum life time of the script and the time that the script should spend in accepting input. If several mega bytes of data are being transfered max_input_time should be reasonably high.

Apache2(the webserver) LimitRequestBody option


Apache2 웹서버의 LimitRequestBody의 기본값은 0(무제한)이기때문에 따로 설정되어있지 않다면 만질필요가 없다.

http://www.radinks.com/upload/config.php

The apache webserver has a LimitRequestBody configuration directive that restricts the size of all POST data regardless of the web scripting language in use. Some RPM installations sets limit request body to 512Kb. You will need to change this to a larger value or remove the entry altogether.

Client side script Uploadify


http://www.uploadify.com/demos/

참고



구글링중 발견한 'Apache Commons Java 라이브러리/컴포넌트'는 Apache2 웹서버와 관계가 없다.


http://serverfault.com/questions/109557/best-practice-apache-file-upload

I think you're confusing Apache httpd (Web Server) with other Apache Group projects. Apache Group hosts the "Commons" project which a large collection of Java libraries for use in your own Java applications.

apache2 httpd 컴파일 옵션 지정


http://blog.naver.com/PostView.nhn?blogId=woodair&logNo=100090608241&parentCategoryNo=38&viewDate=¤tPage=1&listtype=0

raw 영상 , DVD 이미지 파일등 그 크기가 2기가 이상을 상회하는 파일들이 넘쳐나고 있는데 이와같은 파일을 웹을 통해 전송하기 위한 리눅스 컴파일 환경설정에 대한 내용입니다.

1. 커널 2.4 이상이어야 하며,
2. Apache2, PHP5 컴파일시 아래와 같은 컴파일 플레그를 지정함으로 2기가 이상의 대용량 처리 환경을 만들수가 있습니다.

shell] # CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
shell] # export CFLAGS
shell] # cd httpd-2.x.x
shell] # ./configure \
--prefix=/usr/local/apache2 \
--enable-mods-shared=all \
--enable-so
....
.... 
<- Older