- Rabbitmq-c와 Curl 모두 SSL(TLS)연결 시 openssl라이브러리를 사용하는데 서로 다른 버전의 라이브러리를 사용하도록 .lib를 빌드하면 amqp socket만들 때 에러가 발생한다. 꼭 두개의 버전을 맞춰야 함에 유의하자.
- OpenSSL라이브러리 설치
- 라이브러리 다운로드: Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions
- 라이브러리는 Win32 OpenSSL v1.1.1d를 설치하자.
- .exe파일을 다운받아 실행하면 설치파일이 실행된다.
- 설치파일 실행 도중 OpenSSL DLL을 어디에 위치시킬지 경로를 물어보는데 이 경로에 'libcrypto-1_1.dll', 'libssl-1_1.dll' 두개가 설치된다. /bin디렉토리를 선택하자. 이 두개 dll은 우리 프로그램 돌릴때도 .exe경로에 위치시켜야 하므로 꼭 보관해두자.
- libcurl라이브러리 빌드
- 라이브러리 다운로드: curl - Download
- 라이브러리는 curl-7.68.0.zip을 다운로드하자.(버전은 달라도 괜찮지만 맨 상단의 .zip파일을 다운로드 하도록 한다.)
- 다운로드 후 압축을 해제한다. 압축 해제한 폴더 안에 build폴더를 하나 새로 만들자.
- cmake gui를 열어서 Where is the source code에 압축을 해제한 폴더를 선택한다.
- Where to build the binaries에 build폴더를 선택한다.
- configure버튼을 눌러 visual studio버전을 선택하고 platform은 Win32를 선택하자. OK를 누르면 프로젝트 분석 후 내가 선택할 수 있는 옵션을 보여준다.
- 옵션 중 다른거 다 해제하고 CMAKE_USE_OPENSSL, ENABLE_INET_PTON, ENABLE_THREADED_RESOLVER만 체크하자.
- Generate를 누르면 SSL_EAY_DEBUG, SSL_EAY_RELEASE가 리스트에 추가될 것이다. 이 때 꼭 1번에서 설치한 OpenSSL내의 libssl32MTd.lib, libssl32MT.lib가 선택되도록 하자.
- build폴더로 들어가면 CURL.sln 파일이 생성되었음을 확인할 수 있다. 눌러서 프로젝트를 열자.
- 내부에 프로젝트 6개 정도가 보이고 그 중 libcurl프로젝트가 보인다. 속성을 눌러 General로 이동하여 debug의 경우 TargetName을 libcurl32MTd로 변경한다. release의 경우 TargetName을 libcurl32MT로 변경한다.
- C/C++ > Code Generation으로 이동하여 RuntimeLibrary항목을 debug의 경우 /MTd로 변경한다. release의 경우 /MT로 변경한다. 변경하는 이유는 우리가 주로 사용하는 MFC프로그램이 /MT로 빌드되기 때문에 이걸 맞춰줘야만 라이브러리를 가져다 사용할 수 있기 때문이다.
- C/C++ > Output Files로 이동하여 ProgramDatabaseFileName항목을 $(IntDir)$(Targetname).pdb로 변경한다. 이는 libcurl32MTd.lib가 떨어지는 경로에 .pdb파일도 함께 떨어지게 하기 위함이다.
- 위에서 떨어진 libcurl32MTd.lib와 압축해제폴더/include/curl 폴더 두가지를 가져다 쓸 것이니 잘 챙겨두자.
- rabbitmq-c 라이브러리 빌드
- 라이브러리 다운로드: GitHub - alanxz/rabbitmq-c: RabbitMQ C client
- 라이브러리는 git을 clone하든지 download하든지 해서 받자.
- libcurl과 마찬가지로 build폴더를 만들어서 cmake로 소스를 만들자. Configure옵션에 보면 LIB_EAY_DEBUG, LIB_EAY_RELEASE, SSL_EAY_DEBUG, SSL_EAY_RELEASE항목이 보인다. 꼭 1번에서 설치한 openssl폴더 경로에 있는 libcrypto32MTd.lib, libcrypto32MT.lib, libssl32MTd.lib, libssl32MT.lib 가 선택되었는지 확인하자.
- Enable_SSL_SUPPORT를 꼭 체크하고, BUILD_SHARED_LIBS는 체크를 해제하고 나머지는 모두 체크하고 Generate하자. (가끔 Configure나 Generate시 오류가 나는 경우가 있는데 이 때는 CMAKE를 닫고 관리자 권한으로 다시 열어보자. 그러면 잘 되기도 한다.)
- build폴더로 들어가면 rabbitmq-c.sln이 생성되었음을 확인할 수 있다. 눌러서 프로젝트를 열자.
- 내부에 프로젝트가 여러개 보이는데 rabbitmq-static프로젝트의 속성으로 들어가 General > TargetName을 debug의 경우 librabbitmq32MTd로, release의 경우 librabbitmq32MT로 변경한다.
- C/C++ > Code Generation으로 이동하여 RuntineLibrary항목을 debug의 경우 /MTd로 변경한다. release의 경우 /MT로 변경한다.
- C/C++ > Output Files로 이동하여 ProgramDatabaseFileName항목을 $(IntDir)$(Targetname).pdb로 변경한다. 또한 C/C++ > General의 DebugInformationFormat을 Program Database(/Zi)로 변경한다.
- 빌드 시 떨어진 librabbitmq32MTd.lib와 압축해제폴더/librabbitmq폴더 두가지를 가져다 쓸 것이니 잘 챙겨두자.
- 라이브러리 가져다가 SSL로 HTTP, AMQP로 서버와 연결하기.
- 프로젝트는 MFC라이브러리를 포함한 Console application으로 만들자.
- 프로젝트 폴더에 lib와 include를 만들자. lib에는 .lib파일들을 넣어둘 것이고 include에는 #include할 헤더파일들을 모아둘 것이다.
- 헤더파일 가져오기
- 먼저 1번에서 설치한 openssl 경로로 들어가서 include폴더 아래에 있는 openssl폴더를 복사해다가 include 아래에 붙여넣자. 안에 열어보면 aes.h, blowfish.h등이 들어있다.
- 2번에서 챙겨둔 압축해제폴더/include/curl폴더를 가져다가 include 아래에 붙여넣자. 안에 열어보면 curl.h, easy.h등이 들어있다.
- 3번에서 챙겨둔 압축해제폴더/librabbitmq 폴더를 가져다가 include아래에 붙여넣자. 안에 열어보면 amqp.h 등이 들어있다. 폴더명은 편의상 rabbitmq로 바꾸었다.
- 파일이 준비되었으면 프로젝트 속성으로 들어가서 C/C++ > General > Additional Include Directory에 ..\include;..\include\rabbitmq; 요렇게 두개 폴더를 써준다. 굳이 rabbitmq폴더를 여기다 써준 이유는 일부 rabbitmq 헤더들이 include할 때 이 필요하기 때문이다. 이것으로 헤더파일 include는 다 준비되었다.
- 라이브러리 가져오기
- 1번에서 설치한 openssl 경로로 들어가서 lib/VC/ 안의 libcrypto32MTd.lib, libssl32MTd.lib 두개를 가져다가 lib아래 openssl\lib\ 폴더를 만들고 그 아래 위치시킨다.
- 2번에서 챙겨둔 압축해제폴더/build/lib/debug안의 libcurl32MTd.lib, libcurl32MTd.pdb를 가져다가 lib폴더 아래에 curl폴더를 하나 만들고 그 아래 위치시킨다. (릴리즈용을 만들었다면 역시 같은 경로에 복사해두면 된다.)
- 3번에서 챙겨둔 압축해제폴더/build/librabbitmq/debug/ 안의 librabbitmq32MTd.lib와 librabbitmq32MTd.pdb를 lib아래 amqp/rabbit/ 폴더를 만들고 그 아래 위치시킨다.
- 프로젝트 속성으로 들어가서 Linker > General > LinkLibraryDependencies에 ..\lib;를 추가한다.
- 프로젝트 속성의 Linker > Input > Additional Dependencies에 들어가서 위에서 추가한 모든 라이브러리들을(4개) 적어준다. amqp\rabbit\librabbitmq32Mtd.lib;curl\libcurl32Mtd.lib;openssl\lib\libssl32MTd.lib;openssl\lib\libcrypto32MTd.lib; 추가적으로 ws2_32.lib도 적어준다.
- 추가설정
- curl라이브러리를 사용하기 위해서 몇가지 추가 설정이 필요하다. 먼저 property > c/c++ > preprocessor에 "CURL_STATICLIB"를 추가한다. 그리고 ws2_32.lib또한 추가해준다.
- rabbitmq라이브러리를 사용하기 위해서는 1번에서 생성한 openssl폴더의 bin아래에 있는 libcrypto-1_1.dll과 libssl-1_1.dll 두개가 추가적으로 필요하다. 이 두 파일은 .exe가 동작하는 위치에 함께 복사해 두자. (openssl 설치 시 이 .dll을 어디다 둘지 결정하게끔 했는데 만약 windows경로에 뒀다면 아마도 복사하지 않고도 자동으로 링크가 됐을것이다. 그러나 우리는 프로그램을 배포하는 입장이므로 꼭 별도로 이 .dll을 .exe와 함께 배포하도록 한다.)
- 서버와 SSL(TLS)로 연결하기 위해서는 인증서가 필요하다. 인증서는 원희가 만들어둔 cert.pem을 사용하면 되며 프로젝트 소스파일이 있는곳에 붙여넣으면 "cacert.pem"으로 바로 파일 지정이 가능하다. curl라이브러리의 경우 curl_easy_setopt(m_curl, CURLOPT_CAINFO, "cacert.pem"); 을 HTTP 생성자에 넣어두면 바로 입력이 된다. amqp의 경우 smqp_ssl_socket_set_cacert(socket, "cacert.pem")을 해주면 바로 입력이 된다. 리눅스에서 포트가 잘 열렸는지는 netstat -tnlp 명령어로 확인하면 좋다.
- 서버설정
- rabbitmq는 기본적으로 ssl통신을 지원한다. rabbitmq.config 파일을 열어보면 {ssl_listeners, [5671]} 이라는 항목이 주석처리되어있는데 주석을 풀고 포트를 적당히 설정한 후 저장한다. 이후 systemctl restart rabbitmq-server.service 를 입력해서 rabbitmq를 재시작해주면 5671포트로 ssl통신을 할 준비가 되었다.
- 주의사항
- 삽질을 많이 했는데 주된 원인은 openssl때문이었다. openssl은 1.1.0을 기점으로 library이름이 변경되었다. 이전에는 ssleay.lib, libeay.lib 이후에는 libssl.lib, libcrypto.lib. CURL라이브러리와 Rabbitmq-c 라이브러리가 모두 openssl라이브러리를 필요로 하는데 각각 다른 버전의 라이브러리를 사용하니 amqp_ssl을 콜 할때 socket이 생성되지 않는 문제가 발생했다.
- 꼭 로컬PC에 정식 openssl을 '설치!!!!'하고 이 라이브러리를 가지고 나머지 curl과 rabbitmq라이브러리를 생성해야한다.
'Programming > Windows Visual C++' 카테고리의 다른 글
/MT /MD 옵션의 차이 (0) | 2020.03.16 |
---|---|
.lib와 .dll의 차이 (0) | 2020.03.16 |
윈도우 서비란 무엇인가? 서비스 만들기 (0) | 2020.03.16 |
함수에서 문자열을 리턴하는 올바른 방법 (0) | 2020.03.16 |
.h파일 include하는 올바른 방법 (0) | 2020.03.16 |