๐Ÿ” ์ „์ฒด HTTPS ๊ฐœ๋ฐœ ํ™˜๊ฒฝ

18456 ๋‹จ์–ด developmentsecurityhttpsmonorepo
์—ฌ๋ณด์‹œ์˜ค, ์ด ์‹œ๋ฆฌ์ฆˆ์—์„œ๋Š” HTTPS์—์„œ ์–ด๋–ป๊ฒŒ ์™„์ „ํ•œ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ๊ฐ€์ง€๊ณ  ๋‹น์‹ ์˜ ๋กœ์ปฌ ๊ฐœ๋ฐœ ์˜์—ญ์— ํšจ๊ณผ์ ์ธ ์ธ์ฆ์„œ๋ฅผ ์ œ๊ณตํ•˜๋Š”์ง€ ์„ค๋ช…ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์™œ ๋‚˜๋Š” ๊ฐœ๋ฐœ ์ค‘์— HTTPS๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?


์‚ฌ์‹ค ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ HTTPS๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ณด์•ˆ ์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์ฆ (keyclock, Auth0 ๋“ฑ ์ธ์ฆ ์„œ๋น„์Šค ์‚ฌ์šฉ)โ†’ more here ๋˜๋Š” here ์ฐธ์กฐ
  • ์˜ ๊ฐœ๋ฐœ๊ณผ ์ƒ์‚ฐ ํ™˜๊ฒฝ์€ ๊ฐ€๋Šฅํ•œ ํ•œ ๋น„์Šทํ•˜๋‹ค.10th factor์˜ 12-factor app์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.
  • ์ผ๋ถ€ ์™ธ๋ถ€ ์„œ๋น„์Šค(SaaS)์—๋Š” HTTPS(์ฆ‰ Webhook์šฉ)๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ์ธ์ฆ์„œ ์„ค์ •


    ๋ฃจํŠธ CA๋กœ ์„œ๋ช…๋œ ์ธ์ฆ์„œ๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ธ์ฆ์„œ๋Š” ์‹œ์Šคํ…œ๊ณผ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹๋ณ„๋ฉ๋‹ˆ๋‹ค.
    ์šฐ์„ , ์šฐ๋ฆฌ๋Š” ๋กœ์ปฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์œ„ํ•ด ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์„ ์„ ํƒํ•œ ๋‹ค์Œ์—awesome ๋„๊ตฌ mkcert์„ ์‚ฌ์šฉํ•˜์—ฌ ์œ ํšจํ•œ ์ธ์ฆ์„œ๋ฅผ ์ƒ์„ฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

    ๊ฐœ๋ฐœ์ž ํ˜ธ์ŠคํŠธ ์ด๋ฆ„ ์„ ํƒ


    ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์œ„ํ•œ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์„ ์„ ํƒํ•˜์‹ญ์‹œ์˜ค.
    โš ๏ธ ์ถฉ๋Œํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ์กด ๋„๋ฉ”์ธ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค!
    ์ผ๋ฐ˜์ ์ธ localhost ๋˜๋Š” ๋‹ค๋ฅธ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.๋‚˜๋Š” dev.local์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ข‹์•„ํ•œ๋‹ค. ๋‚˜๋Š” ๋‹ค์Œ ๋‹จ๊ณ„์—์„œ ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค.
    ๋กœ์ปฌ dns์— ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Linux์™€ Mac์—์„œ /etc/hosts์ž…๋‹ˆ๋‹ค.๋”ฐ๋ผ์„œ 127.0.0.1 dev.local์— /etc/hosts์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
    ๐Ÿ’ก ์•Œ๋ฆผ: this gist์˜ ์ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์„ ์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•˜๊ณ  ์‚ญ์ œํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค๐Ÿ‘
    ๐Ÿ—’๏ธ ์ฐธ๊ณ : api.dev.local, app.dev.local๊ณผ ๊ฐ™์€ ํ•˜์œ„ ๋„๋ฉ”์ธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ...๋„ˆ๋„ /etc/hosts์— ๊ทธ๊ฒƒ๋“ค์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.*.dev.local์— ์ง์ ‘ ์–ด๋Œ‘ํ„ฐ (์˜ˆ๋ฅผ ๋“ค์–ด /etc/hosts) ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์ง€๋งŒ dnsmasq ๋“ฑ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ์ ์„ ์‹คํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    Mkcert ํšŒ์‚ฌ


    ์šฐ๋ฆฌ๋Š” mkcert์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฃจํŠธCA๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์ธ์ฆ์„œ๋ฅผ ์ƒ์„ฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

    ์„ค์น˜


    ๐Ÿ MacOS ํšŒ์‚ฌ


    acOS์—์„œ Homebrew ์‚ฌ์šฉ
    brew install mkcert
    brew install nss # if you use Firefox
    

    ๐Ÿง Linux


    Linux์— certutil์„ ๋จผ์ € ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.
    sudo apt install libnss3-tools
    curl -Lo /tmp/mkcert https://github.com/FiloSottile/mkcert/releases/download/v1.4.1/mkcert-v1.4.1-linux-amd64
    chmod +x /tmp/mkcert
    sudo mv /tmp/mkcert /usr/local/bin/mkcert
    
    ๋” ๋งŽ์€ ์„ค์น˜ ๋ฐฉ๋ฒ• here ์ฐธ์กฐ๐Ÿ‘Œ

    ํ™œ์šฉ๋‹จ์–ด์ฐธ์กฐ


    ๋จผ์ € ๋กœ์ปฌ CA๋ฅผ ์‹œ์Šคํ…œ ๋ฐ ๋ธŒ๋ผ์šฐ์ €์— ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    $ mkcert -install
    Created a new local CA at "/home/***/.local/share/mkcert" ๐Ÿ’ฅ
    The local CA is now installed in the system trust store! โšก๏ธ
    The local CA is now installed in the Firefox trust store (requires browser restart)! ๐ŸฆŠ
    
    ๋‹ค์Œ์œผ๋กœ, ์šฐ๋ฆฌ๋Š” mkcert๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์ฆ์„œ๋ฅผ ์ƒ์„ฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.๋‚ด ์˜ˆ์‹œ์—ญ dev.local ๊ณผ ์–ด๋Œ‘ํ„ฐ *.dev.local์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    $ mkcert -cert-file certs/local-cert.pem -key-file certs/local-key.pem dev.local *.dev.local
    Using the local CA at "/home/***/.local/share/mkcert" โœจ
    
    Created a new certificate valid for the following names ๐Ÿ“œ
     - "dev.local"
     - "*.dev.local"
    
    Reminder: X.509 wildcards only go one level deep, so this won't match a.b.dev.local โ„น๏ธ
    
    The certificate is at "certs/local-cert.pem" and the key at "certs/local-key.pem" โœ…
    
    ์šฐ๋ฆฌ๋Š” ํ˜„์žฌ certs/local-cert.pem๊ณผ certs/local-key.pem์— ์žˆ๋Š” ์ธ์ฆ์„œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    ๋‹ค์Œ์€ ์ด ์ธ์ฆ์„œ๋ฅผ ๋‹ค๋ฅธ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์— ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    ์ด์ : ๊ฐœ๋ฐœ ์ฐฝ๊ณ ์˜ Makefile์— ๋ชจ๋“  ๋‚ด์šฉ์„ ํฌ์žฅํ•ฉ๋‹ˆ๋‹ค


    ์ด๊ฒƒ์€ ๋‚ด๊ฐ€ ์–ด๋–ป๊ฒŒ ๋‚˜์˜ ๊ฐœ๋ฐœ ์ฐฝ๊ณ ๋ฅผ ์กฐ์งํ–ˆ๋Š”์ง€, ๊ทธ๊ฒƒ์€ ๋งค์šฐ ์ž์‹ ์˜ ์˜๊ฒฌ์„ ๊ณ ์ง‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๊ทธ ์ค‘์—์„œ ๋‹น์‹ ์ด ํ•„์š”๋กœ ํ•˜๋Š” ๊ฒƒ๋งŒ ์–ป๋Š”๋‹ค๐Ÿ˜‰!

    ๐Ÿ“ ํด๋” ๊ตฌ์กฐ


    project_root
    โ”œโ”€โ”€ dev-stack
    โ”‚   โ”œโ”€โ”€ certs
    โ”‚   โ”‚   โ”œโ”€โ”€ .gitignore
    โ”‚   โ”‚   โ”œโ”€โ”€ local-cert.pem
    โ”‚   โ”‚   โ””โ”€โ”€ local-key.pem
    โ”‚   โ”œโ”€โ”€ scripts
    โ”‚   โ”‚   โ”œโ”€โ”€ get-ip.sh
    โ”‚   โ”‚   โ””โ”€โ”€ manage-hosts.sh
    โ”‚   โ”œโ”€โ”€ .env.local
    โ”‚   โ”œโ”€โ”€ .gitignore
    โ”‚   โ”œโ”€โ”€ docker-compose.yml
    โ”‚   โ”œโ”€โ”€ Makefile
    โ”‚   โ””โ”€โ”€ README.md
    

    ํŒŒ์ผ ์ƒ์„ฑ


    ifndef DEV_STACK_DIR
    DEV_STACK_DIR = $(CURDIR)
    endif
    SCRIPTS_DIR=${DEV_STACK_DIR}/scripts
    
    ifndef HOSTNAME
    HOSTNAME = dev.local
    endif
    ifndef SUBDOMAINS
    SUBDOMAINS = docs \
                 traefik \
                 mail \
                 media \
                 portainer \
                 graphql \
                 auth
    endif
    ifndef DATABASE
    DATABASE = postgres
    endif
    ifndef INFRA
    INFRA = traefik \
            maildev \
            minio \
            mkdocs \
            portainer \
            ${DATABASE} \
            graphql-engine \
            keycloak \
            auth-connector
    endif
    
    export HOST_IP := $(shell ${SCRIPTS_DIR}/get-ip.sh)
    
    # HELP
    .PHONY: help
    
    help: ## List of the command available, make {command}
        @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
    
    .DEFAULT_GOAL := help
    
    start:  ## Start the docker stack
        docker-compose up -d ${INFRA}
    
    up: ## Start the docker stack
        docker-compose up ${INFRA}
    
    stop: ## Stop the docker stack
        docker-compose stop
    
    restart: ## Restart the docker stack
        docker-compose restart
    
    down: ## Down the docker stack and remove all containers and networks
        docker-compose down
    
    build: ## Build or rebuild all docker container
        docker-compose build
    
    pull: ## Pull latest image
        docker-compose pull
    
    add-hosts: ## Add Hosts entries for Dev stack
        ${SCRIPTS_DIR}/manage-hosts.sh addhost ${HOSTNAME}
        $(foreach subdomain, $(SUBDOMAINS), ${SCRIPTS_DIR}/manage-hosts.sh addhost $(subdomain).$(HOSTNAME);)
    
    remove-hosts: ## Remove Hosts entries for Dev stack
        ${SCRIPTS_DIR}/manage-hosts.sh removehost ${HOSTNAME}
        $(foreach subdomain, $(SUBDOMAINS), ${SCRIPTS_DIR}/manage-hosts.sh removehost $(subdomain).$(HOSTNAME);)
    
    certs-generate: ## Generate certs for all our domains
        mkcert -install
        mkcert -cert-file certs/local-cert.pem -key-file certs/local-key.pem $(HOSTNAME) *.$(HOSTNAME)
    
    certs-uninstall: ## Uninstall the local CA (but do not delete it)
        mkcert -uninstall
    
    

    ์Šคํฌ๋ฆฝํŠธ


    ip๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.์ƒํ•ด


    #!/bin/bash
    
    # Get host IP address
    
    if [ "$(uname)" = "Darwin" ];then
        ifconfig en0 | grep "inet "| cut -d ' ' -f 2
    else
        ip route get 1.2.3.4 | awk '{print $7}'
    fi
    

    ํ˜ธ์ŠคํŠธ ๊ด€๋ฆฌ์ƒํ•ด


    #!/bin/bash
    
    # copy from https://gist.github.com/irazasyed/a7b0a079e7727a4315b9
    
    # PATH TO YOUR HOSTS FILE
    ETC_HOSTS=/etc/hosts
    
    # DEFAULT IP FOR HOSTNAME
    IP="127.0.0.1"
    
    # Hostname to add/remove.
    HOSTNAME=$2
    
    removehost() {
        echo "removing host";
        if [ -n "$(grep $HOSTNAME /etc/hosts)" ]
        then
            echo "$HOSTNAME Found in your $ETC_HOSTS, Removing now...";
            sudo sed -i".bak" "/$HOSTNAME/d" $ETC_HOSTS
        else
            echo "$HOSTNAME was not found in your $ETC_HOSTS";
        fi
    }
    
    addhost() {
        echo "adding host";
        HOSTS_LINE="$IP\t$HOSTNAME"
        if [ -n "$(grep $HOSTNAME /etc/hosts)" ]
            then
                echo "$HOSTNAME already exists : $(grep $HOSTNAME $ETC_HOSTS)"
            else
                echo "Adding $HOSTNAME to your $ETC_HOSTS";
                sudo -- sh -c -e "echo '$HOSTS_LINE' >> /etc/hosts";
    
                if [ -n "$(grep $HOSTNAME /etc/hosts)" ]
                    then
                        echo "$HOSTNAME was added succesfully \n $(grep $HOSTNAME /etc/hosts)";
                    else
                        echo "Failed to Add $HOSTNAME, Try again!";
                fi
        fi
    }
    
    $@
    

    ์ธ์ฆ์„œ ์‚ฌ์šฉ


    โ†’ ๋‹ค์Œ ๊ฒŒ์‹œ๋ฌผ์—์„œ๋Š” ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ์ธ์ฆ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
  • Nx ์ž‘์—…๊ณต๊ฐ„์— ์žˆ๋Š” Angular ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ๋กœ์ปฌ HTTPS(๋˜๋Š” Angular cli)
  • Nx ์ž‘์—…๊ณต๊ฐ„์—์„œ React ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ๋กœ์ปฌ HTTPS
  • Nx ์ž‘์—…๊ณต๊ฐ„์—์„œ Express app(api)์˜ ๋กœ์ปฌ HTTPS
  • Nx ์ž‘์—…๊ณต๊ฐ„์—์„œ NestJS ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ(api)์˜
  • ๋กœ์ปฌ HTTPS
  • Traefik Docker ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•œ
  • ๋กœ์ปฌ HTTPS

    Github ์ €์žฅ์†Œ


    ์•ผ๊ฐ„ / ์™„์ „ํ•œ https ๊ฐœ๋ฐœ ํ™˜๊ฒฝ


    HTTPS์˜ ์™„์ „ํ•œ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์€ ๋กœ์ปฌ ๊ฐœ๋ฐœ ์˜์—ญ์— ์ ์šฉ๋˜๋Š” ์œ ํšจํ•œ ์ธ์ฆ์„œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ mkcert, Nxworkspace,angular,reactjs,nestjs,express,docker,traefik๋ฅผ ํฌํ•จํ•œ๋‹ค.


    ๋งˆ์ด์–ด๊ทธ


    ์ด ํ”„๋กœ์ ํŠธ๋Š” Nx์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

    ๐Ÿ”Ž Nx๋Š” Monorepos๋ฅผ ์œ„ํ•œ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๊ฐœ๋ฐœ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

    ์ž‘์—…๊ณต๊ฐ„์— ๊ธฐ๋Šฅ ์ถ”๊ฐ€


    Nx๋Š” ๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ๊ณผ ๋„๊ตฌ๋ฅผ ๊ฐœ๋ฐœํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•œ ๋งŽ์€ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
    ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ƒ์„ฑ, ํ”„๋กœ์ ํŠธ ํ…Œ์ŠคํŠธ ๋ฐ ๊ตฌ์ถ•์— ์‚ฌ์šฉ๋˜๋Š” devtools๋ฅผ ํฌํ•จํ•œ๋‹ค.
    ๋‹ค์Œ์€ ํ•ต์‹ฌ ํ”Œ๋Ÿฌ๊ทธ์ธ์ž…๋‹ˆ๋‹ค.

  • React
  • npm install --save-dev @nrwl/react
  • ์›น(ํ”„๋ ˆ์ž„ ํ”„๋ŸฐํŠธ์—”๋“œ ์—†์Œ)
  • npm install --save-dev @nrwl/web

  • Angular
  • npm install --save-dev @nrwl/angular

  • Nest
  • npm install --save-dev @nrwl/nest

  • Express
  • npm install --save-dev @nrwl/express

  • Node
  • npm install --save-dev @nrwl/node
  • community plugins๋„ ๋งŽ์ด ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒ์„ฑ

    nx g @nrwl/react:app my-app์„ ์‹คํ–‰ํ•˜์—ฌ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    You can use any of the plugins above to generate applications as well.


    Nx๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ™์€ ์ž‘์—…๊ณต๊ฐ„์—์„œ ์—ฌ๋Ÿฌ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ๊ณผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ƒ์„ฑ

    nx ์‹คํ–‰...
    View on GitHub

    ์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ