아파치에 URL filtering 기능 구현

zzang2k의 이미지

아파치 웹 서버에 URL 필터링 기능을 구현하려 합니다.

이미 웹 방화벽으로 mod security라는 놈이 나와있는데요.
비슷한 방식으로 필터링 모듈을 추가해서 구현하려 하는데,

아파치에 DSO 모듈을 개발하고 추가해서 제가 작성한 함수로 핸들링하는 부분까지는 알겠는데,
request_rec *r 을 가져와 HTTP메시지의 Header의 첫번째 줄과 마지막 부분을 접근하려 하는데 잘 안되네요?
헤더는 가장 위에 한 줄 밖에 나오지 않고, Header의 마지막 부분을 접근할 수 없는 것 같습니다.
전체 헤더에 정규표현식을 써서 필터링 하려고 하는데 말입니다.

apache2.2.x 버전은 API도 상세히 나와있지 않고 여러모로 분석이 힘드네요.
어느정도 큰 틀은 파악했지만 gdb로 디버깅하면서 봐도 여기저기에서 막히고..^^

답변 달아주실 분이 계신지 ㅜㅜ

thinker0의 이미지

어느 시점에 읽는지에 따라서 틀립니다.

ap_hook_post_read_request() 시점에 읽으시면 됩니다.

	const char *c_length = apr_table_get(r->headers_in, "Content-Length");

	ap_hook_post_read_request(......., NULL, NULL, APR_HOOK_MIDDLE);

아파치 모듈 개발 공부는 가장 쉬운 방법은 아파치 소스 및 기본 모듈들을 스터디 하는게 가장 좋습니다.

Apache-Modules-Book-Application-Development 좋은 책입니다. ^^;

zzang2k의 이미지

ap_hook_header_parser(requestLog_handler, NULL, NULL, APR_HOOK_REALLY_FIRST);
ap_hook_post_read_request(requestLog_handler, NULL, NULL, APR_HOOK_REALLY_FIRST);

이 두가지 hook 함수를 모두 써 봐도..

static int requestLog_handler(request_rec *r)
{
FILE *fp;
conn_rec *c;
c = r->connection;
if((fp = fopen("/usr/local/apache2/logs/yk3_log","a+")) == NULL)
fprintf(stderr, "file open failed\n");

if((fprintf(fp, "the_request : %s\ncontent type : %s ",
r->the_request,
r->content_type
)) == NULL)
fprintf(stderr, "no write\n");

fclose(fp);
}

로그 파일을 읽어보면 헤더의 첫 줄(the_request) 부분은 읽을 수 있는데
content_type은 null 값으로 나오네요..
get 방식으로 들어오면 the_request를 필터링하면 될 듯 한데
post 방식으로 오면 헤더를 끝까지 읽어야하고, 또 MIME 타입을 변경해서 들어오면
읽을 수가 없으니 손 쓸 수가 없네요.

content_type이랑 range, bytes_sent 모두 0으로 나오는 이유도 모르겠고..
아시는 분......도와주세요 ^^

p.s) 추천해 주신 책은 빠른 시일내에 찾아서 봐야겠습니다. 감사합니다. ^^

zzang2k.

thinker0의 이미지

APR_HOOK_REALLY_FIRST

이 의미를 정의하면 안되요. 관련 자료를 보시면 정말 처음이라서.

문의하신 내용을 파싱하는 단계(아파치 파서)가 처리해야 할 일들을 하기 전에 님꼐서 만든 모듈이 작동 하기 때문에.

내용이 없는것 입니다.

그리고 로그 파일 open/close 를 content handler에서 작동 하면 않됩니다. request 들어 올때마다 open/close는 위험합니다.

책을 읽어 보시고 해당 적당한 부분에 등록 해주세요.

위의 내용이라면 별도로 모듈을 개발 필요없이 mod_log_config 관련 정보를 찾아 보시면 원하는 정보를 설정 만으로 원하는 로그를 남길 수 있습니다.

zzang2k의 이미지

우선 그 부분을 ARP_HOOK_REALLY_LAST 로 변경해봐도 되지 않더군요.
아무래도 ap_hook_post_read_request가 ap_hook_create_request 다음에 바로 실행되는 훅 함수라서
님 말씀대로 너무 빠르지 않나 싶습니다.
content handler는 일단 파일로 써서 확인하려고 작성한거구요..

그래서 우선 ap_hook_insert_filter 에 위와 같은 방법으로 접근했더니 일단 다른 값은 얻어올 수 있는데.
Header의 마지막 부분을 읽지 못하네요?

request_rec* r 이 포인터형이니
r->the_request++
으로 접근해도 역시 똑같은 값만. 첫번째 라인만 가르키는 것 같습니다.

헤더를 한줄씩 읽으면서 parsing 하는 방법은 없나요? 목적이 필터링이라서요..^^

zzang2k.

thinker0의 이미지

mod_setenvif.c 참조하세요.

                    const apr_array_header_t
                        *arr = apr_table_elts(r->headers_in);
 
                    elts = (const apr_table_entry_t *) arr->elts;
                    val = NULL;
                    for (j = 0; j < arr->nelts; ++j) {
                        val = elts[j].val;
                    }
zzang2k의 이미지

언제쯤 감을 잡을지 모르겠어요
참고자료 정말 감사힙니다.^^

zzang2k.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.