개발 중인 HTTPS:유틸리티 가이드

Firefox Telemetry에 따르면 이 숫자는 76% of web pages are loaded with HTTPS이며 아직도 증가하고 있다.
소프트웨어 엔지니어는 조만간 HTTPS를 처리해야 하며 빠르면 빠를수록 좋다.개발 환경에서 HTTPS를 사용하여 JavaScript 응용 프로그램에 서비스를 제공하는 이유와 방법을 계속 읽어 보십시오.

개발 환경에서 HTTPS를 사용하는 이유는 무엇입니까?


우선, 당신은 HTTPS를 통해 제작 중인 사이트에 서비스를 제공해야 합니까?네가 정말 자신이 무엇을 하고 있는지 알지 않으면, the default answer is yes.그것은 당신의 사이트를 여러 측면에서 개선할 수 있습니다: 안전성, 성능, 검색엔진 최적화 등등.
HTTPS를 설정하는 방법은 일반적으로 처음 발표할 때 토론되고 많은 다른 문제를 가져온다.데이터는 끝에서 끝까지 암호화해야 합니까? 아니면 역방향 프록시 이전에 암호화하면 충분합니까?인증서는 어떻게 생성합니까?그것은 어디에 보관해야 합니까?HSTS 어때요?
개발진은 가능한 한 빨리 이 문제들에 대답할 수 있어야 한다.만약 네가 이렇게 하지 않는다면, 너는 아마 end up like Stack Overflow wasting a lot of time일 것이다.
또한 가능한 한 생산 환경에 가까운 개발 환경을 가지면 버그가 생산 환경에 도달하는 위험을 줄일 수 있고 이런 버그를 디버깅하는 시간을 줄일 수 있다.끝까지 테스트하는 것도 마찬가지다.
그 밖에 HTTPS 서비스의 페이지에서만 사용할 수 있는 기능도 있다. 예를 들어 Service Workers이다.
근데 HTTPS가 느려요!많은 사람들이 암호화는 복잡하기 때문에 어느 정도는 느려야만 효과가 있다고 생각한다.그러나 현대의 하드웨어와 협의가 생겼다. this is not true anymore.

어떻게 개발 환경을 위해 효과적인 인증서를 생성합니까?


운영 시스템의 경우 TLS 인증서를 쉽게 얻을 수 있습니다. Let's Encrypt에서 하나를 생성하거나 비용을 지불하는 공급자로부터 하나를 구매합니다.
개발 환경에 있어서는 더 까다로운 것 같지만 그렇게 어렵지 않다.

Mkcert: 비뇌 CLI


Filippo Valsorda은 최근에 mkcert 을 발표했는데 이것은 로컬에서 신뢰를 받는 개발 인증서를 생성하는 간단한 cli이다.명령을 한 줄만 실행하면 됩니다.
mkcert -install
mkcert example.com
명령을 실행하는 곳, 즉 ./example.com-key.pem에서 완전히 지원되는 인증서를 제공합니다.

OpenSSL을 사용하여 수동으로 설치

mkcert은 동료와 동일한 인증서를 공유하거나 현지 환경 이외의 다른 시스템을 통해 인증서를 공유해야 하는 경우를 제외하고는 모든 요구 사항을 충족해야 합니다.이 경우 openssl을 통해 인증서를 생성할 수 있습니다.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt
인증서(server.crt)와 키(server.key)는 유효하지만 자동으로 서명됩니다.그 어떤 Certificate Authority명도 이 증서를 모른다.그러나 모든 브라우저는 암호화 연결을 받기 위해 유명한 인증서 발급 기관에 인증서를 요구합니다.자체 발급된 인증서는 인증할 수 없으므로 다음과 같은 짜증나는 경고가 표시됩니다.

이러한 불편을 받아들이고 경고가 발생할 때마다 수동으로 무시할 수 있습니다.그러나 이것은 매우 번거롭고 CI 환경에서의 e2e 테스트를 막을 수 있다.더 좋은 해결 방안은 자신의 로컬 인증서 발급 기구를 만들고 이 사용자 정의 발급 기구를 브라우저에 추가하고 인증서를 생성하는 것이다.
이것이 바로 mkcert이 막후에서 당신을 위해 한 일입니다. 하지만 당신이 직접 하고 싶다면 제가 요점을 하나 썼습니다. 당신에게 도움이 될 것입니다. Kmaschta/205a67e42421e779edd3530a0efe5945.

리버스 프록시 또는 타사 애플리케이션의 HTTPS


일반적으로 최종 사용자는 응용 서버에 직접 접근하지 않는다.반면에 사용자 요청은 부하 균형기나 역방향 에이전트에 의해 처리되고 후자는 백엔드에서 요청을 나누어 주고 캐시를 저장하며 불필요한 요청을 방지한다.이 에이전트들도 복호화 요청과 암호화 응답의 역할을 하는데, 이것은 적지 않다.
개발 환경에서 우리도 역방향 에이전트를 사용할 수 있다!

Traefik 및 Docker Compose를 통한 암호화


Traefik은 역방향 대리로서 개발자에게 많은 장점을 가진다.이 밖에도 GUI와 함께 구성이 간단합니다.이 밖에 도커의 공식 사진 available on docker hub도 있다.
따라서 정적 파일만 제공하는 가설 응용 프로그램의 docker-compose.yml에서 사용하도록 하겠습니다.
version: '3.4'

services:
    reverse-proxy:
        image: traefik # The official Traefik docker image
        command: --docker --api # Enables the web UI and tells Traefik to listen to docker
        ports:
            - '3000:443'  # Proxy entrypoint
            - '8000:8080' # Dashboard
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events
            - ./certs/server.crt:/sslcerts/server.crt
            - ./certs/server.key:/sslcerts/server.key
            - ./traefik.toml:/traefik.toml # Traefik configuration file (see below)
        labels:
            - 'traefik.enable=false'
        depends_on:
            - static-files
    static-files:
        image: halverneus/static-file-server
        volumes:
            - ./static:/web
        labels:
            - 'traefik.enable=true'
            - 'traefik.frontend.rule=Host:localhost'
            - 'traefik.port=8080'
            - 'traefik.protocol=http'
        ports:
            - 8080:8080
이 예에서는 정적 파일 서버 스니퍼 포트가 8080이고 HTTP 방식으로 파일을 제공합니다.이 구성은 Traefik에서 https://localhost의 HTTPS 요청을 처리하고 각 요청을 http://localhost:8080으로 에이전트하여 정적 파일에 서비스를 제공하도록 합니다.
Traefik 엔트리 포인트를 구성하려면 traefik.toml을 추가해야 합니다.
debug = false

logLevel = "ERROR"
defaultEntryPoints = ["https","http"]

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
  [entryPoints.https.tls]
      [[entryPoints.https.tls.certificates]]
      certFile = "/sslcerts/server.crt"
      keyFile = "/sslcerts/server.key"

여기서 우리는 두 개의 입구점이 있는데 그것이 바로 httphttps이다. 각각 감청 포트 80과 443이다.첫 번째는 HTTPS로, 두 번째는 지정된 TLS 인증서를 사용하여 요청을 암호화하도록 구성합니다.

Nginx를 통해 Docker Compose에서 암호화


분명히 우리는 유행하는 Nginx 리버스 에이전트에 대해 똑같은 조작을 할 수 있다.Nginx 자체도 정적 파일에 직접 서비스를 제공할 수 있기 때문에 설정이 더욱 간단합니다.마찬가지로 첫 번째 단계는 docker-compose.yml입니다.
version: '3'

services:
    web:
        image: nginx:alpine
        volumes:
            - ./static:/var/www
            - ./default.conf:/etc/nginx/conf.d/default.conf
            - ../../certs/server.crt:/etc/nginx/conf.d/server.crt
            - ../../certs/server.key:/etc/nginx/conf.d/server.key
        ports:
            - "3000:443"
default.conf의 nginx 구성:
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;

    server_name ~.;

    ssl_certificate /etc/nginx/conf.d/server.crt;
    ssl_certificate_key /etc/nginx/conf.d/server.key;

    location / {
        root /var/www;
    }

    ## If the static server was another docker service,
    ## It is possible to forward requests to its port:
    # location / {
    #     proxy_set_header Host $host;
    #     proxy_set_header X-Real-IP $remote_addr;
    #     proxy_pass http://web:3000/;
    # }
}

응용 프로그램에서 HTTPS 서비스를 직접 제공


때때로 보안 수요는 처음부터 끝까지 암호화되어야 하거나 개발 환경에서 역방향 에이전트를 사용하는 것은 지나친 것 같다.대부분의 경우 일상적인 개발 환경에서 HTTPS에 직접 서비스를 제공할 수 있다.
일반적인 스택을 예로 들겠습니다. express의 REST API를 사용하는 React 응용 프로그램입니다.

Create React 애플리케이션 또는 웹 패키지를 사용하여 서버 개발


당신의 React 응용 프로그램의 평균 안내량은 create-react-app입니다.이 훌륭한 도구는 HTTPS를 직접 처리할 수 있는 내장 기능이 많다.따라서 애플리케이션을 시작할 때 HTTPS=true 환경 변수를 하나만 지정하면 됩니다.
HTTPS=true npm run start
# or
HTTPS=true yarn start
이 명령은 자동으로 생성된 인증서를 통해 https://localhost:3000이 아니라 http://localhost:3000에서 응용 프로그램에 서비스를 제공합니다.그러나 이것은 자체 서명 증서이기 때문에 개발자의 체험은 매우 나쁘다.
자체 HTTPS 인증서(브라우저에서 신뢰하는 권한 서명 사용)를 사용하려는 경우 create-react-app에서는 응용 프로그램을 팝업하지 않고 구성할 수 없습니다(npm run eject).
편집:dev.to reader, 기본 HTTPS 인증서를 동적으로 바꾸기:
  "scripts": {
    "prestart": "(cat ../../certs/server.crt ../../certs/server.key > ./node_modules/webpack-dev-server/ssl/server.pem) || :",
    "start": "react-scripts start",
  },
다행히도, 만약 CRA가 팝업되었거나, 프로젝트가 웹 패키지와 묶여 있다면, HTTPS를 제공할 때, webpack-dev-servercreate-react-app과 같이 간단합니다.패키지 구성에서 두 줄 코드를 사용하여 사용자 정의 HTTPS 인증서를 구성할 수 있습니다.
const fs = require('fs');
const path = require('path');

module.exports = {
    mode: 'production',
    // ...
    devServer: {
        https: {
            key: fs.readFileSync(path.resolve(__dirname, '../../certs/server.key')),
            cert: fs.readFileSync(path.resolve(__dirname, '../../certs/server.crt')),
        },
        port: 3000,
    },
};
다음에 webpack-dev-server을 실행하면 https://localhost:3000에 대한 HTTPS 요청이 처리됩니다.

Express 및 SPDY를 사용하여 HTTP/2 암호화


현재 우리는 HTTPS를 통해 서비스를 제공하는 응용 프로그램의 전단 부분이 생겼고, 우리도 반드시 후단에 대해 같은 조작을 해야 한다.
이를 위해 expressspdy을 사용합니다.어쩐지 이 두 라이브러리의 이름이 모두 속도에 관한 것이었더라니. 왜냐하면 그것들의 설정 속도가 매우 빠르기 때문이야!
const fs = require('fs');
const path = require('path');
const express = require('express');
const spdy = require('spdy');

const CERTS_ROOT = '../../certs/';

const app = express();

app.use(express.static('static'));

const config = {
    cert: fs.readFileSync(path.resolve(CERTS_ROOT, 'server.crt')),
    key: fs.readFileSync(path.resolve(CERTS_ROOT, 'server.key')),
};

spdy.createServer(config, app).listen(3000, (err) => {
    if (err) {
        console.error('An error occured', error);
        return;
    }

    console.log('Server listening on https://localhost:3000.')
});
HTTP/2는 HTTPS, it's possible to serve encrypted content with HTTP first of the name을 제공할 필요가 없지만 HTTPS를 제공할 때 HTTP 프로토콜을 업그레이드할 수 있습니다.HTTP/2의 장점을 더 알고 싶으면 this quick FAQ을 읽으세요.

결론


현대 도구는 최종 사용자를 위해 더욱 안전하고 빠른 응용 프로그램을 구축할 수 있으며, 지금은 안내하기 쉽다.나는 설치 비용이 여전히 낮기 때문에 프로젝트부터 이 라이브러리와 기술을 사용하도록 설득하기를 바란다.
내가 이 블로그에서 사용한 모든 예는 아래의 리포에 수집되었다: marmelab/https-on-dev.HTTPS 개발 경험을 원하는 대로 사용하고 추가하십시오!

좋은 웹페이지 즐겨찾기