未分類

前回までにssh ユーザー名@elephantcat.workみたいなことができるようになりました。

次はVPSで新しいサービスを稼働させるべく、dockerを入れます。

未分類

何かと面倒なdockerでpostgresを動かし、SSLで接続した上に、せっかくSSLなのでクライアント認証する、という企画です。

CAと鍵と証明書の作成

privateなnetworkなのでオレオレCAを作成します。

create_cert.sh

#!/bin/bash
set -euo pipefail

# create root CA
openssl req -new -nodes -text -subj "/CN=ca.local" -out ca.csr -keyout ca.key
chmod og-rwx ca.key
openssl x509 -req -in ca.csr -text -days 3650 -extfile /etc/ssl/openssl.cnf -extensions v3_ca -signkey ca.key -out ca.crt
rm ca.csr

# create server cert
openssl req -new -nodes -text -out server.csr -keyout server.key -subj "/CN=server.local" 
chmod og-rwx server.key
openssl x509 -req -in server.csr -text -days 365 -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
rm server.csr

# create client certs
openssl req -new -nodes -text -out client1.csr -keyout client1.key -subj "/CN=client1.local" 
chmod og-rwx client1.key
openssl x509 -req -in client1.csr -text -days 365 -CA ca.crt -CAkey ca.key -CAcreateserial -out client1.crt
rm client1.csr

# change owner for alpine postgres
sudo chown 70 server.key
  • .certが証明書、.keyが秘密鍵
  • caがオレオレルートCAで、serverがpostgresが動くサーバ、client1がクライアント用
  • domainはとりあえず.local
  • CA自己署名証明書は10年、他は1年で作成
  • サーバの秘密鍵はalpine上のpostgresイメージのUIDに合わせて70に

postgresをdockerで起動(初回)

docker-compose.yml

version: "3"

services:
  db:
    image: postgres:12-alpine
    container_name: postgres
    command: -c ssl=on -c ssl_ca_file=/var/lib/postgresql/ca.crt -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key
    ports: 
      - "5432:5432"
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_DB=postgres
      - POSTGRES_PASSWORD=secret
    volumes:
      - ./ca.crt:/var/lib/postgresql/ca.crt:ro
      - ./server.crt:/var/lib/postgresql/server.crt:ro
      - ./server.key:/var/lib/postgresql/server.key:ro
      - ./data:/var/lib/postgresql/data
  • 公式イメージではありません!

起動!

$ docker-compose up

SSLで接続(パスワード認証)

別のコンテナからホストに繋いで確認します。

$ docker run -it --rm postgres:12-alpine psql "host=(ホストIP) user=postgres password=secret"

結果

psql (12.1)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=# \q

外部からの認証をSSLクライアント認証のみに設定

サーバーを一度落とす

$ docker-compose down

./data/pg_hba.confの最後を以下に書き換える

#host all all all md5
hostssl all all all cert map=cnmap
  • (ローカルを除く)全IPからのTCPホスト接続をパスワード認証
    → (ローカルを除く)全IPからのTCPホスト接続をSSLクライアント認証(ユーザーマッピングはcnmap)

./data/pg_ident.confに以下を加える

cnmap   /^(.*)\.local$  postgres
  • cnmapという名前で、.localで終わるCNにユーザーpostgresをマッピングするルールを定義

設定確認

起動!

$ docker-compose up

パスワード認証で接続

$ docker run -it --rm postgres:12-alpine psql "host=(ホストIP) user=postgres password=secret"

結果

psql: error: could not connect to server: FATAL:  connection requires a valid client certificate
FATAL:  no pg_hba.conf entry for host "172.20.0.1", user "postgres", database "postgres", SSL off

SSLクライアント認証で接続

$ docker run -it --rm \
-v $PWD/client1.crt:/root/.postgresql/postgresql.crt \
-v $PWD/client1.key:/root/.postgresql/postgresql.key \
-v $PWD/ca.crt:/root/.postgresql/root.crt \
postgres:12-alpine psql "host=(ホストIP) user=postgres"
  • ややこしそうに見えるが、~/.postgresql/にクライアント証明書とクライアント鍵と信頼してるCAの証明書を置いて、ホスト+ユーザー指定で繋いでるだけ

結果

psql (12.1)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=# \q

参考リンク

未分類

前提

  • dockerが使える
  • Visual Studio codeが使える
  • x-debugを使用する

docker

docker-compose.yml

version: "3.1"
services:
  wordpress:
    build: .
    restart: always
    ports:
      - 80:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - ./wordpress:/var/www/html
      - ./php.ini:/usr/local/etc/php/php.ini

  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - ./db:/var/lib/mysql

(編集)2021/5/26 不要なvolumeの記述を削除

Dockerfile

FROM wordpress:php7.3
RUN pecl install xdebug \
  && docker-php-ext-enable xdebug

(編集)2021/5/26 誤ったWORKDIR設定を削除

ビルド時に以下のようなメッセージ(タイミングや環境によって異なる)が出るはずなので、これをphp.iniに追加する。

zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so

php.ini

post_max_size = 50M
upload_max_filesize = 50M
memory_limit = 256M
[xdebug]
xdebug.remote_enable=1
xdebug.remote_autostart=1
; ホスト側のIP
; host.docker.internalはdockerのhostマシンのIPを解決してくれます。
; hostマシン以外のIP/WindowとMAC以外の場合は適宜IPを調べて設定してください。
xdebug.remote_host=host.docker.internal
; 空いているport番号
xdebug.remote_port=9000
; xdebugの出力するログの場所。今回は適当に/tmp配下に。
xdebug.remote_log=/tmp/xdebug.log
; Dockerイメージビルド時のメッセージをコピペして追記
zend_extension=?

(追記)2021/5/26 xdebugのバージョンが2から3に上がったらしく、3になると設定変数の名前が大きく変わっている。ほぼ同じ内容を3にしてみた。

post_max_size = 50M
upload_max_filesize = 50M
memory_limit = 256M
[xdebug]
xdebug.mode=debug
xdebug.start_with_request=yes
; ホスト側のIP
; host.docker.internalはdockerのhostマシンのIPを解決してくれます。
; hostマシン以外のIP/WindowとMAC以外の場合は適宜IPを調べて設定してください。
xdebug.client_host=host.docker.internal
; 空いているport番号
xdebug.client_port=9000
; xdebugの出力するログの場所。今回は適当に/tmp配下に。
xdebug.log=/tmp/xdebug.log
; Dockerイメージビルド時のメッセージをコピペして追記
zend_extension=?

https://xdebug.org/docs/upgrade_guide/ja

Visual Studio code

.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9000,
            "pathMappings": {
                // {docker上のdocument root}:{ローカルのdocument root}
                "/var/www/html":"/path/to/wordpress"
            }
        }
    ]
}

参考サイト