[[Linuxめも]]

#contents

GoogleがやたらとSSL対応を勧めてくるんですよ。~
やっぱり今後はSSL対応が必須になる時代が来そうです。

でもSSLって高いイメージがあるし、証明書の更新も面倒。~
今の時代無料でできねーかなと調べてみたらなんかできそうな雰囲気。~
また時間がある時にトライしてみます。
今の時代無料でできねーかなと調べてみたらなんかできそうな雰囲気。

[[Let's Encrypt:https://letsencrypt.jp/]] で無料でSSLが導入できるようです。~
証明書の発行・インストール・更新のプロセスを自動化できるようです。

制限があります。~
https://letsencrypt.org/docs/rate-limits/

制限についての説明はこちらが詳しいです。~
ありがとうございます。~
http://qiita.com/sawanoboly/items/8e3c57aa2e30fc58c4e3

参考
-https://def-4.com/lets-encrypt-multi-domains/
-https://def-4.com/letsencrypt-tls-sni-01-challenge-error/
-https://blog.apar.jp/linux/3619/
-http://qiita.com/tkykmw/items/9b6ba55bb2a6a5d90963

*クライアントソフトCertbotのインストール [#w457122c]

 # wget https://dl.eff.org/certbot-auto
 # chmod 700 certbot-auto

ヘルプは以下で確認できます。

 # ./certbot-auto --help

以下を実行すると、自動的にyumが実行され、必要なパッケージがインストールされます。

 # ./certbot-auto

CentOS6.2ではyumにて python-pip-1.3.1-4.el6.noarch がダウンロードできずにエラーになってしまいました。

epelリポジトリを入れるとハマるみたいです。~
設定を書き換えます。

 # vi /etc/yum.repos.d/epel.repo

 #baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
 mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch
↓
 baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
 #mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch

CentOS5.5など古いOSは以下を参考にさせてもらえば利用が可能そうです。~
https://clouds.tokyo/blog/linux_lets_cent5/

*証明書の取得 [#ede60d3a]

同一サーバで別ドメインの証明書を取得する場合は、443ポートがすでに稼働しているために取得が完了できません。~
そのため開始前にWEBサーバを止めておきます。~
また、メールアドレスの入力と同意の設問はスキップされます。

 # ./certbot-auto certonly

 How would you like to authenticate with the ACME CA?
 -------------------------------------------------------------------------------
 1: Place files in webroot directory (webroot)
 2: Spin up a temporary webserver (standalone)
 -------------------------------------------------------------------------------
 Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

2を入力~
※certbot-autoのバージョンが上がって順番が入れ替わっている場合があるので注意が必要です。

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

メールアドレスを入力

 -------------------------------------------------------------------------------
 Please read the Terms of Service at
 https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.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を入力

 Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c' to cancel):

証明書を導入したいドメインをカンマもしくはスペース区切りで入力

成功すれば /etc/letsencrypt/archive/ドメイン/ 以下に4ファイル生成されます。

-cert1.pem サーバ証明書(公開鍵)
-chain1.pem 中間証明書
-fullchain1.pem サーバ証明書と中間証明書が結合されたファイル
-privkey1.pem 秘密鍵

数字は更新するたびにインクリメントされるようです。~
シンボリックリンクが以下に作成されるので、WEBサーバへの設定は以下を指定します。

-/etc/letsencrypt/live/ドメイン/cert.pem
-/etc/letsencrypt/live/ドメイン/chain.pem
-/etc/letsencrypt/live/ドメイン/fullchain.pem
-/etc/letsencrypt/live/ドメイン/privkey.pem

Apache 2.4.8未満では公開鍵、中間証明書、秘密鍵を使用します。~
それ以上やNginxではサーバ証明書と中間証明書が結合されたファイル、秘密鍵を使用します。

**WEBサーバを停止せずに証明書を取得する [#t3f3a884]

Webrootプラグインを使用することでWEBサーバを停止することなく証明書を取得することができます。~
WEBサーバで公開している絶対パスを指定します。

 # ./certbot-auto certonly --webroot -w /home/example.com/public_html -d example.com

Alias設定をしている場合は以下になります。

 # ./certbot-auto certonly --webroot -w /home/example.com/public_html -d example.com -d www.example.com

複数のドメインで1つの証明書を取得する場合は以下になります。

 # ./certbot-auto certonly --webroot -w /home/example.com/public_html -d example.com -w /home/other.example.com/public_html -d other.example.com

Webrootプラグインを使用すると、/home/example.com/public_html/.well-known/ 以下に一時的にファイルが生成され、認証が行われるようです。

**ワイルドカード証明書を取得する [#lcbbf641]

2018年3月頃にLet's Encryptがワイルドカードの証明書に対応してくれました。~
メールアドレスとドメインを指定してコマンドを実行します。

 # ./certbot-auto certonly \
 --manual \
 --preferred-challenges dns-01 \
 --server https://acme-v02.api.letsencrypt.org/directory \
 --agree-tos \
 --manual-public-ip-logging-ok \
 -m "user@example.com" \
 -d "example.com" \
 -d "*.example.com"

 Saving debug log to /var/log/letsencrypt/letsencrypt.log
 Plugins selected: Authenticator manual, Installer None
 Obtaining a new certificate
 Performing the following challenges:
 dns-01 challenge for example.com
 dns-01 challenge for example.com
 
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Please deploy a DNS TXT record under the name
 _acme-challenge.example.com with the following value:
 
 *******************************************
 
 Before continuing, verify the record is deployed.
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Press Enter to Continue

指示された通りに _acme-challenge.example.com のtxtレコードに表示された文字列を設定します。~
反映されたかの確認は以下で行います。

 $ dig @ns1.example.com _acme-challenge.example.com txt

反映確認後にEnter

 Please deploy a DNS TXT record under the name
 _acme-challenge.example.com with the following value:
 
 *******************************************
 
 Before continuing, verify the record is deployed.
 (This must be set up in addition to the previous challenges; do not remove,
 replace, or undo the previous challenge tasks yet. Note that you might be
 asked to create multiple distinct TXT records with the same name. This is
 permitted by DNS standards.)
 
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Press Enter to Continue

先程のものに追加でtxtレコードを追加し、反映確認後にEnterで取得終了です。

*Apacheの設定 [#a6784222]

ソースでインストールしている場合は --enable-ssl が有効になっているか確認。~
以下の行があるか確認します。

LoadModule ssl_module modules/mod_ssl.so

以下をApacheの設定ファイルに追加します。

Apache 2.4.8未満の場合

 Listen 443
 
 <VirtualHost *:443>
     ServerName ドメイン:443
     DocumentRoot "/home/ドメイン/public_html"
 
     SSLEngine on
     SSLHonorCipherOrder on
     Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
     SSLProtocol -All +TLSv1 +TLSv1.1 +TLSv1.2
     SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
 
     SSLCertificateFile /etc/letsencrypt/live/ドメイン/cert.pem
     SSLCertificateKeyFile /etc/letsencrypt/live/ドメイン/privkey.pem
     SSLCertificateChainFile /etc/letsencrypt/live/ドメイン/chain.pem
 
     <Directory "/home/ドメイン/public_html">
         Options FollowSymLinks
         AllowOverride ALL
         Require all granted
     </Directory>
 
     ErrorLog "logs/ssl_error_log"
     CustomLog "logs/ssl_access_log" combined
 </VirtualHost>

Apache 2.4.8以降の場合

 <VirtualHost *:443>
     ServerName ドメイン:443
     DocumentRoot "/home/ドメイン/public_html"
 
     SSLEngine on
     SSLHonorCipherOrder on
     Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
     SSLProtocol -All +TLSv1 +TLSv1.1 +TLSv1.2
     SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
 
     SSLCertificateFile /etc/letsencrypt/live/ドメイン/fullchain.pem
     SSLCertificateKeyFile /etc/letsencrypt/live/ドメイン/privkey.pem
 
     <Directory "/home/ドメイン/public_html">
         Options FollowSymLinks
         AllowOverride ALL
         Require all granted
     </Directory>
 
     ErrorLog "logs/ssl_error_log"
     CustomLog "logs/ssl_access_log" combined
 </VirtualHost>

**httpへのアクセスをhttpsへ転送させる [#h2c276fa]

.htaccessを設置してhttpにアクセスがあった場合はhttpsへそのまま転送させます。

 RewriteEngine on
 RewriteCond %{HTTPS} off
 RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

*自動更新の設定 [#peb4c288]

crontabに登録しておくことで自動更新が可能です。

通常はこんな感じ

 0 9 * * * /pathto/certbot-auto renew --post-hook "/etc/rc.d/init.d/httpd graceful"

毎月1日午前9時に一括更新する場合

 0 9 1 * * /etc/rc.d/init.d/httpd stop && /pathto/certbot-auto renew --force-renew && /etc/rc.d/init.d/httpd start

毎月1日午前9時に特定のドメインを更新する場合

 0 9 1 * * /etc/rc.d/init.d/httpd stop && /pathto/certbot-auto certonly --standalone -d example.com -d example2.com --renew-by-default && /etc/rc.d/init.d/httpd start

ログは /var/log/letsencrypt/letsencrypt.log に出力されています。

*有効期限などの確認 [#af066d19]

 # ./certbot-auto certificates

 -------------------------------------------------------------------------------
 Found the following certs:
   Certificate Name: example.com
     Domains: example.com
     Expiry Date: 2017-08-22 23:01:00+00:00 (VALID: 55 days)
     Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem
     Private Key Path: /etc/letsencrypt/live/example.com/privkey.pem
 -------------------------------------------------------------------------------

*証明書の破棄 [#da7294f1]

以下のコマンドで削除するドメインを聞かれるので、番号を選択します。

 # ./certbot-auto delete -d sub.example.com
 Which certificate(s) would you like to delete?

*登録しているメールアドレスの確認 [#h5e7c302]

 # cat /etc/letsencrypt/accounts/acme-v02.api.letsencrypt.org/directory/*/regr.json

contactに指定されているものがそうです。

*pip UnicodeDecodeError [#e2090d89]

エラーが出て実行できないようになりました。

 # ./certbot-auto
 Creating virtual environment...
 Installing Python packages...
 Had a problem while installing Python packages.
 
 pip prints the following errors:
 =====================================================
 DEPRECATION: Python 2.6 is no longer supported by the Python core team, please upgrade your Python. A future version of pip will drop support for Python 2.6 Exception:
 Traceback (most recent call last):
   File "/opt/eff.org/certbot/venv/lib/python2.6/site-packages/pip/basecommand.py", line 215, in main
     status = self.run(options, args)
   File "/opt/eff.org/certbot/venv/lib/python2.6/site-packages/pip/commands/install.py", line 272, in run
     with self._build_session(options) as session:
   File "/opt/eff.org/certbot/venv/lib/python2.6/site-packages/pip/basecommand.py", line 72, in _build_session
     insecure_hosts=options.trusted_hosts,
   File "/opt/eff.org/certbot/venv/lib/python2.6/site-packages/pip/download.py", line 329, in __init__
     self.headers["User-Agent"] = user_agent()
   File "/opt/eff.org/certbot/venv/lib/python2.6/site-packages/pip/download.py", line 93, in user_agent
     from pip._vendor import distro
   File "/opt/eff.org/certbot/venv/lib/python2.6/site-packages/pip/_vendor/distro.py", line 1050, in <module>
     _distro = LinuxDistribution()
   File "/opt/eff.org/certbot/venv/lib/python2.6/site-packages/pip/_vendor/distro.py", line 594, in __init__
     if include_lsb else {}
   File "/opt/eff.org/certbot/venv/lib/python2.6/site-packages/pip/_vendor/distro.py", line 922, in _get_lsb_release_info
     stdout, stderr = stdout.decode('utf-8'), stderr.decode('utf-8')
   File "/opt/eff.org/certbot/venv/lib64/python2.6/encodings/utf_8.py", line 16, in decode
     return codecs.utf_8_decode(input, errors, True)
 UnicodeDecodeError: 'utf8' codec can't decode byte 0xa5 in position 22: invalid start byte
 =====================================================
 
 Certbot has problem setting up the virtual environment.
 
 We were not be able to guess the right solution from your pip output.
 
 Consult https://certbot.eff.org/docs/install.html#problems-with-python-virtual-environment for possible solutions.
 You may also find some support resources at https://certbot.eff.org/support/ .

サーバをEUC-JPで設定していることが原因のようです。

 # cat /etc/sysconfig/i18n
 LANG="ja_JP.eucJP"

これで動きました。

 # LANG=ja_JP.UTF-8 ./certbot-auto

*CentOS6.2でPython 3.5以上が必要と言われた [#u46e4ebb]

 # ./certbot-auto renew
 WARNING: couldn't find Python 3.5+ to check for updates.
 Traceback (most recent call last):
   File "<stdin>", line 16, in <module>
   File "/usr/lib64/python3.4/distutils/version.py", line 58, in __lt__
     c = self._cmp(other)
   File "/usr/lib64/python3.4/distutils/version.py", line 176, in _cmp
     if self.version != other.version:
 AttributeError: 'StrictVersion' object has no attribute 'version'

 # yum install -y https://centos6.iuscommunity.org/ius-release.rpm
 # yum install --enablerepo=ius python36 python36-libs python36-devel python36-pip
 # ln -s /usr/bin/python3.6 /usr/bin/python3
 # ln -s /usr/bin/pip3.6 /usr/bin/pip3

*couldn't get currently installed version [#y161bce1]

 # ./certbot-auto renew
 Upgrading certbot-auto 0.40.0 to 0.40.1...
 Replacing certbot-auto...
 Error: couldn't get currently installed version for /opt/eff.org/certbot/venv/bin/letsencrypt:
 Traceback (most recent call last):
   File "/opt/eff.org/certbot/venv/bin/letsencrypt", line 6, in <module>
     from pkg_resources import load_entry_point
 ModuleNotFoundError: No module named 'pkg_resources'

フォルダを削除してしまいます。

 # rm -fr /opt/eff.org/certbot/

*CentOS5で導入する [#x92b8031]

CentOS5ではPythonのバージョンが古いため動作しません。~
互換クライアントがあるようなので、[[dehydrated:https://github.com/lukas2511/dehydrated]]を利用してみます。~
https://community.letsencrypt.org/t/list-of-client-implementations/2103

**dehydratedの設置 [#mdbd26f3]

[[GitHub:https://github.com/lukas2511/dehydrated]]から dehydrated-master.zip をダウンロードします。

 # mkdir /usr/local/etc/dehydrated

解凍したファイル類をアップします。

 # cp /usr/local/etc/dehydrated/docs/examples/config /usr/local/etc/dehydrated/

証明書を取得するドメインを指定します。~
複数の場合は半角スペースで区切ります。

 # echo 'example.com' > /usr/local/etc/dehydrated/domains.txt

**Apacheの設定 [#t19741b6]
***Apacheをパッケージでインストールしている場合 [#dd8a2779]

 # mkdir /var/www/dehydrated
 # mkdir -p /var/www/html/.well-known/acme-challenge
 # vi /etc/httpd/conf/httpd.conf

 <IfModule alias_module>
     Alias /.well-known/acme-challenge /var/www/dehydrated
 </IfModule>

***Apacheをソースからインストールしている場合 [#wa6fc244]

 # mkdir /usr/local/apache2/htdocs/dehydrated
 # mkdir -p /usr/local/apache2/htdocs/.well-known/acme-challenge
 # vi /usr/local/apache2/conf/httpd.conf

 <IfModule alias_module>
     Alias /.well-known/acme-challenge /usr/local/apache2/htdocs/dehydrated
 </IfModule>

**アカウントを登録 [#i08a8024]

 # /usr/local/etc/dehydrated/dehydrated --register --accept-terms

エラーが出た…
 ERROR: Problem connecting to server (get for https://acme-v01.api.letsencrypt.org/directory; curl returned with 60)

ルート証明書が古いことが原因らしいので、新しい証明書を取得。

 # wget https://curl.haxx.se/ca/cacert.pem
 OpenSSL: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
 SSL による接続が確立できません。

 # wget --secure-protocol=SSLv2 https://curl.haxx.se/ca/cacert.pem
 curl.haxx.se|151.101.90.49|:443 に接続しています... 接続しました。
 SSL による接続が確立できません。

ダメだ…。~
手元のパソコンでダウンロードしてからサーバへアップ。屈辱的…

 # cd /etc/pki/tls/certs
 # mv ca-bundle.crt ca-bundle.crt.org
 # mv cacert.pem ca-bundle.crt

 # /usr/local/etc/dehydrated/dehydrated --register --accept-terms

エラーが出た…
 ERROR: Problem connecting to server (get for https://acme-v01.api.letsencrypt.org/directory; curl returned with 35)

opensslのバージョンが古いせいらしい。~
↑これは違うみたい

 # yum update openssl openssl-devel
 Loaded plugins: fastestmirror
 Determining fastest mirrors
 YumRepo Error: All mirror URLs are not using ftp, http[s] or file.
  Eg. Invalid release/
 removing mirrorlist with no valid mirrors: /var/cache/yum/addons/mirrorlist.txt
 Error: Cannot find a valid baseurl for repo: addons

 # vi CentOS-Base.repo

各mirrorlist, baseurlをコメントにし、それぞれ追加

 [base]
 baseurl=http://vault.centos.org/5.5/os/$basearch/
 
 [updates]
 baseurl=http://vault.centos.org/5.5/updates/$basearch/
 
 [addons]
 baseurl=http://vault.centos.org/5.5/addons/$basearch/
 
 [extras]
 baseurl=http://vault.centos.org/5.5/extras/$basearch/
 
 [centosplus]
 baseurl=http://vault.centos.org/5.5/centosplus/$basearch/
 
 [contrib]
 baseurl=http://vault.centos.org/5.5/contrib/$basearch/

curlが古いみたい~
tarをダウンロード~
https://curl.haxx.se/download.html

 # tar xvzf curl-7.58.0.tar.gz
 # cd curl-7.58.0
 # ./configure --enable-libcurl-option
 # make install

改めてアカウントを登録

 # /usr/local/etc/dehydrated/dehydrated --register --accept-terms
 # INFO: Using main config file /usr/local/etc/dehydrated/config
 + Generating account key...
 + Registering account key with ACME server...
 + Done!

これで /usr/local/etc/dehydrated/accounts 以下が生成される。

**証明書の発行 [#v15a4714]

 # /usr/local/etc/dehydrated/dehydrated --config /usr/local/etc/dehydrated/config --cron
 # INFO: Using main config file /usr/local/etc/dehydrated/config
 Processing example.com
  + Signing domains...
  + Generating private key...
  + Generating signing request...
  + Requesting authorization for example.com...
  中略
  + Done!

sedのオプションエラーが出たけど /usr/local/etc/dehydrated/certs/ 以下に証明書が生成されます。

**証明書をApacheに設定 [#cc93ac35]

上記の方法でApacheにSSLの設定をします。

    SSLCertificateFile /usr/local/etc/dehydrated/certs/example.com/fullchain.pem
    SSLCertificateKeyFile /usr/local/etc/dehydrated/certs/example.com/privkey.pem
    SSLCertificateChainFile /usr/local/etc/dehydrated/certs/example.com/chain.pem

**証明書の更新 [#b90e6dc6]

cronで取得時と同様にコマンド実行で可能なようです。

 # /usr/local/etc/dehydrated/dehydrated --config /usr/local/etc/dehydrated/config --cron

**有効期限の確認 [#vdbf9fb2]

 $ openssl s_client -connect example.com:443 < /dev/null 2> /dev/null | openssl x509 -text | grep "Not After"
 Not After : May 11 08:35:01 2018 GMT


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS