サーバ証明書を理解する

サーバ証明書はどんな時に使うのか?

サーバ証明書は、HTTPS通信に対応したサイトにする際に必要になる。HTTPS通信は下記のようなサーバクライアント間の暗号化通信を行うもの。

https.png

HTTP通信とHTTPS通信の違い

HTTPS通信では暗号化通信を行うので、サーバクライアント間で暗号化に使う鍵を事前に交換しておく必要がある。交換した鍵を用いて暗号化通信をすることで安全な通信が実現できる。 diff.png

TLS通信によるメリットをまとめる。

  • 真正性
    サーバ証明書を利用して、サーバが本物であることを証明
  • 通信暗号化
    下記により安全に鍵を交換し、通信を暗号化する
    • サーバの公開鍵を用いた共通鍵の交換
    • 交換した共通鍵を用いた通信暗号化
  • 完全性
    ハッシュ値を用いて、通信の改竄を検知する。 具体的には、データ送信時に共通鍵で暗号化したデータとハッシュ値を送信する。受信側では、受信データのハッシュ値を計算し、送られてきたハッシュ値と等しいかを確かめ、改竄がないかを確認する。

上のような暗号化技術(鍵交換技術、認証技術、共通鍵暗号技術、ハッシュ関数技術)の組み合わせを暗号スイートと呼ぶ example.png

サーバ証明書・TLS/SSL通信・HTTPS暗号アルゴリズム

なぜサーバ証明書が必要?

暗号化通信を行うことで安全な通信ができるようになったが、相手が本物かどうかをクライアントが確認してから通信しないと、悪意あるサイトによるなりすましで、情報を盗まれてしまう可能性がある。そこで利用されるのがサーバ証明書

サーバ証明書は、信頼できる第三者機関の認証局(CA:Certificate Authority)と呼ばれるところから発行される。クライアントはTLSコネクション時にサーバから受け取ったサーバ証明書を、クライアント自身の認証局の情報を基に確認し、信頼できる相手かを判断する。 これによりなりすましを予防できる。

サーバ証明書発行の流れ

  1. サーバが秘密鍵を用意
  2. サーバの秘密鍵CSRを用意
  3. CSR認証局に申請
  4. 認証局ではCSRの内容を審査(実在するかどうか等)
  5. 問題なければ認証局秘密鍵で署名
  6. サーバ証明書をサーバに送る csr.png

参考

githubでcommit間差分用URLを作る

課題修正時に、commitを複数回やってレビューしてもらう場合、みてもらった時からの差分の見せ方がなんとかならないかなーと思っていたのだけど、やはりありました。

例えば下記のようなcommitAをレビューしてもらい、いくつか修正を行いcommitEで再度レビューをお願いしたいような場合には、commitAcommitEの差分を見てもらいたい。

commitA -> commitB -> commitC -> commitD -> commitE

そんな場合には、次の形式でURLを叩いてあげれば、commitAcommitEの差分比較ができる。

リポジトリURL/compare/ファイル変更前のcommitAハッシュ値...ファイル変更後のcommitEハッシュ値

具体的には下記のようなURLを作ってあげるとOK👍

https://github.com/goruchanchan/ruby-practices/compare/d2184f0411c5628979a41a601feed22658c0e3c5...a5fbc5e7baed597087fd3064b17f8fb17edde4dc

上記URLにアクセスするとコミット間の差分が表示される。下の例では4コミット後の差分をまとめたものを表示している。 diff_commit.png

上記URL作成は、Githubの機能として用意されているのでそれを使うと楽。 Files changedタブのChanges from all commitsを選択し、Shiftキーを押しながら比較元と比較先をクリックすると、URLがクリップボードにコピーされる。 Image from Gyazo

アーリーリターン

リーダブルコードに書かれているが、アーリーリターンの美味しさは下記。

  • メソッドの途中でリターンすることで読むコード数を減らせる

    7.5節 関数から早く返す

  • ネストを浅くできる

    7.7節 ネストを浅くする

指摘を受けた部分は下記のところ。

def run_wc(file_path: nil, sentence: nil, l_option: false)
  if sentence.nil?
    "wc: #{file_path}: open: No such file or directory"
  else
    concat_wc_contents(file_path, l_option, sentence)
  end
end

メソッド自体は短いため、早く返すのはそれほどだけど、if文がなくなりネストを浅くできました😃

def run_wc(file_path: nil, sentence: nil, l_option: false)
  return "wc: #{file_path}: open: No such file or directory" if sentence.nil?y

  concat_wc_contents(file_path, l_option, sentence)
end

オレオレ証明書でnginxのサイトをHttps対応する

オレオレ証明書を発行する

証明書発行の流れは下記のような感じ。 certificate.png

オレオレ証明書では、認証局でやることを自分でやることから『オレオレ』証明書と言われる。

オレオレ証明書の発行の流れは下記。

  1. 秘密鍵を作る

    openssl genrsa -out himitsu.key 2048
    
  2. 証明書署名要求を作る

    openssl req -new -key himitsu.key -out goruchan.csr
    

    crt.png

  3. サーバ証明書を作成する

ここは本来は、信用できる第三者認証局(CA)にやってもらう。そうすることで、クライアントは信用できる相手だと判断できる。

  openssl x509 -days 3650 -req -signkey himitsu.key < goruchan.csr > goruchan.crt

nginxの設定ファイルを変更する

公式のConfiguring HTTPS serversを参考に下記を設定。

server {
    listen       443 ssl;
    server_name  goruchan.net;
    ssl_certificate     /home/goruchan/goruchan.net/goruchan.crt;
    ssl_certificate_key /home/goruchan/goruchan.net/himitsu.key;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /home/goruchan/goruchan.net/public;
        index  index.html index.htm;
    }

    location /images/ {
        root /home/goruchan/goruchan.net/public;
    }
    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

設定したらいつもの下記コマンドを実行して、設定を反映する

sudo nginx -s reload

WebサイトにChromeでアクセスしてみると、下記のような感じになる。 oreore2.png どうやらChromeではオレオレのサイトは表示させないようにしているみたい。

簡単に表示するには、safariでやるのが簡単。 で、Safariでアクセスしてみると、矢印部をクリックすることで表示できるようにできる。 oreore3.png Webサイトを閲覧を選択。 oreore4.png パスワードを指定して、当該サイトの証明書をWebブラウザに登録する。 oreore5.png 下記のように鍵付きのWebサイトになりました。 oreore6.png ここまでやってだいぶ怖い思いをしたので、とりあえずWebブラウザからオレオレ証明書を削除しました。lanchpadからキーチェーンを起動して、さっき入れたオレオレ証明書を削除すれば、Safariからオレオレ証明書を削除できました。 oreore7.png

ここまで来たら、認証局に登録するのもやってみたいので、無料で使えるというLet's Encrypt - フリーな SSL/TLS 証明書で証明書を作ってみようと思います。

参考

さくらVPSに独自ドメインを設定する

全体的な作業手順のイメージは下記のような感じ。

sakura_onamae.png

お名前.comでドメインを取得する

https://www.onamae.com/ にアクセスして、好きなドメインを取得する*1

onamae.png

お名前.comで取得したドメインのネームサーバを切り替える

初期だと取得したドメインの名前解決は、当然ながらお名前.comのネームサーバとなっているので、それをさくらのネームサーバに切り替える。

onamae_1.png

onamae_2.png

さくらのDNSに登録する

sakura_1.png

sakura_2.png

sakura_3.png

sakura_4.png

sakura_5.png

以上で設定完了。

設定が反映されるまでに結構時間がかかるので、気長に待つ。自分の場合、寝る前に設定して朝起きたらドメインが有効になっていました。 sakura_6.png

参考

*1: 「さくらのドメイン」でもドメインを取得できるので、「さくら」でまとめてしまった方が楽かも。お名前.comの方が少しだけやすい。

nginxで個人ページを公開する

Beginner’s Guideを読んでいてなんとなく感じたのは、設定ファイルにも種類があるっぽいと感じた。

nginxは、設定ファイルに記述されたディレクティブによって制御されるモジュールで構成されてる。ディレクティブは2種類に分けられる。

種類 説明
シンプルディレクティブ 名前とパラメータをスペースで区切り、セミコロン(;)で終わる
ブロックディレクティブ シンプルディレクティブと同じ構造だが、セミコロンの代わりに、中括弧({と})で囲まれた一連の追加命令がある

※ブロックディレクティブが中括弧の中に他のディレクティブを持つことができる場合、それをコンテキストと呼ぶ。(例: events, http, server, location

上記の観点を入れつつ、下記の設定ファイルを眺めてみると、userworker_processes,errorlog,pidがシンプルディレクティブで、eventshttpがブロックディレクティブということだと思う。

$ sudo find / -name "nginx.conf"
/etc/nginx/nginx.conf
$ cat /etc/nginx/nginx.conf 

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    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  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

http関連の設定を詳しくみてみると、/etc/nginx/conf.d/*.conf;をインクルードしているので、更にそのファイルを見てみる。

$ cat /etc/nginx/conf.d/default.conf 
server {
    listen       80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

上記のlocationが静的コンテンツを提供する部分の設定ということだった。これをみると、デフォルト設定の静的コンテンツは、/usr/share/nginx/htmlを見ていそうなので、このパスのファイル(index.html)を見てみると、nginxを立てたサーバのサンプルWebサイトの内容そのままだった。

よって、手っ取り早く個人ページを公開するには、このindex.htmlを個人のものに変えてしまえばOK。

次にリクエストに応じて、ファイルを異なるローカルディレクトリから提供する場合には、locationを複数定義してあげれば良いみたい。

$ cat /etc/nginx/conf.d/default.conf 
server {
    ...
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /images/ {
        root /usr/share/nginx/data;
    }
    ...

ここでの注意点は、Webサーバ内でlocationを指定するディレクトリ内に、Webクライアントがアクセスするパス名をもつディレクトリがないと404エラーになってしまう点。 下の設定ファイルの内容であれば、Webクライアントはhttp://***/image/sample.pngとアクセスしてくるので、Webサーバ内には、/usr/share/nginx/data/imagesというディレクトリ構成にしておかないとだめ。(/usr/share/nginx/dataだけではだめ。) point.png

オンプレGitLabをDocker-Desktopに立てる

Docker-DesktopにオンプレGitLabを立てる方法を学んだのでまとめておく。

CIとかでpagesに生成物を公開するような場合には、データをDocker内で管理していないと、うまく生成物を上げられないので、マウント先はバインドマウントではなく、ボリュームにする。 バインドマウントとボリュームの違いはDockerドキュメントボリュームの利用を確認する。

コンテナを立てる

Powershellのコマンドでやる場合

下記をPowerShellで叩く。それだけ。

  • マウント用のボリュームを作る
docker volume create gitlab_config
gitlab_config
docker volume create gitlab_logs
gitlab_logs
docker volume create gitlab_data
gitlab_data
  • コンテナを生成する
docker run --detach `
  --hostname gitlab.example.com `
  --publish 443:443 --publish 80:80 --publish 22:22 `
  --name gitlab `
  --restart always `
  --volume gitlab_config:/etc/gitlab `
  --volume gitlab_logs:/var/log/gitlab `
  --volume gitlab_data:/var/opt/gitlab `
  --shm-size 256m `
  gitlab/gitlab-ce:latest

docker-compose.ymlでやる場合

下記をdocker-compose.ymlに保存する。

version: '3.1'

services:
  gitlab:
    image: gitlab/gitlab-ce:latest
    shm_size: 256m
    container_name: gitlab
    restart: always
    hostname: gitlab.example.com
    ports:
      - 443:443
      - 80:80
      - 22:22
    volumes:
      - gitlab_config:/etc/gitlab
      - gitlab_logs:/var/log/gitlab
      - gitlab_data:/var/opt/gitlab    

volumes:
  gitlab_config:
  gitlab_logs:
  gitlab_data:

GitLabにアクセスする

ブラウザで127.0.0.1にアクセスする。コンテナが立ち上がるまでに少し時間がかかるので待つ。アクセスできない間は、応答がないか下記の図が表示される。

gitlab_502

ログイン画面が表示されたら、コンテナ内の/etc/gitlab/initial_root_passwordを開いて、rootの初期パスワードを確認して、ログインする。ログインパスワードは24時間で削除されるので注意。その場合、コンテナ内に入って、GitLabのパスワードリセットを実施する。参考

gitlab_init

ログインできました。

gitlab_initial

今日はとりあえずここまで。そのうちメール設定やCI実行によるPages公開などもまとめよう。

参考