Nginx에서 Digest 인증 사용

Basic 인증은 ID/PASS를 Base64 인코딩하고 있기 때문에 간단하게 디코드 가능하고 보안면에서 바람직하지 않다.
Digest 인증은 MD5로 인코딩되므로 도청/변조의 위험은 Basic 인증보다 낮습니다.
그러나 nginx는 표준으로 Digest 인증을 지원하지 않습니다. 소스로부터 외부 모듈을 추가하여 컴파일함으로써 대응시킬 수 있다.

환경



Windows10Pro의 Hyper-V에 아래의 가상 머신을 작성해 검증
  • CentOS 8.0.1905
  • Nginx 1.17.7

  • Firewalld와 SELinux는 모두 활성화되어 있습니다.

    흐름



    모든 명령은 루트 사용자로 실행됩니다.

    1. 필요한 패키지 설치


    # dnf install gcc pcre pcre-devel make perl httpd-tools
    
    gcc pcre pcre-devel make perl 컴파일 및 설치에 필요httpd-tools 는 Digest 인증에 사용하는 패스워드 파일을 생성한다 htdigest

    2. 소스 다운로드


    # wget "http://nginx.org/download/nginx-1.17.7.tar.gz" -O /tmp/nginx-1.17.7.tar.gz
    # wget "https://github.com/atomx/nginx-http-auth-digest/archive/master.zip" -O /tmp/nginx-http-auth-digest.zip
    # wget "http://zlib.net/zlib-1.2.11.tar.gz" -O /tmp/zlib-1.2.11.tar.gz
    # wget "https://www.openssl.org/source/openssl-1.1.1d.tar.gz" -O /tmp/openssl-1.1.1d.tar.gz
    

    위에서
  • Nginx 본체
  • Digest 인증 모듈 htps : // 기주 b. 코 m / 가위 z이다 t 코 / 닌긴 x-h tp
  • zlib (gzip 압축에 사용)
  • OpenSSL

  • 우선 /usr/local/src/ 에 전개한다
    # tar zxvf /tmp/nginx-1.17.7.tar.gz -C /usr/local/src/
    # unzip /tmp/nginx-http-auth-digest.zip -d /usr/local/src/
    # tar zxvf /tmp/zlib-1.2.11.tar.gz -C /usr/local/src/
    # tar zxvf /tmp/openssl-1.1.1d.tar.gz -C /usr/local/src/
    

    3. 컴파일 및 설치


    # cd /usr/local/src/nginx-1.17.7
    # ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-openssl=/usr/local/src/openssl-1.1.1d --with-zlib=/usr/local/src/zlib-1.2.11 --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --with-cc-opt='-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --add-module=../nginx-http-auth-digest-master/
    # make && make install
    

    4. 부족한 물건을 여러가지 작성



    자동으로 작성되지 않는 물건을 만들어 간다

    4-1. 사용자 생성



    nginx 실행을 위한 사용자 만들기
    # groupadd nginx
    # useradd -g nginx nginx
    # usermod -s /bin/false nginx
    

    4-2. 캐시 디렉토리 작성


    # mkdir -p /var/cache/nginx/client_temp
    

    4-3. 시작 스크립트 작성



    systemd 의 스크립트도 스스로 작성한다.
    # cat <<EOF > /usr/lib/systemd/system/nginx.service
    [Unit]
    Description=The nginx HTTP and reverse proxy server
    After=network.target remote-fs.target nss-lookup.target
    
    [Service]
    Type=forking
    PIDFile=/run/nginx.pid
    # Nginx will fail to start if /run/nginx.pid already exists but has the wrong
    # SELinux context. This might happen when running `nginx -t` from the cmdline.
    # https://bugzilla.redhat.com/show_bug.cgi?id=1268621
    ExecStartPre=/usr/bin/rm -f /run/nginx.pid
    ExecStartPre=/usr/sbin/nginx -t
    ExecStart=/usr/sbin/nginx
    ExecReload=/bin/kill -s HUP $MAINPID
    KillSignal=SIGQUIT
    TimeoutStopSec=5
    KillMode=mixed
    PrivateTmp=true
    
    [Install]
    WantedBy=multi-user.target
    EOF
    

    4-4. 로그 로테이트 설정



    logrotate.d의 구성 파일 만들기
    # cat <<EOF > /etc/logrotate.d/nginx
    /var/log/nginx/*log {
        create 0664 nginx root
        daily
        rotate 10
        missingok
        notifempty
        compress
        sharedscripts
        postrotate
            /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
        endscript
    }
    EOF
    

    4-5.firewalld



    외부에서 액세스 할 수 없으므로 firewalld에 권한 설정
    HTTP, HTTPS를 모두 열어 둡니다.
    # firewall-cmd --add-service=http --zone=public
    # firewall-cmd --add-service=https --zone=public
    

    4-6. 패스워드 파일 작성


    # htdigest -c /etc/nginx/.htdigest_test "test" user
    Adding password for user in realm test.
    New password:
    Re-type new password:
    
    -c 선택적으로 비밀번호 파일 생성"test" 의 부분에 realm명user 의 부분은 인증시의 사용자명

    암호는 대화식으로 입력하라는 메시지가 표시됩니다.

    5. Nginx에 Digest 인증 설정


    # vi /etc/nginx/nginx.conf
    

    평가판으로 / 로 설정
            location / {
                root   html;
                index  index.html index.htm;
                auth_digest "test";
                auth_digest_user_file /etc/nginx/.htdigest_test;
            }
    
    auth_digest 에 패스워드 파일 작성시에 지정한 realm명을 넣는다.auth_digest_user_file 에 패스워드 파일명 지정

    6. Nginx 시작


    # systemctl enable nginx.service
    # systemctl start nginx.service
    

    7. 동작 확인



    브라우저에서 액세스하면 다음과 같은 대화 상자가 표시됩니다.
    설정한 사용자 이름과 비밀번호 입력


    인증이 통과되면 페이지가 표시됩니다.



    덧붙여서 curl 의 경우는 -u "user:password" 이외에 --digest 옵션을 붙인다
    C:\>curl --digest -u "user:password" -I http://192.168.0.31/
    HTTP/1.1 401 Unauthorized
    Server: nginx/1.17.7
    Date: Mon, 24 Feb 2020 04:39:39 GMT
    Content-Type: text/html
    Content-Length: 179
    Connection: keep-alive
    WWW-Authenticate: Digest algorithm="MD5", qop="auth", realm="test", nonce="39e753bf5e53538b"
    
    HTTP/1.1 200 OK
    Server: nginx/1.17.7
    Date: Mon, 24 Feb 2020 04:39:40 GMT
    Content-Type: text/html
    Content-Length: 612
    Last-Modified: Mon, 24 Feb 2020 04:21:48 GMT
    Connection: keep-alive
    Authentication-Info: qop="auth", rspauth="0565bae4b6bfbda5513657687d318700", cnonce="66a3a2f56a85034803fdd085b686f8c3", nc=00000001
    ETag: "5e534f5c-264"
    Accept-Ranges: bytes
    
    

    우선 움직이고 있을 것 같다.

    좋은 웹페이지 즐겨찾기