0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OpenSSLを用いてサーバー証明書を作ってhttps通信

Last updated at Posted at 2024-12-27

サーバー証明書とは

そのサーバの実在証明や、通信内容の暗号化に使用するものである。
正規の認証局を通さず、自分自身のサーバーで発行したサーバー証明書。
今回は自宅内のサーバーとhttps通信したいだけなので問題ない。

なぜこれを行うのか

iPhoneアプリでセンサーの許可を出すためにはhttpsで暗号化されている必要がある。
hostingサービスを使えばよいが、外部に公開されてしまう。
そこでlocal環境でhttpsを使えるようにすればよいと考えた。

インストール

sudo apt update

パッケージリストを更新している。

sudo apt install openssl

OpenSSLをインストール。

openssl version

インストールできているか確認

鍵を作成

openssl genrsa -des3 -out 秘密鍵のパス 2048

openssl
OpenSSLのコマンドラインツールを使うことを示す。

genrsa
RSA方式で秘密鍵を生成するコマンド。

-des3
DES3 (トリプルDES) で鍵を暗号化。
生成される秘密鍵自体にパスワード保護をかける。

-out 秘密鍵のパス
生成した秘密鍵をファイルに保存します。
秘密鍵のパスの部分に、保存先のパスやファイル名を指定する。

2048
鍵の長さを指定します。
2048ビットの鍵を生成します。
一般的に「2048ビット以上」が推奨されている。

コマンド入力後、以下のように秘密鍵のパスワードを要求されるので適当なパスワードを入力。

Enter pass phrase for 秘密鍵のパス:
Verifying - Enter pass phrase for 秘密鍵のパス:

CSRを作成

openssl req -new -key 秘密鍵のパス -out CSRのパス

SSL証明書署名要求 (CSR: Certificate Signing Request) を作成するためのもの。CSRは証明書を発行してもらうために必要なファイル。

req
証明書関連の操作を行うOpenSSLサブコマンド。

-new
新しいCSRを作成。

コマンドを実行すると、以下のような入力を求められる。
これらの情報はSSL証明書に反映されるため、正確に入力すること。

入力例

Country Name (2 letter code) [XX]: JP
State or Province Name (full name) []: Tokyo
Locality Name (eg, city) [Default City]: Shibuya
Organization Name (eg, company) [Default Company Ltd]: Example Inc.
Organizational Unit Name (eg, section) []: IT Department
Common Name (eg, server FQDN or YOUR name) []: www.example.com
Email Address []: admin@example.com

Country Name
→ 国コード (日本ならJP)
State or Province Name
→ 都道府県名 (例: Tokyo)
Locality Name
→ 市区町村名 (例: Shibuya)
Organization Name
→ 会社名や団体名 (例: Example Inc.)
Organizational Unit Name
→ 部署名 (例: IT Department)
Common Name (CN)
→ 証明書を発行するドメイン名 (例: example.com)
※これが最も重要。
Email Address
→ 管理者のメールアドレス。省略可能。

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

これらの項目は必須ではないため、そのままEnterを押して空欄のままで大丈夫。

なぜ空欄で良いのか?
チャレンジパスワードは古い慣習で、現在の証明書発行プロセスでは使われていないらしい。
空欄のままにしておくことで、不要なトラブルを防ぐことが出来るらしい。

サーバ証明書の作成

本来ならば、CSRを認証局に提出してサーバー証明書を作成してもらうのですが、今回はオレオレ証明書なので自作。
自己署名証明書 (Self-Signed Certificate) を生成。

openssl x509 -in CSRのパス -days 365 -req -signkey 秘密鍵のパス -out 作成するサーバ証明書のパス

x509
証明書を管理・表示するためのOpenSSLのサブコマンド。
証明書の生成や表示に使う。

-in CSRのパス
先ほど作成したCSRファイルを指定。

-days 365
証明書の有効期間を設定します。この場合は365日。
必要に応じて -days 730 (2年) などに変更可能。

-req
CSRから証明書を生成することを示す。

-signkey 秘密鍵のパス
証明書に署名するための秘密鍵を指定。

-out 作成するサーバ証明書のパス
生成される証明書の保存先を指定。

実行例

openssl x509 -in /etc/nginx/certs/nginx_server.csr -days 365 -req -signkey /etc/nginx/certs/nginx_server_key.pem -out /etc/nginx/certs/nginx_server.crt
Enter pass phrase for nginx_server_key.pem:

と出るのでパスワードを入力

実行結果

Signature ok
subject=/C=JP/ST=tokyo/L=hoge/O=company/OU=sales/CN=www.test.com

生成された証明書の確認

openssl x509 作成するサーバ証明書のパス -text -noout

これでテスト環境やローカル開発環境でhttpsが使えるようになった。
イントラネットや個人サーバーで一時的にSSLを有効化。
本番環境では正式な認証局(CA)に証明書を発行してもらう必要がある。

Webサーバの立ち上げ

nginxのインストール

sudo apt update
sudo apt install nginx

nginxの設定

sudo nano /etc/nginx/sites-available/default

パスフレーズ付きの秘密鍵からパスフレーズを削除し、パスフレーズなしの新しい秘密鍵を作成する

sudo openssl rsa -in [上でつけた秘密鍵のパス] -out [上でつけた秘密鍵のパス]

sudo openssl rsa -in /etc/nginx/certs/nginx_server_key.pem -out /etc/nginx/certs/nginx_server_key_nopass.pem

nginxのdefault設定ファイルを編集

sudo nano /etc/nginx/sites-available/default

以下に変更

# HTTPサーバー設定 (ポート80)
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # ドキュメントルートとインデックスファイルの設定
    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;

    # サーバー名 (デフォルトサーバー)
    server_name _;

    # HTTPからHTTPSへのリダイレクト
    location / {
        return 301 https://$host$request_uri;
    }
}

# HTTPSサーバー設定 (ポート443)
server {
    listen 443 ssl;
    server_name www.yamada.com;

    # SSL設定 (証明書と秘密鍵のパス)
    ssl_certificate /etc/nginx/certs/nginx_server.crt;
    ssl_certificate_key /etc/nginx/certs/nginx_server_key.pem;
    ssl_password_file /etc/nginx/certs/nginx_passphrase.txt;

    # SSL/TLSプロトコルと暗号スイートの設定
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # ドキュメントルートとインデックスファイルの設定
    root /var/www/html;
    index index.html;

    # ルートパスの設定
    location / {
        try_files $uri $uri/ =404;
    }
}

# コメントアウトされたPHP設定 (必要に応じて有効化)
# location ~ \.php$ {
#     include snippets/fastcgi-php.conf;
#     fastcgi_pass unix:/run/php/php7.4-fpm.sock;
#     # fastcgi_pass 127.0.0.1:9000;
# }

標準では反応してくれなかったので、index.htmlに変更

sudo mv /var/www/html/index.nginx-debian.html /var/www/html/index.html

nginxの起動

sudo systemctl reload nginx

アクセス

https://192.168.x.x/

結果
image.png
こう表示されますが、自分で作成したので当たり前です。

実際に使おう

windows編

  1. 証明書ファイル (.crt) をエクスポート
    Nginxの証明書が nginx_server.crt であることを確認する。
    証明書をWindowsにコピーまたはダウンロード。
    ファイル名例: nginx_server.crt
  2. 証明書のインストール
  3. 証明書をダブルクリック
    .crt ファイルをダブルクリックする。
  4. 「証明書のインストール」を選択
    「証明書のインストール」ウィザードが開く。
  5. ローカルコンピュータまたはユーザーの証明書ストアを選択
    「現在のユーザー」または「ローカルコンピュータ」のどちらかを選択。
    現在のユーザー: 自分だけが証明書を信頼する。
    ローカルコンピュータ: PC全体で証明書が信頼される。(推奨)
    「次へ」をクリック。
  6. 証明書ストアの選択
    「証明書をすべて次のストアに配置する」を選択する。
    「参照」から 信頼されたルート証明機関 を選択する。
    重要: 信頼されたルート証明機関 にインストールしないと、「セキュリティ保護なし」のエラーが出続る。
  7. インストール完了と確認
    インストール完了後、ブラウザを再起動し、HTTPSサイトにアクセスして確認する。

こうなれば完成
image.png

スマホ編

iPhoneやAndroidにも同様に証明書を送信し、インストール後「完全に信頼する証明書」として有効化。

iPhone:
設定 → 一般 → VPNとデバイス管理 → 証明書を信頼

Android:
設定 → セキュリティ → 証明書のインストール

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?