- 投稿日:2020-11-25T23:09:38+09:00
Nginx について纏めてみる
Linuc2の学習のために、Nginxについて纏めてみる。
Apacheと同じぐらい利用するが、こちらもあまり細かな設定までは気にしたことがないので、纏めてみた。インストール
私は Amazon Linux2 を良く使いますが、Amazon Linux2 では標準で Nginx の yum 向けパッケージが提供されていません。
そのため、↓の手順で追加する必要がある。
Amazon Linux 2にExtrasレポジトリからNginxをインストールする
主な設定ファイル
ファイル 説明 /etc/nginx/nginx.conf メイン設定ファイル /etc/nginx/conf.d/default.conf デフォルトサーバーの設定ファイル /etc/nginx/conf.d/ssl/conf SSLの設定ファイル /etc/nginx/conf.d/virtual.conf バーチャルホストの設定ファイル 基本書式 :
ディレクティブ 値;
ブロック構造をとるディレクティブもあります。
親ブロックで設定した内容は子ブロックにも引き継がれます。
ディレクティブ{
他のディレクティブ;
...
}
ディレクティブ 説明 コンテキスト include 他の設定ファイルを読み込む 全て user ワーカープロセスの実行ユーザー main worker_processes ワーカープロセス数 main worker_connections 1つのワーカープロセスが同時に処理できるコネクション数 events log_format アクセスログの書式定義 http access_log アクセスログのパスとログレベル http,server,location error_log エラーログファイルのパスとログレベル main,http,server.location listen リクエストを受け付けるポート番号 server server_name サーバー名 server keepalive_requests 一度の接続で受け付けることのできるリクエスト数の上限 http,server,location keepalive_timeout キープアライブのタイムアウトまでの秒数 http,server,location server_tokens バージョン番号の表示 http,server,location root ドキュメントルート http,server,location index インデックスファイル http,server,location autoindex インデックスリスト表示のon/off http,server,location error_page エラーコードとエラーページノURI http,server,location rewrite リダイレクトの設定 server,location コンテキスト内には様々なディレクティブでパラメータを指定します。
例えば、別のサイトへリダイレクトさせるには、次のように設定します。
※一時的なリダイレクトの場合は、permanent を redirect に書き換えます。server { listen 80; server_name www.example.com; rewrite ^(.*)$ http://www.example.net$1 permanent;SSL/TLS
SSL関連のディレクティブ 説明 ssl onなら有効 ssl_certificate サーバー証明書ファイル、中間CA証明書ファイル ssl_certificate_key サーバー秘密鍵ファイル ssl_protocols バージョン ssl_ciphers 暗号アルゴリズム nginx.confhttp { ssl_ciphers:ECDHE-RSA-AES128-SHA; ssl_protocols TLSv1.2; ssl_prefer_server_ciphers on; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; } server { ssl on; listen 443 ssl; server_name www.example.com; ssl_certificate ssl/server.crt; ssl_certificate_key ssl/server.key; root /var/www/html; location / { index index.html index.htm; }Nginx で ssl_protocols や ssl_ciphers を省略するとどうなるのか?
リバースプロキシ
リバースプロキシ関連のディレクティブ 説明 proxy_pass プロキシ先URI proxy_http_version httpのバージョン proxy_set_header プロキシ先に送られるリクエストヘッダの定義 nginx.confserver{ listen 80 default_server; server_name www.example.com; location / { proxy_pass http://192.168.0.1; proxy_set_header 1.1; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }クライアントからのアクセスではなく、リバースプロキシからのアクセスが記録されてしまいます。
そこでヘッダーを書き換えて、本来のアクセス元をWebサーバーが記録できるようにするためには、
proxy_set_header ディレクティブで、Hostヘッダ、X-Real-IPヘッダー、X-Forwarded-Forヘッダーを定義します。
- 投稿日:2020-11-25T22:10:04+09:00
Linaxのコマンドをまとめました。
はじめに
個人アプリの開発を進めていく中で、環境構築をする際Linaxkコマンドに触れることが多くなってきた為、備忘録もかねて今までに出てきたコマンドをまとめました。
ディレクトリに関するコマンド
コマンド 説明 使用例 cd ディレクトリ(フォルダ)移動 cd 移動したいフォルダ名 ls フォルダの内容をリスト形式で表示する 中身をみたいフォルダに移動して、ls pwd 現在いる位置を表示する 現在いる位置を表示する mkdir フォルダを作成する mkdir フォルダ名 touch ファイルを作成する touch ファイル名 rmdir 空のフォルダを削除する rmdir フォルダ名 rm ファイルやフォルダを削除する mv mv ファイルを移動 mv (移動元ファイル名/フォルダ名) (移動先ファイル名/フォルダ名) cat デファイルの内容を表示する cat ファイル名 grep 指定した文字列がテキスト内に存在した場合その行を抽出する grep "検索したい文字" * ファイル名 chmod ファイルやフォルダのアクセス権限を変更する chmod 権限ファイル名 chown ファイルやフォルダのオーナーやグループを変更する chown 変更したいユーザー名 変更したいファイル名 find ファイルの検索をする find / -name ファイル名 diff ファイルとファイルの内容の違いを表示する diff 旧ファイル名 新ファイル名 history コマンドの履歴を表示する - ln ファイルやフォルダにリンクを設定する ln リンク元ファイル名 リンク先ファイル名/フォルダ名 apropos manページの内容を検索する apropos キーワード less テキストファイルを閲覧する less ファイル名 more ファイルをページ単位で閲覧する more ファイル名 clear 消さずに画面を綺麗にする - mv (移動元ファイル名/フォルダ名) (移動先ファイル名/フォルダ名)
ネットワーク関連を設定したい時
コマンド 説明 ssh sshでログインする ftp ファイルをFTPで転送する route ルーティングの表示や設定を行う システム管理したい時
コマンド 説明 free 空きメモリや、使用中メモリを表示する last ファイルをFTPで転送する最近ログインしたユーザー名を表示する finger ユーザー情報を表示する ユーザー管理したいとき
コマンド 説明 useradd/adduser ユーザーを新規作成する deluser ユーザーを削除する groupadd グループを新規作成する groupdel グループを削除する groupadd ルーティングの表示や設定を行う chfn ユーザー情報を変更する コマンドのオプションや使用方法を知りたいとき
man コマンド名
- 投稿日:2020-11-25T18:26:41+09:00
RailsでTimecop/TimeHelpersを使って時刻を変える方法について
この記事は、Happy Elements Advent Calendar 2020の5日目です。
RailsでTimecop/TimeHelpersを使って時刻を変える方法についての記事です。はじめに
ソーシャルゲームでは、イベントが yyyy年mm月dd日に始まるなど、特定の時刻になると発動することが定番です。
これらのようなイベントの動作を確認するために、サーバ側で時刻を変えることができると、動作テストがしやすくなります。
- 例1 12月2日 15:00開始のガチャAの動作確認をするために、サーバの時間を12/2 16時にセットする
- 例2 バグ報告があったので、1ヶ月前のイベントの時間にセットしてバグ調査をする などサーバ側で時刻を変える方法について、以下の3つの方法に絞って調査しました。
- Timecop
- ActiveSupport::Testing::TimeHelpers
- libfaketimeこの記事では、それぞれがどのようなものか、をまとめました。
Timecop
https://github.com/travisjeffery/timecop
こちらはRailsのgemです。
Time/Date/DateTimeクラスのオーバーライドとして実装されているものでした
https://github.com/travisjeffery/timecop/blob/master/lib/timecop/time_extensions.rb調査を進めると、TimeHelpersという物がRailsに組み込まれていることがわかりました。
TimeHelpersは、Timecopより機能としては少なく、時刻を固定させるのみです。
Timecopは、固定の他に、過去や未来に設定した後に時刻が進むなども可能です。TimecopとTimeHelperでは、Timecopの方がリッチな機能である、と言えると思います。
- 標準のTimeHelpersで十分である
- gemを入れたくない
などの場合は、TimeHelpersの利用が選択肢に上がってくると思います。
2020年現在もメンテナンスはされているようです。ActiveSupport::Testing::TimeHelpers
https://edgeapi.rubyonrails.org/classes/ActiveSupport/Testing/TimeHelpers.html
Rails4.1以降で標準のものです。
時刻を固定・解除するのみです。libfaketime
https://github.com/wolfcw/libfaketime
こちらはRailsの話ではなく、OSにインストールして動くサービスです。
システムコールを改変するものです
- メリット
- プログラムを変えなくていい
- デメリット
- 導入が少し手間
システムコールとは?
libfaketimeでシステムコールの話が出てきたので、ここではシステムコールについて。
strace というコマンドを使って、コマンドを打つと大量にログが出てきます。これがシステムコールです(fstat, close, read, ...etc)。
libfaketimeは、このシステムコールを書き換えて時刻を変えるので、TimecopやTimeHelpersよりも深い部分で動いていると言えると思います。strace date execve("/bin/date", ["date"], 0x7ffc3bc97870 /* 28 vars */) = 0 brk(NULL) = 0x55b92bdc6000 openat(AT_FDCWD, "/usr/local/lib/faketime/libfaketime.so.1", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0$\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=66512, ...}) = 0 ... read(4, "@2020-6-16 20:30:00\n", 4096) = 20 close(4) = 0 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}) = 0 write(1, "Tue Jun 16 20:30:00 JST 2020\n", 29Tue Jun 16 20:30:00 JST 2020 ) = 29 close(1) = 0 close(2) = 0 munmap(0x7f46f7935000, 8) = 0 munmap(0x7f46f7936000, 32) = 0 exit_group(0) = ? +++ exited with 0 +++余談
調査中に、もしTimecopとlibfaketimeを同時に使った場合どうなるのだろう、と思いました。
実験してみたところ、Timecopで設定した時刻がRailsでは得られました。libfaketimeで改変された時間を、さらにTimecopが上書きするという順序になります。
イメージ図は以下の通りです。まとめ
自分が運営中のタイトルでは、開発者の手元では、TimeHelpersを使ってRailsの時刻を変えながらイベントの動作確認などに利用しています。libfaketimeも使えるようになっており、必要であればそちらも利用しています。
こちらの記事では、サーバ側で時刻を変える方法について、Timecop, TimeHelpers, libfaketimeを調査しました。
調査してわかりましたが、どれが優れているというものではありませんでした。
それぞれ、やりたいことの要件に合わせて選択すれば良いと思いました。
もしRailsで時刻を変えたいけど、どうしようと悩んで調べている方がいらっしゃいましたら、
参考にしていただけると幸いです。(注) 記事の中の図は自分で用意しました
参考
https://andycroll.com/ruby/replace-timecop-with-rails-time-helpers-in-rspec/
https://techracho.bpsinc.jp/penguin10/2018_12_25/67780
https://qiita.com/ktrkmk/items/b1361dd43d22dcf5627e
https://qiita.com/Targityen/items/67682d6c80cdcbe1186c終わりに
Happy Elements株式会社 カカリアスタジオでは、
いっしょに【熱狂的に愛されるコンテンツ】をつくっていただけるメンバーを大募集中です!もし弊社にご興味持っていただけましたら、是非一度
下記採用サイトをご覧ください。
https://recruit.happyelements.co.jp/
- 投稿日:2020-11-25T12:17:50+09:00
gigafile便に上がっているファイルをwgetする
gigafile便のファイルをwgetでダウンロードしたい
gigafileで100GB近い動画ファイルを送られ、クラウドで再エンコードしてからダウンロードしようとしたところ、cookie関連を知らなくて調べるのにちょっと時間かかったのでメモ
gigafile便のダウンロードボタンのPHPはcookieを使っているみたいで、こうして一旦ダウンロードページのcookieを保存しておく必要があるようです
$ wget --keep-session-cookies --save-cookies=cookies.txt 【ダウンロードページのリンク】 $ wget --load-cookies cookies.txt -r -k -E 【ダウンロードボタンのリンク】この二行でDLが始まります
時間帯によるけど観測した中では最高80MB/sくらいでダウンロードできてました、いいですねぇ
- 投稿日:2020-11-25T09:08:14+09:00
「俺の仮想マシンルーターがこんなに速いはずはないわ」と思って作った件
概要
この記事は @tnishinaga さんの「俺の仮想マシンルーターがこんなに遅いはずはない/ KernelVM online 1」のタイトルを
若干パクってオマージュしたものになります。
「とりあえずそれなりに妥協して動けばいいや」という具合なのでセキュリティとかいろいろ考慮してないのでご了承ください。
(始めに言っておく)まとめいくら VirtIO を有効にしていてもオーバーヘッドとか VM に載せる OS が違ったりすると速度が上がるわけじゃないかもしれないよ
きっかけ
「以前書いた願望」より
そろそろ仮想化に意欲的になったり「IPv6 IPoE」に興味を持ったりしますが、ハードの予算は取れないしガラケーの需要も減りつつあるし周りも「は? 新しいハード? インフラ? インターネットなんてできりゃいいじゃん、そんなのに金使うくらいなら(ry」という感じでかなり消極的だったりですがいつかは新鯖投入して「今使っている PC ルーターの仮想化」に挑戦したいですね(いつとは
買いました
ヤフオクと某なんちゃら給付金を用いて買いました。
- NEC Express5800/S70 タイプRB(@ヤフオク)
- CPU: Xeon X3430
- メモリ: 9[GB]
- GPU: Quadro FX570
- HDD: 320[GB]
- Gigabit LAN カード,Broadcom BCM5751純正ボード1 x2(@amazon.co.jp)
トータルで3万円ぐらいですが、12年前に組んだ Cerelon PC ルーターより安くてグレードが高k(ry
セットアップ
- みんな大好き CentOS 7 x86_64 を Express5800 に
- VM のホストにグローバルな IPv6 のアドレスを付けてなにかやることがないのでローカルホスト以外つけていません。
- VM のゲストにルーターをポンと構築
- 「まぁ多少のオーバーヘッドはしょうがないかー」精神で
- 「フレッツ光ネクスト ギガラインタイプ」相当の線にしたのでどうせなら「フレッツ光ネクスト ハイスピードタイプ」の上限 200[Mbps]以上が出ればほぼ十分
- とりあえず PPPoE のやりとり用に FreeBSD、IPoE のやりとり用に Debian
- 両方 FreeBSD が良かったのですが早く IPoE の線でいろいろ遊びたくてファイアウォールのルールがネットで転がっている Linux に
- 最後のまとめの方にも書いていますが最終的に FreeBSD だけ VirtIO を無効にして e1000e にしています
- ブリッジは OpenvSwitch
- macvtap でも良かったのですが「OpenvSwitch にフレッツ直結してみた」という一例が見当たらなかった
し面白そうだったのでOpenvSwitch にしたのもひとつありますネットワーク構成 / 計測条件
計測サイトは以下を使用しました。
- iperf.scottlinux.com @ iperf3
- SPEED TEST Powered by RBB SPEED TEST @ ブラウザ iperf3 は10秒間のスループットを計測しました。
計測結果
FreeBSD の VM で VirtIO を有効にして PPPoE で外とのやりとりをしたらダウンの速度は出るけどアップの速度が出ないという結果に。それ以外はまぁまぁなところなのかなと
ただ、たまたま FreeBSD で ookla のスピードテストを走らせるとアップの速度が出るようなのでファイアウォール(の PF)あたりがなにか悪さしてるのではないかといらぬ推測をしてみたり・・・
何はともあれとりあえず VirtIO ではなく e1000e にしてお茶を濁すことにして、v4 over v6 のルーターを作ればいいかということにしました。v4 PPPoE でもまぁまぁ使えてますしwまとめ
いくら VirtIO を有効にしていてもオーバーヘッドとか VM に載せる OS が違ったりすると速度が上がるわけじゃないかもしれないよ
おまけ
VPS とかパブリッククラウドなサービスを使ってるわけではないの Public な iperf のサーバーを探して使いましたが日本国内には正直見つからなったのでどなたかやらないですかね?(SoftEther さんや JANOG で見かけた i-measure な皆さんを遠目で見ながら
追加で HDD を投入した関係で Intel NIC だと若干お高くなったので妥協しました。
「蟹は嫌だ…蟹は嫌だ嫌だ…!」「BroadCom!!」↩
- 投稿日:2020-11-25T08:59:24+09:00
【コピペOK】基本的なLinuxコマンド集【18選】
最近、LAMP環境構築を行っているのですが、その中でLinuxコマンドに多く触れる機会があり、知識のストックも溜まってきたので、今回はコマンドの中でも頻出のものを解説していこうと思います。
予備知識
ディレクトリ
簡単に言えばフォルダのこと。
ルートディレクトリ
そのコンピュータ内の全ディレクトリ、ファイルを格納しているディレクトリ。
ホームディレクトリ
ユーザーが抱える全ディレクトリ、ファイルを格納しているディレクトリ。
カレントディレクトリ
現在作業しているディレクトリ。
絶対パス
ルートディレクトリから見たファイルパス。
相対パス
現在作業中のディレクトリから見たファイルパス。
参照系
pwd
ホームディレクトリから、現在作業中のファイルパスを表示。
【記述例】
$ pwd
【出力例】
/Users/username
ls
現在作業中のディレクトリの、保存されているファイルやディレクトリの一覧を表示。
【記述例】
<!-- 一覧を表示 --> $ ls <!-- 隠しファイル(. から始まる)も含めて表示 --> $ ls -a <!-- 権限などの詳細情報を表示 --> $ ls -l <!-- 隠しファイルも含めて権限などの詳細情報を表示 --> $ ls -la
【出力例】
<!-- ls --> Desktop Sinatra Documents Sites ... <!-- ls -a --> .Trash Documents .bundle Downloads ... <!-- ls -l --> drwx------@ 5 username username 160 11 14 16:12 Applications drwx------@ 9 username username 288 11 24 19:55 Desktop ... <!-- ls -la --> drwx------ 2 username username 64 11 21 14:01 .Trash drwxr-xr-x 4 username username 128 10 20 23:12 .bundle ...
cat
ファイルの中身を表示。スクロールはできないので、1画面に収まるような分量の内容の場合に使用。
【記述例】
$ cat exampleFile
【出力例】
<!-- exampleFileの中身の記述 --> これは見本です。
less
ファイルの内容を表示。スクロールが可能。1画面以上の分量の内容の場合に使用。
【記述例】
$ less exampleFile
【出力例】
<!-- exampleFileの中身の記述 --> これは見本です。 . . .
history
実行したコマンドの履歴を表示。
【記述例】
<!-- コマンドの履歴を表示 --> $ history <!-- 最新のコマンドを5つ表示(数字は任意) --> $ history 5 <!-- historyで表示されたナンバリングに対応するコマンドを実行(数字は任意) --> $ !5 <!-- historyで表示されたナンバリングに対応するコマンドを履歴から削除(数字は任意) --> $ history -d 5
【出力例】
<!-- history --> . . . 848 pwd 849 pwd 850 ls 851 ls -a 852 ls -l 853 ls -la 854 cat 855 ls <!-- history 5 --> 851 ls -a 852 ls -l 853 ls -la 854 cat 855 ls <!-- !855(上記なら ls を実行) --> Desktop Sinatra Documents Sites ... <!-- history -d 853 --> <!-- 853 ls -laを削除 --> . . . 851 ls 852 ls -a 853 ls -l 854 cat 855 ls
作成系
mkdir
カレントディレクトリ内に、ディレクトリを新規作成。
【記述例】
$ mkdir exampleFile
touch
カレントディレクトリ内に、ファイルを新規作成。
【記述例】
$ touch exampleFile
削除系
rm
ファイルやディレクトリの削除。通常は出力無しですが、ファイルやディレクトに記述や保存がされている場合、Y(yes) か N(no) で実行確認を要求されます。
【記述例】
<!-- ファイルの削除 --> $ rm exampleFile <!-- ファイルの強制削除(確認無し) --> $ rm -f exampleFile <!-- ディレクトリの削除 --> $ rm -r exampleDirectory <!-- ディレクトリの強制削除 --> $ rm -rf exampleDirectory
複製系
cp
ファイルやディレクトリのコピーを作成。
【記述例】
<!-- exampleFile を exampleFile2 としてコピー作成 --> $ cp exampleFile exampleFile2 <!-- exampleDirectory を exampleDirectory2 としてコピー作成 --> $ cp -r exampleDirectory exampleDirectory2
移動系
cd
カレントディレクトリ(現在作業中のディレクトリ)の移動。絶対パスか相対パスで指定可能。
【記述例】
<!-- ホームディレクトリに移動 --> $ cd <!-- exampleDirectory に作業場所を移動 --> $ cd exampleDirectory <!-- 一階層上のディレクトリに移動 --> $ cd ..
mv
ファイルの移動や、ファイル名の変更が可能。絶対パスか相対パスで指定可能。
【記述例】
<!-- exampleDirectory1 にある exampleFile1 を exampleDirectory2 に移動 --> $ mv exampleDirectory1/exampleFile1 exampleDirectory2 <!-- exampleFile2 の名前を exampleFile3 に変更 --> $ mv exampleFile2 exampleFile3
便利系
clear
画面をリフレッシュする。
【記述例】
$ clearまたは「control」+「L」でも可能。
shutdown
OSをシャットダウンする。
【記述例】
$ shutdown -h now
ユーザー系
useradd
ユーザーの新規追加。(この時、ユーザー用のホームディレクトリも作成される)
【記述例】
<!-- example と言うユーザー名でユーザー新規作成 --> $ useradd example
passwd
新規作成したユーザーのパスワードを新規登録、既存のユーザーのパスワード変更。(本番環境では"鍵認証"と言う別の認証方法を利用する事が多い)
【記述例】
<!-- example と言うユーザー名のパスワードを変更 --> $ passwd example
userdel
ユーザーの削除。
【記述例】
<!-- example ユーザーの削除 --> $ userdel example <!-- example ユーザーの削除と、削除したユーザーのホームディレクトリも削除 --> $ userdel -r example
su
ユーザーの切り替え。
【記述例】
<!-- example ユーザーに切り替え(カレントディレクトリは同じ) --> $ su example <!-- example ユーザーに切り替え(そのユーザーのホームディレクトリから開始) --> $ su - example
exit
ユーザーのログアウト。多重にログインしている場合は、元のユーザーに戻る。
【記述例】
<!-- 現在使用しているユーザーのログアウト --> $ exit
まとめ
Linuxディストリビューション(Linux系のOS)での環境構築などをする際は、頻繁にLinuxコマンドを使用するので、解説した基本的なコマンドは、ある程度使い慣れておくと役立ちます。
macなら「ターミナル」
Windowsなら「Power Shell」
これらで実行できますので、ぜひお試しください。最後までご覧いただき、ありがとうございました!
筆者:yuki|学習10日目で初案件獲得→現在はフルスタックエンジニア転職に向けて学習中
Qiita:https://qiita.com/yuki4839
Twitter:https://twitter.com/yuki35522891
- 投稿日:2020-11-25T02:47:18+09:00
Let's EncryptでECDSAかつワイルドカードを含むサーバ証明書を発行する
前提条件
DNSサーバ(BIND9)が導入済み
その他のDNSサーバやRoute 53などは環境に応じて書き換えてください。発行先のドメイン名が *.example.jp, example.jp
鍵生成アルゴリズムが ECDSA P_256
生成されるファイルは下記の通り
- privkey.pem (秘密鍵)
- cert.pem (サーバ証明書)
- chain.pem (中間証明書)
- fullchain.pem (サーバ証明書+中間証明書)
- csr.pem (証明書署名要求)[中間ファイル]
検証環境
bash$ uname -sr Linux 4.18.0-193.6.3.el8_2.x86_64 $ cat /etc/redhat-release CentOS Linux release 8.2.2004 (Core) $ openssl version OpenSSL 1.1.1c FIPS 28 May 2019 $ certbot --version certbot 1.9.0 $ named -v BIND 9.11.13-RedHat-9.11.13-6.el8_2.1サーバ証明書生成スクリプトの作成
ユーザは
root
、カレントディレクトリは/root/cert
で作業していきます。1. メインのスクリプト
/root/cert/update-cert.sh#!/bin/bash # ECDSAで秘密鍵を生成する # -out に出力される秘密鍵のファイル名 今回は「privkey.pem」 openssl ecparam \ -genkey \ -name prime256v1 \ -out privkey.pem # 証明書署名要求(CSR)を生成する # -key にひとつ前で指定した秘密鍵のファイル名 # -subj に完全修飾ドメイン名(FQDN) 今回は「*.example.jp」 詳しくは少し下の'補足1'を参照 # -out に出力されるCSRのファイル名 openssl req \ -new \ -config openssl.cnf \ -key privkey.pem \ -subj '/CN=*.example.jp' \ -out csr.pem # 公開鍵に署名してもらう (公開鍵はひとつ前のコマンドでCSRに格納されています) # -m にメールアドレス # -d にFQDN 今回は「*.example.jpとexample.jp」 詳しくは少し下の'補足2'を参照 # --csr にひとつ前で指定したCSRのファイル名 # --manual-auth-hook にトークンをDNSに追加するスクリプト # --manual-cleanup-hook にトークンをDNSから削除するスクリプト certbot certonly \ -n \ --manual \ --agree-tos \ --manual-public-ip-logging-ok \ -m 'admin@example.jp' \ -d '*.example.jp' \ -d 'example.jp' \ --preferred-challenges=dns \ --csr csr.pem \ --manual-auth-hook ./dns-auth.sh \ --manual-cleanup-hook ./dns-cleanup.sh # サーバ証明書をリネームする # この場合、実行時の日付ディレクトリに生成物が移動されます DESTDIR=$(date +'%F') mkdir $DESTDIR mv privkey.pem $DESTDIR/ mv 0000_cert.pem $DESTDIR/cert.pem mv 0000_chain.pem $DESTDIR/chain.pem mv 0001_chain.pem $DESTDIR/fullchain.pemメインのスクリプトはここまでです。
まだ実行しても正常に動作しません。
2. opensslのコンフィグ
openssl.cnf
を作成します。
コピペして末尾2行を書き換えてください。今回は最小限の設定しませんが、コピー元は
/etc/pki/tls/openssl.cnf
にあります。/root/cert/openssl.cnf[ req ] default_md = sha256 distinguished_name = req_distinguished_name string_mask = utf8only req_extensions = v3_req # サブジェクトの初期値を設定 # opensslコマンドの-subjオプションで指定しているため空欄のままで大丈夫です [ req_distinguished_name ] commonName_default = [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation,digitalSignature,keyEncipherment subjectAltName = @alt_names # 以下のFQDNは任意のものに置き換えてください 今回は「*.example.jpとexample.jp」 [ alt_names ] DNS.1 = *.example.jp DNS.2 = example.jp3. DNSSECの鍵を生成
nsupdate
コマンドを使用してトークンをDNSサーバのレコードに追加、削除するための鍵ペアを生成します。bash# # -n HOST に任意の名前 今回は「_acme-challenge.example.jp」 # # ドメイン名にするのが無難です # dnssec-keygen -r /dev/urandom -a HMAC-SHA256 -b 128 -n HOST _acme-challenge.example.jp K_acme-challenge.example.jp.+163+25871 # # 実行すると2種類のファイルが生成されます。 # # [出力された文字列].key と [出力された文字列].private # ls | grep _acme-challenge.example.jp K_acme-challenge.example.jp.+163+25871.key K_acme-challenge.example.jp.+163+25871.private4. トークンをDNSサーバのレコードに追加するスクリプト
dns-01認証で発行されるトークンをDNSサーバのレコードに追加する処理を書きます。
BINDの場合はnsupdate
コマンドを使用しますが、Route 53などは環境に応じた処理に置き換えてください。
Cloudflare DNSのサンプルはCertbotのドキュメント1にあります。/root/cert/dns-auth.sh#!/bin/bash # -k に項番号3で生成されたファイル名 今回は「K_acme-challenge.example.jp.+163+25871.private」 # server に更新するのDNSサーバのIPアドレスまたはドメイン名 今回は「ns1.example.jp」 # update に更新する処理 ドメイン名は環境に応じて置き換えてください。 # ドメイン名の最後に「.」を忘れずに入れてください。 今回は「_acme-challenge.example.jp.」 # $CERTBOT_VALIDATIONにトークンが代入されています。 cat << EOF | nsupdate -k 'K_acme-challenge.example.jp.+163+25871.private' server ns1.example.jp update add _acme-challenge.example.jp. 3600 TXT $CERTBOT_VALIDATION send EOF # 反映されるまで適当に待つ sleep 305. トークンをDNSサーバのレコードから削除するスクリプト
dns-01認証終了後にDNSサーバからレコードを削除する処理を書きます。
項番号4と同様に環境に応じて置き換えてください。/root/cert/dns-cleanup.sh#!/bin/bash # 項番号4のコメントに同じ cat << EOF | nsupdate -k 'K_acme-challenge.example.jp.+163+25871.private' server ns1.example.jp update delete _acme-challenge.example.jp. send EOFDNSサーバの設定
nsupdate
コマンドを受け入れるようにDNSサーバの設定を変更します。bash# # サーバ証明書生成スクリプトの作成の項番号3で生成されたファイルを開いて # # Key の値をコピーします 今回は「thisISdnsSECexampleKEY==」 # cat K_acme-challenge.example.jp.+163+25871.private Private-key-format: v1.3 Algorithm: 163 (HMAC_SHA256) Key: thisISdnsSECexampleKEY== Bits: AAA= Created: 20201119190706 Publish: 20201119190706 Activate: 20201119190706以下、DNSサーバ
/etc/named.conf# named.conf にDNSSECの鍵を追記する # key に項番号3で指定した値 今回は「_acme-challenge.example.jp.」 # 項番号3で指定した値が含まれていないとエラーになるみたいです # secret にひとつ前でコピーしたKey 今回は「thisISdnsSECexampleKEY==」 key "_acme-challenge.example.jp." { algorithm hmac-sha256; secret "thisISdnsSECexampleKEY=="; };/etc/named/example.jp.conf# ドメインの更新を許可する # key にひとつ前で設定した名前を指定する 今回は「_acme-challenge.example.jp.」 zone "example.jp" { type master; # ...(省略)... allow-update { key _acme-challenge.example.jp.; }基本的なDNSサーバの設定は他のサイトを参考にしてください。
テスト
サーバ証明書を発行する前にDNS-01認証のテストを行います。
cert-update.sh
に--dry-run
のオプションを追加して一度実行します。/root/cert/update-cert.sh# ...省略... # certbotコマンドの末尾に--dry-runを追記します certbot certonly \ -n \ --manual \ --agree-tos \ --manual-public-ip-logging-ok \ -m 'admin@example.jp' \ -d '*.example.jp' \ -d 'example.jp' \ --preferred-challenges=dns \ --csr csr.pem \ --manual-auth-hook ./dns-auth.sh \ --manual-cleanup-hook ./dns-cleanup.sh --dry-run # ↑ 追記 # ...省略...実行後に以下のように表示されればテストは成功です。
bash# ./update-cert Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator manual, Installer None Performing the following challenges: dns-01 challenge for example.jp dns-01 challenge for example.jp Running manual-auth-hook command: ./dns-auth.sh Running manual-auth-hook command: ./dns-auth.sh Waiting for verification... Cleaning up challenges Running manual-cleanup-hook command: ./dns-cleanup.sh Running manual-cleanup-hook command: ./dns-cleanup.sh IMPORTANT NOTES: - The dry run was successful. mv: '0000_cert.pem' を stat できません: そのようなファイルやディレクトリはありません mv: '0000_chain.pem' を stat できません: そのようなファイルやディレクトリはありません mv: '0001_chain.pem' を stat できません: そのようなファイルやディレクトリはありません
The dry run was successful.
と表示されなかった場合はエラーの内容から該当箇所を修正してください。
--dry-run
オプションはサーバ証明書が発行されないためmv
コマンドでエラーが表示されています。テストに成功したら
--dry-run
オプションを外して実行します。
update-cert.sh
にサーバ証明書のシンボリックリンクを張る処理やサービス再起動の処理を追記してもいいと思います。cronの設定
ここまで実装したらスクリプトの実行も自動化します。
サーバ証明書の有効期限が3ヶ月のため2ヶ月に1度サーバ証明書を更新します。
下記の例は2,4,6,8,10,12月の18日午前3時36分に更新されます。
認証サーバが混み合わないように0時0分などを避けて適当な日時にしておきます。
出力を/dev/null
に捨てるのはやめましょう。# crontab -e36 3 18 2,4,6,8,10,12 * /root/cert/update-cert.sh >> /var/log/update-cert.log参考サイト
User Guide — Certbot 1.10.0.dev0 documentation
Bind9でDynamicDNSを構築 - K'z Arch@K'z Style(ケイズ・スタイル)
User Guide — Certbot 1.10.0.dev0 documentationのPre and Post Validation Hooks項 ↩