AWS EC2를 활용한 VPN / ADBLOCKER 만들기

목차

개발의 목적

필자는 원래 Zenmate 무료 vpn을 사용하고 있었다. 워낙 옛날때부터 사용하기도하고 VPN 자체로 지역변경은 문제없이 잘되서 크게 문제는 없었다. 하지만 디즈니 플러스도 써보고 싶고 어느 순간부터 속도도 줄어들고, 광고도 많아져서 차라리 유료 VPN을 써보려고 했었다.
그래서 찾았던게 Nord VPN이었다. 국내외 커뮤니티에서 평가나 속도 괜찮은 것 같아서 구입할려고 했었지만 VPN을 바꾸는 목적인 디즈니 플러스도 간혹안된다고도하고 1달씩 하기에는 1만원이 넘는 건 부담스러워서 속도나 편의성 기준으로 찾아보다가 결국엔 EC2를 사용해 속도와 편의성을 모두 가진 VPN을 준비해야겠다고 생각했다.
최종적인 개발목표는 해외리전 EC2에 VPN을 위한 openVPN과 다루기 쉬운 AdBlock으로 Pihole을 EC2에 올리는 사용하는 것으로 정했다.

결론

VPN 속도

좌:EC2VPN 우:VPN없는 SK기가라이트-속도
사진의 왼쪽이 SK 기기라이트에서 VPN을 사용할때 속도이고 오른쪽은 VPN적용이 안된 SK 기가라이트 속도이다. 왼쪽에는 100/50Mbps의 속도를 보이고 오른쪽은 463/474Mbps의 속도가 나온다. VPN 사용중일때도 광랜 환경에서는 핑을 제외하고는 큰 속도 저하는 없을 것으로 보인다.

광고 차단

좌:EC2VPN 우:VPN없는 SK기가라이트-광고
사진의 왼쪽이 VPN을 사용할때 speedtest.net 화면이고 오른쪽은 VPN적용이 안됨 SK 기가라이트 속도이다. 왼쪽에는 광고가 전혀없지만 오른쪽에는 광고가 그대로 나오고 있다. 광고를 안볼 수 있는 것은 큰 장점이지만 광고가 사라지면서 UI의 왜곡도 있는 것으로 보인다.

마무리하며

원래 계획처럼 만드는 것에 성공했고 속도나 광고차단도 문제없이 되었다. 개발 당시에는 AWS 사용비용에 대해 그렇게 민감하지는 않았지만 EC2에 필연적으로 따라오는 Elastic IP,EBS 볼륨,데이터 전송비등에 예상치 못한 요금을 당하면서 AWS 설명서를 더더욱 자세히 읽어야겠다고 느꼈다. 예시로 Elastic IP를 한개의 활성화된 인스턴스에 연결하는 것은 무료지만 중지된 인스턴스에 연결하는 것은 시간당 0.005$를 받는다! 또한 데이터 전송비도 리전마다 다르므로 반드시 개발단계에서 파악해서 돈을 아낄 수 있도록하자

개발에 사용한 도구들

EC2 인스턴스

개발을 시작할때는 온디맨드 인스턴스만 사용했지만 비용절감을 위해 테스트 및 배포단계에서는 최대 5% 내로 정도 중지될 수 있는 스팟 인스턴스로 변경해서 사용하였다. 스팟 인스턴스에 중요한점은 crontab 또는 –restart 명령을 사용해서 인스턴스 재부팅될때 자동으로 시작할 수 있도록 준비하고 미리 테스트해봐야한다는 것이다.
필자는 최저가에 EC2를 사용하는 것으로 목적으로 했기에 다음처럼 설정했다.EBS 볼륨설정은 마그네틱(스탠다드) 8G 최소로, 인스턴스는 t3a.nano로, 보안그룹이나 AMI, Elastic_IP 등은 테스트용 인스턴스에서 배포용 스팟 인스턴스로도 쉽게 적용할 수 있으므로 잘 정리해놓으면 배포때 시간을 아낄 수 있다. 중요한점은 CPU 무제한은 해제해야 추가로 과금이 나오는 걸 줄일 수 있다. 그외에는 큰 문제가 없을 것 같고 Pihole이랑 VPN 포트는 기존 포트는 잘 알려진 포트이니 각자에 맡게 1194과 80에서 수정하면 된다.

인스턴스 설정1
인스턴스 설정2

스팟 인스턴스에서도 온디맨드같이 최대비용(필자의 경우에는 t3.mircro까지 시간당 0.03$)이랑 인스턴스 유형만 잘 설정하고 권장값으로 해도 큰 과금문제없이 잘 작동되는 것 같다.

Docker

Docker는 기존 sudo npm install **** 처럼 프로그램/모듈을 설치하는 것이 아닌 이미 세팅된 프로그램을 리눅스 컨테이너로 불러와 사용하는 것이다. 그 덕분에 세팅하는 시간도 줄어들고 프로그램을 관리할때도 장점이 많다. 다만 컨테이너별로 IP가 할당되기에 다른 컨터이너와 통신을 하려면 조금 까다라운 부분도 있다. 필자도 Docker 장점을 처음에는 잘 몰랐지만 이번에 개발을 하며 Docker을 편리함을 많이 느낄 수 있었다.

OpenVPN

OpenVPN은 VPN 서버를 호스팅할 수 있게 해주는 서버이다. 서버와 클라이어트의 config을 통해 설정할 수 있고 오픈소스이기에 untangled처럼 기능 제한을 받지도않는다!

Pihole

Pi-hole은 광고나 사용하고싶지않은 특정 사이트들을 차단하는 기능을 하는 서버이다. 원래 라즈베리파이에 올려서 사용하도록 만들어졌지만 설치난이도나 쉬운 UI덕에 다른 곳에서도 많이 사용되는 듯한다. 필자도 쉬운 웹 인터페이스가 있다는 것이 큰 장점이라 생각해 선택하게되었다.

개발 과정

EC2에 접속하기

  1. SSH를 위한 Putty 와 SFTP를 위한 Filezila 를 준비한다.

  2. Puttygen을 이용해서 PEM파일을 ppk로 변환한다.

  3. Elastic IP를 생성하고 공공IP를 인스터스를 연결하고 인스턴스를 재부팅시킨다.

  4. Connection-SSH-Auth에 ppk 키파일을 넣고 Host name에 ec2-user@ip주소를 입력해 접속한다. 아래 사진을 참고하자

  5. Filzila의 경우에도 사이트관리자->새 사이트추가로 사이트를 등록하고 ‘키파일선택’ 로그인과 PEM파일의 경로를 잡아주면 된다.

    putty-guide1

    putty-guide2

    filezila-guide1

Docker와 환경 설정하기

1
$ sudo yum update # 최신으로 업데이트
1
2
$ sudo yum install docker # Docker 설치
$ docker --version # Docker가 잘 설치됬는지 확인
1
2
$ sudo usermod -aG docker ec2-user
$ sudo systemctl enable docker # Docker 자동실행 등록
1
2
$ sudo yum install docker # Docker 설치
$ docker --version # Docker가 잘 설치됬는지 확인

Pihole 설정하기

1
2
$ sudo docker pull pihole/pihole # Pihole 설치
$ sudo docker run -d --restart unless-stopped -p 53:53/tcp -p 53:53/udp -p 원하는포트:80 --cap-add=NET_ADMIN -e ServerIP=IP주소 -e WEBPASSWORD=원하는비밀번호 -e DNSMASQ_LISTENING=all --name pihole pihole/pihole # 웹으로 접속하기위한 포트번호, IP주소, 비밀번호를 지정해주면 실행시킬 수 있다! [IP주소:원하는포트]를 입력해서 잘 되는지 확인해보자 홈페이지가 뜬다면 잘 설치된 것 이다.

OpenVPN 설정하기

1
2
$ sudo docker pull kylemanna/openvpn # openVPN 설치
$ docker --version # Docker가 잘 설치됬는지 확인
1
2
$ mkdir ovpn-data # openVPN할 폴더 지정
$ OVPN_DATA="/home/ec2-user/ovpn-data" # openVPN 설치를 위한 환경변수를 지정한다.

폴더 생성 확인 이후에는 재부팅되고나서도 알아서 환경변수를 가져올 수 있도록 ec2-user에 있는 .bashrc를 수정해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions

export OVPN_DATA=/home/ec2-user/ovpn-data

이런식으로 bashrc 파일에 수정해준다

1
2
$ docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm kylemanna/openvpn ovpn_genconfig -u udp://IP주소 # IP주소는 putty에서 접속할때 사용한 부여받은 주소를 적어준다
$ docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it kylemanna/openvpn ovpn_initpki #암호화 시작 Common name에는 서버이름을, 그 외에는 암호를 적자! 약간 시간이 걸리므로 기다리자!

이후 생성된 openvpn.config 파일에 아래쪽에 다음처럼 수정해준다.

1
2
3
4
5
6
7
### Push Configurations Below
push "block-outside-dns"
push "dhcp-option DNS 172.17.0.3"
push "dhcp-option DNS 172.17.0.2" # Docker가 어떤 IP로 할당할지모르니 2번과 3번째 IP를 모두 등록한다.
#push "dhcp-option DNS 8.8.8.8"
#push "dhcp-option DNS 8.8.4.4" # 기존 DNS는 반드시 주석처리하자!
push "comp-lzo no"
1
2
3
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it kylemanna/openvpn easyrsa build-client-full CLIENTNAME nopass # 이제 접속을 위한 클라이언트 파일을 만들자  
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm kylemanna/openvpn ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn # 현재 있는 디렉토리에 클라이언트의 접속을 위한 ClIENTNAME.ovpn 파일이 만들어진다. 접속을 위해 필요하므로 반드시 sftp로 다운로드하자
docker run -v $OVPN_DATA:/etc/openvpn -d --restart unless-stopped --name openvpn -p 원하는포트:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn # 반드시 보안규칙에 추가한 포트와 왼쪽에 입력하는 포트와 일치해야한다! 2번 확인하자!

마지막으로 다운로드한 ClIENTNAME.ovpn의 위쪽을 다음처럼 수정한다.

1
2
3
4
5
6
7
8
client
nobind
dev tun
remote-cert-tls server
register-dns
block-outside-dns

remote EC2의 IP주소 입력한포트 udp

이제 openVPN 클라이언트를 설치하고 잘되는지 테스트해보자. 참고로 Warning 로그는 해결하는 법도 같이 뜨니 신경쓰이면 설정을 추가해도 괜찮다.

작동확인 및 검증하기

이제 Pihole과 openVPN이 모두 잘 작동되는지 확인해보자 Pihole 웹페이지 툴-네트워크에 들어가면 녹색으로 잘 연결됬는지 확인할 수 있다.

Conclusion1

이렇게 DNS에 적은 주소 녹색으로 보인다면 잘 연결된 것이다. 다음으로는 네이버와 쿼리창을 비교해서 pihole이 잘 작동하는지를 확인하자

Conclusion2

이제 VPN겸 애드블록 서버가 완성되었다. 필자도 배포하고 사용한지 얼마되지않아 확실하지는 않지만 2일에 총 0.12달러이므로 1달에 약 1.8달러 일것으로 예상이된다. 정말로 디즈니 플러스만 됬다면 더할나위없이 좋았을 것이다.

시행착오

Q1. VPN은 접속되지만 DNS 오류가 뜰 경우
A1. 서버쪽 Config파일에서 저장이 잘 안되서 발생한다. 간혹 Docker가 이상한 IP를 주는 경우도 있었는데 이때는 docker inspect openvpn 을 써서 openvpn이 있는 컨테이너의 주소를 찾아서 입력하면된다.

Q2. Pihole에서 OpenVPN을 인식하지 못할때
A2. 항상 그렇지는 않지만 대부분의 경우에는 Pihole을 먼저 실행한 후에 openVPN을 실행시켜야한다! 순서에 주의하자!

Q3. 도커 컨테이너 재부팅후 자동으로 시작되지않을때
A3. docker ps -a 를 사용해서 컨테이너 작동여부를 찾고 기존 컨테이너를 docker rm -f $(docker ps -a -q) 를 사용해서 삭제한 다음 다시 docker run 명령어들을 실행시켜보자

Q4. 인도 리전(뭄바이) VPN 속도가 안나올때 / 추천하는 리전은?
Q4. 필자도 전엔 몰랐지만 뭄바이 리전은 속도가 잘해야 50mbps/150mbps이다. 즉 다운속도 느리기에 웹서핑에서도 속도 감소가 느껴진다. 그래서 뭄바이가 가장 저렴한 리전임에도 불구하고 결국 최종선택지가 되지는 않았다. 인스턴스 비교사이트에서 자신에게 가장 맞는 인스턴스와 지역을 찾아보자 필자는 개인적으로 t3a.nano와 오리건 리전을 추천한다.

참고한 자료들과 같이보기 좋은 자료들

  1. https://m.blog.naver.com/hikari1224/221821047611
  2. https://ora-sysdba.tistory.com/entry/Cloud-Computing-Amazon-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4%EC%97%90-SFTP%EB%A5%BC-%EC%97%B0%EA%B2%B0%ED%95%B4%EB%B3%B4%EC%9E%90
  3. https://hub.docker.com/r/pihole/pihole
  4. https://medium.com/fillory/openvpn-pihole-ad-blocking-on-aws-lightsail-for-3-50-mo-7e814eafff84
  5. https://hub.docker.com/r/kylemanna/openvpn
  6. https://starseeker711.tistory.com/133
  7. EC2관련 AWS DOCS