初めてのnginxでオレオレ証明書https（2020/12/19）

## やること

- 未だにnginxをちゃんと触っていなかったので学習
- dockerで構成
- 複数のアプリケーションサーバにプロキシ
- nginxサーバとクライアント間をオレオレ証明書でhttps

## 全体的なファイル構成

```sh
├── app # アプリケーションサーバ類
│   ├── main
│   │   └── index.html
│   └── sub
│       └── index.html
├── docker
│   └── docker-compose.yml
└── proxy # nginx + ssl
    ├── conf.d
    │   ├── default.conf
    │   └── main.conf
    ├── mime.types #
    ├── nginx.conf
    └── ssl
        ├── server-private.pem
        ├── server-public.key
        ├── server.csr
        ├── server_self_signed.crt
        └── subjectaltname.ext
```

## docker-compose

```yml:docker-compose.yml
version: '3'

services:
  main-server:
    image: nginx
    container_name: 'main-server'
    volumes:
      - ../app/main:/usr/share/nginx/html
    ports:
      - 7000:80

  sub-server:
    image: nginx
    container_name: 'sub-server'
    volumes:
      - ../app/sub:/usr/share/nginx/html
    ports:
      - 7001:80

  reverse-proxy:
    image: nginx
    volumes:
      - ../proxy:/etc/nginx
    ports:
      - 80:80
      - 443:443
```

### nginxでプロキシ

```conf:proxy/nginx.conf
user  nginx;
events {
    worker_connections  16;
}
http {
    charset UTF-8;
    # log format設定
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /etc/nginx/access_log main;
    # 仮想サーバの設定ディレクトリ
    include ./conf.d/*.conf;
}
```

```conf:proxt/conf.d/main.conf
server {
    listen 80;
    return 301 https://$host$request_uri; # http to https
}

server {
    listen 443 ssl;
    server_name localhost; # ドメイン
    keepalive_timeout   70;

    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_buffer_size     16k;
    ssl_certificate     /etc/nginx/ssl/server_self_signed.crt;
    ssl_certificate_key /etc/nginx/ssl/server-private.pem;

    location /main {
        proxy_pass http://host.docker.internal:7000/;
        proxy_redirect off;
    }
    location /sub {
        proxy_pass http://host.docker.internal:7001/;
        proxy_redirect off;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
```

### アプリサーバー
```html:app/main/index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
    <title>main</title>
  </head>
  <body>
    <h1>main</h1>
  </body>
</html>
```

```html:app/sub/index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
    <title>sub</title>
  </head>
  <body>
    <h1>sub</h1>
  </body>
</html>
```

### オレオレ証明書作成

```sh:証明書作成
openssl genrsa -out server-private.pem 2048 # RSA形式で1024ビットの秘密鍵を作成
openssl rsa -in server-private.pem -pubout -out server-public.key # 公開鍵を生成
openssl req -new -key server-private.pem > server.csr # CSR作成
openssl x509 -req -in server.csr -signkey server-private.pem 
          -out server_self_signed.crt -days 825 -extfile subjectaltname.ext # 自己署名証明書発行
```

```txt:subjectaltname.ext
subjectAltName=DNS:localhost
```

ここまでできたら`server_self_signed.crt`をホストの証明書に登録します。
登録したら信頼するのを忘れない様にします。
https://qiita.com/colomney/items/887f9ea7b68a3b427060

備忘的に実装だけを書きましたので、詳細についてはそれぞれご確認お願いします。


#### 参考/引用元

https://nginx.org/en/docs/beginners_guide.html
https://qiita.com/zawawahoge/items/d58ab6b746625e8d4457
https://qiita.com/kunichiko/items/12cbccaadcbf41c72735
https://qiita.com/katsunory/items/97f5a4738863776fbaf4
https://kazuhira-r.hatenablog.com/entry/20180803/1533302929