Memo

メモ > サーバ > 各論: エトセトラ

■OS
■Linuxの歴史 Multics: 1965年にMITとAT&Tベル研究所とジェネラル・エレクトリック社で開発されたOS OSという概念が生まれたころ、多目的なOSを作ろうと作成されたOS 多くの機能が搭載されたが、当時のハードウェアでは能力不足で使い物にならなかった UNIX: 1969年にアメリカのベル研究所で開発されたOS シンプルで軽いことが売り(今はPCの性能が上がったが、サーバ管理には余計なリソースを使わないOSの方が好ましい) Multicsとは逆に、当初はシングルタスクOSだった そのため、ラテン語で「単一の」を意味する「uni(ユニ)」をもとにMulticsをもじってUNICSと名付けられ、後にUNIXと改名した ソースコードが公開されていたため爆発的に人気が出たが、しばらくしてライセンス契約制になり、徐々に縛りはきつくなった BSD: 1978年にカリフォルニア大学バークレー校の開発者グループが開発した 「BSD」は「Berkeley Software Distribution」の略称とされている オリジナルのUNIXを改良したOSで、派生版としてFreeBSDやmacOSが作成された Linux: 1991年にフィンランドの学生であるリーナスさんが開発した 「UNIXは良いものだけど、ライセンスの縛りが面倒」というところに反発して作られたので、UNIXを真似て独自に一から開発された ソースコードは無料で公開されライセンス料も求めなかったため、広く利用されるようになった 3分間で人に説明できるようになるUnixとLinuxの違い https://eng-entrance.com/unix_linux 「MacはLinuxだった」って本当? 「そうだね……」元Mac雑誌編集者は昔語りを始めた:ヤマーとマツの、ねえこれ知ってる?(1/4 ページ) - ITmedia NEWS https://www.itmedia.co.jp/news/articles/2201/26/news077.html ■Linuxディストリビューション Linuxはオープンソースなので、多くの独自Linuxが存在する 以下に「Red Hat Enterprise Linux」系統と「Debian」系統を記載する Red Hat Enterprise Linux(RHEL): Red Hat社が開発した企業向けのLinux(企業向けとは言え、Linuxの規約上ソースコードは公開されている) Linuxは無償だがサポートが無い 一方RHELはサポートや責任面で安心感を得られるため、企業に多く導入された Fedora: Red Hat社が支援するコミュニティー「Fedora Project」によって開発されているLinux 積極的に先進的な技術を取り入れている CentOS: Red Hat社が公開したソースコードをもとに、商標や商用パッケージを除外して作成されたLinux もともと Red Hat社の許可を得ずに作られていたが、後に承認を得た 有償サポートはなく、開発も当然ながらRHELよりもワンテンポ遅れる Amazon Linux: CentOS6をもとにAmazon Linuxが作られ、CentOS7をもとにAmazon Linux 2が作られた Debian: ボランティアが中心になって開発を進められているLinux 100%フリーソフトウェアであり続けると宣言されている Ubuntu: Debianをベースに「誰にでも使いやすい最新かつ安定したOS」を目指して作られた フリーソフトとして提供されている Raspberry Pi OS: Debianをベースに、Raspberry Pi用の子供向けの教育用および小規模な開発者向けに作られた 【目的別】初心者におすすめのLinuxディストリビューション7選 https://eng-entrance.com/linux_beginner_distribution ■OSのサポート期間 各OSのリリース日とサポート終了日を表にまとめてみた - Qiita https://qiita.com/yunano/items/4757f86f9e92bb4f503f ■Linuxの起動処理 systemd超入門 | Developers.IO https://dev.classmethod.jp/cloud/aws/systemd-getting-started/ systemd エッセンシャル http://redhat.lookbookhq.com/systemd-essential Linuxがブートするまで - Keichi Takahashi https://keichi.net/post/linux-boot/
■Linuxのディレクトリ構成
bin ... 一般ユーザ、管理ユーザ向けコマンド。ブートするときに必要な、システムの基本コマンド。binaries sbin ... 管理ユーザ向けコマンド。ブートするときに必要な、管理ユーザ用コマンド etc ... 設定ファイル。Editable Text Configuration(後付の意味) lib ... binやsbinなどに置かれたコマンドやプログラムが利用するライブラリ module ... カーネルモジュール lib64 ... 64bitライブラリ opt ... Linuxインストール後、追加でインストールしたパッケージ(ソフトウェア) dev ... デバイスファイル(ハードウェアもファイルとして扱うという、Linuxの設計思想のため) sys ... ドライバ関連のプロセス srv ... システムに提供された固有のデータ proc ... プロセスファイルシステム。カーネルの情報 boot ... システムの起動に必要なブートローダ関連のファイルや、カーネルイメージ lost+found ... システムのバックアップや復元用 mnt ... 外部記憶装置を配置するディレクトリ(スワップなど) media ... 外部記憶装置を自動的に配置するディレクトリ(CD-ROMなど) root ... rootユーザのホームディレクトリ tmp ... 一時的なファイル。リブートすると消える var ... システム運用中にサイズが変化するファイル。頻繁に書き換えられるデータファイル。variable log ... ログファイル spool ... メールやプリンタジョブ蓄積場所 run ... 起動中サーバのプロセスID tmp ... 一時的なファイル。リブートしても消えない www ... Webサーバ用のデータ usr ... 読み出しが可能でユーザが共有できるファイル bin ... 一般ユーザ、管理ユーザ向けコマンド。ブートのときには使用しない、平常時用の基本コマンド sbin ... 管理ユーザ向けコマンド。ブートのときには使用しない、平常時用のシステム管理コマンド lib ... ライブラリ share ... 筋腫に依存しないファイル local ... Linuxインストール後、追加でインストールしたパッケージ。bin, sbin, lib などにあたるコマンド home ... 一般ユーザのホームディレクトリ Filesystem Hierarchy Standard - Wikipedia https://ja.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Linuxの基本の基本。Linuxの基本的なディレクトリ構成 http://oxynotes.com/?p=5987 Linuxのディレクトリ構造(一覧)を理解する http://www.linuxmaster.jp/linux_skill/2010/02/06linux.html なぜ,/var や /etc が /etc や /cfg というディレクトリ名ではないのか? http://d.hatena.ne.jp/ytakano/20100715/1279219401 WindowsのあのフォルダはUNIX/Linuxで言えばあそこだ http://qiita.com/yuba/items/669f718fe6e62dbaab19 Linuxディレクトリ構造 - Qiita https://qiita.com/nys9302/items/a8ddeedd3cd9d0deb332
■Linuxのログファイル
トラブルがあった場合など、ログファイルの内容を確認することで調査の手掛かりになることがある 主なログファイルには、以下のようなものがある /var/log/cron /var/log/httpd/access_log /var/log/httpd/error_log /var/log/maillog /var/log/messages /var/log/secure ログファイルについての詳細は、Command.txt の「ログを確認」も参照
■Linuxのソースコード
Linuxのコアである、カーネルのソースコードは以下にある リーナスさんが管理しているのはLinuxのすべてではなく、公式版のカーネル The Linux Kernel Archives https://www.kernel.org/ Linuxカーネル - Wikipedia https://ja.wikipedia.org/wiki/Linux%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB 以下などを参考に、断片でもいいのでソースコードに触れておきたい 習得すればメリット大!Linuxカーネルをビルドできるようになろう | 日経クロステック(xTECH) https://xtech.nikkei.com/atcl/nxt/column/18/01448/102000002/ Linuxカーネルのソースコードを読んで、システムコールを探る (1/3):main()関数の前には何があるのか(6) - @IT https://www.atmarkit.co.jp/ait/articles/1703/01/news171.html 負荷とは何か - naoyaのはてなダイアリー https://naoya-2.hatenadiary.org/entry/20070222/1172116665 「Hello World!」の中身を探る意義と環境構築、main(C言語)のアセンブラコードの読み方 (1/4):main()関数の前には何があるのか(1) - @IT https://www.atmarkit.co.jp/ait/articles/1703/01/news166.html
■パッケージ管理システム
rpm: Red Hat社が開発した、Linuxのパッケージ管理システム。「アールピーエム」と読む パッケージの依存関係は解決しないが、パッケージを個々に管理するときに使える yum: パッケージ統合管理システム。「ヤム」と読む 内部ではrpmコマンドが実行されている パッケージの依存関係を自動で解決してくれる RHELやCentOSでも利用されている apt: パッケージ統合管理システム。「アプト」と読む DebianやUbuntuなどでは、yum ではなく apt-get などを使用する ubuntuパッケージ管理centosとの対比備忘録 - Qiita https://qiita.com/smallpalace/items/57bf018909644e7c3e70 yumコマンドとAPT系コマンドの違い - Qiita https://qiita.com/hal-bo/items/1e0568120c545bf723c6 ■利用例 yumの場合、例えば
# yum install httpd # yum install nginx
のように、コマンドを実行してアプリケーションのインストールなどを行える Yellowdog Updater Modified https://ja.wikipedia.org/wiki/Yellowdog_Updater_Modified IT業界で横行する恥ずかしい英語発音 http://qiita.com/ryounagaoka/items/290885ee3291b393fe1f yum 名前の由来 http://poormemory.seesaa.net/article/356576330.html 以下のようにすると、インストール済みのアプリケーションを一覧できる そのままだと大量に表示されるので、grepで絞り込んで表示するといい
# yum list installed # yum list installed | grep postfix
インストール済パッケージを一括アップデートする場合、以下のようにする 実行後はOS自体を再起動するといい
# yum -y update
個別にアップデートを行う場合、以下のようにする 必要に応じて関連するサービスの再起動を行う
# openssl version # yum list openssl # yum update openssl # service httpd restart
■有名どころのリポジトリ EPEL: 「Extra Packages for Enterprise Linux」の略 RHELやCentOS向けに、デフォルト以外の拡張パッケージを提供している別のリポジトリ Fedoraで開発・テスト・改良された高品質のパッケージを、RHELやCentOSのような互換ディストリビューションで利用可能にすることを目的としている Remi: RetHat社に務めている「remi collet」さんという人がメンテンナンスしている外部のパッケージ RedHat社はCentOSの元になったRedHat Linuxの提供元 EPELに依存しているので、Remiを使うにはあらかじめEPELのインストールが必要 Webtatic: 更新されたWeb関連のパッケージを含むRHELやCentOSリポジトリ RHELやCentOS向けに、Web開発/ホスティングソフトウェアの最新の安定したマイナーリリースを提供する こちらでもPHP7が提供されている Amazon Linux Extras: AWSのAmazon Linuxで利用できるリポジトリ OSの安定性を確保しつつ、最新のソフトウェアを利用できるようにするために提供されている 以下はRemiからPHP7.1をインストールする場合の例
# yum -y install epel-release … EPELのリポジトリを追加 # rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm … Remiのリポジトリを追加 # yum -y install --enablerepo=remi-php71 … RemiのリポジトリからPHP7.1をインストール
なお、登録されているリポジトリは
# yum repolist
で確認できる 「yum install epel-release」や「--enablerepo=remi」の意味,本当に理解して使ってますか? - akamist blog https://akamist.com/blog/archives/648 yumリポジトリ一追加リスト 完全版 http://qiita.com/bezeklik/items/9766003c19f9664602fe
■バックグラウンドで処理を実行する(簡易な方法)
プログラムを実行する際に & を付けると、バックグラウンドで実行できる プログラムを停止したい場合、kill で該当のプログラムを停止する 以下は挙動を確認するための簡易なプログラム
$ vi hello.sh
#!/bin/bash while true do echo "Hello World." >> hello.log sleep 1 done
以下のようにすると通常実行できる 1秒ごとに「Hello World.」というテキストが hello.log に出力される 「Ctrl+C」でキャンセルできる
$ chmod 0755 hello.sh $ ./hello.sh Hello World. Hello World. Hello World. Hello World. Hello World.
以下のように & を付けると、バックグラウンドで実行される psコマンドで実行を確認できる
$ ./hello.sh & [1] 5412 $ ps aux | grep hello pi 5412 0.0 0.0 4496 2916 pts/0 S 18:18 0:00 /bin/bash ./hello.sh pi 5501 0.0 0.0 4016 612 pts/0 S+ 18:19 0:00 grep --color=auto hello $ kill 5412
以下のように nohup も付けておくと、ユーザがログアウトしても処理が維持される また、nohup を付けた場合は同階層の nohup.out にログが出力される この場合も、プログラムの停止は kill で行う
$ nohup ./hello.sh & [1] 5543
以下のようにすると、nohup.log にechoの内容が表示され、error.log にエラーが出力される
$ vi hello.sh
#!/bin/bash while true do echo "Hello World." sleep 1 done
$ nohup ./hello.sh > nohup.log 2> error.log & [1] 5780
Linuxコマンド(Bash)でバックグラウンド実行する方法のまとめメモ - Qiita https://qiita.com/inosy22/items/341cfc589494b8211844 プロセス管理: nohup, disown, kill - Heavy Watal https://heavywatal.github.io/dev/nohup.html 【 nohup 】コマンド――端末を閉じてもログアウトしても処理を続ける:Linux基本コマンドTips(137) - @IT https://www.atmarkit.co.jp/ait/articles/1708/24/news022.html サーバの接続切れてもコマンドを実行する ~ nohup - 忘れないようにメモっとく http://akiniwa.hatenablog.jp/entry/2013/08/26/163655 nohup コマンドで任意の場所にログを出力する方法 - 約束の地 https://obel.hatenablog.jp/entry/20180208/1518054980 SSH 接続先でサーバを立ち上げっぱなしにしてログアウトするための Bash の書き方 - Corredor https://neos21.hatenablog.com/entry/2018/09/26/080000 nohupで実行したコマンドの出力をnohup.out以外のファイルに保存する https://kazmax.zpp.jp/linux/nohup_stdout.html nohup コマンド - Qiita https://qiita.com/sinsengumi/items/759ce48e844a46ed8091 nohupとリダイレクトを自分のために調べてみた - Qiita https://qiita.com/TsuyoshiUshio@github/items/6ef090795eae6ffaa903 Linux: nohupと&の違い - Qiita https://qiita.com/wifecooky/items/a4856e200212858f8c99 以下によると、nohupは「デーモンとして実行するための貧弱な方法」とされている デーモンについては、このファイル内にある「バックグラウンドで処理を実行する(サービス)」も参照 unix - What's the difference between nohup and a daemon? - Stack Overflow https://stackoverflow.com/questions/958249/whats-the-difference-between-nohup-and-a-daemon
■バックグラウンドで処理を実行する(Supervisor)
Supervisor を実際に操作してデーモン化に触れてみる https://www.ritolab.com/entry/224 Supervisorの基本コマンド - Qiita https://qiita.com/mokkos/items/473978ef0699df3173f5 Supervisorは、プロセスを監視して落ちたら起動しなおしてくれたりするツール(つまりデーモン化できる) Supervisorを起動すると、設定している管理対象も一緒に起動してくれる 「無限ループで処理するプログラムをバックグラウンドで実行しておけばいいが、落ちた場合の対処を考えたい」のような場合に有効そう (systemdでも同じことは実現できるが、Supervisorだと「root権限で無くても起動や停止ができる」などのメリットがあり、手軽に利用できるようになる) EC2のAmazon Linux 2にSupervisorを導入する - Breath Note https://blog.shinki.net/posts/amazon-ilnux-2-supervisor Amazon Linux 2にSupervisorを設定する - ハマログ https://blog.e2info.co.jp/2021/04/11/amazon-linux-2_supervisor/ Supervisor入門(AmazonLinux2 + Supervisor4系) インストールからハマったポイント|スクショはつらいよ https://chariosan.com/2019/11/10/supervisor4_al2/ Amazonlinux2でsupervisorを動かすまで - zuntan02のはてなブログ https://zuntan02.hateblo.jp/entry/2019/06/27/205849 amazon linuxにsupervisorを入れたメモ - Qiita https://qiita.com/abouch/items/3f4b422c7d9048936629 Supervisorの使用方法 - TASK NOTES https://www.task-notes.com/entry/20170311/1489224418 SupervisorでLaravelのQueue worker管理 | ソフトウェア開発のギークフィード https://www.geekfeed.co.jp/geekblog/laravel_queue_with_supervisor/ ■準備 下準備として以下を実行しておいたが、今回の検証では恐らく無くても大丈夫
# localectl set-locale LANG=ja_JP.UTF-8 # localectl status # timedatectl set-timezone Asia/Tokyo # timedatectl status # yum -y install httpd # vi /etc/httpd/conf/httpd.conf # service httpd start # chkconfig httpd on # yum -y install php php-mbstring php-gd
■インストール CentOS7の場合、yumでインストールする
# yum install supervisor # curl -o /etc/rc.d/init.d/supervisord https://raw.githubusercontent.com/Supervisor/initscripts/master/redhat-init-equeffelec # chmod 755 /etc/rc.d/init.d/supervisord
Amazon Linux 2 の場合、yumではインストールできない 以下のようにpip経由でインストールする
# pip3 -V pip 20.2.2 from /usr/lib/python3.7/site-packages/pip (python 3.7) # pip3 install supervisor WARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead. Collecting supervisor Downloading supervisor-4.2.2-py2.py3-none-any.whl (743 kB) |■■■■■■■■■■■■■■■■| 743 kB 23.2 MB/s Installing collected packages: supervisor Successfully installed supervisor-4.2.2 # supervisord -v 4.2.2
なお Amazon Linux 2 でも、起動した時期によってはpip3が使えない その場合は先にpip3をインストールする AmazonLinux2でPython3環境構築 - Qiita https://qiita.com/hiren/items/17984191da2ab8955174
$ python -V Python 2.7.18 $ pip --version -bash: pip: コマンドが見つかりません $ pipenv --version -bash: pipenv: コマンドが見つかりません $ sudo yum install -y python3 $ python3 -V Python 3.7.10 $ pip3 --version pip 20.2.2 from /usr/lib/python3.7/site-packages/pip (python 3.7)
■設定 以下はAmazon Linux 2の場合に作業する(CentOS7の手順でインストールした場合、作成済みになっている)
# mkdir /etc/supervisord.d # mkdir /var/log/supervisor # vi /etc/logrotate.d/supervisor
/var/log/supervisor/*.log { missingok weekly notifempty nocompress }
ログローテートについては、Basis.txt の「ログ保存期間を設定」も参照 以降はCentOS7とAmazon Linux 2のどちらの場合も必要な作業 ただしCentOS7の場合、3箇所ある /usr/local/bin という箇所を /usr/bin にする(supervisord がここに置かれているため)
# echo_supervisord_conf > /etc/supervisord.conf # cp -p /etc/supervisord.conf /etc/supervisord.conf.org # vi /etc/supervisord.conf
;logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log logfile=/var/log/supervisor/supervisord.log ;pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid pidfile=/var/run/supervisord.pid ;[include] ;files = relative/directory/*.ini [include] files = supervisord.d/*.ini
# vi /etc/systemd/system/supervisord.service
[Unit] Description=Supervisor process control system for UNIX Documentation=http://supervisord.org After=network.target [Service] ExecStart=/usr/local/bin/supervisord -n -c /etc/supervisord.conf ExecStop=/usr/local/bin/supervisorctl $OPTIONS shutdown ExecReload=/usr/local/bin/supervisorctl $OPTIONS reload KillMode=process Restart=on-failure RestartSec=50s [Install] WantedBy=multi-user.target
■起動と確認 設定が終わったら起動する
# systemctl start supervisord # systemctl status supervisord ● supervisord.service - Supervisor process control system for UNIX Loaded: loaded (/etc/systemd/system/supervisord.service; disabled; vendor preset: disabled) Active: active (running) since 木 2021-12-23 15:38:20 JST; 2s ago Docs: http://supervisord.org Main PID: 453 (supervisord) CGroup: /system.slice/supervisord.service └─453 /usr/bin/python3 /usr/local/bin/supervisord -n -c /etc/supervisord.conf 12月 23 15:38:20 ip-10-1-0-201.ap-northeast-1.compute.internal systemd[1]: supervisord.service holdoff time over, scheduling restart. 12月 23 15:38:20 ip-10-1-0-201.ap-northeast-1.compute.internal systemd[1]: Stopped Supervisor process control system for UNIX. 12月 23 15:38:20 ip-10-1-0-201.ap-northeast-1.compute.internal systemd[1]: Started Supervisor process control system for UNIX. 12月 23 15:38:21 ip-10-1-0-201.ap-northeast-1.compute.internal supervisord[453]: 2021-12-23 15:38:21,080 CRIT Supervisor is running as root...age. 12月 23 15:38:21 ip-10-1-0-201.ap-northeast-1.compute.internal supervisord[453]: 2021-12-23 15:38:21,081 WARN No file matches via include "...ini" 12月 23 15:38:21 ip-10-1-0-201.ap-northeast-1.compute.internal supervisord[453]: 2021-12-23 15:38:21,086 INFO RPC interface 'supervisor' in...ized 12月 23 15:38:21 ip-10-1-0-201.ap-northeast-1.compute.internal supervisord[453]: 2021-12-23 15:38:21,086 CRIT Server 'unix_http_server' run...king 12月 23 15:38:21 ip-10-1-0-201.ap-northeast-1.compute.internal supervisord[453]: 2021-12-23 15:38:21,086 INFO supervisord started with pid 453 Hint: Some lines were ellipsized, use -l to show in full.
プログラムのデーモン化を試す CentOS7の場合、「ec2-user」というユーザ名では無いので、適宜調整する
# vi /home/ec2-user/hello.sh
#!/bin/sh while true do sleep 5s echo "hello "`date` done
# vi /etc/supervisord.d/hello.ini
[program:hello] directory=/home/ec2-user command=/bin/sh hello.sh user=root autostart=true autorestart=true stdout_logfile=/home/ec2-user/hello.log redirect_stderr=true
# systemctl restart supervisord # systemctl status supervisord
以下でログが出力され続けていることを確認できる
# tail -f /home/ec2-user/hello.log
以下で管理対象になっていることが確認できる
# supervisorctl status hello RUNNING pid 4395, uptime 0:00:06
以下のようにプロセスを強制終了させても、すぐに新しく起動されることが確認できる
# ps aux | grep hello root 4395 0.0 0.0 115412 1492 ? S 15:07 0:00 /bin/sh hello.sh root 4463 0.0 0.0 112812 972 pts/0 R+ 15:09 0:00 grep --color=auto hello # kill 4395 # ps aux | grep hello root 4466 0.0 0.0 115408 1448 ? S 15:09 0:00 /bin/sh hello.sh root 4469 0.0 0.0 112812 976 pts/0 S+ 15:09 0:00 grep --color=auto hello
また、/etc/supervisord.d/hello.ini を削除してから supervisord を再起動すると、上記のプロセスは現れなくなる ■挙動の確認 以下で停止と再開ができる ini ファイルで autostart と autorestart が true に設定されている場合、「systemctl restart supervisord」によって自動的に起動される
# supervisorctl status hello RUNNING pid 4682, uptime 0:00:18 # supervisorctl stop hello hello: stopped # supervisorctl status hello STOPPED Dec 28 03:24 PM # supervisorctl start hello hello: started # supervisorctl status hello RUNNING pid 4698, uptime 0:00:02
以下で管理対象からの除外と再追加ができる ini ファイルで autostart と autorestart が true に設定されていても、「systemctl restart supervisord」によって自動的に起動されない
# supervisorctl status hello STOPPED Dec 28 03:27 PM # supervisorctl stop hello hello: stopped # supervisorctl remove hello hello: removed process group # supervisorctl status # supervisorctl add hello hello: added process group # supervisorctl status hello RUNNING pid 4765, uptime 0:00:08
■トラブル: インストール時にエラー CentOS7の場合はyumでインストールできるようだが、Amazon Linux 2の場合はインストールできなかった 上記のとおり、pipでインストールできた
# yum install supervisor 読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd パッケージ supervisor は利用できません。 エラー: 何もしません
■トラブル: 起動時にエラー 色々なページの解説どおりに進めても、以下のエラーになって起動できなかった エラーの例
# systemctl start supervisord # systemctl status supervisord ● supervisord.service - Supervisor process control system for UNIX Loaded: loaded (/etc/systemd/system/supervisord.service; disabled; vendor preset: disabled) Active: activating (auto-restart) (Result: exit-code) since 木 2021-12-23 15:26:18 JST; 17s ago Docs: http://supervisord.org Process: 32763 ExecStart=/usr/bin/supervisord -n -c /etc/supervisord.conf (code=exited, status=203/EXEC) Main PID: 32763 (code=exited, status=203/EXEC) 12月 23 15:26:18 ip-10-1-0-201.ap-northeast-1.compute.internal systemd[1]: supervisord.service failed.
/var/log/messages を確認すると、以下のエラーになっていた
Dec 23 06:32:09 ip-10-1-0-201 systemd: Started Supervisor process control system for UNIX. Dec 23 06:32:09 ip-10-1-0-201 systemd: Failed at step EXEC spawning /usr/bin/supervisord: No such file or directory Dec 23 06:32:09 ip-10-1-0-201 systemd: supervisord.service: main process exited, code=exited, status=203/EXEC Dec 23 06:32:09 ip-10-1-0-201 systemd: Unit supervisord.service entered failed state. Dec 23 06:32:09 ip-10-1-0-201 systemd: supervisord.service failed.
「/usr/bin/supervisord が存在しない」となっている /usr/bin のパスを /usr/local/bin に修正すると起動できた(インストール方法によっては、ファイルの場所が異なるみたい)
# systemctl daemon-reload # systemctl start supervisord # systemctl status supervisord
なお「systemctl daemon-reload」はキャッシュクリアのようなものだと思われる systemctl daemon-reload って何 - Qiita https://qiita.com/taro-hida/items/ec187c0fae893177e575 ■トラブル: supervisorctlコマンドを使用できない いつの間にかsupervisorctlコマンドが使えなくなっていたので、対応したときのメモ supervisordを再起動する
$ sudo /usr/local/bin/supervisorctl version unix:///tmp/supervisor.sock no such file $ sudo service supervisord restart $ sudo /usr/local/bin/supervisorctl version 4.2.5
ec2-userで .bash_profile の最終行に設定を追加
$ vi .bash_profile $ source ~/.bash_profile
追加した内容は以下のとおり
alias sudo='sudo env PATH=$PATH'
以下のとおり、呼び出せるようになった
$ sudo supervisorctl status artisan-queue:artisan-queue_00 RUNNING pid 28312, uptime 0:02:34 artisan-schedule:artisan-schedule_00 RUNNING pid 28313, uptime 0:02:34
■バックグラウンドで処理を実行する(サービス)
UNIXではバックグラウンドプロセス(常駐プログラム)を「デーモン」と呼ぶ daemonはギリシャ語由来の言葉で「精霊」「守護者」の意味。善でも悪でもない、目には見えない霊的存在を指す 転じて、バックグラウンドで動作して様々な雑務をこなしてくれるプロセスをデーモンと呼ぶようになった (なお、「悪魔」はdemonなのでスペルが異なる) 「サービス」も同じ意味で使われる 一例だが、以下のようにしてApacheのサービスを起動できる
# service httpd start
■nohup とデーモンの違い デーモンのざっくりした定義としては以下らしい 1. バックグランドで動作している 2. 制御端末を持たない 3. 他のプロセスグループに属さない 4. 親プロセスが init nohup は3・4を満たしてないので、デーモンとは言わないみたい systemd や supervisord などでサービス化されてるものはデーモンと呼んで良さそう supervisord については、前述の「バックグラウンドで処理を実行する(Supervisor)」を参照 nohup コマンド - Qiita https://qiita.com/sinsengumi/items/759ce48e844a46ed8091 unix - What's the difference between nohup and a daemon? - Stack Overflow https://stackoverflow.com/questions/958249/whats-the-difference-between-nohup-and-a-daemon ■サービスの起動方法が複数ある経緯 直接起動する場合
# /usr/sbin/apachectl start
他のサービスと同じような手順で扱えるようにするため、起動スクリプトが用意された 内部では /usr/sbin/apachectl を呼んでいる(/etc/rc.d/init.d/httpd をviなどで開けば、内容を確認できる)
# /etc/rc.d/init.d/httpd start
/etc/rc.d/init.d/ から /etc/init.d/ にシンボリックリンクが張られているので、以下のコマンドでも可能
# /etc/init.d/httpd start
さらに環境変数の影響を受けにくいようにした 内部では /etc/init.d/httpd を呼んでいる(/sbin/service をviなどで開けば、内容を確認できる)
# service httpd start
CentOS7からは、systemctlコマンドで行うようになった。serviceでも可能だが、systemctlコマンドにリダイレクトされる
# systemctl start httpd.service
apacheの起動について https://okwave.jp/qa/q1237460.html apachectlコマンドとhttpdの違い http://www.wegirls.tech/entry/2016/09/29/075200 デーモンの起動・終了にはserviceコマンドを利用しよう http://heartbeats.jp/hbblog/2013/06/service-start-stop.html 起動スクリプト(httpd)を読んでみた - まどろみの思考空間 http://hogespace.hatenablog.jp/entry/2013/06/13/222637 Systemdを使ってさくっと自作コマンドをサービス化してみる - Qiita https://qiita.com/DQNEO/items/0b5d0bc5d3cf407cb7ff ■設定を再読込 設定ファイルを編集して反映させたいだけなら、以下で十分かも。 restartでなければ反映されない項目もあるかも。要検証
# service httpd reload
■サービスを作成 実行すると「Hello World.」という文字を出力し続けるだけのプログラムを作成
# cd /opt/ # vi hello.sh
#!/bin/bash while true do echo "Hello World." >> /tmp/hello.log sleep 1 done
# chmod 0755 hello.sh # ./hello.sh
例えば以下のようにすると、バックグラウンドで処理できる
# nohup ./hello.sh & # ps aux | grep hello root 4030 0.0 0.2 113284 1408 pts/0 S 23:18 0:00 /bin/bash ./hello.sh root 4168 0.0 0.1 112812 972 pts/0 S+ 23:20 0:00 grep --color=auto hello $ kill 4030
このプログラムを、サービスとして起動する まずは以下に、Unit定義ファイルを作成する ファイル中にある「Restart = always」は、プロセスやサーバが不意に落ちた時に自動再起動するモード
# vi /etc/systemd/system/hello.service
[Unit] Description = hello daemon [Service] ExecStart = /opt/hello.sh … 実行したいファイルの場所を絶対パスで指定 Restart = always Type = simple [Install] WantedBy = multi-user.target
これでサービスを作成できた 以下、動作確認
# systemctl list-unit-files -t service | grep hello … サービスの状態を確認(Unitがサービスとして認識されたか確認) hello.service disabled # systemctl enable hello … サービスの自動起動を有効化 Created symlink from /etc/systemd/system/multi-user.target.wants/hello.service to /etc/systemd/system/hello.service. # systemctl list-unit-files -t service | grep hello … サービスの自動起動を確認 hello.service enabled # systemctl start hello … サービスを起動 # systemctl status hello … サービスの起動を確認 ● hello.service - hello daemon Loaded: loaded (/etc/systemd/system/hello.service; enabled; vendor preset: disabled) Active: active (running) since 日 2021-01-10 23:26:05 JST; 23s ago Main PID: 4274 (hello.sh) CGroup: /system.slice/hello.service ├─4274 /bin/bash /opt/hello.sh └─4310 sleep 1 1月 10 23:26:05 localhost.localdomain systemd[1]: Started hello daemon. # systemctl stop hello … サービスを停止 # systemctl disable hello … サービスの自動起動を無効化 # systemctl list-unit-files -t service | grep hello … サービスの自動起動の無効化を確認 hello.service disabled
Systemdを使ってさくっと自作コマンドをサービス化してみる - Qiita https://qiita.com/DQNEO/items/0b5d0bc5d3cf407cb7ff Linuxコマンド(Bash)でバックグラウンド実行する方法のまとめメモ - Qiita https://qiita.com/inosy22/items/341cfc589494b8211844 nohupをとデーモンの違いは何ですか? http://www.366service.com/jp/qa/295e6c772018443ae515774ff6d83538
■処理の進捗を表示
Linux環境なら、pvをインストールしておくと便利そう MySQL インポートの進捗表示 - Qiita http://qiita.com/hiroq/items/efd8c3580c9c9457c869 Linuxメモ : パイプ処理の進捗を表示するpv(Pipe Viewer)の使い方 - もた日記 http://wonderwall.hatenablog.com/entry/2017/08/03/072500
■Gitなしで差分を管理
※試行錯誤中 以下の仕組みで定期的にファイル一覧を記録しておき、 その結果をdiffコマンドなどで比較することで、差分を管理できるかもしれない ファイル数が多すぎるとエラーになるようなので注意(どれくらいのファイル数が上限なのかは未確認)
# mkdir /var/www/vhosts/test/log # chown apache. /var/www/vhosts/test/log # vi /var/www/vhosts/test/list.sh
LC_ALL=C ls -dl $(find /var/www/vhosts/test/html) | grep '^[^d]' > /var/www/vhosts/test/log/`date +'%Y%m%d-%H%M%S'`.log
# chown apache. /var/www/vhosts/test/list.sh # chmod 744 /var/www/vhosts/test/list.sh # vi /etc/crontab
00 09 * * * apache /var/www/vhosts/test/list.sh
上記コマンドは、以下をもとに作成した。 ls -lコマンドの結果をサブディレクトリ含めてフルパスで列挙したい - Qiita https://qiita.com/dwatarub/items/768c5eb263b49198952e Linux: LSコマンドでファイルのみ・ディレクトリのみを表示する方法 - Qiita https://qiita.com/frozencatpisces/items/9e09f55ede49ef0c64dd grepでこういう時はどうする? - Qiita https://qiita.com/hirohiro77/items/771ffb64dddceabf69a3 以下は最終的には使わなかったが、一応メモしておく。 ディレクトリの中を再帰的に全部を一覧表示するコマンド4種 - それマグで! https://takuya-1st.hatenablog.jp/entry/2015/02/18/151623 findコマンドの使い方: UNIX/Linuxの部屋 http://x68000.q-e-d.net/~68user/unix/pickup?find findで特定のディレクトリを除外 - Qiita https://qiita.com/snaka/items/928d0d47f67bcee600b0 findコマンドで特定のディレクトリ以下を無視する方法 - mollifier delta blog https://mollifier.hatenablog.com/entry/20090115/1231948700 複数のディレクトリを除外してfindしてあれこれする https://gist.github.com/kiyotune/3825822 findコマンドの-pruneオプションのススメ | roshi.tv::blog https://www.roshi.tv/2011/02/find-prune.html findコマンドで複雑な検索条件を設定する - Qiita https://qiita.com/catfist/items/5504511fa5a028fc7c41
■C言語でプログラムを作成する流れ
■gccの確認 gccはGNUが作成しているフリーのCコンパイラ Linuxではコンパイラはこれを使えばいい
$ gcc -dumpversion 4.4.7
※単に「gcc」のみだと「gcc: no input files」というエラーになる ※gccがインストールされていない場合、以下のコマンドで開発ツールを一括インストールできる
# yum -y groupinstall "Base" "Development tools"
■ライブラリ関数 カーネル(kernel。英語で「核」)がLinuxOSの核 ハードウェアを操作するためのソフトウェア部品のことをデバイスドライバ、略してドライバと呼ぶ ドライバを扱えるのはカーネルだけで、カーネルに仕事を頼むためにはシステムコールと呼ばれる仕組みを使用する C言語では、システムコールもライブラリ関数も見た目や使い方は変わらない 関数はLinuxが用意しているライブラリに収められている ライブラリは色々なものがあるが、C言語の重要な命令(例えば printf や exit など)は 標準Cライブラリ(standard C library)、通称libcに格納されている Linuxが普段使用するlibcはGNUが管理するGNU libcで、略してglibcと呼ばれる ■Hello, world!
$ mkdir hello $ cd hello/ $ vi hello.c
#include <stdio.h> int main(int argc, char *argv[]) { printf("Hello, world!\n"); return 0; }
$ ls hello.c $ gcc hello.c $ ls a.out hello.c $ ./a.out Hello, world!
■出力ファイル名を指定
$ gcc -o hello hello.c $ ./hello Hello, world!
■ソースコードからインストール
基本的に以下の流れでインストールする ただし yum や apt-get など、できるだけコマンドでインストールする方がバージョンアップなど管理が楽
$ cd /usr/local/src … 作業ディレクトリに移動 $ wget https://example.com/example-2.1.tar.gz … ソースコードの圧縮ファイルを取得 $ tar -xvf example-2.1.tar.gz … 圧縮ファイルを展開 $ cd example-2.1 … 展開して作成されたディレクトリ内に移動 $ ./configure … インストール環境を調査し、その状況を記述したMakefileファイルを作成 $ make … configureで作成されたMakefileをもとにして、ソースコードをコンパイル $ make install … makeで生成されたバイナリファイルなどを、規定のディレクトリにコピー(インストール)
./configure;make;make installにはどんな意味がある? http://www.itmedia.co.jp/help/tips/linux/l0302.html configure, make, make install とは何か - Qiita https://qiita.com/chihiro/items/f270744d7e09c58a50a5 Makefile ことはじめ - Qiita https://qiita.com/kasei-san/items/ad25df63260e86c5cc71 C言語を使うならMakeを使おうよ - Qiita https://qiita.com/j8takagi/items/74232a00cc33623f7844 cやc++をビルドしたいので ./configureスクリプトの作り方調べた - Qiita https://qiita.com/hadashiA/items/9da2b424965952707a6d make - make installはどこにインストールされる?(77528)|teratail https://teratail.com/questions/77528 makeを使ってソフトウェアをビルドしてみよう:仕事で使える魔法のLAMP(8) - @IT https://www.atmarkit.co.jp/ait/articles/1106/07/news131.html
■アクセス権メモ
■パーミッションとグループ パーミッションとは、ファイルの「読み込み」「書き込み」「実行」の権限のこと パーミッションは ・オーナーの「読み込み」「書き込み」「実行」権限 ・グループの「読み込み」「書き込み」「実行」権限 ・その他の「読み込み」「書き込み」「実行」権限 と、計9つの属性を設定する オーナー・グループ・その他の意味は以下のようになります。 オーナー ... ファイルの所有者 グループ ... ファイルの所有者が属するグループ 他人 ... ファイルの所有者以外の人(Webブラウザでアクセスしてくる人も含む) パーミッションは「-rwsr-xr-x」のように表示される (最初の「-」はファイルを表す。ディレクトリの場合は「d」となる) アルファベットの意味は ・「r」が表示されていれば読み込み可能。 ・「w」が表示されていれば書き込み可能。 ・「x」が表示されていれば実行可能。 ・「-」が表示されていれば権限無し。 となっており、左からオーナー・グループ・その他 となっている 例えば -rw-r--r-- … オーナーに読み込みと書き込みの権限が与えられており、グループとその他の人に読み込みの権限が与えられている -rwx---r-x … オーナーに読み込みと書き込みと実行の権限が与えられており、その他の人に読み込みと実行権限が与えられている -rwxrwxrwx … すべての人にすべての権限が与えられている となる パーミッションを数値で表す場合、このアルファベットの並びを3桁ずつの2進数に見立て、それを10進数に直す 以下は実際の例 -rw-r--r-- … 110 100 100 と見立てる。110を10進数で表すと6、100は4なので「644」となる -rwx---r-x … 111 000 101 と見立てる。111を10進数で表すと7、000は0、101は5なので「705」となる -rwxrwxrwx … 111 111 111 と見立てる。111を10進数で表すと7なので「777」となる ■SUID(Set User ID)
# ls -l /usr/bin/passwd -rwsr-xr-x. 1 root root 30768 2月 22 20:48 2012 /usr/bin/passwd ↑sになっている。どのユーザがプログラムを実行した場合でも、ファイルの所有者の権限で実行される これにより、root権限の無い一般ユーザが /etc/shadow を編集できる
SUIDとは http://www.itmedia.co.jp/enterprise/articles/0804/08/news014.html Linux: SUID、SGID、スティッキービットまとめ - Qiita https://qiita.com/aosho235/items/16434a490f9a05ddb0dc ■SGID(Set Group ID) どのユーザがプログラムを実行した場合でも、グループの所有者の権限で実行される ■SUIDとSGIDの確認
# find / -perm -4000 -o -perm -2000
ざっくり概要!Linuxセキュリティに関する基礎知識まとめ https://eng-entrance.com/linux-security-basic ■スティッキービット
# ls -ld /tmp drwxrwxrwt. 5 root root 4096 5月 7 17:53 2016 /tmp ↑tになっている。実際のパーミッションに関係なく、ファイルもしくはディレクトリの所有者と、rootユーザーのみが名前の変更と削除を行える すべてのユーザーがファイルやディレクトリを作成できるようにしたいが、作成したファイルやディレクトリを他人が消せないようにしたい という場合に使用される
■ユーザの停止
逆引きUNIXコマンド/ユーザアカウントをロック・アンロックする方法・usermodコマンド http://linux.just4fun.biz/?%E9%80%86%E5%BC%95%E3%81%8DUNIX%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89/%E3%8...
# usermod -L xxxxx … ユーザ xxxxx をロック(パスワードで認証できなくなる) # usermod -U xxxxx … ユーザ xxxxx のロックを解除
以下の方法でもロック&解除できる
# passwd -l xxxxx # passwd -u xxxxx
以下で確認し、パスワードのフィールド(コロン区切りで2つ目の値)の先頭に「!」が追加されていればロック中
# cat /etc/shadow
上記の方法は、どちらもパスワード認証のロック。鍵認証には影響しないので注意 鍵認証の場合は一例だが、以下の方法でロック&解除できる(鍵ファイルを読めないようにしてロック)
# chmod 000 /home/xxxxx/.ssh/authorized_keys … ユーザ xxxxx をロック # chmod 600 /home/xxxxx/.ssh/authorized_keys … ユーザ xxxxx のロックを解除
■鍵の変換
id_rsa⇒pem⇔ppk 相互変換 | Punio Kid Works http://www.puniokid.com/tips/linux/69/ SSH秘密鍵 id_rsa -> putty形式&OpenSSH形式に変換 - Qiita https://qiita.com/dskst/items/391fc55018fbf3cf795e ■id_rsa → ppk 1. PuTTYgenを起動 2. 「Load」ボタンをクリックしてid_rsaを開く 3. 「Save private key」ボタンをクリックしてppkファイルを保存 ■ppk → pem 1. PuTTYgenを起動 2. 「Load」ボタンをクリックしてppkファイルを開く 3. メニューの「Conversions → Export OpenSSH key」でエクスポート ■pem → ppk 1. PuTTYgenを起動 3. メニューの「Conversions → Import Key」でpemファイルを選択し、任意でパスワードを設定 3. 「Save private key」ボタンをクリックしてppkファイルを保存
■ユーザのシェルログイン制御
以下の方法で、シェルの使用を禁止・許可することができる シェルログインを禁止した状態でも、SSHトンネル接続でデータベースにアクセスしたりはできるみたい(要検証)
# usermod -s /sbin/nologin xxxxx … ユーザ xxxxx のシェルログインを禁止する # usermod -s /bin/bash xxxxx … ユーザ xxxxx のシェルログインを許可する
■FTPを使用する
FTP、FTPS、SFTP、SCP:ファイル転送プロトコルを解説 | Integrate.io https://www.integrate.io/jp/blog/the-complete-guide-to-ftp-ftps-sftp-and-scp-ja/ FTP・FTPS・SFTP・SCPの違いについて FTPS でデータを適切に保護 - Ipswitch https://www.ipswitch.com/amp/jp/how-to-properly-protect-data-with-ftps/UGd2YmFta0lRZDd4VDJlUWwwalRJb... 暗黙的FTPSモードと明示的FTPSモードについて
■SFTP用ユーザの追加(鍵認証なし)
※SFTPは実質SSHなので、ユーザ追加の手順はSSHと同じ
# vi /etc/ssh/sshd_config
PasswordAuthentication yes … パスワード認証を許可
# useradd webmaster # passwd webmaster # usermod -a -G apache webmaster
■FTP用ユーザの追加(グループで管理)
※公開ディレクトリ上位の権限をapacheに変更、 グループに読み書き実行権限を付与、 FTPユーザにapacheグループを追加、 という手順でアップロードを許可している。以下参考。
# adduser --shell /sbin/nologin --home /var/www/vhosts/main/ refirio-main # passwd refirio-main # adduser --shell /sbin/nologin --home /var/www/vhosts/pre/ refirio-pre # passwd refirio-pre # usermod -a -G apache refirio-main # usermod -a -G apache refirio-pre # chown apache. /var/www/vhosts/main/ # chown apache. /var/www/vhosts/pre/ # chmod 775 /var/www/vhosts/main/ # chmod 775 /var/www/vhosts/pre/
■シェルの設定を即座に反映させる
シェルの設定はログインしなおしたときに反映されるが、sourceコマンドで即座に反映させることができる
# vi ~/.bash_profile # source ~/.bash_profile
【 source 】コマンド/【 . 】コマンド――シェルの設定を即座に反映させる:Linux基本コマンドTips(169) - @IT https://www.atmarkit.co.jp/ait/articles/1712/21/news015.html
■時差
JST 日本標準時 UTC+0900 UTC 協定世界時 UTC+0000 PDT 米国太平洋標準時(夏時間) UTC-0700 などがある。AWSのサーバメンテナンスなど、JST以外で告知されることは多いので注意 計算がややこしければ、以下などで確認するといい 例えば 「On May 30, 2019 between 2:00 PM and 2:10 PM PDT」 は、日本時間では 「2019年5月31日の6時〜6時10分」 となる。「2:00 PM」という表記にも注意 時差計算 https://www.jisakeisan.com/
■Cronを使用する
# vi /etc/crontab
で設定できる 実行ユーザ名を省略すると、root権限で実行されるので注意 (プログラムからログファイルを作成した場合などに、所有者がrootのファイルとなる) /etc/crontabと/etc/cron.d設定ファイルの書き方 | server-memo.net http://www.server-memo.net/tips/etc-crontab.html cronの日時指定を、基礎から学ぶ(分,時,日,月,曜日の指定、◯分ごと、月末起動、など) - YoheiM .NET https://www.yoheim.net/blog.php?q=20190902 「crontab -e」でも設定できるが危険 crontab -e は「絶対に」使ってはいけない http://d.hatena.ne.jp/ozuma/20120711/1342014448 ただしcrontabコマンドで編集すれば、書式に問題があれば教えてくれるというメリットはある viでファイルを直接編集する場合は、書式チェックはされないので注意 書式自体に問題がある場合、Cron自体が動かずにエラーメールも届かないみたい Cronでの定期実行用ファイルは、以下に置くこともできる それぞれの意味は、後述の「定期実行用のファイルを置く場合」を参照 /etc/cron.d /etc/cron.daily /etc/cron.hourly /etc/cron.monthly /etc/cron.weekly /etc/anacrontab ユーザごとのcronは /var/spool/cron/ 内に実行ユーザ名のファイルに記録される 具体的には以下のようなファイルに記録される(Webminでcronを登録した場合も、ここに記録される) /var/spool/cron/apache /var/spool/cron/root 【違い】/etc/crontabと/var/spool/cron/[user] - Qiita https://qiita.com/takahashi-kazuki/items/77d669d4414c6ec185f9 Cronの実行結果は以下に記録される /var/log/cron ■Cronの設定例 一例だが、/etc/crontab で以下のように設定する
# 1分ごとに実行 * * * * * root /root/sample.sh # 5分ごとに実行 */5 * * * * root /root/sample.sh # 毎時20分に実行 20 * * * * root /root/sample.sh # 毎日1時に実行 0 1 * * * root /root/sample.sh # 毎月1日9時に実行 0 9 1 * * root /root/sample.sh
■Cron実行結果のエラーを無視する 以下のように「 >> /dev/null 2>&1」を追加すると、処理中にエラーや警告が発生してもメール通知されない ただしエラーを無視する場合、別途実行ログを残す仕組みの構築を推奨
*/5 * * * * root /root/sample.sh >> /dev/null 2>&1
いい加減覚えよう。 `command > /dev/null 2>&1`の意味 - Qiita https://qiita.com/ritukiii/items/b3d91e97b71ecd41d4ea [Server & Network] Crontab: スクリプトを定期的に実行しログを残す http://www.d-wood.com/blog/2013/09/16_4644.html cron で > /dev/null して椅子を投げられないための3つの方法 http://sfujiwara.hatenablog.com/entry/20120613/1339547638 ■Cron実行結果を任意のログファイルに記録 「 >> 」でのリダイレクト先をファイルにすると、ログを記録できる
*/1 * * * * apache /usr/bin/php /var/www/html/cron/test.php >> /var/www/html/cron/cron.log 2>&1
■Cron実行結果を任意のメールアドレスに通知 ※未検証 以下のようにすることで、任意のメールアドレスに通知できるらしい 「2>&1」とすることで、標準エラー出力もメールで送信できるらしい
0 * * * * /usr/local/sbin/test.sh 2>&1 | mail example@example.com
まとめサイト: cron で実行されたコマンドから出力されたメッセージをメールで送信する方法 https://chibitcpu.blogspot.com/2012/10/cronmail.html ■Cron実行結果を通知しない Cron設定ファイルで「MAILTO=root」という箇所を「MAILTO=""」に変更すると通知されなくなる 定時実行プログラム CRON からのメール通知を無効化する https://ez-net.jp/article/AA/lfeElXBI/SYxriXSrub2c/ Anacronの場合も同様に、/etc/anacrontab ファイルを以下のように編集する
#MAILTO=root MAILTO=""
■定期実行用のファイルを置く場合 以下のディレクトリ内にもcron用のファイルを置くことができる /etc/cron.d ... 1分に1回実行される /etc/cron.daily ... 1日に1回実行される /etc/cron.hourly ... 1時間に1回実行される /etc/cron.monthly ... 1ヶ月に1回実行される /etc/cron.weekly ... 1週間に1回実行される /etc/anacrontab ... 1日に1回実行される。その時間に電源が入っていなかったなどがあっても遅延実行される。詳細は後述の「Cronを使用する > Anacronについて」を参照 ■Cronの利用を許可する・禁止する 以下のファイルに、Cronの利用を許可する・禁止するユーザの名前を登録できる ファイルがなければ新規に作成する /etc/cron.allow /etc/cron.deny Linux、「/etc/cron.allow」「/etc/cron.deny」とはなんぞや?|マコトのおもちゃ箱 〜ぼへぼへ自営業者の技術メモ〜 http://piyopiyocs.blog115.fc2.com/blog-entry-703.html ■Cronを2サーバで1分ごとに実行する 「*/2」と書くと「0, 2, 4, 6 ...」分に実行され、 「1-59/2」と書くと「1, 3, 5, 7 ...」分に実行される この設定を2つサーバに行うと、2サーバで1分ごとに実行できる
*/2 * * * * … サーバ1 1-59/2 * * * * … サーバ2
crontabで奇数分や偶数分などに実行する指定を簡単に書く方法 - Qiita https://qiita.com/kawaz/items/e9050dd409cfa56dec6a ■Cronを15秒ごとに実行する よほどのことがなければ1分ごとで問題ないはずだが、参考程度に
* * * * * /var/www/cron/test.php & sleep 15; /var/www/cron/test.php & sleep 15; /var/www/cron/test.php & sleep 15; /var/www/cron/test.php
■Cronを特定の時間以外に実行する 以下のようにすると、3時を除いて実行できる
0 0-2,4-23 * * *
Crontabで特定の時間を除いて毎時実行 #Pistatium http://kimihiro-n.appspot.com/show/5871384039260160 ■Cronの読み方 crontab - Wikipedia https://ja.wikipedia.org/wiki/Crontab 「日本語ではクーロンという読みが慣習的に広く用いられているが、英語では通常クロンまたはクローンと発音する。」 ■Anacronについて anacronとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典 https://wa3.i-3-i.info/word11749.html 「指示した時間に指定したプログラムを動かしてくれる」 「お仕事をする周期を1日単位でしか指定できない」 「お仕事をする時間にコンピュータの電源が切れていたら、次に電源が入ったときに、その間のお仕事をもう一回させることができる」
■SSLを強制する
SSLでないURLにアクセスされたとき、SSLのURLにリダイレクトする方法 Apacheとnginxで方法は異なる またAWSでロードバランサーを使用している場合、そちらで設定することができる ■Apache このファイルの「Apacheでリクエストを操作する」を参照 AWS.txt の「ロードバランサー」の「SSLにリダイレクトさせる(Apache)」も参照 ■nginx このファイルの「nginxでリクエストを操作する」を参照 AWS.txt の「ロードバランサー」の「SSLにリダイレクトさせる(nginx)」も参照 ■ロードバランサー このファイルの「ロードバランサーでリクエストを操作する」を参照 AWS.txt の「ロードバランサー」の「SSLにリダイレクトさせる」も参照
■Apacheでリクエストを操作する
http://www.example.com/school/ 内へのアクセスを https://example.jp/ に転送(リダイレクト)する例(階層を上げて、SSLも強制) school フォルダ直下に .htaccess を作成して設定するものとする ロリポップで設定する場合、「Lolipop.txt」の「HTTPからHTTPSにリダイレクトする」を参照 また特殊文字のエンコードを防ぐため、必要に応じて「[R=301,L]」は「[R=301,L,NE]」にするといい 日本語URLを含むリダイレクトの罠にかかっても無事でいられる2つの対策 https://alaki.co.jp/blog/?p=2394 ■一括指定なら以下
RewriteEngine On RewriteRule ^(.*)$ https://example.jp/$1 [R=301,L]
■個別にURLを並べるなら以下
RewriteEngine On RewriteRule ^$ https://example.jp/ [R=301] RewriteRule ^about/$ https://example.jp/about/ [R=301] RewriteRule ^education/$ https://example.jp/educatio/ [R=301] RewriteRule ^education/kyoto/$ https://example.jp/educatio/kyoto [R=301] RewriteRule ^education/tokyo/$ https://example.jp/education/tokyo [R=301] RewriteRule ^education/fukuoka/$ https://example.jp/education/fukuoka [R=301] RewriteRule ^summary/$ https://example.jp/summary [R=301] RewriteRule ^summary/course001/$ https://example.jp/summary/elementary_training [R=301] RewriteRule ^summary/course003/$ https://example.jp/summary/secondary_specialty [R=301] RewriteRule ^summary/course004/$ https://example.jp/summary/advanced_encouragement [R=301]
リダイレクトの後の処理が実行されてしまう場合、[R=301] の部分を [R=301,L] に変更する 特に理由がなければ [R=301,L] としておく方がいいかもしれない ■トップページにアクセスしたら /about/ にリダイレクトする例
RewriteEngine On RewriteRule ^$ /about/ [R=301,L]
■メモ 正規表現が不要な単純なリダイレクトなら、 RewriteRule ではなく Redirect permanent を使うべきか 要検証 いま復習しておきたい、301リダイレクトの設定あれこれ。|ビリオンプランのスタッフブログ http://www.billionplan.com/blog/seo/redirect-htaccess-301.html
■Apacheにレスポンスタイムを記録
/etc/httpd/conf/httpd.conf のLogFormatに %D を追加するとマイクロ秒単位で、%T を追加すると秒単位でレスポンスタイムが記録される 以下は設定例 LogFormat "%h %l %u %t \"%!414r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D" combined これで、各行の最後に「16255」のような数値が記録されるようになる この場合、処理に16255マイクロ秒、つまり0.016255秒かかったことになる ※1秒 = 1,000ミリ秒 = 1,000,000マイクロ秒 Apacheのレスポンスタイムをログ記録する http://d.hatena.ne.jp/stfuawsc/20090608/1244438262 Apacheのリクエスト処理時間(%T or %D)は正確には何の時間か http://dev.ariel-networks.com/Members/inoue/response-time/ Apacheのレスポンス分析に必要なスクリプトまとめ http://koduki.hatenablog.com/entry/2012/11/24/171534 Apacheのログから応答速度分布やエラー状況を分析する(原始的な方法) http://www.teradas.net/archives/5298/
■Apacheでバーチャルホスト
※一つのサーバに複数のドメイン・サブドメインを割り当てて使用する サーバリソースの有効活用ができる ※バーチャルホストの作成場所は任意だが、 /var/www/html 内に作ると、各バーチャルホスト用に非公開ディレクトリを設けられないので避ける(/var/www/html 自体が公開ディレクトリのため) ここでは /var/www/vhosts 内に作成するものとする。その際の各ディレクトリ名を /var/www/vhosts/example.com/ /var/www/vhosts/pre.example.com/ のようにすると、ドメインが未決定の場合に問題になる また、ドメインが変更される可能性もあるし、複数ドメインが割り当てられる可能性もある よって /var/www/vhosts/example/ /var/www/vhosts/pre_example/ のように作成するほうが良さそう 複数サイトを管理しないのなら、単に product や staging や develop でいいかもしれない が、後から他サイトがつかされる可能性はあるので、案件名が判る文字をディレクトリ名に含めておく方が無難 ※IPアドレスでアクセスしたときはIPアドレスもしくはサーバ名だけが表示されるページにアクセス、 ドメインを指定してアクセスしたら対応するページにアクセス。 とすると管理しやすいかも ※バーチャルホストが不要な案件でも、後々検収環境が追加されたりを想定して、常にバーチャルホストにしておくといいかも ※SSL用の設定は丸ごと移行させないと、デフォルト値が上書きされない状態で反映されるかも?要検証 名前ベースの仮想ホスト http://www.adminweb.jp/apache/virtual/index2.html バーチャルホスト設定(Apache) http://centossrv.com/apache-virtualhost.shtml
# mkdir -p /var/www/vhosts/main/html … バーチャルホスト用ドキュメントルートディレクトリ作成 # vi /etc/httpd/conf/httpd.conf … Apache設定ファイル編集
# # Use name-based virtual hosting. # NameVirtualHost *:80 … コメント解除(バーチャルホスト有効化) # # NOTE: NameVirtualHost cannot be used without a port specifier # (e.g. :80) if mod_ssl is being used, due to the nature of the # SSL protocol. #
# vi /etc/httpd/conf.d/virtualhost.conf … バーチャルホスト設定ファイル作成
<VirtualHost *:80> … httpアクセス ServerName any … デフォルトのアクセスを指定 DocumentRoot /var/www/html </VirtualHost> <VirtualHost *:80> … httpアクセス ServerName refirio.net … refirio.net でアクセスされた場合 DocumentRoot /var/www/vhosts/main/html … /var/www/vhosts/main/html をドキュメントルートとする <Directory "/var/www/vhosts/main/html"> Options Includes ExecCGI FollowSymLinks AllowOverride All Order allow,deny Allow from all </Directory> </VirtualHost>
最低限、以下の記述だけで動作する。Directoryの指定は一箇所にまとめておくとメンテナンスしやすそう
<VirtualHost *:80> ServerName refirio.net DocumentRoot /var/www/vhosts/main/html </VirtualHost>
■SSL(必要に応じて) 続いて、必要に応じてSSL用の設定を行う apacheで複数のSSL設定を行う http://y-stream.blogspot.jp/2011/09/apachessl.html Apache2.2 の VirtualHost を SSL を使うサイトにも適用 http://qiita.com/da0shi/items/70572e1da228795e0d4b vi http://ext.omo3.com/vi/index.html ApacheでSSL(https)で複数のバーチャルホストの設定 http://istks.net/2322 なおApache 2.2.12以降ならSNIに対応しているので、バーチャルホストで複数のSSL証明書を利用できる 詳細は後述の「1サーバに複数のSSL証明書を設定する」を参照
# vi /etc/httpd/conf/httpd.conf
NameVirtualHost *:80 NameVirtualHost *:443 … 追加する
# vi /etc/httpd/conf.d/ssl.conf … ApacheSSL設定ファイル編集
<VirtualHost _default_:443> の項目をすべてコメントアウトする (「<VirtualHost _default_:443>」と「</VirtualHost>」の行も含めてコメントアウトする) たとえ内容がカラでも、後で設定する「<VirtualHost *:443> 〜 </VirtualHost>」が反映されないため
# vi /etc/httpd/conf.d/virtualhost.conf … バーチャルホスト設定ファイル編集
<VirtualHost *:443> … httpsアクセス ServerName refirio.net … refirio.net でアクセスされた場合 DocumentRoot /var/www/vhosts/main/html … /var/www/vhosts/main/html をドキュメントルートとする ErrorLog logs/ssl_error_log … 以降はSSL用の設定 TransferLog logs/ssl_access_log LogLevel warn SSLEngine on SSLProtocol all -SSLv2 -SSLv3 SSLCipherSuite DEFAULT:!EXP:!SSLv2:!DES:!IDEA:!SEED:!RC4:!3DES:!RSA SSLCertificateFile /etc/httpd/conf/ssl.crt/refirio.net.20170410.crt SSLCertificateKeyFile /etc/httpd/conf/ssl.key/refirio.net.20170410.key SSLCertificateChainFile /etc/httpd/conf/ssl.crt/ica.refirio.net.20170410.crt </VirtualHost>
もともと ssl.conf の VirtualHost 内にあった設定を記載し、 さらに ServerName や SSLCertificateFile の設定を追加している ■動作確認
# chown refirio. /var/www/vhosts/main/html/ … ドキュメントルートの所有者を「refirio」に変更 # ll /var/www/ … ドキュメントルートの所有者を確認 合計 24 drwxr-xr-x 2 root root 4096 10月 5 11:45 cgi-bin drwxr-xr-x 3 root root 4096 10月 9 00:19 error drwxr-xr-x 5 refirio refirio 4096 9月 27 17:43 html drwxr-xr-x 3 root root 4096 9月 27 09:29 icons # service httpd configtest … 設定ファイルの構文をチェック # service httpd restart … httpdを再起動 httpd を起動中: [ OK ] # vi /var/www/vhosts/main/html/index.html … テストページ作成
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>テスト / main</title> </head> <body> <p>テスト / main</p> </body> </html>
■サブドメインなしでのアクセス refirio.net で /var/www/html を表示し、 test.refirio.net で /var/www/vhosts/test/html を表示するような場合、 上の設定を行うと /var/www/html へアクセスできなくなる可能性がある。 その場合、以下のように /var/www/html へのアクセスを明示的に設定する。
<VirtualHost *:80> ServerName refirio.net DocumentRoot /var/www/html </VirtualHost>
IPアドレス経由でのアクセスなら、以下のように設定できる。
<VirtualHost *:80> ServerName 203.0.113.1 DocumentRoot /var/www/html </VirtualHost>
もしくは以下のように、最初に any を定義しておくとデフォルトのアクセスを指定できる
<VirtualHost *:80> ServerName any DocumentRoot /var/www/html </VirtualHost>
一つのApacheサーバーで複数ドメインのサイトを公開する方法 | 技術系のメモ https://humble-mumble.com/apache-multiple-sites/ ■エイリアスの指定 ※未検証 同じディレクトリに複数のドメインを割り当てる場合、 ServerName のセットをいくつも並べなくても ServerAlias で対応できる mod_rewrite と組み合わせれば、ドメイン統一のためのリダイレクトも対応できる バーチャルホストのサーバ名別名でVirtualHost設定を簡素に - Qiita https://qiita.com/Vit-Symty/items/eb7d98a1576e93b3b130 ■ログでバーチャルホストを区別 バーチャルホスト https://httpd.apache.org/docs/2.0/ja/logs.html#virtualhosts バーチャルホストごとにApacheログを分けない場合、どのアクセスがどのバーチャルホストに対してのアクセスなのか区別できなくなる /etc/httpd/conf/httpd.conf のLogFormatに「%v」と書いておくと test.refirio.net のような値として記録されるので、必要なら調整する 以下は設定例
LogFormat "%h %l %u %t \"%!414r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D %{X-Forwarded-For}i %{X-Forwarded-Proto}i %v" combined
test.refirio.net のような値ではなく、例えばサブドメイン「test」でアクセスした際に「test」と記録したい場合、以下のように設定する 「combined_test」の部分は、他のログ設定と重複しない値にする 以下は設定例
<VirtualHost *:80> ServerName test.refirio.net DocumentRoot /var/www/test LogFormat "%h %l %u %t \"%!414r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D %{X-Forwarded-For}i %{X-Forwarded-Proto}i test" combined_test CustomLog logs/access_log combined_terraport env=!no_log </VirtualHost>
ただしバーチャルホストが増えると管理しづらいので、前に挙げた方法を推奨 ■ワイルドカード http://203.0.113.1/ http://refirio.work/ http://www.refirio.work/ http://test1.refirio.work/ http://test2.refirio.work/ のようなURLでアクセスできるようにする サブドメインに応じたディレクトリを参照するようにし、サブドメインの追加はディレクトリの追加のみでできるようにする
名前 種別 内容 A 203.0.113.1 * A 203.0.113.1
以下のように設定する
# mkdir -p /var/www/vhosts/203.0.113.1/html # echo "refirio.work" > /var/www/vhosts/203.0.113.1/html/index.html # mkdir -p /var/www/vhosts/refirio.work/html # echo "refirio.work" > /var/www/vhosts/refirio.work/html/index.html # mkdir -p /var/www/vhosts/www.refirio.work/html # echo "www.refirio.work" > /var/www/vhosts/www.refirio.work/html/index.html # mkdir -p /var/www/vhosts/test1.refirio.work/html # echo "test1.refirio.work" > /var/www/vhosts/test1.refirio.work/html/index.html # mkdir -p /var/www/vhosts/test2.refirio.work/html # echo "test2.refirio.work" > /var/www/vhosts/test2.refirio.work/html/index.html # vi /etc/httpd/conf.d/virtualhost.conf
<VirtualHost *:80> ServerName refirio.work ServerAlias *.refirio.work … ワイルドカードでアクセスできるようにする VirtualDocumentRoot "/var/www/vhosts/%0/html" … 「%0」には「203.0.113.1」「refirio.work」「www.refirio.work」のような値が入る <Directory "/var/www/vhosts/*/html"> … すべてのディレクトリに対して設定 Options Includes ExecCGI FollowSymLinks AllowOverride All Order allow,deny Allow from all </Directory> </VirtualHost>
# service httpd restart
なお、常に同じディレクトリを参照させるなら、以下の指定のみで対応できる
# vi /etc/httpd/conf.d/virtualhost.conf
<VirtualHost *:80> ServerName refirio.work ServerAlias *.refirio.work DocumentRoot /var/www/html <Directory "/var/www/html"> Options Includes ExecCGI FollowSymLinks AllowOverride All Order allow,deny Allow from all </Directory> </VirtualHost>
ムームーDNSでワイルドカードをご利用いただけるようになりました! | ムームードメイン https://muumuu-domain.com/?mode=info&id=3039 VirtualDocumentRootを使って複数ドメインをスッキリ管理(Apache) - y-kawazの日記 http://d.hatena.ne.jp/y-kawaz/20110725/1311610727 【apache】VirtualDocumentRootで、ディレクトリを作るだけでサブドメインが作れる at softelメモ https://www.softel.co.jp/blogs/tech/archives/2189
■Apacheでエイリアス
※未検証 Apache | Aliasディレクティブ:特定のパスへのリクエストに対してドキュメントルート以外のディレクトリを割り当てる https://www.javadrive.jp/apache/ini/index12.html 【Apache】Aliasを使ってみよう - Qiita https://qiita.com/erik_t/items/8d463596f1660290e8a3 Alias と ScriptAliasについて http://safe-linux.homeip.net/web/linux-apache_ref-02.html Apache | ApacheからCGI(Perl)を利用できるように設定する(ScriptAliasディレクティブ) https://www.javadrive.jp/apache/php/index5.html#section2
■Apacheでユーザディレクトリ
http://example.com/~refirio/ のようなURLを使えるようにする
# vi /etc/httpd/conf/httpd.conf … httpdの設定ファイルを編集
<IfModule mod_userdir.c> # # UserDir is disabled by default since it can confirm the presence # of a username on the system (depending on home directory # permissions). # #UserDir disabled UserDir enabled … enabledに変更 (Apache再起動時に「UserDir "enable" keyword requires」のエラーなるようなら、コメントアウトする) # # To enable requests to /~user/ to serve the user's public_html # directory, remove the "UserDir disabled" line above, and uncomment # the following line instead: # #UserDir public_html UserDir "/home/*/public_html" … ユーザディレクトリの場所を設定 </IfModule>
# service httpd configtest … 設定ファイルの構文をチェック # service httpd restart … Apacheを再起動 httpd を停止中: [ OK ] httpd を起動中: [ OK ]
上の場合、/home/refirio/public_html/index.html には /~refirio/ でアクセスできるようになる ApacheでUserDir公開の、メモ書き http://qiita.com/ms2sato/items/299278b2492c96cb80ae
■Apacheでリバースプロキシ
http://refirio.net/proxy_test/ にアクセスすると http://example.com/proxy_test/ の内容が表示されるように設定できる あらかじめ以下にページを作成するものとする(ブラウザでアクセスできる通常のページなら大丈夫) http://example.com/proxy_test/
# vi /etc/httpd/conf/httpd.conf … refirio.net サーバで設定を追加
ProxyRequests Off ProxyPass /proxy_test/ http://example.com/proxy_test/ ProxyPassReverse /proxy_test/ http://example.com/proxy_test/
# systemctl restart httpd … Apacheを再起動
以下でアクセスできる http://refirio.net/proxy_test/ ■リバースプロキシ + Basic認証 参照先のページにBasic認証がかかっていても、上と同じ手順でリバースプロキシを設定できる 参照元と参照先の両方のページにBasic認証がかかっていると、参照先のBasic認証のみが要求される (参照元のBasic認証は、そもそも読み込まれないと思われる) ■参考 Apache 2.4 で リバースプロキシの設定 - Qiita https://qiita.com/okiyuki99/items/83c1fb07644cd232d91e Apache リバース プロキシ サーバを設定する方法 - CA Single Sign-On - 12.52 SP2 - Japanese - Japan - CA Technologies ドキュメント https://docops.ca.com/ca-single-sign-on/12-52-sp2/jp/apache-139364421.html mod_proxy - Apache HTTP サーバ バージョン 2.4 https://httpd.apache.org/docs/2.4/ja/mod/mod_proxy.html mod_proxy - Apache HTTP サーバ バージョン 2.2 https://httpd.apache.org/docs/2.2/ja/mod/mod_proxy.html
■1サーバに複数のSSL証明書を設定する
※Apacheが2.2.12以降、OpenSSL 0.9.8j以降ならSNI(Server Name Indication)に対応しているので、バーチャルホストで複数のSSL証明書を利用できる これらより前のバージョンを使う場合は注意が必要 クライアント側も、IE6以前・Android2以前・フィーチャーフォンといった環境ではアクセスできない とは言え、現状は気にせず使えるはず 名前ベースのバーチャルホストでSSLを使う(SNI) | あぱーブログ https://blog.apar.jp/linux/378/ ApacheのSNIについて [がらくたネット] https://e-garakuta.net/techinfo/doku.php/linux/apache-sni SNIとは? CDNでSSL配信を行うための基礎知識 - ブログ - Jストリーム https://www.stream.co.jp/blog/blogpost-38236/ 以下、調査した内容 1 台のサーバーに複数の証明書をインストールできますか。|SSL/TLS サーバー証明書 SureServer|サイバートラスト https://www.cybertrust.co.jp/sureserver/support/faq/k7sy5mbvynff.html 1つのIPアドレスに対して1つのSSL証明書。というのが原則ではある 複数のドメインでSSLを利用する場合 | COMODO JAPAN https://comodo.jp/guide/multidomain.html 複数のドメインでSSLを利用したければ、マルチドメインタイプもしくはワイルドカードの証明書が必要 ワイルドカードは複数サブドメインに対応するためのものなので、まったく異なるドメインならマルチドメインタイプが必要 1つのサーバーで複数の証明書が使える、SNIって?|SSL基礎知識|Zenlogic - ファーストサーバ株式会社のレンタルサーバー https://zenlogic.jp/user-support/knowledge/ssl/sni.html SNIで1台のサーバ上に複数のSSLサイトを運用 - 前編 | さくらのナレッジ https://knowledge.sakura.ad.jp/3160/ 1個の IP アドレスで複数の SSL サイトを設置する方法 | BestSSL https://www.bestssl.net/support/others/how-to-set-multi-ssl-site/ 1サーバで複数のドメイン&証明書を使いたいという要望は多いため、SNIという技術が作られた ただし対応ブラウザの制約がある(WindowsXP、IE6、Android2、フィーチャーフォンなどは非対応) マルチドメイン | SSLサーバ証明書 |GMOグローバルサイン【公式】 https://jp.globalsign.com/service/ssl/products_price/mdomainssl.html 一例として、グローバルサインによるマルチドメインの解説と価格表 ■AWSの場合 EC2の場合、上と同じ状況 ELBの場合、そもそもSNIに対応していないので不可 ALBの場合、SNIに対応しているので可 ALBで複数証明書 | ナレコムAWSレシピ https://recipe.kc-cloud.jp/archives/10771 AWS Developer Forums: 複数ドメインのSSL証明書を1つのELB ... https://forums.aws.amazon.com/thread.jspa?threadID=239338 ELBに複数のSSLを割り当てる @AWS | https://shoroji.com/2017/11/3879/ EC2に複数の固定IPを設定することは可能みたい これなら通常のSSL証明書でも使えるかも。要検証 EC2に複数のグローバルIPを付与してみた - サーバーワークスエンジニアブログ http://blog.serverworks.co.jp/tech/2016/11/01/attach_eip/ ■さくらのクラウドの場合 さくらのクラウドで複数の固定IPを設定する場合、 共有セグメントではなく専用セグメントにする必要があるみたい。要検証 さくらのクラウド基礎知識 https://www.slideshare.net/sakura_pr/elementary-knowledge-of-sakura-cloud さくらのクラウド導入セミナー(2016.10) 第一部 導入編 https://www.slideshare.net/sakura_pr/20161018-sakura-cloud-introduction-67339981 ■単体サーバに設定する手順 /etc/httpd/conf.d/virtualhost.conf で証明書などの設定を行う際に以下のように設定するが、
<VirtualHost *:443> ServerName refirio.net DocumentRoot /var/www/vhosts/main/html 〜略〜 </VirtualHost>
以下のようにIPアドレスを指定することで、IPアドレスごとに証明書を設定できるみたい(要検証)
<VirtualHost 203.0.113.1:443> ServerName refirio.net DocumentRoot /var/www/vhosts/main/html 〜略〜 </VirtualHost>
マルチドメインでのSSLの設定(CentOS7) - Qiita https://qiita.com/oinuman/items/365f70b31a825db15ed7 SNI がまだそこまでポピュラーではないのでサーバ証明書を扱うには 1 枚に 1 つの IP address が要るのでお困りのそこのあなた!! - してみむとて http://d.hatena.ne.jp/blooper/20121027/1351360911 ■疑問 以前、固定IPを1つだけ持つさくらの専用サーバに対して、複数ドメインのSSLを設定している マルチドメイン証明書では無いはずだが、難なく設定できたのは謎 ■COMODO JAPAN INC への問い合わせ内容 マルチドメインのSSL証明書を https://comodo.jp/ で購入する前提で、実際に問い合わせたときの内容
> 対象サイトが2つあり、両方ともSSLに対応させたいです。(今後3つ以上に増える可能性もあります。) > ただしコストを抑えるために、サーバは1つでバーチャルホストで構築する予定です。 > サーバはAWSのEC2(1台単独)か、さくらのクラウド(1台単独)を予定しています。 > この場合、以下の認識が正しいか確認したいです。 かしこまりました。 > ・固定IPが1つのサーバに、通常のSSL証明書を複数設定することは不可 はい。仰る通りでございます。 固定IPを複数追加可能でしたら、通常の証明書を複数設定可能です。 > ・マルチドメイン証明書なら、2つ以上のドメインに対応できる。SSLの導入手順は、通常のSSL証明書と変わりない はい。仰る通りでございます。 > ・通常の証明書でも複数IPを設定(AWSでEIPを複数設定、さくらクラウドの専用セグメントで複数IP)すれば、2つ以上のドメインに対応できる はい。上述の通りです。 > ・2サイト運用中に3サイト目を追加したい場合、SSL証明書の差し替え作業が3サイト分必要 マルチドメインSSLは、 1枚の証明書で複数のコモンネームに対応することができますので、 証明書の差し替えは、1枚のみとなります。 > その他懸念点や注意すべき点、「こういう場合は利用できない」などございましたら、お知らせいただけると幸いです。 今後追加させるドメインが5ドメイン以内でしたら、 コストメリットが高いマルチドメインおトクパックをお勧めさせていただきます。 https://comodo.jp/products/otokupack.html CSRを作成する際、代表となる一つのコモンネームを決めていただき、 そのコモンネームにてCSRを生成してください。 その他、他認証局と同様ではありますが、注意点を挙げさせていただきます。 ・Apache1系では、ご利用になれません。 ・フィーチャーフォンからのアクセスには対応しておりません。 引き続き、どうぞ宜しくお願い申し上げます。 その他、ご不明な点等がございましたら、お気軽にお問い合わせください。
■SSL証明書の内容を確認する
Certificate.txt の「ツールで証明書情報を確認」を参照
■Apache+SSLでRC4暗号化を外す
サーバのセキュリティチェックなどで、SSLの設定で「SSLCipherSuite」に「RC4」が使用されている …と指摘されたときの対応方法について 以下、指摘内容
SSL/TLS が弱い RC4 暗号を使用: RC4 は、出力に一定のバイアスがあるため、暗号文を統計的に解析できる現実性が高いことが発見されています。 想定される攻撃としては、ブラウザに悪質な JavaScript をインジェクトするものがひとつの例として考えられます。 これにより、ターゲットの Web サイトとの間に複数の接続が確立され、 同じ HTTP Cookie が暗号化された形で複数回 Web サイトに送信されるようになります。 そこから、攻撃者は大量の暗号文サンプルを入手でき、それを統計的な解析に利用できるようになります。
具体的な対内容は以下のとおり confファイルで
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
を以下のように変更して、Apacheを再起動する(CentOS6の場合)
SSLCipherSuite DEFAULT:!EXP:!SSLv2:!DES:!IDEA:!SEED:!RC4:!3DES:!RSA
上記設定は、以下などのファイルに書かれていることが多い /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/virtualhost.conf 設定内容の意味やCentOS7での設定方法は、以下のページに詳しく書かれている CentOS6.9/CentOS7.4でWebサーバのSSLのセキュリティ対策 - Qiita https://qiita.com/qiitamatumoto/items/f93286fc82ec9a0cdff7
■TLS1.2の対応状況を確認する
決済システムを導入している案件で、決済会社から以下のメールが送られてきた TLS1.2に対応している必要があるらしいので調査
この度ペイジェントでは、決済システムのセキュリティをより安全に保つため 暗号化通信プロトコルTLS1.2未満の使用を停止することにいたしました。 加盟店様システムの環境によりましては、TLS1.2未対応の場合、 決済することができなくなります。 まずは加盟店様にて影響有無をご確認頂き、 TLS1.2のシステム対応を進めて頂ければと存じます。
SSL/TLSの暗号化通信をTLS1.2 のみに制限する - ex1-lab https://ex1.m-yabe.com/archives/3054 適当なサーバから、対象サーバに対して以下を実行(以下は refirio.net に実行する場合) 「Protocol : TLSv1.2」と表示されているので大丈夫そう
# openssl s_client -connect refirio.net:443 -tls1_2 New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1.2
ブラウザからも確認できる 詳細は以下などのページを参考に ブラウザでTLSのバージョンを確認・設定する方法 - kin29.info https://kin29.info/%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%A7tls%E3%81%AE%E3%83%90%E3%83%BC%E3%82... TLSのバージョンの確認方法 - M&T Technology, Inc. https://support.m-t.com/web/web%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AB%E9%96%A2%E3%81%97%E3%81... WindowsVistaやIE10など、古い環境もサポートが切られることになる 対応状況などは以下のページが解りやすい Yahoo!セキュリティセンター | 2018年6月1日以降、古いブラウザー、パソコン、スマートフォンなどでは、Yahoo! JAPANのウェブサービスが順次ご利用いただけなくなります。 https://security.yahoo.co.jp/news/tls12.html
■SSL証明書のピンニングについて
AWSから以下のメールが送られてきた 「証明書のピン留め」という言葉が見慣れなかったので調べたメモ
お客様が AWS アカウント の AWS Certification Manager (ACM) に、少なくとも 1 つの有効期限内の Amazon 発行のパブリック証明書 [1] をお持ちの方にご連絡しております。 2023 年 2 月 1 日から 2023 年 3 月 31 日までの間に、Amazon は Amazon が発行したすべてのパブリック証明書を、旧来の中間 CA, intermediate certificate authority (ICA) から、2022 年 10 月に導入された複数の中間 CA (ICA) /下位認証局のいずれかに移行します。 ICA はルート CA にチェーンされ、お客様が受け取って使用するリーフ証明書の発行に使用されます。 新しい ICA の詳細については、AWS セキュリティブログ [2] をご参照ください。 証明書のピン留めによって既存の ICA 情報を明示的に利用しない限り、お客様による操作は必要ありません。 ICA にピン留めする場合は、AWS セキュリティブログ [2] にて ICA および実行できるアクションの詳細をご確認頂けます。 既存の証明書の新しい ICA への移行は、追加の通知なしで行われます。 移行された証明書には、現在の証明書と同様に、既存の証明書の有効期限が保持されます。 証明書の発行日は ICA の移行日に変更されます。 注意事項としては、新たにリクエストされた Amazon パブリック証明書は、2022 年 10 月 8 日時点で、既に新しい ICA から発行されています。 また Amazon は、過去 3 か月間に使用されていないパブリック証明書を新しい ICA に移行しております。 Amazon は 2023 年 5 月末までに、旧来の ICA を失効し、中間 CA に関する既知の問題を修正するとともに、ACM が発行する証明書をより最新の証明書規格に準拠するものに移行する予定です。 [1] https://www.amazontrust.com/repository/ [2] https://aws.amazon.com/blogs/security/amazon-introduces-dynamic-intermediate-certificate-authorities...
所持ドメインから不正な証明書を発行されないようにする技術だが、 意図しないアクセスブロックが発生することがあるなど、デメリットの方が大きいとなって利用されなくなった。 …とのこと。 自堕落な技術者の日記 : HPKP(HTTP Public Key Pinning)公開鍵ピニングについて考える - livedoor Blog(ブログ) http://blog.livedoor.jp/k_urushima/archives/1811745.html 証明書のピンニングはやめましょう | DigiCert.com https://www.digicert.com/jp/blog/certificate-pinning-what-is-certificate-pinning 証明書のピンニングはやめましょう https://rms.ne.jp/sslserver/basis/pinning2/ 【お知らせ】パブリック証明書の発行元が AWS Certificate Manager (ACM) の中間認証局 (ICA) に変更されます | SunnyCloud https://www.sunnycloud.jp/column/20220922-01/ AWSで証明書のピン止めを行う方法は、一応以下で解説されている。 ただし公式にも非推奨である旨が警告されている。 証明書のピンニングの問題 - AWS Certificate Manager https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/troubleshooting-pinning.html 【AWS】無料のサーバ証明書を公開鍵ピンニングする - Qiita https://qiita.com/ruddy95/items/07735c1f25fba6a38fc2
■Apacheでfavicon.icoの404エラーを記録させない
favicon.icoを設置しない場合でaccess_logにfavicon.icoの404エラーを記録させたくない場合、 /etc/httpd/conf/httpd.conf に以下の設定を追加する
SetEnvIf Request_URI "favicon\.ico" no_log
error_log にも記録させたくない場合、以下の設定も追加する (404エラーを記録させないだけなら、ErrorDocumentなしでも十分かも?要確認)
Redirect 404 /favicon.ico ErrorDocument 404 "File Not Found"
【Apache】favicon.icoをログに出さない! http://dblog3024.blog.fc2.com/blog-entry-2.html Apache > favicon.icoをエラーログに残さず、ファイルIOも発生させない方法 http://d.hatena.ne.jp/tama0905/20110820/1313824404
■nginxでIPアドレス直接アクセスを禁止する
※未検証 IPアドレスのアクセスが必要なら、プログラムで制御するのも有効 IP直でのアクセスをnginxで禁止する - ik-fib's page https://ik-fib.com/2019/07/nginx-ip-direct-access-block/ nginxでIPアドレス指定でのアクセスを弾く - YoshinoriN's Memento https://yoshinorin.net/2018/06/05/nginx-block-ip-access/ Nginx で http も https も IP 直打ちのアクセスを弾きたい - べにやまぶろぐ http://beniyama.hatenablog.jp/entry/2015/04/05/100000
■nginxでリクエストを操作する
■インデックスファイルを省略する 以下のようにすると、ファイル名を省略してアクセスしたときに index.php が表示される 無ければ index.html が表示される
server { location / { index index.php index.html; }
以下のように指定しても同じ
server { index index.php index.html;
Laravelなどを使っている際に try_files でクエリを処理している場合、 「location /」に「index index.php index.html;」を追加しても意図したように処理されない 以下のように個別に指定すると、そのディレクトリ内はindexの指定が有効になる(以下の場合は tool ディレクトリ内が対象) もっといい設定方法が無いかは要確認
server { location / { try_files $uri /index.php?$query_string; } location /tool/ { index index.php index.html; }
■SSLを強制する ロードバランサーが無い場合
server { listen 80; server_name refirio.net; return 301 https://refirio.net$request_uri; } server { listen 80; listen 443; server_name www.refirio.net; return 301 https://refirio.net$request_uri; } server { listen 443 ssl default_server; server_name refirio.net; 〜略〜 }
nginxでhttpsのwwwなしURLにリダイレクトさせる設定 - くろもワークス https://blog.kuromoworks.com/entry/2017/10/31/234648 [Nginx] httpをhttpsにリダイレクトする | ハックノート https://hacknote.jp/archives/29730/ ロードバランサーがある場合 (サーバ名を「server_name _;」としている場合、「return 301 https://www.refirio.net$request_uri;」のように指定する)
server { listen 80 default_server; listen [::]:80 default_server; server_name localhost; root /usr/share/nginx/html; if ($http_x_forwarded_proto = 'http') { return 301 https://$server_name$request_uri; }
■リダイレクトする /etc/nginx/nginx.conf で以下のように設定する
# /hoge/foo.html にアクセスしたら302リダイレクト location /hoge/foo.html { rewrite ^(.*)$ http://example.com/hoge/foo.html redirect; } # /foo/bar.html にアクセスしたら301リダイレクト location /foo/bar.html { rewrite ^(.*)$ http://example.com/foo/ permanent; }
Nginxのリダイレクト設定のメモ - Qiita https://qiita.com/kt_higa/items/f26ba1453164c82d6ad5 nginxのrewriteを使ったリダイレクト | Skyarch Broadcasting https://www.skyarch.net/blog/?p=7088 ■URLを書き換える(Apacheのmod_rewriteに相当) /etc/nginx/nginx.conf で以下のように設定する
# /test/ にアクセスしたら /test.html の内容を表示 location /test/ { rewrite /(.*)/ /$1.html last; }
■nginxにレスポンスタイムを記録
/etc/nginx/nginx.conf のlog_formatで $request_time を設定する 以下の例では、あわせてアクセス元プロキシのプロトコルとホストも記録している
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; ↓以下のように変更 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" $request_time $http_x_forwarded_proto $host';
ELB経由のnginxでアクセス元IPアドレスをアクセスログの$remote_addrとして書くようにする - Qiita https://qiita.com/toshihirock/items/1de2613bb7c95d486dc1 nginx: ログ出力形式の変更と、ログにレスポンスタイムを出力する方法 - エラーの向こうへ https://tech.mktime.com/entry/259 Nginxアクセスログのフォーマットにホスト名を入れてLogwatchにも対応させる https://parudou3.com/nginx/616/
■nginxでバーチャルホスト
nginxでデフォルトのバーチャルホストを設定する方法 - Linux入門 - Webkaru https://webkaru.net/linux/nginx-default-server/ ■前提 refirio.net でアクセスできるサーバに test.refirio.net を追加する /var/www/vhosts/test/public を公開ディレクトリにする ■バーチャルホスト設定
$ sudo su - # mkdir -p /var/www/vhosts/test/public … 公開ディレクトリを作成 # chown nginx. /var/www/vhosts/test # chmod 775 /var/www/vhosts/test # chown nginx. /var/www/vhosts/test/public # chmod 775 /var/www/vhosts/test/public # vi /var/www/vhosts/test/public/index.php … テストページを作成
<?php echo shell_exec('hostname') ?>
# vi /etc/nginx/nginx.conf … バーチャルホストの設定を追加(すでにある「server { 〜 }」の設定をもとにするといい)
server { listen 80; listen [::]:80; server_name test.refirio.net; root /var/www/vhosts/test/public; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { try_files $uri /index.php?$query_string; auth_basic "Auth"; auth_basic_user_file /var/www/vhosts/test/public/.htpasswd; } # redirect server error pages to the static page /40x.html # error_page 404 /404.html; location = /40x.html { } # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { } location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/vhosts/test/public$fastcgi_script_name; include fastcgi_params; } }
# service nginx configtest … 設定ファイルの構文をチェック # service nginx restart … nginxを再起動
■DNS設定 test.refirio.net の向け先を上記サーバに設定 ■最低限の設定例 ※未検証 最低限、以下の設定のみで動作するみたい この場合、default_server を指定した example2.com がデフォルトのホストになる(IPアドレスでアクセスしたときに参照される) default_server の指定がなければ、最初に指定された example1.com がデフォルトのホストになる
server { listen 80; server_name example1.com; } server { listen 80 default_server; server_name example2.com; } server { listen 80; server_name example3.com; }
■ログでバーチャルホストを区別 nginxの場合、log_formatに「$host」を指定することでバーチャルホストを区別できるようになる このファイル内にある「nginxにレスポンスタイムを記録」内の記述も参照
■nginxでリバースプロキシ
※ロードバランサーのように負荷分散を行うが、ロードバランサーとは異なりレスポンスはリバースプロキシが返す これにより、リバースプロキシがレスポンスをキャッシュして負荷を軽減させたりなどができる Nginxによるリバースプロキシの設定方法 http://qiita.com/schwarz471/items/9b44adfbec006eab60b0 Nginx でリバースプロキシサーバーつかってみる。Apache -> Nginx http://qiita.com/murachi1208/items/d04797b0b61e69018938 リバースプロキシって何?触りだけ学んだサーバー/インフラ入門 http://qiita.com/growsic/items/fead30272a5fa374ac7b Nginx でリバースプロクシを立てるときに気にすべき proxy_next_upstream 設定 - 無印吉澤 http://muziyoshiz.hatenablog.com/entry/2017/10/25/235114 Nginxのリーバスプロキシ化(Apacheと共存) - Qiita https://qiita.com/mike-ayumu/items/5f255bab07606759a8e5 ここでは以下2台のサーバがあるものとし、 203.0.113.1 サーバにアクセスしたときに 203.0.113.2 サーバの内容を返すように設定するものとする http://203.0.113.1/(プライベートIP 10.0.0.1) ... nginxが動作しているものとする http://203.0.113.2/(プライベートIP 10.0.0.2) ... Apache+PHPが動作しているものとする □203.0.113.1
# vi /etc/nginx/conf.d/proxy.conf … リバースプロキシ用の設定ファイルを作成
server { server_name refirio.net; … サーバー名を指定 proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; location /sample/ { … sampleディレクトリをプロキシアクセスにする proxy_pass http://10.0.0.2/sample/; … 10.0.0.2 サーバにアクセスさせる } location /sample2/ { … sample2ディレクトリをプロキシアクセスにする proxy_pass http://10.0.0.2/sample2/; … 10.0.0.2 サーバにアクセスさせる } }
# service nginx restart … nginxを再起動
□203.0.113.2 特に設定しなくても動作に問題はないが、そのままだとアクセスログには 203.0.113.1 のIPアドレスのみが記録されることになる /etc/httpd/conf/httpd.conf のLogFormatに %{X-Forwarded-For}i を追加すると、アクセスした人本来のIPアドレスが記録される ■リバースプロキシでキャッシュを使う ※アプリケーションサーバのレスポンスをnginxがキャッシュすることにより、負荷軽減&高速化を実現できる ※WordPressなどに使用する場合、管理ページではキャッシュさせないなどの対応が必要 Nginx - リバースプロキシキャッシュ設定(基本的)! http://www.mk-mode.com/octopress/2014/04/23/nginx-proxy-cache-setting/ 【nginx】WordPress でキャッシュしてはいけないページ(ファイル、ディレクトリ)設定!!! http://oki2a24.com/2014/07/03/set-do-not-cache-wordpress-page/ nginxで特定のページをキャッシュさせないように設定したい https://teratail.com/questions/13018 正規表現で「URLに○○が含まれている場合はキャッシュを返さない」のように設定できるみたい。要調査 nginxでWordPressの設定する時に出てくるディレクティブのメモ https://nskw-style.com/2012/server/nginx-directives.html 特定URLの場合にキャッシュさせない、はできるみたい。要調査 □203.0.113.1
# mkdir /var/cache/nginx … キャッシュと一時ファイル保存用のディレクトリを作成 # chown nginx. /var/cache/nginx # vi /etc/nginx/nginx.conf … nginxの設定ファイルを編集
「index index.php index.html index.htm;」の次の行に以下を追加 proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=my-key:8m max_size=50m inactive=120m; proxy_temp_path /var/cache/nginx/tmp; … キャッシュと一時ファイル保存用のディレクトリ
# vi /etc/nginx/conf.d/proxy.conf … リバースプロキシ用の設定ファイルを編集
「location /sample/ { 〜 }」のブロック内に以下を追加 proxy_ignore_headers Cache-Control; … バックエンド側のCache-Controlヘッダでno-cache が指定されていても無視する proxy_cache my-key; proxy_cache_valid 200 302 60m; … HTTPレスポンスが200か302の場合は60分キャッシュする proxy_cache_valid 404 10m; … HTTPレスポンスが404の場合は10分キャッシュする
# service nginx restart … nginxを再起動
キャッシュをクリアしたい場合、以下のディレクトリ内にあるデータをすべて削除する /var/cache/nginx/cache/ /var/cache/nginx/tmp/
■nginxをロードバランサーにする
nginxをHTTPロードバランサのように使う http://mogile.web.fc2.com/nginx/http/load_balancing.html Nginx リバースプロキシサーバ構築 https://sys-guard.com/yuu_linux/19-01.php ※未検証 upstreamコンテキストで複数のプロキシ先サーバを定義できる このプロキシサーバ群をリバースプロキシの対象にすれば、nginxをロードバランサーとして使えるみたい /etc/nginx/nginx.conf で以下の設定を追加し、
upstream myapp { server web1.example.com; server web2.example.com; server web3.example.com; }
/etc/nginx/conf.d/proxy.conf で以下のように設定すれば、処理の振り分けができるみたい
location / { proxy_pass http://myapp; }
/etc/nginx/nginx.conf で以下のように設定すると、リクエストの 3/5 はweb1に向かうみたい
upstream myapp { server web1.example.com weight=3; server web2.example.com; server web3.example.com; }
AWSならELBを使う方が可用性の担保が容易 nginxをロードバランサーにする場合、ELBとは違い可用性は独自に担保する必要がある FloatingIPにするなどを検討する EC2 Nginx で高可用性+ロードバランス(Floating IP パターン) https://blog-kazuhisya.rhcloud.com/2014/08/10/floating-ip-with-nginx-load-balancer/
■環境によってWebP画像を表示
■WebP WebP - Wikipedia https://ja.wikipedia.org/wiki/WebP そろそろWebPに切り替えよう。変換方法や対応ブラウザ、使い方を解説! | Web Design Trends https://webdesign-trends.net/entry/13745 次世代画像形式のWebP、そしてAVIFへ。変わり続ける技術に対応するweb制作の黄金解 - ICS MEDIA https://ics.media/entry/201001/ WEBP変換ツール (jpg、pngとwebpを相互変換) https://lab.syncer.jp/Tool/Webp-Converter/ ■画像の振り分け表示 WebPと従来の画像を正しく振り分ける.htaccessファイル - アイデアマンズブログ https://blog.ideamans.com/2019/02/webphtaccess.html nginxにおけるWebP画像の選択的レスポンスの設定方法 - Qiita https://qiita.com/miyanaga/items/94447efae0bf767b9f2b ■nginxで実際に試したもの
# vi /etc/nginx/conf.d/www.conf
# Acceptリクエストヘッダに image/webp が含まれていたら、変数 $webp_suffix に ".webp" を代入 # 含まれていない場合、$webp_suffix は空文字 map $http_accept $webp_suffix { default ""; "~*image/webp" ".webp"; } server { 〜略〜 # PNG・GIF・JPEGへのリクエストについて location ~* \.(png|gif|jpe?g)$ { # VaryヘッダとしてAcceptを返す add_header Vary Accept; # WebP対応ブラウザでは、image.png.webp、image.pngを探す # 非対応のブラウザでは、image.png、image.pngを探す # いずれもない場合は404を返す try_files $uri$webp_suffix $uri =404; }
# service php-fpm restart # service nginx restart
以下のようなHTMLで画像を呼び出すと、IEでは「image.png」が表示され、Chromeでは「image.png.webp」が表示される 画像ファイルはあらかじめそれぞれを配置しておく
<img src="images/image.png">
■Apache・Nginxのエラーログフォーマットを変更
error_log に記録するIPアドレスを、Proxyを考慮したものにしたい…という場合に調べたもの 公式の解説によると、「情報を追加したり削除したりしてエラーログをカスタマイズすることは できません。」とのこと。 Nginxも同様 ログファイル - Apache HTTP サーバ http://httpd.apache.org/docs/2.0/ja/logs.html#errorlog nginxのerror_logはformat指定できない. - としたにあんの左脳 http://toshitanian.hatenablog.com/entry/2013/10/25/023838 上記Apacheのドキュメントには 「情報を追加したり削除したりしてエラーログをカスタマイズすることはできません。 しかし、リクエストに対するエラーログのエントリは、 対応するエントリがアクセスログにあります。 例えば、上の例のエントリはアクセスログのステータスコード 403 のエントリに対応します。 アクセスログはカスタマイズ可能ですので、 そちらを使うことによりエラーの状況に関する情報をより多く手に入れることができます。」 と書かれているので、アクセスログを併用する前提みたい。恐らくNginxも同じ思想
■ロードバランサーでリクエストを操作する
SSLの強制は、各サーバで対応しなくてもロードバランサーで対応できることがある AWSのALBの場合、AWS.txt の「ロードバランサー」の「SSLにリダイレクトさせる」を参照
■rsync(一方向同期)
※web1サーバの /var/www/html/rsync の内容を、web2サーバの /var/www/html/rsync に同期 ※rsyncが同期のためのコマンド。ただし手作業でコマンドを実行する必要がある lsyncdを使うと、ほぼリアルタイムに自動同期させることができる という関係性みたい rsyncとlsyncdでEC2サーバーを同期する http://qiita.com/katsukii/items/5c2cbd8f69ffd7cb213f lsyncとrsyncを使ったリアルタイム同期 https://systemexpress.co.jp/centos/lsyncrsync.html CentOSにおけるファイル同期(lsyncd+rsync) | 静岡県浜松市・関東 -Web制作・開発なら株式会社WETCH(ウェッチ) https://www.wetch.co.jp/note/centos%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%95%E3%82%A1%E3%82%A4%E... ポートや鍵のファイルを指定 http://ikm.hatenablog.jp/entry/2013/05/27/140336 ■同期元サーバ:キーを作成 ※rootユーザ、保存先はデフォルトのまま、パスワードなしで作成する場合
# ssh-keygen -t rsa # cat .ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAA 〜略〜 93ciNXZFZSlzXfqfZwD/7809G7 root@web1.refirio.net
■同期先サーバ:ユーザを作成 ※rsyncが配置したファイルだと分かるように、同期用にrsyncユーザを作成する場合
# useradd rsync # usermod -G wheel rsync # usermod -a -G apache rsync # visudo
# %wheel ALL=(ALL) ALL %wheel ALL=(ALL) ALL … コメント解除していなければ解除
■同期先サーバ:キーの設定 ※同期用ユーザが接続できるようにする
# mkdir -p /home/rsync/.ssh … 公開鍵格納用ディレクトリを作成 # chmod 700 /home/rsync/.ssh … 公開鍵格納用ディレクトリのパーミッションを変更 # vi /home/rsync/.ssh/authorized_keys … 公開鍵をauthorized_keysに保存
ssh-rsa xxxxxxxxxx … 作成した公開鍵の内容を全てコピーして貼り付ける
# chmod 600 /home/rsync/.ssh/authorized_keys … authorized_keysのパーミッションを変更 # chown -R rsync:rsync /home/rsync … ユーザディレクトリの所有者を変更
■同期元サーバ:接続確認 同期元サーバから同期先サーバへSSH接続を確認 接続できなければ、鍵ファイルやや上位ディレクトリの所有者とパーミッションを確認する (rsyncユーザから読み込めるようにする)
# ssh -p 10022 rsync@10.0.1.17
■同期元サーバ:lsyncdインストール
# yum -y install epel-release # yum install --enablerepo=epel lsyncd
以下でrsyncコマンドの動作を確認できる
# rsync -e "ssh -p 10022" -avz --delete /var/www/html/rsync rsync@10.0.1.17:/var/www/html
「rsync error: some files/attrs were not transferred」のエラーが表示される場合、以下のようにすれば表示されないみたい
# rsync -e "ssh -p 10022" -avzO --delete /var/www/html/rsync rsync@10.0.1.17:/var/www/html
「O」は「ディレクトリのタイムスタンプを保持しない」みたい rsyncでエラーが出たけどコピーはできてる - ごずろぐ http://gozuk16.hatenablog.com/entry/2014/09/30/224900 ■同期元サーバ:自動同期設定
# vi /etc/lsyncd.conf
settings { logfile = "/var/log/lsyncd/lsyncd.log", statusFile = "/var/log/lsyncd/lsyncd.stat", maxProcesses = 2, statusInterval = 1, insist = 1 } sync { default.rsync, source = "/var/www/html/rsync", target = "rsync@10.0.1.17:/var/www/html/rsync", delay = 2, exclude = { "*.swp" }, rsync = { archive = true, compress = false, rsh = "ssh -p 10022" } }
# service lsyncd start … lsyncdを起動 # chkconfig --add lsyncd # chkconfig lsyncd on … lsyncdの自動起動を設定
■同期元サーバ:動作確認
# tail /var/log/lsyncd/lsyncd.log … 同期されるたびにログが記録される
何も記録されていない場合、以下で設定ファイルの文法チェックをするといい
# lsyncd -nodaemon -log scarce /etc/lsyncd.conf
以下で指定したファイルは、環境によってはあらかじめ作成しておく必要があるかも? logfile = "/var/log/lsyncd/lsyncd.log", statusFile = "/var/log/lsyncd/lsyncd.stat", lsyncdでサーバ間のファイルを双方向に同期させる https://2017.l2tp.org/archives/314 以下のようなエラーが表示される場合、ディレクトリやファイルのパーミッションを確認する 直上のディレクトリのパーミッションが大丈夫でも、さらに上位のディレクトリのパーミッションも影響する
rsync: ERROR: cannot stat destination "/home/centos/html": Permission denied (13) rsync error: errors selecting input/output files, dirs (code 3) at main.c(565) [Receiver=3.0.9] rsync: connection unexpectedly closed (9 bytes received so far) [sender] rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
今回の場合、以下のように「centos」のパーミッションが原因で同期できなかった 「chmod 0775 centos」とすれば同期できるようになった(アクセスをグループで制御しているものとする) パーミッション最後のピリオドは、SELinuxに由来するもので関係ない
# cd /home # ll 合計 0 drwx------. 3 centos centos 133 12月 5 15:34 centos drwx------ 3 rsync rsync 95 12月 2 21:46 rsync
■rsync(双方向同期)
※web1サーバとweb2サーバの /var/www/html/rsync が双方向に同期したい場合、 「rsync(一方向同期)」の設定を、同期元と同期先を逆にして追加設定する ※ただしそれだけだと、意図しないファイルの削除や復元が発生する場合がある 以下の設定を追加することで対応する ※ロードバランサー経由で複数のWebサーバへアクセスしている際に、同期されるまでのタイムラグが問題になる場合、 スティッキーセッションを使うなどしてアクセスされるサーバを固定するといい ただしcurl経由でのリクエストなど、Cookieが扱えずにスティッキーセッションが機能しない場合があるので注意 lsyncdで双方向同期するなら、delete='running' がいい http://iga-ninja.hatenablog.com/entry/2015/02/28/230014 rsyncとlsyncdを使ったディレクトリの双方向同期 http://qiita.com/kaihei777/items/5bb4f381c6b4c31be055 lsyncdでサーバ間ファイルを同期をさせてみた https://www.didgedil.li/2016/07/17/lsyncd/
# vi /etc/lsyncd.conf
sync { default.rsync, source = "/var/www/html/rsync", target = "rsync@10.0.1.17:/var/www/html/rsync", delay = 2, delete = "running", … 追加(意図しないファイルの削除を避ける) init = false, … 追加(意図しないファイルの復元を避ける) exclude = { "*.swp" }, rsync = { archive = true, compress = false, rsh = "ssh -p 10022" } }
# service lsyncd restart … lsyncdを再起動
※rsyncに「owner = true」「group = true」を設定すると所有者を含めて複製されるらしいが、反映されなかった 「同じグループのユーザからはファイルの読み書きを許可する」のような指定ができないことになり、これだと問題がある 仮に「web-userでアップロード&web-userで同期」としても PHPが作成したファイルやディレクトリは所有者apacheとなり、同期によってやはり所有者が変わることになる 同期はrsyncユーザで行い、「FTPでアップロードするのはweb1のみで、web2には原則としてアップロードしない」なら運用できるかも ※上の解決策。前提として所有者は含めない方が、アップロードされたファイルなのか同期されたファイルなのかが明確になって良さそう 代わりに chmod g+s /var/www/html/rsync として、rsyncディレクトリ内で作成されたファイル・ディレクトリのグループを親ディレクトリのグループに合わせると良さそう そうすればファイルの読み書きに支障はなくなるし、アップロードされたのか同期されたのかも明確になる
■rsync(バックアップ)
以下はrsyncで2台のサーバが双方向同期しているAWSのEC2環境で、実際にAMIを作成したメモ テスト的にAMIから古いEC2を立ち上げたとき、 即座に同期が始まって古いファイルで上書きされたりを防ぐため、 AMI作成前に同期を無効にして作成後に再度有効にした 作成前に、両方のサーバで同期を無効にしておく
# systemctl stop lsyncd # systemctl disable lsyncd # systemctl | grep lsyncd
AMIを作成する (「再起動しない」は「有効化」にして作成したが、可能なら再起動して作成すると確実) 作成後に、両方のサーバで同期を有効にする
# systemctl start lsyncd # systemctl enable lsyncd # systemctl | grep lsyncd
■Sendmailでメールを送信する
# sendmail example+to@example.com From: example+from@example.com To: example+to@example.com Subject: Mail title Mail body. .
sendmailコマンドの使い方: UNIX/Linuxの部屋 http://x68000.q-e-d.net/~68user/unix/pickup?sendmail sendmailコマンドの使い方: UNIX/Linuxの部屋 http://x68000.q-e-d.net/~68user/unix/pickup?sendmail
■メールのキューを削除する
メールを正しく送信できなかった場合、 /var/spool/clientmqueue/ ... MSPモード(MTAを使わないメール送信)の場合 /var/spool/mqueue/ ... MTAの場合 に一時的に貯められる ここに大量のメールが溜まってしまった場合、送信してしまうかファイルを削除してしまうかになる 削除する場合、以下のコマンドを実行する
# rm -f /var/spool/clientmqueue/* # rm -f /var/spool/mqueue/*
clientmqueueディレクトリ以下に吐き出される大量ファイルの対処法 http://ameblo.jp/itboy/entry-10024985559.html MSP(メール配信プログラム)モードで実行する http://seesaawiki.jp/w/engineernochiebukuro/d/MSP%A1%CA%A5%E1%A1%BC%A5%EB%C7%DB%BF%AE%A5%D7%A5%ED%A5...
■PHPMailerを使ってSMTPでメールを送信する
SMTPでの送信を一から書くのは大変なので、PHPMailerなどを使うといい ローカルのXAMPPで常に接続エラーになる場合、適当なレンタルサーバに設置して試すと大丈夫なことがある 以下ページ内の「v5.2.28」からダウンロードすると、class.phpmailer.php と class.smtp.php を入手できる 以降のメモでは、このファイルを使用している Tags - PHPMailer/PHPMailer https://github.com/PHPMailer/PHPMailer/tags ■外部のSMTPで送信
<?php require_once 'PHPMailer/class.phpmailer.php'; require_once 'PHPMailer/class.smtp.php'; // SMTPサーバ: ホスト define('SMTP_HOST', 'smtp.refirio.net'); // SMTPサーバ: メールアカウント define('SMTP_USERNAME', 'example@refirio.net'); // SMTPサーバ: メールパスワード define('SMTP_PASSWORD', 'xxxxxxxxxx'); // SMTPサーバ: プロトコル (ssl または tls) define('SMTP_SECURE', 'ssl'); // SMTPサーバ: 送信ポート (ssl:465, tls:587) define('SMTP_PORT', '465'); // メール送信準備 $mail = new PHPMailer(); $mail->isSMTP(); $mail->SMTPAuth = true; $mail->Host = SMTP_HOST; $mail->Username = SMTP_USERNAME; $mail->Password = SMTP_PASSWORD; $mail->SMTPSecure = SMTP_SECURE; $mail->Port = SMTP_PORT; // メール内容定義 $mail->CharSet = 'UTF-8'; $mail->Encoding = 'base64'; $mail->setFrom('from@example.com', 'メール送信者'); $mail->addAddress('to@example.com', 'メール受信者'); $mail->Subject = 'SMTPからの送信テスト'; $mail->Body = "テスト。\r\nこれはテストです。"; // メール送信 if (!$mail->send()) { exit('Error: ' . $mail->ErrorInfo); } exit('complete');
外部のSMTPがメールを送信するので、/var/log/maillog には送信ログが記録されなかった ■ローカルのSMTPで送信
<?php require_once 'PHPMailer/class.phpmailer.php'; require_once 'PHPMailer/class.smtp.php'; // SMTPサーバ: ホスト define('SMTP_HOST', 'localhost'); // SMTPサーバ: 送信ポート define('SMTP_PORT', '25'); // メール送信準備 $mail = new PHPMailer(); $mail->isSMTP(); $mail->SMTPAuth = false; $mail->Host = SMTP_HOST; $mail->Port = SMTP_PORT; // メール内容定義 $mail->CharSet = 'UTF-8'; $mail->Encoding = 'base64'; $mail->setFrom('from@example.com', 'メール送信者'); $mail->addAddress('to@example.com', 'メール受信者'); $mail->Subject = 'ローカルSMTPからの送信テスト'; $mail->Body = "テストメール。\r\nこれはローカルSMTPからの送信テストです。"; // メール送信 if (!$mail->send()) { exit('Error: ' . $mail->ErrorInfo); } exit('complete');
/var/log/maillog には以下のような送信ログが記録された
Jun 7 11:44:05 aws-terraport sendmail[24154]: x572i5mI024154: from=<from@example.com>, size=587, class=0, nrcpts=1, msgid=<68af5fe5c0a0bf037ad9cb157165d3b1@monitor.example.com>, proto=ESMTP, daemon=MTA, relay=localhost [127.0.0.1] Jun 7 11:44:06 aws-terraport sendmail[24156]: STARTTLS=client, relay=gmail-smtp-in.l.google.com., version=TLSv1/SSLv3, verify=FAIL, cipher=ECDHE-RSA-AES128-GCM-SHA256, bits=128/128 Jun 7 11:44:07 aws-terraport sendmail[24156]: x572i5mI024154: to=<to@example.com>, delay=00:00:02, xdelay=00:00:02, mailer=esmtp, pri=120587, relay=gmail-smtp-in.l.google.com. [74.125.204.27], dsn=2.0.0, stat=Sent (OK 1559875447 s15si706778pgj.350 - gsmtp)~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 3130,1 末尾
■添付ファイルを送信する メール送信の前部分に、以下のコードを追加すれば添付ファイルを送信できる 添付ファイルは、もちろん指定の場所に存在している必要がある addAttachmentは、複数回実行して複数のファイルを添付することもできる
// ファイル添付 $mail->addAttachment('files/sample.pdf');
また、addAttachment で第2引数を指定すれば、そのファイル名で添付することができる 例えば以下の場合、「test.pdf」という名前で添付ファイルが送信される
// ファイル添付 $mail->addAttachment('../files/sample.pdf', 'test.pdf');
■参考 メール送信がうまくいかないときに読む記事(そういう質問をされたときに読ませる記事) - Qiita https://qiita.com/ShibuyaKosuke/items/309c0a7d969baf0ea8d1
■メールを確認する
■POP と IMAP ユーザがメールを取り込むとき、「POP」や「IMAP」といったプロトコルが利用される POPはメールを手元に取り込むためのシンプルな手順で、サーバの負荷も軽く高速な処理が可能 サーバのメールボックスからメールを手元に受信し、 メールの管理はローカルコンピュータのメールクライアントソフト(「Thunderbird」や「Microsoft Outlook」など)で行う 複数の端末でメールを確認したい場合には向かない IMAPは上記のようなPOPの弱点を解決するために開発されたプロトコルで、メールの管理をサーバ側で行なう 具体的には「メール送信済み」「メール受信」「メールの下書き」をサーバ側で管理する これにより、端末が複数ある場合でもメールを管理できる ■Maildir と Mailbox メールボックスの形式には Maildir と Mailbox がある Mailboxは複数のメッセージが1つのファイルに連結された形式で保存される その仕組み上、大きなファイルとなる また1つのファイルを読み書きするため、デッドロックが発生する可能性やファイル破損の可能性がある Maildirでは「1通のメール = 1つのファイル」となり、「cur」「new」「tmp」という 3つのディレクトリが作成される new … 未読メールの保管場所 cur … 既読メールの保管場所 tmp … 配送中メールの一時保管場所(システムが一時的な処理のために使用するディレクトリ。通常は空の状態になっている) メールクライアントソフトで、メール受信した際の挙動で「サーバにメールを残す」設定した場合、メールは「new」から「cur」に移動される そうでない場合、メールは「new」から削除される ファイル名は「1639205681.Vfd04I155a9cM401882.refirio.net:2,RS」のようになり、「2,RS」部分でメールの状態を表す 「1,」で始まるとき、実験的セマンティクス 「2,」で始まるとき、コンマに続く各文字は独立したフラグを表す フラグ「P(passed)」 … ユーザがこのメッセージを他の人へ再送/転送/バウンスした フラグ「R(replied)」 … ユーザがこのメッセージに返信した フラグ「S(seen)」 … ユーザはこのメッセージを閲覧した(最後まで読み通してはいないかもしれない) フラグ「T(trashed)」 … ユーザはこのメッセージをゴミ箱に移した(ゴミ箱は後日、ユーザの手で空にされることになる) フラグ「D(draft)」 … ユーザはこのメッセージを下書きとみなしている(これはユーザの裁量で切替えられる) フラグ「F(flagged)」 … ユーザ定義フラグ(ユーザの裁量により切替えられる) ■参考 【メール】Maildir と Mailbox の解説 | 100%レンタルサーバーを使いこなすサイト https://go-journey.club/archives/9377 Maildirの仕様について | ijo.cc http://ijo.cc/it/ja/server/maildir_spec/ Using maildir format http://cr.yp.to/proto/maildir.html ■メールを実際に確認 Command.txt の「メールをコマンドで表示」「バーチャルメールボックスのメールを確認」を参照
■root宛のメールを削除する
■即座に削除する
# cat /dev/null > /var/spool/mail/root
新しいメールが /var/spool/mail/root にありますを停止する方法 https://genchan.net/server/9970 気付いたらrootメールが溢れてる http://multix.jp/rootmail-overflow/ /var/spool/mail/rootを削除する https://cloudpack.media/1024 ■ログローテートで削除する
# vi /etc/logrotate.d/mail
/var/spool/mail/root { su root root daily rotate 14 missingok notifempty compress }
以下で想定の結果を確認できる
# logrotate -dv /etc/logrotate.conf
以下で実際にローテートが実行される
# logrotate /etc/logrotate.conf
なお今回の場合、「su root root」の指定が無いと以下のようなエラーになってローテートされないので注意
rotating pattern: /var/spool/mail/root after 1 days (14 rotations) empty log files are not rotated, old logs are removed considering log /var/spool/mail/root error: skipping "/var/spool/mail/root" because parent directory has insecure permissions (It's world writable or writable by group which is not "root") Set "su" directive in config file to tell logrotate which user/group should be used for rotation.
ログローテートについては、Basis.txt の「ログ保存期間を設定」も参照
■MailHogでメールの受信をテストする
ローカルでメール受信のテストに使える Vagrantの場合は必要性はあまり感じないかもしれないが、ローカルのDocker環境などでは有効かも MailHogでメール送受信のテストをする - Qiita https://qiita.com/hideji2/items/1919d5759cf42146f919 ■導入
# wget https://github.com/mailhog/MailHog/releases/download/v0.2.1/MailHog_linux_amd64 # chmod +x MailHog_linux_amd64 # ./MailHog_linux_amd64 2019/06/06 16:27:39 Using in-memory storage 2019/06/06 16:27:39 [SMTP] Binding to address: 0.0.0.0:1025 [HTTP] Binding to address: 0.0.0.0:8025 2019/06/06 16:27:39 Serving under http://0.0.0.0:8025/ Creating API v1 with WebPath: Creating API v2 with WebPath: [APIv1] KEEPALIVE /api/v1/events [APIv1] KEEPALIVE /api/v1/events [APIv1] KEEPALIVE /api/v1/events
「KEEPALIVE」の文字が表示されたら起動に成功していると思われる。初回は2〜3分かかるかも? この状態で以下にアクセスすると、メールの一覧画面が表示された このために Vagrantfile を編集したり…は不要だった http://192.168.33.10:8025/ Ctrl+C で終了される 終了すると、上記画面も表示されなくなった MailHog実行用に、ターミナルを1つ立ち上げておくと良さそう ■コマンドで送信 以下のようにすれば、コマンドからMailHog経由でメールを送信できる
$ echo "test" | mail -s "title" -S "smtp=smtp://localhost:1025" -r from@example.com to@example.com $ echo "テスト。 これはテストです。" | mail -s "テストメール" -S "smtp=smtp://localhost:1025" -r from@example.com to@example.com
「-S」でSMTPサーバを指定できる mailコマンドでSMTPサーバを指定してメール送信する方法 | ぴぐろぐ https://pig-log.com/mail-smtp-linux/ ■PHPからSMTPで送信 例えばPHPMailerを使用した場合、以下のようにすればMailHog経由でメールを送信できる
<?php require_once 'PHPMailer/class.phpmailer.php'; require_once 'PHPMailer/class.smtp.php'; // SMTPサーバ: ホスト define('SMTP_HOST', 'localhost'); // SMTPサーバ: 送信ポート define('SMTP_PORT', '1025'); // メール送信準備 $mail = new PHPMailer(); $mail->isSMTP(); $mail->Host = SMTP_HOST; $mail->Port = SMTP_PORT; // メール内容定義 $mail->CharSet = 'UTF-8'; $mail->Encoding = 'base64'; $mail->setFrom('from@example.com', 'メール送信者'); $mail->addAddress('to@example.com', 'メール受信者'); $mail->Subject = 'MailHogからの送信テスト'; $mail->Body = "テスト。\r\nこれはMailHogからの送信テストです。"; // メール送信 if (!$mail->send()) { exit('Error: ' . $mail->ErrorInfo); } exit('complete');
■PHPの mail 関数で送信 mhsendmailを追加導入すれば、PHPのメール送信関数からMailHog経由でメールを送信できる
# curl -sSLO https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64 # chmod +x mhsendmail_linux_amd64 # mv mhsendmail_linux_amd64 /usr/local/bin/mhsendmail # vi /etc/php.ini
sendmail_path = "/usr/local/bin/mhsendmail --smtp-addr=localhost:1025"
# service httpd restart
mb_send_mail 関数で送信してMailHogで受信できる ただしこの方法だと日本語メールは文字化けする 現状対処方法は見つけられていない php.ini でSMTPサーバを指定する方法はあるようだが、Windows専用の設定らしい dockerコンテナでPHPからのメール送信とhttpsに対応する - Qiita https://qiita.com/kinoleaf/items/0b0002aa03993e58e2f0 ■Dockerで利用 ※未検証 dockerコンテナでPHPからのメール送信とhttpsに対応する - Qiita https://qiita.com/kinoleaf/items/0b0002aa03993e58e2f0 ■XAMPPで利用 ※未検証 XAMPP にメールサーバ? それ MailHog でサクッとできるよ - てっきんの具。 https://www.tecking.org/archives/5717
■バウンスメールを解析
Command.txt の同項目を参照
■MySQLのデータベース文字コード
utf8_unicode_ciではなく、utf8_general_ciにしておくのが無難 MySQLのutf8_general_ciとutf8_unicode_ciの違い http://program.sagasite.info/wiki/index.php?MySQL%E3%81%AEutf8_general_ci%E3%81%A8utf8_unicode_ci%E3... utf8_unicode_ci に対する日本の開発者の見解 http://blog.kamipo.net/entry/2015/03/08/145045 MySQLの照合順序 http://qiita.com/Vit-Symty/items/159c27d7d62c78ee9ce7 ※今はutf8だけでなく、utf8mb4についても検討する
■PostgreSQLでEUC_JPのデータベースを作成
psql -l … データベースの文字コードを確認 dropdb test … 一旦testデータベースを削除する場合 createdb -E EUC_JP --locale=ja_JP.EUC_JP test --template=template0 … 文字コードを指定してtestデータベースを作成
PostgreSQLのinitdbと違うロケールでDB作成 http://wsjp.blogspot.jp/2012/04/postgresqlinitdbdb.html PostgreSQLエラー「createdb: データベースの生成に失敗しました: ERROR: 符号化方式 EUC_JP がロケール ja_JP.UTF-8 に合いません」の原因と解決方法 http://nobuneko.com/blog/archives/2011/10/postgresqlcreatedb_error_euc_j.html 以下、「他にこのデータベースを使っている 1 個のセッションがあります。」のように表示された場合の対象方法 アクセスしているユーザを調べて強制的に追い出す
psql test … testデータベースに接続 SELECT * FROM pg_stat_activity; … アクセスしているユーザを調べる SELECT pg_terminate_backend(567) FROM pg_stat_activity WHERE usename = 'usename'; … procidとusernameを指定して追い出す \q … ログアウト
具体例
SELECT pg_terminate_backend(7960) FROM pg_stat_activity WHERE usename = 'postgres'; SELECT pg_terminate_backend(5484) FROM pg_stat_activity WHERE usename = 'postgres'; SELECT pg_terminate_backend(7404) FROM pg_stat_activity WHERE usename = 'postgres';
「WHERE usename = 'postgres'」は無くても大丈夫かも? 参考 http://blog.kter.jp/?cat=80
■SSIを使用する
【SSI】ssiを実装するにあたって - Qiita https://qiita.com/yoshida-hi/items/4909c578b098f172efdb 拡張子 .shtml でSSIを有効にする場合、httpd.conf か .htaccess に以下の内容を追加(AddType の行は無くてもいいみたい)
Options +Includes AddType text/html shtml AddHandler server-parsed shtml
拡張子 .html でもSSIを有効にする場合、AddHandler の行を以下のように変更
AddHandler server-parsed html shtml
例えば ssi/test.html という以下のファイルがある場合、
<p>test</p>
以下のように include を使用するとファイルの内容を表示できる パスは公開フォルダが基準になる(「/」は公開フォルダ直下となる)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>テスト</title> </head> <body> <h1>テスト</h1> <p>テスト。</p> <!--#include virtual="/ssi/test.html" --> <p>テスト。</p> </body> </html>
■サーバ2台構成でWordPress(rsyncでファイル双方向同期、MySQLレプリケーションでデータベース同期)
■前提 AWSに環境を構築したときのメモ web1とweb2の二台に、WordPressの動作する環境が構築済みとする ■ホスト名の設定(web1、web2とも)
# hostnamectl set-hostname web1.refirio.net # vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 refirio.net refirio.net ↓ 127.0.0.1 localhost web1.refirio.net localhost4 localhost4.localdomain4 refirio.net refirio.net
# vi /etc/sysconfig/network
HOSTNAME=web1.refirio.net
※web2では「web1.refirio.net」という名前で同様の設定を行う ■レプリケーションの設定 web1をMaster、web2をSlaveとする □Master
$ curl http://10.0.1.42/ # vi /etc/my.cnf
[mysqld] log-bin=mysql-bin server-id = 1001
# systemctl restart mysql # mysql -u root -p mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO repl@10.0.1.42 IDENTIFIED BY 'gV0+8k6BM#z7'; mysql> FLUSH PRIVILEGES; mysql> SELECT host,user FROM mysql.user; mysql> FLUSH TABLES WITH READ LOCK; … データ手動コピー前にテーブルロック mysql> SHOW MASTER STATUS; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000002 | 633 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) # cd /var/lib/mysql # ll # tar czf wordpress.tar.gz wordpress … MySQLのデータをバックアップ mysql> UNLOCK TABLES; … データ手動コピー後にテーブルロック解除 # cp /var/lib/mysql/wordpress.tar.gz /usr/share/nginx/html/wordpress.tar.gz
□Slave
$ wget http://10.0.1.253/wordpress.tar.gz # cd /home/centos # cp /home/centos/wordpress.tar.gz /var/lib/mysql/wordpress.tar.gz $ curl http://10.0.1.253/ … 疎通テスト $ mysql -h 10.0.1.253 -u repl -p … 疎通テスト
※最初MySQLで通信できなかった。内部通信を許可するために、セキュリティグループに「default」を追加 http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-network-security.html#default-securit...
# systemctl stop mysql # cd /var/lib/mysql … MySQLのデータをバックアップから復元 # mv wordpress wordpress.backup # tar xvzf wordpress.tar.gz # vi /etc/my.cnf … レプリケーション設定
[mysqld] server-id=1002
# systemctl start mysql # mysql -u root -p mysql> CHANGE MASTER TO … Masterへの接続情報を設定 MASTER_HOST='10.0.1.253', MASTER_USER='repl', MASTER_PASSWORD='gV0+8k6BM#z7', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000002', … 「SHOW MASTER STATUS」で確認した「File」 MASTER_LOG_POS=633; … 「SHOW MASTER STATUS」で確認した「Position」 mysql> FLUSH PRIVILEGES; mysql> START SLAVE; … レプリケーションを開始
□いったん動作確認 Master側でテーブルを作成&データを登録し、Slave側にも反映されていることを確認する ■WordPressの接続設定を調整 □Master
mysql> GRANT ALL PRIVILEGES ON wordpress.* TO wordpress@10.0.1.253 IDENTIFIED BY 'Hy8R63mAdF'; … WordPress用ユーザ追加 mysql> GRANT ALL PRIVILEGES ON wordpress.* TO wordpress@10.0.1.42 IDENTIFIED BY 'Hy8R63mAdF'; … WordPress用ユーザ追加 mysql> FLUSH PRIVILEGES; mysql> SELECT host,user FROM mysql.user;
□両方のサーバにHyperDBをインストール
# cd # wget http://downloads.wordpress.org/plugin/hyperdb.zip # unzip hyperdb.zip # cd hyperdb # cp db-config.php /home/kusanagi/wordpress/DocumentRoot/ # chown kusanagi. /home/kusanagi/wordpress/DocumentRoot/db-config.php # cp db.php /home/kusanagi/wordpress/DocumentRoot/wp-content/ # chown kusanagi. /home/kusanagi/wordpress/DocumentRoot/wp-content/db.php # cd /home/kusanagi/wordpress/DocumentRoot/ … 公開ディレクトリへ移動 # vi db-config.php
217行目あたり
$wpdb->add_database(array( 'host' => DB_HOST, // If port is other than 3306, use host:port. 'user' => DB_USER, 'password' => DB_PASSWORD, 'name' => DB_NAME, ));
以下のように編集(「write」と「read」の指定を追加)
$wpdb->add_database(array( 'host' => DB_HOST, // If port is other than 3306, use host:port. 'user' => DB_USER, 'password' => DB_PASSWORD, 'name' => DB_NAME, 'write' => 1, 'read' => 1, ));
228行目あたり
$wpdb->add_database(array( 'host' => DB_HOST, // If port is other than 3306, use host:port. 'user' => DB_USER, 'password' => DB_PASSWORD, 'name' => DB_NAME, 'write' => 0, 'read' => 1, 'dataset' => 'global', 'timeout' => 0.2, ));
以下のように編集(「host」の指定を変更)
$wpdb->add_database(array( 'host' => DB_HOST_RO, // If port is other than 3306, use host:port. 'user' => DB_USER, 'password' => DB_PASSWORD, 'name' => DB_NAME, 'write' => 0, 'read' => 1, 'dataset' => 'global', 'timeout' => 0.2, ));
WordPressの設定ファイルをバックアップし、設定ファイルを編集
# cp -p wp-config.php wp-config.php.backup # vi wp-config.php
32行目あたり
define('DB_HOST', 'localhost');
以下のように編集
//define('DB_HOST', 'localhost'); define('DB_HOST', '10.0.1.253'); define('DB_HOST_RO', '10.0.1.42');
■rsync設定(一方向同期) □同期元サーバ:キーを作成
# ssh-keygen -t rsa # cat .ssh/id_rsa.pub ssh-rsa AAAAB3NzaC 〜略〜 JKFwq52AwP root@web1.refirio.net
□同期先サーバ:ユーザを作成
# useradd rsync # usermod -G wheel rsync # usermod -a -G apache rsync # usermod -a -G kusanagi rsync
□同期先サーバ:キーの設定
# mkdir -p /home/rsync/.ssh # chmod 700 /home/rsync/.ssh # vi /home/rsync/.ssh/authorized_keys
ssh-rsa xxxxxxxxxx
# chmod 600 /home/rsync/.ssh/authorized_keys # chown -R rsync:rsync /home/rsync
□同期元サーバ:接続確認
# ssh -p 22 rsync@10.0.1.42
□同期元サーバ:lsyncdインストール
# yum install --enablerepo=epel lsyncd # chmod 0775 /home/kusanagi # mkdir /home/kusanagi/rsync # chown kusanagi. /home/kusanagi/rsync # chmod 0775 /home/kusanagi/rsync # cd /home/kusanagi/rsync # rsync -e "ssh -p 22" -avz --delete /home/kusanagi/rsync rsync@10.0.1.42:/home/kusanagi … 動作確認
□同期元サーバ:自動同期設定
# vi /etc/lsyncd.conf
settings { logfile = "/var/log/lsyncd/lsyncd.log", statusFile = "/var/log/lsyncd/lsyncd.stat", maxProcesses = 2, statusInterval = 1, insist = 1 } sync { default.rsync, source = "/home/kusanagi/rsync", target = "rsync@10.0.1.42:/home/kusanagi/rsync", delay = 2, exclude = { "*.swp" }, rsync = { archive = true, compress = false, rsh = "ssh -p 22" } }
# systemctl start lsyncd.service # systemctl enable lsyncd.service # systemctl is-enabled lsyncd.service
■rsync設定(双方向同期) 「rsync(一方向同期)」の設定を、同期元と同期先を逆にして追加設定する
# cat .ssh/id_rsa.pub ssh-rsa AAAAB3NzaC 〜略〜 kATrJQOJ+J root@web2.refirio.net # ssh -p 22 rsync@10.0.1.253 # rsync -e "ssh -p 22" -avz --delete /home/kusanagi/rsync rsync@10.0.1.253:/home/kusanagi
■WordPress同期 □同期を停止させておく web1&web2:
# sudo su - # systemctl stop lsyncd.service
□公開フォルダを退避 web1&web2:
# cd /home/kusanagi/wordpress # mv DocumentRoot DocumentRootTmp # mkdir DocumentRoot # chown kusanagi. DocumentRoot # chmod 0775 DocumentRoot
□上位ディレクトリのパーミッションを調整
# chmod 0775 /home/kusanagi
□公開フォルダで同期をテスト web1:
# vi DocumentRoot/index.php # rsync -e "ssh -p 22" -avz --delete /home/kusanagi/wordpress/DocumentRoot rsync@10.0.1.42:/home/kusanagi/wordpress
web2:
# vi DocumentRoot/test.php # rsync -e "ssh -p 22" -avz --delete /home/kusanagi/wordpress/DocumentRoot rsync@10.0.1.253:/home/kusanagi/wordpress
□自動同期対象を変更 web1&web2:
# vi /etc/lsyncd.conf
/var/www/html/rsync ↓ /home/kusanagi/wordpress/DocumentRoot
※2箇所あるパスを修正
# systemctl start lsyncd.service
自動同期を確認後、また停止させておく
# systemctl stop lsyncd.service
□公開フォルダを戻す web1で公開ディレクトリ内をWordPressに戻す (web2では公開ディレクトリ内をカラにしておく)
# mv DocumentRoot DocumentRootTmp2 # mv DocumentRootTmp DocumentRoot
□ファイルの所有者を調整 web1&web2: /home/kusanagi/wordpress 内で作られたファイルの所有者を kusanagi にする
# chown kusanagi. /home/kusanagi/wordpress # chmod 0775 /home/kusanagi/wordpress # chmod g+s /home/kusanagi/wordpress # chmod g+s /home/kusanagi/wordpress/DocumentRoot
web1:
# find /home/kusanagi/wordpress -type d -print | xargs chown kusanagi. # find /home/kusanagi/wordpress -type f -print | xargs chown kusanagi.
□WordPressを同期 web1の公開ディレクトリ内はWordPress、 web2の公開ディレクトリ内はカラ、 という状態でweb1で以下を実行。同期テストする
# rsync -e "ssh -p 22" -avz --delete /home/kusanagi/wordpress/DocumentRoot rsync@10.0.1.42:/home/kusanagi/wordpress
完了したら、web2からも同期をテストする
# rsync -e "ssh -p 22" -avz --delete /home/kusanagi/wordpress/DocumentRoot rsync@10.0.1.253:/home/kusanagi/wordpress
どちらも大丈夫なら、自動同期を開始してテストする
# systemctl start lsyncd.service
自動同期も大丈夫なら、管理画面から記事の登録やメディアのアップロードなどをテストする
■独自ドメインを設定する(ムームードメイン)
■WHOIS情報 情報公開 … 弊社情報代理公開 ■ネームサーバ設定変更 サービス … ムームーDNS ムームーDNSセットアップ ネームサーバ1 … dns01.muumuu-domain.com ネームサーバ2 … dns02.muumuu-domain.com ■ムームーDNSのセットアップ情報(カスタム設定) No サブドメイン 種別 内容 優先度 1 A 153.121.33.84 2 www A 153.121.33.84
■コントロールパネルからリモートコンソールを使う(さくらの専用サーバ)
リモートコンソールを実行できない場合Javaのセキュリティが影響している可能性がある Windowsのコントロールパネルから「Java」を選択し、 「セキュリティ」タブの「例外サイト・リスト」に以下のURLを追加する (契約者によってURLが違う可能性があるので要確認。) http://ds-proxy30-u.sakura.ne.jp
■OS再インストール(さくらのVPS)
OS再インストール https://help.sakura.ad.jp/app/answers/detail/a_id/2408
■システム障害対策
障害対策の資料では、以下のような略語が使われることがある S/W ... SoftWare ソフトウェア H/W ... HardWare ハードウェア N/W ... NetWork ネットワーク I/F ... InterFace インターフェース I/O ... Input/Output 入出力 C/S ... Client/Server クライアントサーバシステム
■接続元引越時のTODO
オフィスの移転(引っ越し)を行う場合、アクセス制限用のIPアドレスを調整する必要がある 以下などは要確認 ・コントロールパネルでの設定 ・/etc/sysconfig/iptables ・/etc/hosts.deny ・/etc/hosts.allow ・その他 httpd.conf や .htaccess など

Advertisement