Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

아파치 서버 2.4를 위한 mod_aspdotnet 마이그레이션

지난 글에서 소개한,

아파치 서버에서 ASP.NET을 실행하는 mod_aspdotnet 모듈
; https://www.sysnet.pe.kr/2/0/11290

mod_aspdotnet 모듈이 현재 개발자의 사정인지 2009년 이래로 더 이상 업데이트가 안되고 있습니다. 그래서, 별로 기능 업데이트를 할 수는 없지만 Apache 2.4에서도 돌아갈 수 있게끔 변경한 버전을 다음의 github에 배포했습니다.

stjeong/mod_aspdotnet
; https://github.com/stjeong/mod_aspdotnet

개인적으로도 사실 시간이 많지 않아 별로 기능 업데이트를 할 생각은 없지만 그래도 누군가 contributor로 참여해 기능을 추가할 수 있는 여지는 남기는 것이 좋을 것 같아 repo를 열었습니다. (관심있으신 분은 참여를! ^^)




우선, 소스코드는 다음의 마지막 snapshot을 이용했습니다.

mod-aspdotnet-code-222.zip
; https://sourceforge.net/p/mod-aspdotnet/code/HEAD/tarball

Apache 2.4 지원을 위해 xampp를 이용해 설치한 아파치 서버의 include, lib 폴더를 사용했습니다.

나머지 작업은 이제 Apache 2.4로 소스코드를 마이그레이션하는 건데요. 다음의 문서에 따라 은근히 변한 것이 있습니다.

API Changes in Apache HTTP Server 2.4 since 2.2
; https://httpd.apache.org/docs/2.4/developer/new_api_2_4.html

우선, remote_ip와 remote_addr 필드가 변경되었습니다.

conn_rec->remote_ip and conn_rec->remote_addr
  ==> conn_rec->client_ip and conn_rec->client_addr

또한, ap_log_... 관련 함수에 3번째 인자로 module_index가 추가되었습니다.

#ifdef DOXYGEN
AP_DECLARE(void) ap_log_rerror(const char *file, int line, int module_index,
                               int level, apr_status_t status,
                               const request_rec *r, const char *fmt, ...);
#else
#ifdef AP_HAVE_C99
/* need additional step to expand APLOG_MARK first */
#define ap_log_rerror(...) ap_log_rerror__(__VA_ARGS__)
#define ap_log_rerror__(file, line, mi, level, status, r, ...)              \
    do { if (APLOG_R_MODULE_IS_LEVEL(r, mi, level))                         \
             ap_log_rerror_(file, line, mi, level, status, r, __VA_ARGS__); \
    } while(0)
#else
#define ap_log_rerror ap_log_rerror_
#endif
AP_DECLARE(void) ap_log_rerror_(const char *file, int line, int module_index,
                                int level, apr_status_t status,
                                const request_rec *r, const char *fmt, ...)
                                __attribute__((format(printf,7,8)));
#endif

아파치 모듈 인덱스는 소스 코드에 AP_DECLARE_MODULE를 해주면 된다고 해서 포함시켰습니다.

#ifdef AP_DECLARE_MODULE
AP_DECLARE_MODULE(mod_aspdotnet);
#endif

그 외에 다음과 같은 컴파일 오류가 발생했는데요.

Error C2079 'apr_sockaddr_t::sin6' uses undefined struct 'sockaddr_in6' mod_aspdotnet   e:\git_clone\mod_aspdotnet\trunk\apache2_4_include\apr_network_io.h 269 

mod_aspdotnet.cpp 파일에 ws2tcpip 헤더 파일을 추가하는 것으로 해결했습니다.

#include <ws2tcpip.h>

위의 작업까지만 해주면 일단 Apache 2.4 지원을 위한 마이그레이션은 대충 완료됩니다.




문제는, Visual Studio 2017에서 빌드하는 경우 C++/CLI 프로젝트의 어셈블리가 .NET 4.0에 의존성을 갖는다는 점입니다. 이 때문에 Apache.Web.dll이 .NET 2.0 GAC가 아니라 .NET 4.0 GAC에 등록됩니다.

따라서, Apache 2.4에서 .NET 2.0~3.5용의 ASP.NET을 구동하는 경우 crash가 발생하는데 디버깅을 해 보니 다음의 라인에서 발생합니다.

static apr_status_t asp_net_stop(void *dummy)
{
    global_conf->pHostFactory->Destroy(); // pHostFactory == nullptr

    if (global_conf->pHostFactory) {

        global_conf->pHostFactory->Release();
    }
    if (global_conf->pCorRuntime) {
        global_conf->pCorRuntime->Stop();
        global_conf->pCorRuntime->Release();
    }

    // ...[생략]...
}

이 상태에서 아파치 에러 로그(\xampp\apache\logs)는 다음과 같이 보여줍니다.

[Wed Aug 30 17:14:16.117970 2017] [core:notice] [pid 16020:tid 544] mod_aspdotnet: CorBindToRuntimeEx has loaded version v2.0.50727 of the .NET CLR engine.
ed Aug 30 17:16:00.679504 2017] [core:error] [pid 1764:tid 584] (-2146304894)Unknown error: mod_aspdotnet: Could not create the .NET interface for the Apache.Web.HostFactory.
[Wed Aug 30 17:16:00.679504 2017] [core:crit] [pid 1764:tid 584] (-2146304894)Unknown error: mod_aspdotnet: Failed to start Asp.Net Apache.Web host factory
AH00016: Configuration Failed

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Apache.Web, Version=2.4.0.2199, Culture=neutral, PublicKeyToken=9b9b842f49b86351' or one of its dependencies. The system cannot find the file specified.
File name: 'Apache.Web, Version=2.4.0.2199, Culture=neutral, PublicKeyToken=9b9b842f49b86351'
   at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
   at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
   at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
   at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
   at System.Activator.CreateInstance(String assemblyName, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(String assemblyName, String typeName)
   at System.AppDomain.CreateInstance(String assemblyName, String typeName)

위의 오류를 해결하기 위해 CLR 4를 로드하도록 변경했고 하위 호환성으로 .NET 2.0~3.5용의 ASP.NET이 동작하게 되어 있습니다.

단지, 현재 .NET 2.0~3.5만 설치된 환경에서 ASP.NET을 Apache 2.4에서 구동하는 방법은 없습니다. 만약 원한다면 Visual Studio 2008 설치 후 소스코드를 빌드하시면 됩니다.




위의 작업을 모두 마치고 나면 바이너리에 대한 마이그레이션은 전부 끝나지만 아쉽게도 httpd.conf에 대한 변경 사항이 Apache 2.4에서 달라진 것이 있어 기존의 mod_aspdotnet 사용 방법의 문서대로 하면 다음과 같은 오류가 발생합니다.

[Thu Aug 31 11:22:44.772053 2017] [authz_core:error] [pid 22704:tid 2724] [client ::1:63160] AH01630: client denied by server configuration: C:/temp/xampp/aspdocs/test.aspx

웹 브라우저 화면에는 이런 메시지가 뜹니다.

접근이 거부됨!

요청한 객체에 접근할 수 있는 권한이 없습니다. 읽기 보호가 되어 있거나 웹서버가 읽을 수 없도록 되어 있습니다. 

만약 이것이 서버 오류라고 생각되면, 웹 관리자에게 연락하시기 바랍니다. 

Error 403

localhost
Apache/2.4.27 (Win32) OpenSSL/1.0.2l PHP/7.1.8 mod_aspdotnet/2.4 

문제는 다음의 설정이었는데,

    <Directory "c:/temp/xampp/aspdocs">
    Options FollowSymlinks ExecCGI
    Order allow,deny
    Allow from all
    DirectoryIndex index.htm index.aspx index.asp
    </Directory>

아래의 문서에 보면 2.4에서 바뀌었다고 합니다.

Client denied by server configuration
; https://wiki.apache.org/httpd/ClientDeniedByServerConfiguration

따라서, mod_aspdotnet for Apache 2.4의 경우 다음과 같은 식으로 .conf 파일을 변경해야 합니다.

LoadModule aspdotnet_module modules/mod_aspdotnet.so
AddHandler asp.net asax ascx ashx asmx aspx axd config cs csproj licx rem resources resx soap vb vbproj vsdisco webinfo

<IfModule mod_aspdotnet.cpp>
    AspNetMount /aspdocs "c:/temp/xampp/aspdocs"
    Alias /aspdocs "c:/temp/xampp/aspdocs"

    <Directory "c:/temp/xampp/aspdocs">
Require all granted
    </Directory>

    AliasMatch /aspnet_client/system_web/(\d+)_(\d+)_(\d+)_(\d+)/(.*) "C:/Windows/Microsoft.NET/Framework/v$1.$2.$3/ASP.NETClientFiles/$4"

    <Directory "C:/Windows/Microsoft.NET/Framework/v*/ASP.NETClientFiles">
    Options FollowSymlinks
    Order allow,deny
    Allow from all
    </Directory>

</IfModule>




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 9/4/2017]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 151  152  153  154  155  156  157  158  159  160  161  162  163  [164]  165  ...
NoWriterDateCnt.TitleFile(s)
944정성태11/11/201031517VC++: 43. C++/CLI 컴파일 오류 - error C2872: 'IServiceProvider' : ambiguous symbol could be ...
943정성태11/8/201030649디버깅 기술: 30. windbg ".loadby sos" 명령어 [2]
942정성태11/7/201042265.NET Framework: 187. 실행 시에 메서드 가로채기 - CLR Injection: Runtime Method Replacer 개선 [7]파일 다운로드3
941정성태11/6/201025163.NET Framework: 186. windbg로 확인하는 .NET CLR LCG 메서드(DynamicMethod) [1]파일 다운로드1
940정성태11/6/201026022.NET Framework: 185. windbg로 확인하는 .NET CLR 메서드파일 다운로드1
939정성태10/24/201033008Windows: 51. RDP로 접속한 Windows Server 2008 R2 환경에서 Aero Glass 활성화 [1]
938정성태10/23/201024772디버깅 기술: 29. Windbg - Hyper-V 윈도우 7 원격 디버깅 구성 [1]
937정성태10/22/201030902DDK: 5. NT Legacy 드라이버: 프로세스(EXE) 생성/제거 모니터링 [3]파일 다운로드1
936정성태10/21/201029905DDK: 4. Device Driver 응용 프로그램의 빌드 스크립트 - 두 번째 이야기 [2]파일 다운로드1
935정성태10/17/201030520디버깅 기술: 28. Windbg - 윈도우 핸들 테이블 [3]
934정성태10/11/201033520디버깅 기술: 27. Windbg - Local Kernel Debug 모드 [2]
933정성태10/10/201025688.NET Framework: 184. 닷넷에서 호출 스택의 메서드에 대한 인자 값 확인이 가능할까? [2]파일 다운로드1
932정성태10/10/201028928DDK: 3. NT Legacy 드라이버를 이용하여 C#에서 Port 입출력파일 다운로드1
931정성태9/30/201023488오류 유형: 108. Net.Tcp Listener Adapter 서비스 시작 실패
930정성태9/30/201022773웹: 16. 윈도우 미디어 플레이어 - 일시 정지/시작을 스크립트에서 감지
929정성태9/17/201024051웹: 15. IE 9 - 작업 표시줄의 웹 사이트 바로가기 사용자 정의 - JumpLists [3]파일 다운로드1
928정성태9/16/201028222VC++: 42. 쓰기 전용 파일(예: 로그 파일)의 동기화 방법파일 다운로드1
927정성태9/14/201038099VC++: 41. UTF-8 포맷의 INI 파일에 대한 GetPrivateProfile... API 사용 불가 [2]
926정성태9/9/201027361Team Foundation Server: 41. 빌드 스크립트에 Code Coverage 추가 [1]파일 다운로드1
925정성태9/8/201031291Team Foundation Server: 40. Visual Studio 2010 - Code Coverage 결과를 외부 XML 파일로 출력하는 명령행 도구 제작 [1]파일 다운로드1
924정성태9/6/201021546개발 환경 구성: 88. SCVMM이 설치된 도메인에 참여하지 않은 Hyper-V 호스트 추가
923정성태9/5/201027540오류 유형: 107. SCVMM Agent 설치 오류 - Failed to configure the WS-Management service.
922정성태9/4/201036183오류 유형: 106. Hyper-V 가상 머신의 네트워크 끊김 현상
921정성태9/2/201030203DDK: 2. Device Driver 응용 프로그램의 빌드 스크립트 [2]파일 다운로드1
920정성태9/1/201034674오류 유형: 105. WMI - The RPC server is unavailable [2]
919정성태8/30/201040726DDK: 1. Visual Studio 2010 - Device Driver 제작- Hello World 예제 [3]파일 다운로드1
... 151  152  153  154  155  156  157  158  159  160  161  162  163  [164]  165  ...