(컴파일 없이) nginx에서 환경 변수 불러오기
요약
lua 모듈 쓰면 겁나 편하지만, 사정상 사용할 수 없다면 셸 스크립트 방식도 고려해보자.
상황
- nginx에서 특정 url에 대해 ip를 제한해야 하는데, ip 설정을 동적으로 하고 싶었다. (하지만 db 설정 없이)
- nginx에서 환경 변수를 읽어들이는 방법을 찾아보니 perl 모듈이나 lua 모듈을 사용하라는데, nginx를 직접 컴파일해야 한다는 점이 걸렸다. (컴파일 공포증)
아무것도 컴파일하지 않고, 추가로 설치하는 일도 없이 할 수는 없을까?를 고민하다가 최근 재미 들린 셸 스크립트를 활용해보기로 했다.
서비스는 docker 이미지로 만들어져, aws의 ECS에 올라가 있다.
1. ip로 url 접근 제한하기
/admin/
url에 대해서 특정 ip만 접근하도록 해보자.
먼저 nginx.conf
의 /admin 부분에 주석문(# admin_ip_whitelist
)을 하나 추가했다.
# nginx.conf
...
# 로드 밸런서를 사용하는 경우 이 부분들이 필요하다.
set_real_ip_from 172.17.0.0/16; # 로드 밸런서의 ip 대역을 넣어준다.
real_ip_header X-Forwarded-For;
...
# 로드 밸런서가 없다면 아래 부분만 있어도 된다.
location /admin {
uwsgi_pass unix:///var/run/default-uwsgi.sock;
include uwsgi_params;
# admin_ip_whitelist
}
...
그 다음 docker 이미지의 CMD 부분에 셸 스크립트를 넣는다.
# Dockerfile
...
ADD ./run.sh /
CMD /run.sh
이제 run.sh
파일을 작성한다.
#!/bin/bash
if [ -n "$IP_WHITELIST_FOR_ADMIN" ]; then
IP_WHITELIST="allow ${IP_WHITELIST_FOR_ADMIN};\n"
IP_WHITELIST+="deny all;"
sed -i "s@# admin_ip_whitelist@${IP_WHITELIST}@g" /etc/nginx/nginx.conf
fi
supervisord -n # 이건 원래 Dockerfile의 CMD 부분에서 실행하던 명령어
이제 ECS의 Task Definition에서 IP_WHITE_LIST_FOR_ADMIN
환경변수를 추가하면 해당 IP만 /admin
에 접근할 수 있다.
2. ELB의 vpc 대역으로 특정 url 접근 제한하기
이번에는 /api/special
에 대해 같은 vpc 내부의 요청만 허용해보자. (1번 작업을 해두었다고 가정한다.)
nginx.conf
의 /api/special 부분에 주석문(# vpc_ip_range
)을 추가한다.
location /api/special {
uwsgi_pass unix:///var/run/default-uwsgi.sock;
include uwsgi_params;
# vpc_ip_range
}
그리고 run.sh
에 다음 내용을 추가한다.
# run.sh
...
if [ -n "WRITE_API_ACCESS_ONLY_VPC" ]; then
# 서버의 IP 네트워크 내역을 검출하는 방법.
# 주의! 네트워크가 여럿인 경우엔 결과 값도 여러 개로 나오므로, 이를 배열에 저장하여 사용해야 함
VPC_SUBNET_MASK=`ip -o -f inet addr show | awk '/scope global/ {print $4}'`
VPC_IP_RANGE="allow ${VPC_SUBNET_MASK};\n"
VPC_IP_RANGE="deny all;"
sed -i "s@# vpc_ip_range@${VPC_IP_RANGE}@g" /etc/nginx/nginx.conf
fi
...
이제 ECS의 Task Definition에서 WRITE_API_ACCESS_ONLY_VPC
값을 설정하면(어떤 값으로든), /api/special
이라는 경로는 VPC 내부에서만 접근할 수 있게 된다.
배운 점
-
shell script를 좀더 제대로 배워보고 싶어졌다. 알면 알수록 활용성이 올라갈 듯.
-
sed 같은 유닉스 기본 명령도 많이 알아보자.
-
docker와 환경 변수 독립이라는 개념이 유닉스나 시스템 엔지니어링에 익숙하지 않은 사람(=나)에게 큰 도움이 되는 듯.
COMMENTS