Basic Auth 란 서버에서 인가되지 않은 사용자들의 접근을 제한할 수 있는 인가 시스템입니다.
만약 관리자 페이지와 같이 일반 사용자들에게 접근을 허용하면 안되는 URL 이 있는경우, Basic Auth 를 사용하면 인가되지 않은 사용자들의 접근을 제한할 수 있습니다. 또 Nginx 에서 가장 손쉽게 사용자 접근을 제한할 수 있는 방법입니다.
결과 화면부터 보여드리자면, 저희는 아래와 같이 admin 페이지에 접속시 인가된 유저를 식별할 수 있도록 인가 과정을 요구하는 환경을 구축할겁니다.
admin, notAdmin 이라는 URL 을 추가했습니다. 일반 사용자들은 /getServerInfo, /notAdmin 으로부터 특별한 인가 과정없이 리소스를 요청할 수 있지만, 반대로 /admin 으로부터는 리소스를 마음대로 요청하지 못하도록 basicAuth 를 적용한 상황입니다.
더 자세한 스프링부트 환경 구축 내용이 궁금하다면, 지난 포스팅을 참고하자!
@RestController
@PropertySource(value = "application.yml")
public class ServerController {
@Value("${serverName}")
private String serverName;
private Integer visitedCount = 0;
@GetMapping("/getServerInfo")
public ResponseEntity<Map<String, String>> getServerInfo(){
visitedCount++;
Map<String, String> serverInfo = new HashMap<>();
serverInfo.put("ServerName:", serverName);
serverInfo.put("visitedCount:", visitedCount.toString());
return ResponseEntity.ok(serverInfo);
}
@GetMapping("/admin")
public ResponseEntity<Map<String, String>> getAdmin(){
Map<String, String> serverInfo = new HashMap<>();
serverInfo.put("Are you a admin?", "yes!!!!!!!");
return ResponseEntity.ok(serverInfo);
}
@GetMapping("/notAdmin")
public ResponseEntity<Map<String, String>> notAdmin(){
Map<String, String> serverInfo = new HashMap<>();
serverInfo.put("Are you a admin?", "no!!!!!!!");
return ResponseEntity.ok(serverInfo);
}
}
다음으로 Nginx 에서 HTTP 프로토콜을 통해 인증을 구현하는 ngx_http_auth_basic_module 모듈이 설치되어 있어야합니다.
이는 일반적으로 apt 명령으로 일반적으로 패키지를 통한 설치를 진행했다면 기본적으로 포함되어 있는 모듈입니다.
그런데 Basic Auth 의 보안성을 더 강화하기 위해선, 비밀번호를 암호화해서 저장해야합니다. 비밀번호를 암호화해서 저장하는 방법은 간단하게 OpenSSL 을 사용하는 방법과, 아파치 유틸리티(htpasswd) 를 이용하는 방법이 있습니다.
저희는 이번에 htpasswd 를 사용하겠습니다. 아래와 같이 설치를 진행해주세요!
$ apt-get install apache2-utils // htpasswd 모듈 설치
$ htpasswd -cm /etc/nginx/.htpasswd "Basic Auth 아이디"
$ New password: "Basic Auth 비밀번호"
$ Re-type new password: "Basic Auth 비밀번호"
ex) $ htpasswd -cm /etc/nginx/.htpasswd msung99
$ New password: 1234
$ Re-type new password: 1234
Basic Auth 계정의 아이디,비밀번호가 담긴 .htpasswd 파일은 아이디:비밀번호 와 같은 구조로 만들어야합니다. 이때 비밀번호는 MD5 로 암호화 되어있어야 해서, htpasswd 를 활용해서 암호화를 진행해준 것입니다.
계정 생성후 ls-al 로 출력해보면 아래와 같이 .htpasswd 파일이 생성된 모습을 볼 수 있습니다.
또한 .htpasswd 의 내용을 cat 으로 출력해보면 아래처럼 계정정보가 암호화되어 저장된 것을 볼 수 있습니다.
다음으로는 이번 포스팅에서 가장 중요한 내용인 upstream 서버 접근 제한입니다. 앞서 설명드렸듯이, 아래와 같은 2가지 조건을 만족시키도록 설정해주셔야합니다.
"/admin" URL 에는 일반 사용자가 접근 불가능합니다. 오직 Basic Auth 로 인가에 성공한 유저만 해당 URL 로 부터 원하는 리소스를 얻어낼 수 있습니다.
다른 URL 에는 일반 사용자가 요청을 가능하게 해야합니다.
upstream backend{
server 111.11.111.111:8080;
}
server{
listen 80;
location / {
proxy_pass http://backend;
}
location /admin {
proxy_pass http://backend;
auth_basic "접근제한!";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
위와 같이 server{ } 블럭의 location 블럭에서 HTTP 인증을 설정하면 돕니다. 이렇게 설정하면 특정 페이지인 /admin 페이지에 대해서만 HTTP 인증을 요구합니다.
우선 아래와 같이 /notAdmin 페이지에 리소스를 요청해봅시다. 그러면 인가 과정없이 원하는 결과를 손쉽게 얻어낼 수 있습니다.
반대로 Basic Auth 를 적용한 /admin 페이지를 접근하려면 아래처럼 htpasswd 계정을 요구하는 모습을 확인할 수 있습니다.
그리고 계정정보를 정상적으로 입력하면 관리자페이지에서 원하는 리소스를 제공받는 모습도 확인할 수 있습니다!
추가적으로 알면 좋을 기타적인 문법에 대해서도 알아보겠습니다. 위와 같은 특정 페이지 접근시 BasicAuth 인증을 요구하는 방법 외에도 방법은 다양하니까요!
아래처럼 http 블럭에 설정할 경우 모든 가상호스트의 접근에 basicAuth 인증 요구를 할 수 있습니다.
http {
auth_basic "message"; # 로그인 팝업창 메시지
auth_basic_user_file /etc/nginx/.htpasswd; # 로그인시 필요한 사용자 계정과 비밀번호 정보 파일
}
google.com 과 같은 도메인에 대해서도 접근제한을 시킬 수 있습니다. 아래와 같이 server_name 에 도메인 이름을 넣어주면 google.com 의 하위 페이지에 있는 모든 페이지는 BasicAuth 인증을 요구합니다.
server {
listen 80;
server_name google.com;
auth_basic "접근을 제한합니다.";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
...
}
}
이렇게 Nginx 를 활용할때 BasicAuth 로 보안성을 더 강화하는 방법에 대해 알아보았습니다. 다음 포스팅에서는 https, HTTP/2 프로토콜 적용등을 다루어서 더 보안을 강화하는 방법에 대해 알아보겠습니다!
Nginx Basic Authentication 암호 설정방법
nginx와 http basic auth로 사용자 인증하기