2018年6月20日水曜日

Let's EncryptをNginxで使用する

目的

自宅にSSL接続が行えるWebServerが必要になったので用意


構成

ドメイン(https://test.yoshio.me)が使えるようにする

WebサーバはNginx

サーバーとなるのはRaspberry pi3B


準備

必要なソフトのインストール

$cd certbotを置きたいパス
$sudo apt-get install git
$git clone https://github.com/certbot/certbot
$cd certbot

証明書取得

Certbotをスタンドアロンモードで使用しWebサーバー無しで証明書を取得

$./certbot-auto certonly --standalone -t

足りないパッケージが出るため、yを押して承認



2020/06/13追記

コンパイルを省略する為にスクリプトが別箇所からバイナリを取ってくるらしく必要なライブラリがハッシュが違うと言ってくる

THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.
    pycparser==2.19 from https://www.piwheels.org/simple/pycparser/pycparser-2.19-py2.py3-none-any.whl#sha256=bc15573b7c6edd24407526dbbc7a0bd33d80d8af44231c37f58d73f56ff9cab6 (from -r /tmp/tmp.ULi7aj6FeV/letsencrypt-auto-requirements.txt (line 115)):
        Expected sha256 a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3
             Got        bc15573b7c6edd24407526dbbc7a0bd33d80d8af44231c37f58d73f56ff9cab6

    zope.component==4.6 from https://www.piwheels.org/simple/zope-component/zope.component-4.6-py2.py3-none-any.whl#sha256=74f55521dec189c08d98341edce929eba6bb2404662d1878f1b289af46f6f6a5 (from -r /tmp/tmp.ULi7aj6FeV/letsencrypt-auto-requirements.txt (line 137)):
        Expected sha256 ec2afc5bbe611dcace98bb39822c122d44743d635dafc7315b9aef25097db9e6
             Got        74f55521dec189c08d98341edce929eba6bb2404662d1878f1b289af46f6f6a5

修正方法は多くあり、apt-get install certbot

もしくはcertbot-autoを開き、Expected sha256を得られる値に書き換える



Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): xxx@xxx.xxxx

Emailアドレスを入れろ(お知らせとセキュリティ情報に使用)と言われるので、とりあえず入れる

-------------------------------------------------------------------------------
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel: A

-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
-------------------------------------------------------------------------------
(Y)es/(N)o: N
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel): test.yoshio.me

一つ目がサービスの利用規約に同意しろ、二つ目が入力したメルアドにお知らせを送っていいかです

Cleaning up challenges
Problem binding to port 80: Could not bind to IPv4 or IPv6.

もしも既にport80が何かに使われていると上記のようなメッセージが出ますので素直にサーバーを止めます

Timeout during connect (likely firewall problem)

このエラーは80番ポートを開けていない時に出ます。80番と443番を開けておきましょう

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/test.yoshio.me/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/test.yoshio.me/privkey.pem
   Your cert will expire on 2018-09-18. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot-auto
   again. To non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Congratulations!と出たら成功です、

期限は3ヶ月なので2018-09-18まで有効の証明書を/etc/letsencrypt/live/test.yoshio.me/以下に手に入れました

Nginx設定(SSLでアクセス出来るかテスト)

nginx設定変更

設定を書き換えて、とりあえず証明書を使ってSSLを実現します

$vim /etc/nginx/sites-enabled/default

SSLを見るようにする

listen [::]:80 default_server;
#追加
listen 443 ssl;

証明書の参照

server_name _;
#追加
ssl_certificate /etc/letsencrypt/live/test.yoshio.me/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/test.yoshio.me/privkey.pem;

本変更で完了です nginxを起動させます

$sudo /etc/init.d/nginx start

注意点

引っかかったところとしては、SSLはポート443だが、80しか開けていなかったためアクセスできないエラーに陥った


Nginx設定(証明書自動更新準備)


webrootを使った更新

-wで設定するファイルはlet's encryptがアクセスして来る箇所になる模様、あとでnginxの設定値を変えてアクセスを許可する

sudo mkdir /var/www/letsencrypt
./certbot-auto certonly --webroot -w /var/www/letsencrypt -d test.yoshio.me --agree-tos --force-renewal -n

実行後のログで下記のようなことが出たら成功です


Requesting to rerun ./certbot-auto with root privileges...
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for test.yoshio.me
Using the webroot path /var/www/letsencrypt for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/test.yoshio.me/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/test.yoshio.me/privkey.pem
   Your cert will expire on 2018-09-18. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot-auto
   again. To non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

80番ポートをLet's Encrypt専用にする

/etc/nginx/sites-enabled/defaultを書き換えます

server {
    listen 80 default_server;
 listen [::]:80 default_server;
  
   location ^~ /.well-known {
  root /var/www/letsencrypt;
    }
 
    location / {
  return 301 https://$host$request_uri;
 }
}
server {
    listen 443 ssl;
 
 root /var/www/html;
 
 index index.html;
 
 server_name _;
 ssl_certificate /var/letsencrypt/live/test.yoshio.me/fullchain.pem;
 ssl_certificate_key /var/letsencrypt/live/test.yoshio.me/privkey.pem;
 
     location / {
     try_files $url $url/ =404;
 }
}

証明書リニューアルテスト

コマンドを叩いてテストして見る、以下のようなログが出たら完了

$./certbot-auto renew --force-renewal

Requesting to rerun ./certbot-auto with root privileges...
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/test.yoshio.me.conf
-------------------------------------------------------------------------------
Plugins selected: Authenticator webroot, Installer None
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for test.yoshio.me
Waiting for verification...
Cleaning up challenges

-------------------------------------------------------------------------------
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/test.yoshio.me/fullchain.pem
-------------------------------------------------------------------------------
Plugins selected: Authenticator webroot, Installer None

-------------------------------------------------------------------------------

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/test.yoshio.me/fullchain.pem (success)
-------------------------------------------------------------------------------

Cronを使っての自動実行

設定ファイルを用意

意味は毎月24日の朝6時に上でやったコマンドを実行してねということです

$sudo vim /etc/cron.d/letencrypt
00 06 24 * * /usr/local/certbot/certbot-auto renew --force-renewal

cronに読み込み

$sudo crontab letencrypt
$sudo crontab -l
00 06 24 * * /usr/local/certbot/certbot-auto renew --force-renewal && /etc/init.d/nginx reload

上記だと24日の朝6時という時間帯オンリーなので、本来はスクリプトに飛ばしてばらけた時間にアクセスするべきだと思う


以上!


追記(2020/06/13)

Go言語でひとまずSSLを試す方法

なお、sudoでgoを使う場合は、sudo「コマンドが見つかりません」PATHが初期化されているときの対処法を参照してroot権限で443ポートが使えるようにする

$ cat web.go 
package main

import (
  "fmt"
  "net/http"
  "log"
)

func handler(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintf(w, "Hello, World")
}

func main() {
  var crtPath = "/etc/letsencrypt/live/Your Domain/fullchain.pem";
  var keyPath = "/etc/letsencrypt/live/Your Domain/privkey.pem";
  http.HandleFunc("/", handler)
  log.Fatal(http.ListenAndServeTLS(":443", crtPath, keyPath, nil))
}

Raspberry Pi 3Bをセットアップするまで

久しぶりにRaspberry Piを購入したためセットアップしたのでメモを残す

環境構築

物理的なもの

  1. Mac OS HighSierraが入ったMac
  2. Raspberry Pi 3B
  3. Micro USBタイプのACアダプタ
  4. Micro SD
  5. USB接続のキーボード

物理的に必要なものは上記5つを用意

OS

OSをダウンロード、今回はサーバーを構築したかったのでRaspbian stretch liteという最小限の構成で行く

重たいのならば、近くのサーバーからダウンロード

RaspbianMirrors

Liteならば、Raspbian Liteから最新版をダウンロード


SD Cardへの書き込み

書き込み先を見つける

$diskutil list

容量が近そうなアドレスを見つける

今回のケースは、/dev/disk2であった

書き込むためにアンマウントをする

$sudo diskutil unmountDisk /dev/disk2

書き込む

$sudo dd bs=1m if=2018-04-18-raspbian-stretch-lite.img of=/dev/disk2

Raspberry pi初起動

起動

Micro SDをRaspberry piに装着し、電源オン

電源投入で赤LEDが点灯し、即隣の緑LEDが点滅するとMicroSDからデータを読み込んでいる

緑LEDが点灯しない場合は、おそらくFirmの書き込み先が異なっていたりする

SSH接続

$sudo raspi-config

コンフィグが開くので、5 Interfacing Options -> P2 SSHと選択してEnableにする

Macからssh pi@ipアドレスで接続確認

終了

基本的にはここから先はSSH経由で出来る事ばかりなので一度再起動をする

終了

$sudo shutdown -h now

再起動

$sudo shutdown -r now

2018年6月17日日曜日

Google Cloud Speech APIをGo言語で実施

目的

GoでGoogle Cloud Speech APIを使ってText To Speechを行います


完成系

コードはGithubに置いてあります

GitHub

必要なライブラリ

  1. $go get golang.org/x/oauth2
  2. $go get google.golang.org/api/texttospeech/v1beta1

事前準備

  1. Google APIを登録
  2. Google Cloud APIにアクセスして登録

    新規プロジェクト作成、APIとサービスからライブラリとしてCloud Text-to-Speech APIを有効化します

    認証情報より、認証情報を作成、その他のクライアントをクリックし認証が出来るようにします

    ここで出てくるクライアントIDとクライアントシークレットが大切です

  3. コード作成
  4. GitHubを参考に最低クライアントID(26行目)とクライアントシークレット(27行目)を書き換え

    const (
     TEXT = "こんにちは!"
     GENDER = "FEMALE"
     LANGUAGE = "ja-JP"
     VOICENAME = "ja-JP-Standard-A"
    
     AUDIO_ENCODE = "LINEAR16"
     SPEAKING_RATE = 1
    
     CLIENT_ID = " Your Client ID "
     SECRET_KEY = " Your Secret KEY "
    
     OUTPUT = "output.mp3"
    )
    
  5. ビルドと実行
  6. 現状一ファイルなのでgo run main.goを行う

    するとコンソールにURLが出て来るので、そこにアクセス

    Google Accountでログインすると認証コードが出て来るので、それをコンソールにコピペしてエンター

  7. 出来上がりのファイル
  8. 出来上がったファイルはデフォルトだと実行したフォルダの下にoutput.mp3というファイル名で出来上がっている

    こちらを実行すれば、TEXTで定義されているセリフが入っています


まとめ

Google Cloud Speech APIを使わなくてもTranslate APIを使えばもっと楽に出来たりしますが、今回はGoogle APIの使い方を学ぶということで

package texttospeechをちゃんと使用すれば、もっといい方法があると思いますが、最低限ということで