nginx(openresty) + digest 크로스컴파일 삽질기록

2016. 12. 27. 23:10Programming/Server

반응형

- 우리 회사에서 사용하는 장비의 웹 환경은, Openresty가 크로스컴파일되어 fcgi로 api를 주고받는 형식이다.


- 예전에 칩셋의 제조사가 한번 바꼈었는데, 예전의 칩셋을 사용하는 장비들은 모두 digest방식을 지원했다. 하지만 어째서인지, 최근 칩셋을 사용하는 플랫폼에는 digest방식을 지원하는 기능이 빠져있었다.


- 어찌어찌해서 기존의 플랫폼을 참조하여, digest방식을 지원하는 UI를 만들었다. 그런데 문제가 있었다. 쿼리 스트링을 사용해서 api를 호출하려 하니, 계속해서 재인증을 요청한다.


- 도무지 원인을 알 수가 없었기에, nginx 문서와 가이드를 한참을 뒤져보고, 또 설정파일을 분석하느라 약 2주일이 걸렸다. 바짓가랑이라도 잡는 심정으로 전임자가 만들어놓고 간 openresty 빌드 스크립트를 구동시켜봤지만, 제대로 동작하지 않았다.


- 결국 2주정도 머리를 싸멘 뒤에서야 원인을 알 수 있었는데, samizdatco/nginx-http-auth-digest 모듈에 버그가 있었다. digest에 쿼리스트링이 포함되어있으면, 정확히 말해서 ?를 포함한 특정 특수문자가 포함되어 있으면 파싱이 제대로 되지 않았다.


- 도무지 어떻게 해야되는건지 알수가 없었는데, 우연히 검색하다가 2013년도에 나랑 비슷한 문제로 고민하던 사람을 발견한다. (#samizdatco/nginx-http-auth-digest의 18번 이슈) 그리고 그 문제가 수정된 코드도 발견했다. (#samizdatco/nginx-http-auth-digest의 19번 이슈) 정확히 말하면, 18번 이슈에 문제를 야기한 agemmell이, '13일 전에 yanchenko-igor가 이 문제를 수정했지만 아직 머지되지 않았다'라는 글을 보고 19번 이슈를 발견하게 됐다.


- 일단 19번 이슈에서 파생된, yanchenko-igor/nginx-http-auth-digest 모듈을 clone했다. 이 이후에 뭐가 수정됐을 지 몰라서, diff로 확인해보니 18번 이슈의 마지막에 agemmell이 야기한대로 p=p 한 줄이 누락되어있었다. agemmell과 마찬가지로 p=p 라인을 추가했다.


- 문제는 이제 openresty의 크로스 컴파일이었다. 이전에 크로스 컴파일을 경험해본 적이 없는 나로썬, 빌드스크립트 하나를 가지고 무작정 뛰어들수밖에 없었다. 그나마 좀 다행이라면 전임자가 만들어둔 빌드 스크립트덕에, 컴파일러에 전달해야하는 파라메터(예를들면 칩셋이라던지)등을 크게 고민하지 않아도 됐다는 점 하나였다.


- Openresty를 크로스 컴파일할 때, 통상적인 방법으로는 안된다는 사실을 꽤 뒤늦게 깨닳았다. 처음에는 빌드스크립트를 그냥 구동하니, cpu가 맞지 않다는 오류가 떴다. 빌드 스크립트에 컴파일러가 /bin/usr/gcc로 잡혀있었다.


- 컴파일러를 타겟 시스템의 컴파일러로 변경하고, 다시 빌드스크립트를 동작한다. 이번엔 LuaJIT을 빌드하는 도중에, minilua를 실행하려고 하다가 에러가 난다. minilua는 타겟 시스템 용으로 빌드됐는데, 이를 호스트 시스템에서 실행하려고 하니 에러가 나는 것이다.


- 결국 한참을 헤매이다 전임자들에게 연락을 했다. 결국 scratchbox2라는 툴을 이용하면 된다는 내용을 들었는데, 사용하는 법을 몰라서 헤맸다. 전임자의 계정으로 로그인한 후, scratchbox2를 실행시켰지만 역시 빌드는 되지 않았다.


- 어느정도 빌드가 된다 싶었는데, asm.h를 참조하는 부분에서 에러가 났다. 전임자에게 연락해보니 타겟 시스템의 asm을 참조해야 하는데, 호스트 시스템의 asm을 참조해서 에러가 나는 것 같다고 했다. 결국 sb2의 옵션을 찾다가, -eR 옵션으로 실행시키면 에뮬레이트 모드로 동작한다는 걸 알았다.


- 에뮬레이트 모드로 동작하니 타겟 시스템이 루트 디렉토리인 것 처럼 동작하긴 하지만, 호스트 시스템에 설치된 perl이나 git등을 사용할 수 없었다. 결국 나는 호스트 시스템에서 빌드에 필요한 프로그램과 파일들을 하나씩 복사해왔다. 어느정도 잘 돌아간다 싶었더니, limits.h나 std*.h등을 찾지 못하는 불상사가 발생했다.


- 한참을 환경변수와 씨름하다가, 뭔가 굉장히 간단한 걸 놓치고 있다는 생각이 들었다. 전임자가 '나는 -R같은 옵션은 준 적이 없었는데.'라고 말한게 퍼뜩 떠올랐다. sb2-init을 다시 실행하고, clean후 다시 타겟 시스템에서 빌드를 시도했다. 역시 호스트 시스템의 asm을 참조하는지, asm을 실행할 수 없다는 에러가 떴다.


- 전임자의 scratchbox2 설정파일을 열어봤더니, 타겟 시스템의 컴파일러 외에 하나의 파일을 더 전달한다. 파일 이름은 hisispec이었는데, 정확히 어떤 파일인지는 아직 확인하지 못했다. 내 루트패스에 있는 scratchbox2의 설정파일을 열고, 해당 파일의 위치를 추가해준다. 여전히 호스트 시스템의 asm을 참조하는 듯 했다.


- 다시 타겟 시스템에서 sb2-init을 실행시켰다. 다만 sb2-init <alias> <gcc path>:<hisispec path>의 형태로 실행시켜서, 추가적인 파일을 전달했다. 빌드 스크립트에서 다른 유틸들의 경로를 참조하지 못하는 바람에, 빌드 에러가 발생했다.


- 폴더들의 위치를 재조정한 뒤에 빌드하니, 정상적으로 빌드된다. 게다가 장비에 빌드 결과물을 넣고 실행하니, 정상적으로 digest가 동작한다. 글은 그다지 길지 않지만, 무려 한달을 삽질해낸 결과이다. 굉장히 골치아픈 일이긴 했지만, 단순한 유지보수보다 훨씬 재밌는 경험이었다.

반응형