「Web」の版間の差分
(mod_authz_core) |
(Substitution) |
||
| (同じ利用者による、間の5版が非表示) | |||
| 1,982行目: | 1,982行目: | ||
==== mod_rewrite ==== | ==== mod_rewrite ==== | ||
[https://httpd.apache.org/docs/current/ja/rewrite/ Apache mod_rewrite - Apache HTTP Server Version 2.4] | [https://httpd.apache.org/docs/current/ja/rewrite/ Apache mod_rewrite - Apache HTTP Server Version 2.4] | ||
https://grok.com/share/c2hhcmQtMw%3D%3D_051d98f7-939d-4c82-977d-c30f506b61c7 | |||
リダイレクトを扱うモジュール。非常によく使うので重要。 | リダイレクトを扱うモジュール。非常によく使うので重要。 | ||
* RewriteEngine: mod_rewriteの機能のON/OFF。基本は使う前にOnにするだけ。 | |||
* RewriteBase: ベースURLを指定。サブディレクトリー以下で、相対パスでリダイレクトする際に使用。 | |||
* RewriteCond: RewriteRuleの実行条件指定。 | |||
* RewriteRule: 実際のURL変換ルール。 | |||
* RewriteMap: 外部ファイルからマッピングを取得して変数に割り当てる。 | |||
* RewriteOptions: mod_rewriteの動作オプション設定。 | |||
===== RewriteBase ===== | |||
ベースURLを指定。サブディレクトリー以下で、相対パスでリダイレクトする際に使用。記述の簡略化が可能。 | |||
# /blogディレクトリ内の.htaccessの場合 | |||
RewriteBase /blog/ | |||
RewriteRule ^archives/([0-9]+)$ archives/detail.php?id=$1 [L] | |||
# 上記は /blog/archives/123 → /blog/archives/detail.php?id=123 になる | |||
===== RewriteRule ===== | |||
mod_rewriteのコア。マッチしたパターンを置換先にリダイレクトする。 | |||
RewriteRule Pattern Substitution [flags] | |||
====== 例 ====== | |||
内部リダイレクト (フレームワーク用) | |||
RewriteRule ^(.+)$ /index.php?url=$1 [L,QSA,B] # デフォルト | |||
外部リダイレクト (SEO用) | |||
RewriteRule ^old-category$ /new-category [R=301,L,NC] # ケース無視 | |||
フルセット(HTTPS + クリーンURL) | |||
# HTTPS強制 | |||
RewriteRule ^(.*)$ <nowiki>https://%{HTTP_HOST}/$1</nowiki> [R=301,L] | |||
# クリーンURL | |||
RewriteCond %{REQUEST_FILENAME} !-f | |||
RewriteRule ^(.*)$ /index.php [L,QSA,B] | |||
====== Substitution ====== | |||
置換先の文字列。いくつかありえる。 | |||
* ファイルシステムパス | |||
* URLパス | |||
* 絶対URL | |||
* - (ダッシュ): 置換しない。環境変数設定などのフラグの設定用。 | |||
加えて以下の特殊文字も使用可能。 | |||
* 後方参照 (RewriteRule) $N | |||
* 後方参照 (RewriteCond) %N | |||
* サーバー変数 %{} | |||
* マッピング関数 ${mapname:key~default} | |||
====== Flags ====== | |||
[https://httpd.apache.org/docs/current/ja/rewrite/flags.html RewriteRule Flags - Apache HTTP Server Version 2.4] | |||
指定可能なフラグが大量にある。が、よく使うものは少数。よく使う準。 | |||
* L|last: これ以上ルールを処理しない。関数でいうreturn/exit/break相当。これを指定しない場合、上のほうのRewriteRuleで書き換えた結果を、後続のRewriteRuleで処理することになる。基本は1 RewriteRuleにつき1L。ほぼ常につける。 | |||
* QSA|qsappend: Query String Append。本来、書き換えする際、?%{QUERY_STRING}を自分で明示的にしない限り、クエリー文字列は破棄される。破棄せずに自動的に引き継いでくれる。リダイレクトするときに、クエリー文字列も引き継いでほしいことが多いのでよく指定する。ほぼ常につける。 | |||
* R|redirect: 外部リダイレクト、HTTPリダイレクトを行う。これを指定しない場合、内部リダイレクト (URLは変わらない)。R=のあとに有効なHTTPステータスコードを指定できる。302=temp (デフォルト) /301=permanent/303=seeotherのシンボリック名がある。 | |||
* NC|nocase: Patternのマッチの大文字小文字を無視する。 | |||
* B (escape backreferences): 変換前に非英数字をエスケープする。後方参照時に基本的に使う。URLのマッピング前に、URL内のエスケープを解除する。したがって、後方参照時に、エスケープが解除される。このフラグを適用すると、後方参照内の英数字以外がエスケープされる。例えば、検索フォームでx & y/zを入力すると、アドレスバーやリクエストはエスケープしてくれる。が、後方参照はエスケープを解除してしまうので、BがないとURLにx&y/zがそのまま登場して不正なURLになる。 | |||
* PT|passthrogh: Alias/ScriptAlias/Redirectを解釈したい場合に使用。 | |||
L(100%) > QSA(90%) > R(70%) > NC(50%) > B(40%) > PT(20%) | |||
あまり使わない。 | |||
* E|env: 環境変数を設定する。 [E=VAR:VAL] # 環境変数VARにVALを代入。 [E=VAR] # 環境変数VARを空で定義。 [E=!VAR] # 環境変数VARを解除。 | |||
* UnsafeAllow3F: 基本は使わない。Apache v2.2までは、URLクエリー文字列内部に?がある場合、バックリファレンスで?がそのままだった。が、v2.4からはエンコードして%3Fにしている。この動きが困る場合だけつける。レガシー互換用。本来ならアプリで対応すべき内容。 | |||
[L,QSA] をデフォルトフラグに思っておくとよい。R/NC/B/PTは状況に応じて、状況にマッチしたら必須になる。 | |||
===== RewriteCond ===== | |||
RewriteCond TestString CondPattern [flags] | |||
RewriteCondはルールの条件 (if文相当) の定義指令。RewriteRuleの直前に配置する。 | |||
RewriteRuleで使用可能な変数をテストしてRewriteRuleで書き換えるかどうか振り分ける。 | |||
====== 例 ====== | |||
# 1. ファイルが存在しない場合のみリライト | |||
RewriteCond %{REQUEST_FILENAME} !-f | |||
RewriteCond %{REQUEST_FILENAME} !-d | |||
RewriteRule ^(.*)$ /index.php [L] | |||
# 2. HTTPS接続を強制 | |||
RewriteCond %{HTTPS} off | |||
RewriteRule ^(.*)$ <nowiki>https://%{HTTP_HOST}%{REQUEST_URI}</nowiki> [R=301,L] | |||
# 3. 特定のUser-Agentをブロック | |||
RewriteCond %{HTTP_USER_AGENT} (malicious-bot|spammer) [NC] | |||
RewriteRule .* - [F] | |||
# 4. ホットリンク防止 | |||
RewriteCond %{HTTP_REFERER} !^$ | |||
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?example\.com/ [NC] | |||
RewriteRule \.(jpg|png|gif)$ - [NC,F,L] | |||
====== 後方参照 ====== | |||
backreferenceという構文。Pattern/TestString部分で丸括弧で囲んだ部分を、Substitution/CondPatternでも参照可能。N=0-9の数字で、RewriteRuleは$N、RewriteCondは%Nで参照。N=0はマッチ全体。 | |||
RewriteRuleの場合、[B]オプションを指定して、原則エスケープする。 | |||
====== 変数 ====== | |||
{| class="wikitable" | |||
!HTTP headers: | |||
!connection & request: | |||
! | |||
|- | |||
|HTTP_ACCEPT | |||
HTTP_COOKIE | |||
HTTP_FORWARDED | |||
HTTP_HOST | |||
HTTP_PROXY_CONNECTION | |||
HTTP_REFERER | |||
HTTP_USER_AGENT | |||
|AUTH_TYPE | |||
CONN_REMOTE_ADDR | |||
CONTEXT_PREFIX | |||
CONTEXT_DOCUMENT_ROOT | |||
IPV6 | |||
PATH_INFO | |||
QUERY_STRING | |||
REMOTE_ADDR | |||
REMOTE_HOST | |||
REMOTE_IDENT | |||
REMOTE_PORT | |||
REMOTE_USER | |||
REQUEST_METHOD | |||
SCRIPT_FILENAME | |||
| | |||
|- | |||
!server internals: | |||
!date and time: | |||
!specials: | |||
|- | |||
|DOCUMENT_ROOT | |||
SCRIPT_GROUP | |||
SCRIPT_USER | |||
SERVER_ADDR | |||
SERVER_ADMIN | |||
SERVER_NAME | |||
SERVER_PORT | |||
SERVER_PROTOCOL | |||
SERVER_SOFTWARE | |||
|TIME_YEAR | |||
TIME_MON | |||
TIME_DAY | |||
TIME_HOUR | |||
TIME_MIN | |||
TIME_SEC | |||
TIME_WDAY | |||
TIME | |||
|API_VERSION | |||
CONN_REMOTE_ADDR | |||
HTTPS | |||
IS_SUBREQ | |||
REMOTE_ADDR | |||
REQUEST_FILENAME | |||
REQUEST_SCHEME | |||
REQUEST_URI | |||
THE_REQUEST | |||
|} | |||
特によく使うものは以下。 | |||
* REQUEST_FILENAME: リクエストされたファイルのサーバー上の絶対パス。 | |||
* REQUEST_URI: /index.htmlのようなリクエストURIのパス部分。URLクエリーはQUERY_STRINGにある。 | |||
====== CondPattern ====== | |||
CondPatternはTestStringに対する正規表現 (PCRE) が基本。ただし、いくつかの追加の構文が使用可能。 | |||
# !文字の前置でCondPatternの否定になる。 | |||
# 辞書比較演算子が使用可能。 | |||
## < | |||
## > | |||
## = | |||
## <= | |||
## >= | |||
# 数値比較演算子が使用可能。 | |||
## -eq | |||
## -ge | |||
## -gt | |||
## -le | |||
## -lt | |||
## -ne | |||
# ファイル属性テスト。 | |||
## -d: ディレクトリー判定。 | |||
## -f: ファイル判定。 | |||
## -F: 内部リクエスト経由のファイル判定。サーバー性能に影響ある。 | |||
## | |||
## -l/-h/-L: シンボリックリンクの判定。-lt/-leとの混同防止で-h/-Lも使用可能。 | |||
## -s: ファイル判定+0超過ファイル。 | |||
## -U | |||
## -x: 実行権限 | |||
# TestStringが特殊値exprの場合、CondPatternはap_exprとみなす。 | |||
ファイル属性テストの-d/-fはよく使う。 | |||
====== Flags ====== | |||
RewriteCondの第3引数にフラグを指定できる。これは以下の3種だけ指定可能で、CondPatternに作用する。 | |||
* nocase|NC (No Case): 大文字小文字の違いを無視。 | |||
* ornext|OR (OR next condition): RewriteCondを複数記載時に、デフォルトのANDではなくORで判断する。 | |||
* novary|NV (No Vary): 条件にHTTPヘッダーを使用した場合、このフラグはレスポンスのVaryヘッダーに使用ヘッダーの追加を抑制する。あまり使わない。 | |||
ORをよく使う。 | |||
===== Debug ===== | |||
RewriteRuleは条件が複雑になりがちで、デバッグが重要。いくつか方法がある。 | |||
Log Level alert rewrite:trace3 | |||
mod_rewriteはLogLevelでのログ用にtrace1-trace8 (debug-emergに対応?) までのログレベルを用意している。 | |||
trace8=debug未満では、何のログも出力しない。2超過は性能が落ちるのでデバッグ用にだけ使う。 | |||
==== auth ==== | ==== auth ==== | ||
[https://httpd.apache.org/docs/2.4/ja/howto/auth.html 認証、承認、アクセス制御 - Apache HTTP サーバ バージョン 2.4] | [https://httpd.apache.org/docs/2.4/ja/howto/auth.html 認証、承認、アクセス制御 - Apache HTTP サーバ バージョン 2.4] | ||
| 2,059行目: | 2,269行目: | ||
Require not ip 192.168.1.1 | Require not ip 192.168.1.1 | ||
</RequireAll> | </RequireAll> | ||
====== Require ====== | |||
* [https://httpd.apache.org/docs/2.4/en/mod/mod_authz_user.html mod_authz_user - Apache HTTP Server Version 2.4] | |||
* [https://httpd.apache.org/docs/2.4/mod/mod_authz_host.html mod_authz_host - Apache HTTP Server Version 2.4] | |||
* [https://httpd.apache.org/docs/2.4/en/mod/mod_authz_groupfile.html mod_authz_groupfile - Apache HTTP Server Version 2.4] | |||
httpd v2.4で刷新された認証指令。非常に重要。 | |||
Require [not] <entity-name> [<entity-name> ...] <argument> | |||
上記のような書式。<entity-name> (プロバイダー) が複数あって、これで識別する。 | |||
* Require all granted: 全員許可 | |||
* Require all deniede: 全員禁止。 | |||
* Require env <env-var> [<env-var> ...]: いずれかの環境変数がある場合許可。 | |||
* Require method <http-method> [<http-method>...]: 指定したHTTPメソッドのみ許容。 | |||
* Require expr <expression>: <expression> がtrueの場合許容。 | |||
* Require user <userid> [<userid>...]: 指定したユーザーのみ。 | |||
* Require group <group-name> [<group-name>...]: 指定したグループのみ。 | |||
* Require valid-user: 有効なユーザーのみ (パスワードファイルに記載のあるユーザーのみ) | |||
* Require ip <ip> [<ip>...]: 指定したipのみ。ip/netmaskやip/CIDRの表記も可能。 | |||
* Require host <host-name> [<host-name>...]: 指定ホストのみ。 | |||
* Require forward-dns <> | |||
* Require local: ローカルのみ。 | |||
===== Basic ===== | ===== Basic ===== | ||
2025年10月14日 (火) 17:20時点における最新版
Other
Tool
いくつかWeb関係の開発で役立つツール集を公開しているサイトがある。
localhost
RFC 6761 で規定。RFC 2606で予約。DNSに登録されることはないため、テスト目的で使用可能。ループバック (送信元にそのまま返す) インターフェイス。
IPv4=127.0.0.1/IPv6=::1とされている。
DB vs. file
https://chatgpt.com/share/67f78855-b640-800b-84c9-ed3ada7fef48
データはアクセス元によって、速度や負荷が異なるらしい。それぞれ特徴がある。
- ファイル (JSON/php):
- インメモリーDB: Redis
- RDB: 排他処理。検索・集計。書込用。
書き込みの最終はRDBとして、そこからよく使うものを、書き込みの少ないものを、インメモリーDBやファイルに引き上げるような感じがする。
Application
検索機能のGET/POST
検索機能にGETとPOSTのどちらを使うか?という議論がある。
データ登録するわけなじゃないのだから、GETがいいんじゃない?
POSTだと、JSONをそのまま送れるので、複雑なケースに対応できる。特に、配列の送信が重要。
GETのほうが検索条件をブックマークにできたり、URLを共有できるので、基本は便利。
ただし、検索などのパラメーターが長くなる場合、使用できない。そもそも検索でそんなに長いパラメーターというのがまずいかもしれない。2000文字あれば十分という説がある。
レート制限対策
いろいろ方法がある。
- cronなどでデータをサーバー上 (DBなど) に定期保存して、保存データを表示させる。
- 配列を利用して、1回のリクエストでまとめて取得する。
- インターバルを設ける。
- HTTP 429/413を検知して、リトライする。
指数関数的バックオフ
- APIレート制限は何か、どのように対処するのか?
- Exponential backoff - Wikipedia
- 指数バックオフ | Memorystore for Redis | Google Cloud
- バックオフパターンで再試行 - AWS 規範ガイダンスリトライ時は以下のアルゴリズムがいいらしい。
wait_interval = base * 2^n +/- jitter
wait_intervalは、API が HTTP 429 で応答した場合に、システムがリクエストを再試行するまでの時間となります。baseは最初の間隔、つまり最初の再試行までの待ち時間です。この値には3000msを使用することをお勧めします。nは、現在の呼び出しの前にリクエストが通らなかった数です。複数のスレッドやプロセスを使用して並行してAPIを呼び出している場合、nの値は現在のスレッド/プロセスにスコープされます。この値は、現在のスレッド/プロセスが、最後に成功した応答から何回 429 "Too Many Requests" エラーに遭遇したかを表します。jitterは 0 からbaseの間の乱数です。これは、複数のスレッド/プロセスが全く同時にAPIを呼び出さないように、リクエストを少しずつ分散させるために使用されます。システムが待機するたびに、この乱数値を再計算しwait_intervalの合計に加算するか減算するか、ランダムで選択してください。
再送とリロード
https://chatgpt.com/c/67e25ec2-26bc-800b-acd9-0aa197476788
POSTなどデータ登録系のAPI呼び出しした際、そのままリロードすると、同じ登録処理が再送されてしまう。特に、URLクエリーで登録パラメーターを渡す場合など。
更新後に、リダイレクトでパラメーターを消す。これだと安全でシンプル。
あるいは、登録に使ったデータで、表示もする。ただ、処理失敗時や、キャッシュDBとの整合性がややこしいことがある。
https://grok.com/share/c2hhcmQtMw%3D%3D_6cd6ea6f-48b8-402a-9401-7edda0fded18
二重送信の対策がいろいろある。JavaScriptに依存しない方式。
- PRGパターン: フォーム送信後、サーバー側での処理完了後にリダイレクト (Post/Redirect/Getパターン)。これにより更新ボタン誤操作による再送信を防止。特に、URLクエリーで登録パラメーターを渡す場合などに有効。
- フォームトークンによる一意性確保: フォーム送信時に一意のトークンを発行し、サーバー側でトークンを検証、処理後に無効化または再生成。同一トークンは拒否。
- サーバー側でのリクエスト制限: 同一ユーザー・セッションからのリクエスト頻度を制限。セッションやDBに最後の送信時刻を記録。
1+2がシンプルで効果的とのこと。スパムが懸念される場合に、リクエスト制限を追加。
javascript前提でいいなら、submitで実装。
登録フォーム
https://grok.com/share/c2hhcmQtMw%3D%3D_9b8894da-350e-4de9-b51d-531f9eb40ce7
例えば、パスワード設定フォームを追加する場合など、何かの設定の設定フォームの実装方法。
password.php+password.tplがある。
GET password.phpでpassword.tplを表示。
フォームを入力してsubmitしたら、POST password.phpを呼び出し。
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['register'])) {とかでリクエストメソッドを確認。
POSTならパラメーターをチェックして、エラーならエラー表示。問題ないならindex.phpにリダイレクトとかすると、むやみにファイルが増えなくていい。
Naming
https://grok.com/share/c2hhcmQtMw%3D%3D_be0ed272-6be3-4b41-b654-859926dfd227
name属性の値はチェインケースがいい。HTMLの文脈だとチェインケースが主流。
URL
クエリー配列
- クエリストリングで配列を表現をするケースをざっと調べる - コード日進月歩
- PHPでクエリパラメータから配列を受け取る物語 #JavaScript - Qiita
- PHP: http_build_query - Manual
やり方がいくつかある。
- CSV文字列で受取後分割: https://www.sakdor.net/test/?var=1,2,3 explode(",",$_GET[var]);
- 配列添字
- http://www.sakdor.net/test/?var%5B%5D=1&var%5B%5D=2&var%5B%5D=3
- http://www.sakdor.net/test/?var%5Ba%5D=1&var%5Bb%5D=2&var%5Bc%5D=3
- http:www.sakdor.net?var[0]=1&var[1]=2&var[2]=3
データが決まっているならcsvがシンプル。
CGI
https://chatgpt.com/c/67634332-a3b8-800b-87a2-e21bd21a1cfc
WordPressなどのWebアプリだとファイル拡張子が登場しない。これはいくつかの仕組みが組み合わさって実現されている。
- パーマリンク設定 によるクリーンなURL構造の生成。
- .htaccess(Apache) や リライトルール によるURLの書き換えとルーティング。
- index.php を起点とする動的な処理。
- テンプレート階層 に従って適切なPHPファイルを呼び出す。
.htaccessでindex.phpにリダイレクトして、index.phpから全て処理している。これにより省略できている。
同じ用に、アプリ側が対応していれば、index.fcgiに全部リダイレクトして、パスを解釈してくれるなら、/でのアクセスもできる気がする。
apache - How can I run a FastCGI script in root url (/ - without path)? - Stack Overflow
スペースの扱い
https://grok.com/share/c2hhcmQtMw%3D%3D_9c2c3143-b190-42f7-a985-20444806187e
URLは、RFC3986に従って、特殊文字のエンコードが必要。スペースは特殊文字。
%20がスペースのエンコーディングだが、+はURLクエリーパラメーター (?key=value) 内のスペース表現で登場することがある。ただ、+はクエリーパラメーター以外の文脈ではスペースとして認知されない。%2Bはスペース時代の%エンコード。
基本的に、URLクエリーパラメーターに指定する場合、JavaScriptの場合encodeURIComponent (PHP urlencode=クエリー用、rawurlencode=パス用) でエンコードする。これで、スペースや+が適切にエンコードされる。
ただ、HTMLフォームでgetを使用する場合、Webブラウザーが自動的にクエリーパラメーターをapplication/x-www-form-urlencoded形式にするので、スペースが+になる。
HTTP
Content-Disposition
Content-Disposition - HTTP | MDN
RFC 6266 - Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)
Content-Disposition: inline Content-Disposition: attachment Content-Disposition: attachment; filename="filename.jpg"
filenameでファイル名を指定する。ここの値は二重引用符で囲む。スペースを含む場合に必須になる。
multipart/form-data
rfc7578
ファイルアップロード用のMIME type。
リクエストヘッダー
Content-Type: multipart/form-data; boundary=--hogehoge
リクエストボディー
--hogehoge Content-Disposition: form-data; name="user_name" Content-Type: text/plain test --hogehoge Content-Disposition: form-data; name="email" sample@mail.com --hogehoge Content-Disposition: form-data; name="gender" male --hogehoge Content-Disposition: form-data; name="user_profile" filename="image.jpeg" Content-Type: image/jpeg \xff\xd8\.... --hogehoge--
ヘッダーでmultipart/form-dataを明記して、ボディーでデータを指定する。
curlでの送信理由。
-Fで送信データをname=data形式で指定する。ファイルの内容を指定する場合、@filenameで指定する。これを指定すると、リクエストボディーのfilename扱いにしてくれる模様。-Fを指定すると、-H 'Content-Type: multipart/form-data'が自動付与される。たぶん、-dと同様に-X POSTもつく。
curl -X POST -F file1=@/var/tmp/sample.jpg https://xxxxx.net/xxxxxx
データとテキストを同時送信したい場合、-Fで複数指定する。
curl -X POST -F 'age=30' -F file1=@/var/tmp/sample.jpg https://xxxxx.net/xxxxxx
curlだと上記のboundaryなどをうまくやってくれるのだと思う。
リクエストボディー全体をファイルデータにする場合。
curl -X POST -H 'Content-Type: image/jpeg' --data-binary @/var/tmp/sample.jpg https://xxxxx.net/xxxxxx
IP address
出典: 固定IPアドレスの取得方法 ~実は簡単!フリーランスの方も必見です~|VPN活用日記|トピックス|グローカルネットの快適VPN【公式】| 株式会社グローカルネット。
自宅サーバーを行う際、固定IPアドレスが必要になる。
取得方法がいくつかある。
- 契約しているプロバイダでオプションとして申し込む方法
- 固定IPアドレスに対応しているSIMを契約する方法
- VPNを利用した固定IPアドレスの提供会社を利用する方法
VPNの固定IPアドレスが安いらしい。ryoかsuwakoが解説していた気がする。
Authentication
認証方式がいくつかある。HTTPで定義される認証方式 (HTTP認証) が有名。
Basic認証
出典: Basic認証 - Wikipedia。
Authorization HTTPヘッダーにBasicのあとに [username:password] をBASE64でエンコードして送信する認証方式。
GET /private/index.html HTTP/1.1 Host: example.com Authorization: Basic cm9vdDpwYXNzd29yZA==
盗聴や改ざんが簡単だが、シンプルという利点がある。
Basic認証のキャッシュを削除する(ログアウトする) | DevelopersIO
ログアウト時は、hoge@domainのようにパスワードを省略した任意のユーザー名でログインを試みて既存のログイン状況を上書きする模様。
Digest認証も共通。
Digest認証
Basic認証・Digest認証・Form認証をざっくり理解 #Security - Qiita
HTTP標準の認証。Basic認証とほぼ同じ。ただし、パスワードをハッシュ化している。そのため、DBのパスワードが流出した場合に比較的安全。
OAuth
Ref
OAuth (オーオース) 権限の認可のための標準。OAuth 2.0が最新の標準。
以下が登場人物。
- resource owner: あるサイトのユーザー。
- resource server: あるサイトのユーザーのデータの保有サーバー。
- clent: クライアントアプリ。リソースサーバーのデータを使用したい。
- authorization server: クライアントにサイトへのアクセスを認証するサーバー。アクセストークンを発行して行う。
アクセストークンが実質的なパスワードのようなものだが、resource serverのパスワードを直接渡していない点が重要な違い。パスワードを直接渡さないことで、機能別に権限を細かく利用可否を制御できる。
処理の流れ。
- client->resource owner: Authorization Request。ここでユーザーが手操作でアクセスを承認する。
- client<-resource owner: Authorization Grant。
- client->authorization server: Authorization Grant。承認された情報でアクセストークンを要求。
- client<-authorization server: Access Token
- client->resource server: Access Token。アクセストークンでアクセス。
- client<-resource server: Access Token
Consumer Key/Secret: アプリ識別用のID/PW。
Access Token: サイトにアクセスするためのパスワード。
API
REST
About
https://grok.com/share/c2hhcmQtMw%3D%3D_ce6a55f0-0855-4a59-b94e-34a1060ee92f
Representational State Transfer。Webサービスの設計手法。状態を転送する。URLとHTTPメソッドを使って、リソースをやりとりする設計。CRUDなんかがこれ。
例えば、商品一覧は/itemsにアクセスGETして、単一商品は/items/1みたいな感じ。
URL=リソース、HTTPメソッド=操作というルールでAPIを設計する。直観的で再利用や保守もしやすいシステムになる。
例えば、セミナーの申し込みのような、動詞を伴う処理の場合。動作を名詞にして、その動作のPOSTみたいな形にする。
GET /api/seminars
GET /api/seminars/123/registrations/789
セミナーが複数絡んだりして複雑な場合や、シンプルにしたいなら、申込自体を独立リソースにする。
例えば、ログイン・ログアウトはセッションの作成・削除で考える。
POST /api/sessions
DELETE /api/sessions
サインアップは GET /users/new、実際の登録はPOST /usersとか。
バージョン
/api/v1とかでバージョン番号のプレフィクスを付けるのが一般的。
公開しなくて、内部的なapiで変更箇所を自分で全部対応できるなら、別になくてもいい。
破壊的変更時にv2などで上げる。
例えば、変更したくなったら、v1にオプションでパラメーターを追加して、ある程度たまった段階で、v2で任意だったのを必須にするとかする。
移行したら、v1の応答にDeprecation: trueとかSunset: 2026-01-01で通知するとか。
Routing
Webアプリを新しく作る際の画面構成。基本的にRoutingと一致のこと。
1機能1ルートみたいな感じ。あとはCRUDに対応したルート。オブジェクト指向になっているとなお良い。
- /register
- /login
- /logout
- /users
- /users/books/
- /my/books/
- /books
- /books/new
- /books/:id
CSR形式のアプリの場合、サーバー側には/api/を前置したルートを用意して、そちらにGET/POSTで必要なデータ処理する感じ。
複数レコードの登録
複数レコードの登録・更新・削除のREST APIについて調べてみた話(+@ Graph API) - junode | 個人開発ブログ
既存のAPIは単一リソースの処理しかないことが多い。JavaScriptなどで単一リソースを何回も呼べばいいというのはそうだけど、JavaScriptなしでは動作しない。一括処理用のAPIを作るしかなくないか?
REST WebAPIのプラクティス | yamarkz.com
delete_bulkなどのような一括処理用のAPIを作るしかない。内部的には単一処理のAPIを作る感じだったとしても。
パラメーター
json - REST API Best practices: args in query string vs in request body - Stack Overflow
パラメーターの指定に3種類ある。
- リクエストボディー
- クエリー
- パス
パスはIDなどを指定する場合だけわかりやすい。それ以外のオプションはクエリーのほうがいい。
ボディーは、通常サーバーのアップロード・ダウンロードデータとして使われる。クエリーはデータの指定に使う。
この原則に従うとシンプルだろう。
- URIには長さの制限がある。
- ボディー
- 引数が非常に多い場合。
- 画像などバイナリーデータ。
- キー・値構造を持たない場合。
- クエリー文字列
- 引数を簡単に確認できる。
- 共通の引数の場合。
API Server
認証
https://grok.com/share/c2hhcmQtMw%3D%3D_3f170c15-108d-44a3-bcc9-c4bfe545c9e9
APIサーバーでは、OAuthのような認証手順を一般的にとる。つまり、最初にトークンを発行する。
セッション情報
https://grok.com/share/c2hhcmQtMw%3D%3D_900d375c-0e8f-4765-be2a-514d504b6177
APIサーバーは通常、ステートレスな設計が推奨される。大量のリクエストが想定され、スケールアウトが必要になるので、セッション共有は扱いが複雑で不利になる。また、クライアントが多様で、他のサーバーからも利用されるので、クッキーに依存したセッション管理は向いていない。
そのため、トークンベースの認証が採用される。トークンにユーザーIDが埋め込まれていて、照合時にユーザーIDを取り出す方式が一般的。
それ以外だと、都度リクエストパラメーターを指定するとか。
レスポンス設計
https://grok.com/share/c2hhcmQtMw%3D%3D_de320f67-f064-4f8f-a147-cbf2e4594bcd
レガシーコードだと、全部200で応答本体に独自ステータスコードを持たせるというのがあったりする。
HTTPステータスコードは、リクエスト全体の成否を示す。クライアントが最初に確認する情報。Restful APIのベストプラクティス。
独自ステータスコードをHTTPステータスコードにも対応付けたらいい。それだけだからそんなに難しくない。
- 400 Bad Request: リクエストパラメーターエラー時の一般。
- 401 Unauthorized: 認証関係。
- 403 Forbidden: 認証済みだが、特定リソースへのアクセス制限時。
- 404 Not Found: 指定されたリソースが不在時。
- 422 Unprocessable Entity: 必須パラメーター類はそろっているが、値が無効な場合 (負の値、不正な座標値)。
- 500 Internal Server Error: DB接続エラー、SQL実行エラーなど、予期しないエラー発生時。
- 503 Service Unavailable: 一時的なサーバーの問題。DBメンテナンス中、過負荷など。
- 409 Conflict: リクエストがDBの状態と競合する場合。チェックイン済みの場所にチェックインとか。
- 429 Too Many Requests: レートリミット送信。
- 405 Method Not Allowed
後は、JSON APIというリクエストとレスポンスのボディーのJSONの標準形式があるので、これに準拠するとよさそう。
// 成功時
{
"data": {
"checkin_id": "12345",
"timestamp": "2025-10-07T10:39:00Z",
"latitude": 35.6895,
"longitude": 139.6917
}
}
// エラー時
{
"errors": {
"code": "1001",
"message": "チェックインに失敗しました。指定された場所から遠すぎます。",
"current_distance_meters": 1500,
"max_allowed_distance_meters": 100
}
}
トップレベル要素を配置することで、クライアントはこのプロパティーの有無で成否を判断できて処理が楽になるとか。まあ、そうか。
MVCだと、Modelがビジネスロジックで、エラーコードを定義することが多いので、ここでmapとかstaticメソッドを作ってやるとよさそう。
Swagger
About
API Documentation & Design Tools for Teams | Swagger
【初心者向け】Swaggerとは?シンプルに解説 - NRIネットコムBlog
API管理のためのツールセット。OpenAPI (旧Swagger API) というAPIの文書化の仕様に準拠したAPI文書の作成ツール。
具体的には以下の3ツールがある (Swagger Documentation | Swagger Docs)。
- Swagger Editor: API文書作成のエディター。YAMLかJSON形式でAPIを記述する。
- Swagger UI: APIを対話的に操作可能なエディター。Swagger Editorの生成結果的なもの。
- Swagger CodeGen: 複数のプログラミング言語向けにクライアントやサーバーコードの自動生成ツール。
APIは外部から呼び出しに使われる都合、重要。正確で一貫性のある設計が求められる。
- API設計を統一的な形式で記述でき、開発者間での形式のずれや誤解・不一致を防ぎ、一貫性のあるAPI開発が可能。
- API文書を自動生成できる。
Install
Editor
[Swagger Editor] のオンラインエディターで始めるのが手っ取り早い。他に、VSCodeの拡張機能で記述する方法もある。
VSCodeだとswaggerで検索してヒットする [OpenAPI (Swagger) Editor] とか。
Visual Studio CodeでOpenAPI(Swagger) Editorを使用する #VSCode - Qiita
[Alt-P] (> OpenAPI SwaggerUI preview) でプレビュー表示できる。
OpenAPI
About
openapi: 3.0.4
info:
title: Sample API
description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
version: 0.1.9
servers:
- url: http://api.example.com/v1
description: Optional server description, e.g. Main (production) server
- url: http://staging-api.example.com
description: Optional server description, e.g. Internal staging server for testing
paths:
/users:
get:
summary: Returns a list of users.
description: Optional extended description in CommonMark or HTML.
parameters: # リクエストパラメータ 省略可能。
- name: test
in: query
schema:
type: string
responses:
"200": # status code
description: A JSON array of user names
content:
application/json:
schema:
type: array
items:
type: string
以下が基本構成。
openapi: 3.0.4
info:
title: Sample API
description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
version: 0.1.9
servers:
- url: http://api.example.com/v1
description: Optional server description, e.g. Main (production) server
- url: http://staging-api.example.com
description: Optional server description, e.g. Internal staging server for testing
paths:
/users:
get:
summary: Returns a list of users.
description: Optional extended description in CommonMark or HTML.
parameters: # リクエストパラメータ 省略可能。
- name: test
in: query
schema:
type: string
responses:
"200": # status code
description: A JSON array of user names
content:
application/json:
schema:
type: array
items:
type: string
pathsの中に、APIパスとHTTPメソッドと応答の記載が基本。
responses.content
responses.content以下にmimeType別に応答を書く。同じapiでも複数のmime typeを許容できるからだろう。ただ、実際はapplication/jsonだけのことが多い。
schema以下で応答の種類を書く。基本は以下のどちらかだろう。
schema:
type: array
items:
type: string
# ["string"]
schema:
type: object
properties:
data:
type: string
# {data: "string"}
リクエストパラメーター
parameters、requestBodyにリクエストパラメーターを記載。
# クエリーパラメータ
/tests:
get:
summary: テストAPI(一覧)
parameters:
- name: data
in: query
schema:
type: string
/tests:
post:
summary: テスト登録API
requestBody:
content:
application/json:
schema:
type: object
properties:
data:
type: string
Components Section
- Components Section | Swagger Docs
- swaggerでAPIの仕様書を書こう! #初心者 - Qiita
- OpenAPI (Swagger) 超入門 #REST-API - Qiita
- 現場で必要になるswaggerの知識 #初心者 - Qiita
Swaggerを使うことのかなり大きな利点。Components。
APIは、APIのルートパスのオブジェクトを返したり、受け付けたりする。パスごとにこれを何回も書くことになる。SwaggerではこれをComponentとして定義しておいて、その参照で記述を省略できる。
components:
schemas:
object名:
type: object
properties:
プロパティ1:
type: string
format: string
description: "プロパティ1の説明"
example: "プロパティ1の例"
プロパティ2:
type: string
format: string
description: "プロパティ2の説明"
example: "プロパティ2の例"
required:
- プロパティ1
- プロパティ2
content:
application/json:
schema:
$ref: '#/components/schemas/object名'
こんな感じで参照して流用できる。
Using $ref
APIの文書作成時に、リソースを複数で参照したいことがある。OpenAPI 3.0で相互参照機能が導入された。
$refキーワードを使う。
components:
schemas:
User:
properties:
id:
type: integer
name:
type: string
responses:
"200":
description: The response
schema:
$ref: "#/components/schemas/User"
定義と参照を上記のように行う。
$refはJSON Reference (JSON pointer) 記法になっている。#以降はファイル内参照を意味する。先頭の#で現在のファイル。
$ref: 'document.json#/myElement' のように記載することで、別のファイル内のコンポーネントを参照できる。
どこでも使えるわけではない。値として使える場所にだけ使える。例えば、以下のようにパスのところに直接指定はできない。
openapi: 3.0.4 # Incorrect! info: $ref: info.yaml paths: $ref: paths.yaml
paths:
/users:
$ref: "../resources/users.yaml"
/users/{userId}:
$ref: "../resources/users-by-id.yaml"
値の文脈としてしか使えないので、パスの中身として使う。
Escape Characters
| Character | Escape With |
|---|---|
~
|
~0
|
/
|
~1
|
エスケープ文字が独特なので注意する。
/blogs/{blog_id}/new~posts
$ref: "#/paths/~1blogs~1{blog_id}~1new~0posts"
Example
https://grok.com/share/c2hhcmQtMw%3D%3D_e2b6d5e1-dd0d-4412-8858-a99c09f15a0c
$ref記法を使うことで、ファイル分割できる。
JSON Referenceでリソースを直接参照することで対応する。
openapi.yml
openapi: 3.0.3
info:
title: Sample API
version: 1.0.0
paths:
/users: {$ref: './paths/users.yaml#/paths/~1users'}
components:
schemas:
User: {$ref: './paths/users.yaml#/components/schemas/~1User'}
# 必要なら共通のスキーマを別ファイルで管理
$ref: './components/schemas.yaml#/schemas'
paths/users.yml
paths:
/users:
get:
summary: ユーザー一覧を取得
responses:
'200':
description: 成功
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
/users/{id}:
get:
summary: ユーザー詳細を取得
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/User'
components:
schemas:
User:
type: object
properties:
id:
type: string
name:
type: string
email:
type: string
required:
- id
- name
こんな感じで、ファイルに必要なものを全部記載して、$refでリソースを参照することで、完全に分離できる。
Grouping Operations With Tags
Grouping Operations With Tags | Swagger Docs
tags指令で、複数の別のAPIをグループ化できる。
tags:
-name
Data Models
Supported JSON Schema Keywords
OpenAPI 3.0はJSON Schema Specificationの部分セットを拡張して使っている。
以下のキーワードはJSON Schemaと同一。
titlepatternrequiredenumminimummaximumexclusiveMinimumexclusiveMaximummultipleOfminLengthmaxLengthminItemsmaxItemsuniqueItemsminPropertiesmaxProperties
以下のキーワードは微修正して対応。
type– the value must be a single type and not an array of types.nullis not supported as a type, use thenullable: truekeyword instead.format– OpenAPI has its own predefined formats and also allows custom formats.description– supports CommonMark syntax for rich text representation.items– must be present iftypeisarray. The item schema must be an OpenAPI schema and not a standard JSON Schema.properties– individual property definitions must follow OpenAPI schema rules and not standard JSON Schema.additionalProperties– the value can be a boolean (trueorfalse) or an OpenAPI schema.default– the default value must conform to the specified schema.allOf– the subschemas must be OpenAPI schemas and not standard JSON Schemas.oneOf– the subschemas must be OpenAPI schemas and not standard JSON Schemas.anyOf– the subschemas must be OpenAPI schemas and not standard JSON Schemas.not– the subschema must be an OpenAPI schema and not a standard JSON Schema.
Adding Examples
リクエストパラメーターや、レスポンスボディーの例を記載できる。
exampleかexamples (複数) を使う。
parameters:
- in: query
name: status
schema:
type: string
enum: [approved, pending, closed, new]
example: approved # Example of a parameter value
parameters:
- in: query
name: limit
schema:
type: integer
maximum: 50
examples: # Multiple examples
zero: # Distinct name
value: 0 # Example value
summary: A sample limit value # Optional description
max: # Distinct name
value: 50 # Example value
summary: A sample limit value # Optional description
exampleは例が1この場合にだけ使える。
examplesは例が複数ある場合。区別できるようにまず名前があって、その下にvalueの下にプロパティーなどを記載する。
valueの部分はxml/htmlとかにもできる。リクエスト、レスポンスの文脈だとvalueで十分。
Other
returnCode
https://grok.com/share/c2hhcmQtMw%3D%3D_682b0476-5ab3-449c-a956-9385962c66ce
HTTPステータスコードじゃなくて、レスポンス本体のカスタムコードで、APIの結果を返すAPIがあったりする。これのSwaggerでの表現方法。
enumとdescriptionで記載する。
paths:
/example:
post:
summary: カスタムレスポンスコードのサンプルAPI
requestBody:
content:
application/json:
schema:
type: object
properties:
input:
type: string
responses:
'200':
description: リクエストが正常に処理されました。returnCodeで結果を確認してください。
content:
application/json:
schema:
type: object
properties:
returnCode:
type: integer
description: |
以下の対応。
- 000000: 正常終了
- 200001: 申し込み済
- 990001: パラメータエラー
- 999999: API実行エラー
enum: [0, 1, 2, 3]
example: 0
message:
type: string
description: 処理結果の詳細メッセージ
example: "Operation completed successfully"
example:
returnCode: 0
message: "Operation completed successfully"
'500':
description: サーバー内部で予期しないエラーが発生しました。
content:
application/json:
schema:
type: object
properties:
returnCode:
type: integer
description: 処理結果を示すコード(この場合はサーバーエラー)。
example: 3
message:
type: string
example: "Internal server error"
descriptionで箇条書きで記載。箇条書きのために、descriptionの直後に|を入れて改行リテラル表記にする。それと並行してenumで値のパターンを定義する。
HTML出力
HTMLの出力までしたい場合、npmが必要。
いくつか方法がある。redocly/cliが悪くない。
npm install -g @redocly/cli redocly build-docs --output index.html base.yml
こんな感じでswaggerのyamlファイルをindex.htmlに出力できる。
JSON Schema
About
好きに記載可能なJSONに対して、JSONデータの構造とバリデーションルールを定義するための言語・仕様。これにより、JSONを使う入出力に対して、形式を定義できる。バリデーションなどを自動チェックできたりする。文書の自動生成や、データ変換などにも使える。
JSON Schema自体もJSONになっている。
Swaggerでのリクエスト・レスポンスボディーの定義などで採用されている。
例えば、プロパティーの存在、必要性。データの型、値の範囲などを検証できる。プロパティーの存在だけでも意味がある。
Example
{
"name": "John Doe",
"age": 30,
"email": "john.doe@example.com",
"address": {
"street": "123 Main St",
"city": "New York",
"state": "NY",
"zip": "10001"
},
"phoneNumbers": ["123-456-7890", "987-654-3210"]
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer",
"minimum": 18
},
"email": {
"type": "string",
"format": "email"
},
"address": {
"type": "object",
"properties": {
"street": {
"type": "string"
},
"city": {
"type": "string"
},
"state": {
"type": "string",
"maxLength": 2
},
"zip": {
"type": "string",
"pattern": "\\d{5}"
}
},
"required": ["street", "city", "state", "zip"]
},
"phoneNumbers": {
"type": "array",
"items": {
"type": "string",
"pattern": "\\d{3}-\\d{3}-\\d{4}"
}
}
},
"required": ["name", "age", "email", "address", "phoneNumbers"]
}
基本はtype: objectを記載して、properties以下にプロパティー名とtypeを定義する感じ。
type=arrayの場合はitems
重要なプロパティー
- required
- type
- properties: type=object時
- properties.<key>
- type: 該当keyの型。
- pattern: type=string時に使う、パターン。
- minLength/maxLength: type=string時の文字数。
- minimum/max: 数値系の最小・最大値。
- items: type=array時
Reference
JSON data types
JSON Schema - Type-specific Keywords
typeで指定可能な型がある。
- array
- boolean
- null
- numeric types (integer/number): integerは整数のみ。numberは整数+浮動小数点数。
- multipleOf: 指定した数値の倍数である制約。
- minimum/maximum: 最小値、最大値。
- exclusiveMinium/exclusiveMaximum: 最小値、最大値 (指定値を含まない、<>相当)。またはtrueを指定するとminimum/maximumが含まない値に変わる。
- object
- regular expressions
- string
Schema annotations and comments
JSON Schema - Schema annotations and comments
注釈とコメントがある。必須ではない。JSONスキーマの追加情報の提供に使われる。
Annotations
- title
- description
- default
- examples
- readOnly
- writeOnly
- deprecated
JSON API
Web APIにはJSONベースのフォーマットを使おう #WebAPI - Qiita
Web APIでやりとりするJSONの記述方法の書式の一つ。
JSON:API — A specification for building APIs in JSON
{
"data": {
"type": "checkin",
"id": "12345",
"attributes": {
"timestamp": "2025-10-07T10:37:00Z",
"latitude": 35.6895,
"longitude": 139.6917
}
},
"meta": {
"processed_at": "2025-10-07T10:37:00Z"
}
}
{
"errors": [
{
"status": "400",
"code": "1001",
"title": "Check-in failed",
"detail": "The specified location is too far away.",
"source": {
"parameter": "latitude"
},
"meta": {
"current_distance_meters": 1500,
"max_allowed_distance_meters": 100
}
}
]
}
Network
環境変数
https://grok.com/share/c2hhcmQtMw%3D%3D_1fce8739-56a3-47a5-8a8c-55d209a0b37b
ネットワーク関係のツールは、いくつか共通の環境変数を参照する。curlで定義されている環境変数を流用して参照していることが多い。
- poxy関係: http_proxy/https_proxy/no_proxyは重要
- http_proxy
- htttps_proxy
- no_proxy
- ftp_proxy
- all_proxy
- RSYNC_PROXY
内部リクエスト時には、proxy設定があると、プロキシーサーバーにリクエストに行って不都合起きることがあるので注意する。
ssh
ssh-addの自動登録
ssh agentに秘密鍵の登録は以下のコマンド。
ssh-add <秘密鍵のpath>
ただし、上記コマンドは再起動すると登録が消えるので毎回必要。
~/.ssh/configに以下の内容を記入しておくと、次回からkeychainから自動で読み込まれるらしい (macOS で再起動しても ssh agent に秘密鍵を保持させ続ける二つの方法 #SSH - Qiita)。
Host * UseKeychain yes AddKeysToAgent yes
うまくいかなかった。
ssh-addをPC起動する度に自動的に実行させるための設定 | AIFAN
id_rsaの場合はIdentityFileを省略できるが、それ以外は指定が必要な模様。
Host * UseKeychain yes AddKeysToAgent yes IdentityFile ~/.ssh/id_ed25519
ssh経由でのリダイレクト出力
bash - How to remotely write to a file using SSH - Super User
ssh経由で標準入力内容からファイルをリダイレクトで作成したいことがある。
sshのコマンド部分を文字列にすればOK。
ssh user@remotehost -T "cat > /remotefile.txt" <<-EOT Some text EOT
-Tで擬似端末を無効にしている。
パスフレーズの省略
SSH多段接続時とgit cloneでSSH鍵参照時に、パスフレーズを要求される。毎回要求されるのが手間。これを省略する方法がある。 ~/.ssh/configに以下の設定を記述する。
Host * AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/id_ed25519
- AddKeysToAgent=yesにすると、ssh-agentの実行時に自動的に鍵を追加する。
- UseKeychain=macOS専用。OSのキーチェーンからパスフレーズの検索を試みる。
- IdentityFile=SSH秘密鍵の絶対パス。デフォルトは~/.ssh/id_rsa。
上記3点で自動入力を試みる。 macOSで行う分には上記だけでパスワードは聞かれない。これをリモートでもやりたいなら、ssh-agentに登録が必要。 ログイン時に1回実行してくれたらいいので、ログインシェルの設定の~/.bash_profileに以下を記述。
echo 'ssh-add --apple-use-keychain' >>~/.bash_profile
これで端末の起動時に鍵を自動登録してくれるので、リモートでもパスフレーズを要求されない。
ssh_config
ssh_config(5): OpenSSH SSH client config files - Linux man page
重要な設定・構文がある。
TOKENS
macのman ssh_configに詳しい。
使用可能な指令が限定されている。
HostName (Macのみ)
- %h=リモートホスト名。Hostの指定部。
- %p=リモートポート。
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
- ssh接続をする際に「WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!」と出てつながらない|テクニカルブログ|日本情報通信株式会社
- 「SSHホスト鍵が変わってるよ!」と怒られたときの対処 #SSH - Qiita
ssh example.comなどを実行すると、IPアドレスの振り直しなどで、ホストの公開鍵が変わっていた場合、中間者攻撃への対策として失敗する。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that a host key has just been changed. The fingerprint for the RSA key sent by the remote host is SHA256:. Please contact your system administrator. Add correct host key in /Users/z.ken.senoo/.ssh/known_hosts to get rid of this message. Offending RSA key in /Users/z.ken.senoo/.ssh/known_hosts:1 Host key for [example.com]:3023 has changed and you have requested strict checking. Host key verification failed. Connection closed by UNKNOWN port 65535 Connection closed by UNKNOWN port 65535
$HOME/.ssh/known_hostsの該当行を削除すれば解決する。以下のコマンドでも対応してくれる。
ssh-keygen -R example.com
いや、うまくいかない。~/.ssh/known_hostsに以下の該当ドメインの除外設定が必要な模様。
@cert-authority example.com ssh-rsa
「sshd(8) - OpenBSD manual pages」に記載がある。
The marker is optional, but if it is present then it must be one of “@cert-authority”, to indicate that the line contains a certification authority (CA) key, or “@revoked”, to indicate that the key contained on the line is revoked and must not ever be accepted. Only one marker should be used on a key line.
...
When performing host authentication, authentication is accepted if any matching line has the proper key; either one that matches exactly or, if the server has presented a certificate for authentication, the key of the certification authority that signed the certificate. For a key to be trusted as a certification authority, it must use the “@cert-authority” marker described above.
https://chatgpt.com/c/67f321e3-3b78-800b-b263-3e7169488367
通常、known_hostsには、接続済みのホストの公開鍵を記録し、次回以降の接続時の確認に使う。ただ、この場合、IPアドレスが動的に変更する場合や、鍵が頻繁に変更される場合に、警告になる。この対策として、@cert-authorityで、同じ行のホスト鍵を署名したCA鍵を信頼する。これにより、同一のCAの複数ホストを一括で信頼する。
curl
HTTPの通信のコマンドラインでの確認でよく使う。
Basic
- -X: メソッド指定
- -d/--data-urlencode: リクエストボディー (key=value)を指定。-X POSTも自動指定になる。
curl -H "Content-Type: application/json" -d '{"name":"佐藤", "mail":"sato@example.com"}' localhost:5000/api/v1/users\
curl -H "Content-Type: application/json" -d @body.json localhost:5000/api/v1/users\
JSONで送信する場合、ヘッダー指定が必須。
*-F: multipart/formのform指定。
curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html" http://www.example.com/postit.cgi
@でfilename相当の指定。;でmime typeも指定できる。
@/</;type=自体を送信したい場合、-Fではなく、--form-stringを指定する。
curl: (60) SSL certificate problem: self-signed certificate
Ref: curlで「自己署名証明書」を受け入れるには【curl: (60) SSL certificate problem: self signed certificate】 | LFI.
--insecureオプションを指定すると、localhostなどでの自己署名証明書を許可する。
curl: Failed writing body
以下のようにhead -n 1を指定するとcurlがエラーを出力する。
curl -H "Content-Type: application/json; charset=utf-8" -H "X-HD-apitoken:$TOKEN" -d "{\"dbSchemaId\":$dbSchemaId, \"limit\":1, \"offset\":$offset}" https://$DOMAIN/$ACCOUNT/api/csvexport/version/1.0 | head -n 1
curl: Failed writing body
curlは標準出力に全部書き込めたかチェックしているようで、head -n 1で切り捨てたらcurlはエラーになる。
対策は、curl -sで出力を抑制するとのこと。これで解決。
Teleport
踏み台サーバー (Jump server/Jump host) をよりよく管理するためのサーバーソフトウェア。
アクセスログなどを一元管理できる。商用版とオープンソース版がある。
基本的にteleportのサーバーを一度経由して、各種の踏み台サーバーにアクセスする。経由先が1個増えるが、そのおかげで監査ログを取得できたり、権限などを一括管理できる。
ただ、teleportで監査ログを残すには、基本的にtshを経由する必要があり、既存のIDEなどのssh想定のソフトだと工夫が必要。tsh経由でやったり、rsyncで間にtshを挟むような工夫が必要。
Install
How to configure SSH Certificate-Based Authentication
[Download Teleport: Secure and Easy Infrastructure Access | Teleport] から自分のパソコンのtshをインストールする。
以下の環境変数を設定する。
- TELEPORT_AUTH:
- TELEPORT_LOGIN:
- TELEPORT_PROXY: teleportプロキシーサーバーのアドレス。重要。
tsh
teleportのコマンドラインクライアント。
tsh loginでteleportにログインする。
環境変数
tsh CLI reference | Teleport Docs
- TELEPORT_AUTH:
- TELEPORT_LOGIN:
- TELEPORT_PROXY: teleportプロキシーサーバーのアドレス。重要。
上記3個が特に重要。
ProxyJump+ProxyCommand
How To Use SSH ProxyJump and SSH ProxyCommand
https://goteleport.com/blog/ssh-proxyjump-ssh-proxycommand/
~/.ssh/config のProxyJumpとProxyCommandの違いを整理する。
どちらも中間サーバーを経由したリモートサーバーアクセスの指令。
- ProxyJump: 最も簡単な方法。OpenSSH v7,5以上で使用可能。中間サーバーでポート転送対応が前提条件。ProxyJumpは内部でProxyCommandを使う。
- ProxyCommand: ProxyJump搭乗前の方法。中間サーバーを介して標準入力と標準出力を転送して機能。
ProxyJumpの方が現代的だが、ProxyCommandの方が柔軟性が高い。
ProxyJumpの使用例。
ssh -J <jump server> <remote server>ssh -J <jump server1>,<jump server2>,<jump server3> <remote server>
|
ProxyCommand
ssh -o ProxyCommand="ssh -W %h:%p <jump server>" <remote server>
|
~/.ssh/configの例。
Host remoteserver
|
ssh remoteserver で<jumpserver> 経由でremoteserverに接続できる。
一般的に、ProxyJumpが推奨される感がある。ただ、teleportを導入している場合、ProxyJump/ProxyCommandを使うと、tshを経由していないのでteleportにログが残らないらしい。
tsh経由ssh
ProxyJump/ProxyCommandを使わない場合、以下の形式でtshを使ってアクセスするのが基本。
tsh ssh 踏み台サーバーホスト名
tsh sshでteleportサーバーが管理している踏み台サーバーが見えるので、そこに接続できる。tshの後のsshは基本的に通常のsshと同じなので、sshの後にsshのコマンドを連鎖でき、対象サーバーにも一発でアクセスできる。
tsh ssh -At <jump host> ssh -A <target host>
-tでttyに繋いで標準入出力を接続。-Aはフォワーディング。ローカルのssh-addの情報などを連携できる。
<jump host>の~/.ssh/configを用意しておくことで、<target host>にホスト名を指定したりできる。
ProxyJump/ProxyCommandと異なり、これだとちゃんとログを残せる。
tsh経由scp
tsh経由の踏み台サーバーへのファイル転送はやや工夫が必要。
tsh scpというコマンドが一応ある。が、これはネストなどには未対応。やる場合、以下のように2回実行になる。
FR=test.file TO=/path/to/test.file tsh scp $FR <jump host>:$TO; tsh ssh -At <jump host> scp $TO <target host>:$TO
高ではなく、rsyncを使えば一発でいける。
rsync -e "tsh ssh -A <jump host> ssh" ./test.file <target host>:~/
これが基本。
PhpStorm
JetBrains SFTP | Teleport Docs
teleportの公式にマニュアルがあるが、記述が非常に不親切。これだと踏み台サーバーにしかアクセスできない。その先にアクセスできない。
多段SSHの設定を残しておいて、ファイル転送だけrsyncで行う形になる。
PhpStormのSSH configurationsのホスト名がスクリプトの引数に渡されるので、踏み台からAWSにsshでログインするホスト名やパソコンの~/.ssh/configのHostとの一致必要な点に注意する。
USERNAME=
IPV4=
VPCID=
cat <<-EOT >>~/.ssh/config
Host $VPCID
ForwardAgent yes
User $USERNAME
ServerAliveInterval 30
SendEnv -LC_* -LANG
ProxyJump $USERNAME@teleport.security:3023
Host $USERNAME
ForwardAgent yes
ProxyJump $VPCID:22
User $USERNAME
Hostname $USERNAME.example.com
ServerAliveInterval 30
SendEnv -LC_* -LANG
Host $USERNAME.$VPCID
# for automatic upload by PHPStorm
LocalForward 22224 $USERNAME.$VPCID:22
# for XDebug
RemoteForward 9000 localhost:9000
ForwardAgent yes
Host db-*
HostName $IPV4
LocalForward 3307 localhost:22
ProxyCommand ssh $VPCID -W %h:%p
ForwardAgent yes
Host *
AddKeysToAgent yes
PasswordAuthentication no
User $USERNAME
ForwardAgent yes
ServerAliveInterval 30
IdentityFile ~/.ssh/id_ed25519
# for macOS
UseKeychain yes
EOT
こんな感じの多段SSHの設定を用意。 踏み台サーバーにも同じホスト名でアクセスできるように、以下のような内容の~/.ssh/configをまだならば設定しておく。
AWS_HOSTNAME=
|
rsync executable
rsyncで使用する (-eオプション)、以下の内容のシェルスクリプトを作成して実行権限を付与して任意の場所 (例: ~/project/tsh_ssh.sh) に配置する。
cd ~/project/
|
PhpStorm設定
PhpStormで以下を設定する。
- [Tools]-[Deployment]-[Configuration]
- [+]-[SFTP]
- [Create New Server]-[New server name: 任意の名前 (例=rsync)]-[OK]
- [Connection] タブを以下に設定。
- Type=SFTP
- SSH configuration=以下を設定。
- Host: <ホスト名> (例: ~/.ssh/configと踏み台サーバーの~/.ssh/configのホスト名と同じにする)
- User name: ユーザー名
- Port: 22
- Authentication type: OpenSSH config and authentication agent
- Root path=転送先のベース。
- [☑️Use Rsync for download/upload/sync]
- Rsync Settings=以下を設定。
- Shell executable path=tsh_ssh.shのパス (例=~/project/tsh_ssh.sh)
- [Mappings] タブを以下に設定。
- Local path: ローカルパソコンのディレクトリー
- Deployment path: /
- Web path: /
- [Settings]-[Build, Execution, Development]-[Development]-[Options]-[Upload changed files automatically to the default server]=[On explicit save action]
- ☑️Delete remote files when local are deleted
以上で完了。後は同期したいファイルをPhpStormで開いて、右クリック-[Deployment]-[Upload to]/[Download from] でファイル転送できる。
[☑️Use Rsync for download/upload/sync] のチェックを外せば、rsyncを使わないファイル転送になる。
Wireshark
TLS
Ref: SSL/TLSの復号#1 ~Wiresharkの設定~ | 東陽テクニカ | “はかる”技術で未来を創る | ワン・テクノロジーズ・カンパニー.
Wiresharkで通信パケットを確認する場合、デフォルトでTLSで暗号化されているので、内容がわからない。WiresharkでTLSに対応しておく必要がある。
[Preferences]-[Protocols]-[TCP] を選ぶ。
- ☑Allow subdissector to reassemble TCP stream
- ☑Reassemble out-of-order semgemnts
上記をチェックしておく。デフォルトでチェックされていた。
続いて、セッションごとのPre-Master Secretを登録する。
Chrome/Firefoxだと、環境変数SSLKEYLOGFILEを設定すれば、このファイルにTLSセッションキーを出力するので、これをWiresharkで読み込むことで、復号対応する。
以下のコマンド相当で、任意のファイル・場所にログファイルを指定する。
export SSLKEYLOGFILE=/tmp/sslkey.log
Macだとlaunchctlで設定しておくといい。これでWebブラウザー経由の場合は見えるようになる。
Other
ネットワーク名
CentOS 7のネットワーク名「enp1s0」という文字列の謎に迫る #CentOS - Qiita
enp1s0とか最近のGNU/Linuxのネットワーク名が意味不明。
ソースコードに命名規則がある。
* Two character prefixes based on the type of interface: * en -- ethernet * sl -- serial line IP (slip) * wl -- wlan * ww -- wwan * * Type of names: * b<number> -- BCMA bus core number * ccw<name> -- CCW bus group name * o<index>[d<dev_port>] -- on-board device index number * s<slot>[f<function>][d<dev_port>] -- hotplug slot index number * x<MAC> -- MAC address * [P<domain>]p<bus>s<slot>[f<function>][d<dev_port>] * -- PCI geographical location * [P<domain>]p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>] * -- USB port number chain
- en: ethernet (有線LAN)
- wl: wlan
- p1: PCI bus 1
- s0: slot 0
Security
DoS攻撃
いくつか対策方法がある。
サーバーログにIPアドレスが残るから、それで攻撃元の国を特定して、該当国を一括アクセス拒否。これが効果あるかもしれない。
攻撃元の国は途上国とかが多いだろうから。IPアドレスは簡単に変更できるが、国を変えるのはたいへんだろう。
バリデーションの実装
基本的に、バックエンドで主にチェックして、フロントエンドはUXの向上目的で実装する。データの重複チェックはDBアクセスが必要だったりするから。また、API経由などフロントがそもそもないケースもある。
ただ、社内システムのような、画面経由でしか使わない。悪者がほぼいないと思われるケースは、フロントエンドでの検証だけでも十分に感じる。
二重送信
submitボタンのダブルクリック、リロード、ブラウザーバック・フォワードなど、フォーム周りで注意が必要な保安要素がある。
- ボタン連打
- ブラウザーバック
- リロード (PRG)
項目ごとにすべき対策が異なる。
連打
- フォームの二重送信を防止する方法 - 福岡・東京のシステム開発会社 (株)ユーフィット
- さいきょうの二重サブミット対策 #JavaScript - Qiita
- JavaScriptを利用してフォームの二重送信を防止する|CodeZine(コードジン)
- JavaScriptでformの2重送信を防止する | にせサギ ネットサギ体験ブログ
- Javascriptで送信ボタン二度押しによる二重送信を防止する方法 | Yuta Ihara.com
基本は、ボタンのsubmitのイベント内でdisabled=trueでの無効化。
似た考え方で、スプラッシュのモーダル表示もあり。これがわかりやすいかもしれない。
$("form").submit(function() {
var self = this;
$(":submit", self).prop("disabled", true);
setTimeout(function() {
$(":submit", self).prop("disabled", false);
}, 10000);
});
停止にしたら、二度通せなくなるので、タイムアウトで戻すとよい。
Other
Access Denied! Your IP address is blacklisted because of malicious behavior in the past
Webサイトを開くと、[Access Denied! Your IP address is blacklisted because of malicious behavior in the past] のメッセージが表示されてアクセスできないことがあるらしい。
Spamhausというスパムデータのブラックリスト共有サービスがあり、Apache HTTP Serverのspamhaus moduleでこれを使っていて拒否している可能性がある模様。
spamhauに解除申請するとすぐに解除してくれて、反映に12時間くらいかかる模様。
Browser
Bookmarklet
AutoScroll
https://chatgpt.com/share/683d5e8b-1744-800b-9fc9-a2e5c05754ca
MacのChromeはマウスホイールの中ボタンクリックのオートスクロールに対応していない。
面倒なので、ブックマークレットで対応する。
/* AutoScroll */
javascript:(function(){
if(window.autoScrollInterval){
clearInterval(window.autoScrollInterval);
window.autoScrollInterval = null;
/* alert("⏹ 自動スクロール停止"); */
} else {
/* ここでスクロール速度を調整(1 = 遅い、10 = 速い)*/
const speed = 1;
window.autoScrollInterval = setInterval(() => {
window.scrollBy(0, speed);
/* この間隔も調整可能(ミリ秒) */
}, 20);
/* alert("▶ 自動スクロール開始"); */
}
})();
クリックするたびに、自動スクロールのオン・オフが切り替わる。便利。
Chromium
Extension
Chromme系で愛用拡張機能を列挙する。
Profile
https://chatgpt.com/c/67aca944-1fcc-800b-973e-7bf3207b9b91
Webサイトのアカウントを切り替えたい場合、Webブラウザーのプロファイル機能で、アカウント情報を分離できる (Googleアカウントではなくて)。
これでA用、B用など用途ごとにプロファイルを作って、それでセッションやブックマークなどを分けられる。
devtool/開発者ツール
- Webブラウザーの開発者ツールでのJavaScriptデバッグ | GNU social JP Web
- ブラウザーの開発者ツールとは
- JavaScript をデバッグする | Chrome DevTools | Chrome for Developers
イベントリスナー
[Elements]-[Event Listeners]-[handler]-右クリック-[Show function definition] でイベントリスナー関数の定義を確認できる。
イベント監視
How to find out which JavaScript events fired? - Stack Overflow
monitorEvent関数で監視できるらしい。他に、FirefoxのFirebugのlog eventsでも監視できるらしい。
Network conditions
開発者ツールの[Network]タブを開いてリロードしても、[No internet]と表示されることがある。
これはオプション設定の問題。上のツールバーの[Disable cache]の右が[Offline] だとこうなる。これを[No throttling]にすると解決する。クリックミスだと思われる。
IE Edge
保存された情報
Edgeで「保存された情報」の表示を無効にする方法 - shikumika’s diary
全部非表示にできるが、個別には削除できない模様。
[edge://wallet/settings]-[個人情報]-[基本情報の保存と入力]=[オフ]
これで全部無効になる。
[保存されたデータ] ならShift-Deleteで選択肢を削除できた模様。
Safari
Windows Safari
一応ある。2012-05-09のSafari 5.1.7までWindows版が提供されていた。DL1531。
開発者ツール
PCでスマホサイトを見る方法 – Safari編|東京渋谷のWeb制作会社・ホームページ制作会社|株式会社イー・バード
Safariの開発者ツールは癖がある。
[設定]-[詳細]-[☑️Webデベロッパ用の機能を表示]
[開発]-[レスポンシブデザインモードにする]
スーパーリロード
サポートへようこそ|メールのトラブルやホームページに関するお問い合わせ、 CMS操作方法など各種サポート情報をご案内しております。/各ブラウザでの強制リフレッシュ(スーパーリロード)
Shift-更新ボタン
Firefox
カメラ
https://chatgpt.com/share/680eaa72-118c-800b-b032-34842d9a6c18
Firefoxでカメラが機能しないことがある。確認すべき事項がいくつかある。
- Firefoxの設定でカメラを有効にする。アプリの再起動必要。
- Webブラウザーのアドレスバー左側でカメラを許可する。1ができていないとカメラの項目が表示されない。
Free
無料で使用可能な共用ホスティングサービスがある。
スタードメイン無料サーバー
ドメインをセットで利用する必要があるものの、スタードメインのスタードメイン無料サーバーがけっこういい。
無料レンタルサーバー | スタードメイン - ドメイン取得 100円(税込)~
jpドメインの金額が相場の中では安い方で、それに無料サーバーがついていくる点。
- ディスク容量 20GB
- DB 1GB
ただし、SSHやコマンドは使えないので、FTPでWordPressを展開して設置するとか、そういう簡単な使い方だけ。ただ、それでもWordPressでWebサイトを構築するくらいなら十分だと思う。
CORESERVER
Coupon
A8.netで自己アフィリエイトがある。これを経由すると少しお得になる。契約初回のみ。更新はだめ。
リージョン
GMOデジロック:レンタルサーバー「コアサーバー」、西日本リージョンを新設し、リージョン選択サービスを開始 | GMOインターネットグループのプレスリリース
2018-01-31から西日本リージョンも選べるようになったらしい。適宜分散させるといいかもしれない。
Pay
以下が可能。
- クレジットカード
- Amazon Pay
Amazon Payが使えるからAmazon PayでOK。
料金プラン | レンタルサーバー CORESERVER(コアサーバー)
料金表を見る限り、12か月以上がお得。迷ったら12か月でいいと思う。確信やキャンペーンがあるなら24/36も。
更新を考えるのが面倒だから、36でいいかも。
メール
- Custom_Filter_of_Coreserver - PukiWiki
- スパムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)
- カスタムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)
情報
- CoreServer_Mail_Custom - PukiWiki
- coreserverのメール設定:BWT Lab.:SSブログ
- バリューサーバーのフィルター設定でスパムメール(迷惑メール)対策する方法 - QWERTY.WORK
- コアサーバー V1にてカスタムフィルターで「ごみ箱」を指定したときの確認方法 – AWMTの、できるかな?
ルールが特殊なので注意する。
ゴミ箱に振り分ける場合。
順1 で[./.Trash] を指定
順2
- 条件: [
.*] - 処理:
./、に振り分ける
条件部分には正規表現が使えるように見える。
破棄にしないといけない。転送する場合、カスタムフィルターの中に転送を入れる。条件を.*にする。
カスタムフィルターにくせがある。
- エスケープ(\を前置する)が必要な文字は「'」「"」「|」「`」「~」「?」「!」
ポイント
https://chatgpt.com/c/680398be-247c-800b-911e-df207cb6c6a3
- 日本語はBASE64でエンコードされているので、そのままだとヒットしない可能性が高い。BASE64でエンコードされたキーワードの指定が必要な可能性が高い。
- 検索範囲=[全体] は全部にANDで入っていることを期待している感じがするので、Subjectに絞り込む。
1個目のBASE64が重要な気がする。これで様子を見る。
やっぱりうまくいかない。
Thunderbirdのメールフィルターで処理する。これが確実。サーバー側で対応していないから、外出先で適用されないのが欠点だが。
Value Domain ネットde診断 byGMO
2024-06-07 Friからバリュードメイン系の利用者に無料で提供しているセキュリティー診断ツール。
CGI
- CORESERVERでのFastCGI/CGI版PHPの利用手順 – senooken JP
- FastCGI版PHP 各バージョンのPHP設定方法 | よくある質問 | サポート | レンタルサーバー CORESERVER(コアサーバー)
- PHPをCGIとして動かす方法を教えてください | よくある質問 | サポート | レンタルサーバー CORESERVER(コアサーバー)
- レンタルサーバー各社でのPythonの実行方法まとめ
CORESERVERでのCGIの設定方法がある。
| 項目 | FastCGI | CGI |
|---|---|---|
| バージョンの変更 | 管理画面 | .htaccess内の
|
| 設定ディレクトリー | /virtual/<username>/public_html/.fast-cgi-bin/
| |
| CGIの実行ファイル | phpXX.fcgi
|
phpXX.cgi
|
| PHPの設定ファイル | phpXX.ini
|
php.ini
|
| 設定の反映タイミング | バージョン切替時 | 即時 |
~/public_html/.fast-cgi-bin/のphpXX.fcgi phpXX.cgiがCGIの実行ファイル。このファイルか最後の行のexecのパスを変更すると、自前コマンドに変更可能。
FastCGIは管理画面からバージョンを変更したタイミングで反映される。ただ、ファイル拡張子が.phpじゃないとこのFastCGIが実行されない模様。
CGIは.htaccessに以下の内容を記述してCGI板PHPのバージョンを指定する。
AddHandler application/x-httpd-phpcgiXX .php
cgiのファイルには実行権限が必要。
chmod +x py.py
拡張子がないとダメな模様。加えて、.htaccessに以下の記述。
AddHandler cgi-script .py
これでpy.pyで動作はする。
拡張子じゃなくてファイル名で実行したい場合、SetHandlerでしていする (AddType, AddHandler, SetHandlerの違い – senooken JP)。
<FilesMatch py$>
SetHandler cgi-script
</FilesMatch>
これでpyでもアクセスできる。
FastCGI版の場合、以下のような設定でファイル名でマッチさせれば実行できそうな気もするが。
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
500
<FilesMatch gnusocial$>
SetHandler application/x-httpd-php
</FilesMatch>
pythonがphpとして認識され、テキストがそのまま表示される。
SetHandler fcgid-scriptにしたらFastCGIで動作する。プログラムがFastCGI対応になっている必要がある。
<FilesMatch gnusocial$>
SetHandler fcgid-script
</FilesMatch>
Function
サーバー間コピー
CORESERVERのサーバー間コピー | GNU social JP Web
巨大ファイル・大量ファイルを転送する場合、長時間プロセスになって、サーバーに強制終了される可能性がある。なので、scp/rsyncじゃなくて、レンタルサーバーのファイル転送機能を使う。
CORESERVERのサーバー間コピーは、リモート→ローカルの1方向のコピー。
「coreserverのサーバー間コピーで発生したquotaの問題 - 渡米生活。(日記)」にあるように、ファイル数が多いとコピー漏れがあるので、事前にtarで1ファイルにまとめてからコピーすると検証しやすい。
- コントロールパネル-[サイト設定]-[サーバー間コピー]
- [サーバー間でのファイルコピー設定]-[サーバー間コピーの新規作成] で以下を入力して [サーバー間コピーを新規作成する]
- サーバー間コピー名: コピーのタスク名
- ローカル: 転送先の現在のサーバーのディレクトリー
- 転送方式: 更新 (削除なし)。基本はこれで問題なく、他に [ミラー (削除なし)]、[差分 (削除なし)] を用途に応じて選択
- リモート: 転送元のリモートサーバーの情報を入力。リモートディレクトリーはホームディレクトリーからの相対指定。
これでOK。以下の3点に特に注意する。
- リモート→ローカルの方向へのコピー。
- リモートディレクトリーはリモートディレクトリーの中身がコピーされる。指定したディレクトリー自体は転送されない。
- ローカルもリモートもディレクトリーはホームディレクトリーからの相対指定になるが、先頭に/が必要。
[サーバー間でのファイルコピー設定] 画面が表示されるので、作成した項目の [アクション] 列の [> (実行ボタン)] を選びます。
[サーバー間コピーの実行] の確認モーダルが表示されるので [サーバー間コピーを実行する] を選びます。
3分後ほどにコピーが始まります。タスクのログが [/.servercopy.log] に出力されます。
例
- 転送先: senooken@m9.coreserver.jp
- ローカルディレクトリ=/public_html/nc.senooken.jp (実体=/virtual/public_html/nc.senooken.jp)
- リモート
- FTPサーバー名=m9.coreserver.jp
- FTPアカウント=
- FTPパスワード
- リモートディレクトリー=/public_html/tmp/ (実体=/virtual/public_html/tmp)
Analytics
Exam
## About
https://gnusocial.jp/notice/4506679
### 全般
- マーケティング・ビジネス実務検定
- IMA検定
- Web検定
- ネットマーケティング検定
### 解析系
- ウェブ解析士
- GAIQ
- 統計検定
- Webアナリスト検定
GAIQが無料だしどうせ使うからいいかな。
https://wacul-ai.com/blog/access-analysis/google-analytics-method/gaiq/
https://www.plan-b.co.jp/blog/seo/12792/
## URL
- https://ceres-inc.jp/business-tips/recommended-webmarketing-shikaku/
- https://mynavi-creator.jp/blog/article/qualification-for-web-marketer
- https://www.icloud.co.jp/article/exam/features-and-5-acquisition-benefits.html
- https://digitor.jp/textbook/web-analytical-qualification/
Tool
サイト分析用のツールがいくつかある (2023年ブログランキング!おすすめブログランキングサイト比較【一般人向け】)。
- SimilarWeb
- Ubersuggest
- ahrefs
- Googleキーワードプランナー
閲覧数取得
出典: GoogleAnalyticsで自サイトの人気記事ランキングを表示する方法 | アフィリエイトJAPAN。
- [行動]-[サイトコンテンツ]-[全てのページ]
- [表示する行数]=5000
- [エクスポート]=TSV
流入元特定
「会員登録画面の流入元探索方法について - Google アナリティクス コミュニティ」どのページから会員登録があったか、会員登録に結びつく記事は非常に重要。
こんにちは。
探索レポートでユーザーセグメントを作成する集計方法はいかがでしょうか。
・自由形式レポートを作成
・セグメント作成 > ユーザーセグメント
・条件は page_view > パラメータ page_location > 含む:会員登録画面のURL を指定
・「会員登録画面閲覧ユーザー」などセグメント名をセットして保存
・探索レポートにセグメントを適用
・ディメンション:セッションの参照元 / メディア、ランディング ページ + クエリ文字列
・指標:セッション
ご確認よろしくお願いいたします。
※ページ閲覧の発生しなかったセッションはランディングページが (not set)になります。
開きっぱなしのタブから再訪問するセッションなどが該当します。ご参考までに。
PMProでも似たような回答。
Google Analytics 4 can track ecommerce conversions and then assign page value to posts that were a part of their conversion path for that engaged session.
Server
httpd
Apache HTTP Server
About
httpdの利用可能な情報。
https://chatgpt.com/c/6761f851-df0c-800b-86e9-1624b458d66d
# 使用可能な指令一覧 apachectl -L httpd -L # 使用可能なモジュール一覧 apachectl -M httpd -M
.htaccessで使用可能な指令の一覧。
.htaccessで使用可能な指令一覧 – senooken JP
Operation
サーバーの稼働や状態確認などで重要な操作がいくつかある。systemd前提。
ログ・状態確認。
sudo systemctl status apache2
sudoをつけないと詳細ログを確認できない。
sudo systemctl restart apache2 sudo systemctl start apache2 sudo systemctl stop apache2
Access Control
- Access Control - Apache HTTP Server Version 2.4
- Authentication and Authorization - Apache HTTP Server Version 2.4
- mod_authz_core - Apache HTTP Server Version 2.4
DoS攻撃対策などで重要な設定。
mod_authz_core/mod_authz_hostがコアモジュール。mod_rewriteも関係ある。
基本構文は以下。
Require host <address> Require ip <ip address>
1番目の形式はドメイン名。2番目はIPアドレス。部分マッチする。マッチしたもののアクセスを許可する。
Requireの直後にnotを指定してアクセス禁止にできる。こちらが重要。
mod_cgi
mod_cgi - Apache HTTP Server Version 2.4
CGIプロトコルのApacheモジュール。cgi-scriptにハンドラーを割り当てるとCGIとして扱う。
mod_fcgid
mod_fcgid - Apache HTTP Server Version 2.5
FastCGIプロトコルのApacheモジュール。AddHandlerかSetHandlerでfcgid-scriptハンドラーに割り当てられると、FastCGIとして処理される。
プログラム側もFastCGIに対応している必要がある。
Error
sudo systemctl status apache2
● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
Drop-In: /etc/systemd/system/apache2.service.d
└─privatetmp.conf
Active: failed (Result: exit-code) since Fri 2024-12-06 15:09:28 JST; 12s ago
Docs: https://httpd.apache.org/docs/2.4/
Process: 38461 ExecStart=/usr/sbin/apachectl start (code=exited, status=1/FAILURE)
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/ports.conf:8
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: [Fri Dec 06 15:09:28.259153 2024] [core:warn] [pid 38464] AH00117: Ignoring deprecated use of DefaultType in line 122 of /etc/apache2/apache2.conf.
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00112: Warning: DocumentRoot [/home/gree/frontend/greenet/htdocs_net] does not exist
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00526: Syntax error on line 7 of /etc/apache2/conf-available/rewrite-greenet.conf:
Dec 06 15:09:28 z-ken-senoo apachectl[38464]: RewriteRule: unknown flag 'UnsafeAllow3F'
Dec 06 15:09:28 z-ken-senoo apachectl[38461]: Action 'start' failed.
Dec 06 15:09:28 z-ken-senoo apachectl[38461]: The Apache error log may have more information.
Dec 06 15:09:28 z-ken-senoo systemd[1]: apache2.service: Control process exited, code=exited, status=1/FAILURE
Dec 06 15:09:28 z-ken-senoo systemd[1]: apache2.service: Failed with result 'exit-code'.
Dec 06 15:09:28 z-ken-senoo systemd[1]: Failed to start The Apache HTTP Server.
AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/ports.conf:8
NameVirtualHost指令が廃止予定なので、行を削除して対応する。
AH00117: Ignoring deprecated use of DefaultType in line 122 of /etc/apache2/apache2.conf.
- Gentooの~amd64にApache 2.4.1が来たので試してみた https://meihong.work/computer/server-administration/apache/gentoo%E3%81%AEamd64%E3%81%ABapache-2-4-1%E3%81%8C%E6%9D%A5%E3%81%9F%E3%81%AE%E3%81%A7%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/
- Upgrading to 2.4 from 2.2 https://httpd.apache.org/docs/2.4/upgrading.html
- DefaultType Directive https://httpd.apache.org/docs/2.4/en/mod/core.html#defaulttype
DefaultTypeはnone以外意味がなく、警告表示になる模様。
.htaccess
directive
.htaccessで使用可能な指令一覧 – senooken JP
.htaccessで使用不能なよく登場して誤解する指令を整理しておく。
- Alias
- ScriptAlias
- Directory/DirectoryMatch
- Location/LocationMatch
逆にOKなもの。
- Files/FilesMatch
mod_rewrite
Apache mod_rewrite - Apache HTTP Server Version 2.4
https://grok.com/share/c2hhcmQtMw%3D%3D_051d98f7-939d-4c82-977d-c30f506b61c7
リダイレクトを扱うモジュール。非常によく使うので重要。
- RewriteEngine: mod_rewriteの機能のON/OFF。基本は使う前にOnにするだけ。
- RewriteBase: ベースURLを指定。サブディレクトリー以下で、相対パスでリダイレクトする際に使用。
- RewriteCond: RewriteRuleの実行条件指定。
- RewriteRule: 実際のURL変換ルール。
- RewriteMap: 外部ファイルからマッピングを取得して変数に割り当てる。
- RewriteOptions: mod_rewriteの動作オプション設定。
RewriteBase
ベースURLを指定。サブディレクトリー以下で、相対パスでリダイレクトする際に使用。記述の簡略化が可能。
# /blogディレクトリ内の.htaccessの場合 RewriteBase /blog/ RewriteRule ^archives/([0-9]+)$ archives/detail.php?id=$1 [L] # 上記は /blog/archives/123 → /blog/archives/detail.php?id=123 になる
RewriteRule
mod_rewriteのコア。マッチしたパターンを置換先にリダイレクトする。
RewriteRule Pattern Substitution [flags]
例
内部リダイレクト (フレームワーク用)
RewriteRule ^(.+)$ /index.php?url=$1 [L,QSA,B] # デフォルト
外部リダイレクト (SEO用)
RewriteRule ^old-category$ /new-category [R=301,L,NC] # ケース無視
フルセット(HTTPS + クリーンURL)
# HTTPS強制
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
# クリーンURL
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php [L,QSA,B]
Substitution
置換先の文字列。いくつかありえる。
- ファイルシステムパス
- URLパス
- 絶対URL
- - (ダッシュ): 置換しない。環境変数設定などのフラグの設定用。
加えて以下の特殊文字も使用可能。
- 後方参照 (RewriteRule) $N
- 後方参照 (RewriteCond) %N
- サーバー変数 %{}
- マッピング関数 ${mapname:key~default}
Flags
RewriteRule Flags - Apache HTTP Server Version 2.4
指定可能なフラグが大量にある。が、よく使うものは少数。よく使う準。
- L|last: これ以上ルールを処理しない。関数でいうreturn/exit/break相当。これを指定しない場合、上のほうのRewriteRuleで書き換えた結果を、後続のRewriteRuleで処理することになる。基本は1 RewriteRuleにつき1L。ほぼ常につける。
- QSA|qsappend: Query String Append。本来、書き換えする際、?%{QUERY_STRING}を自分で明示的にしない限り、クエリー文字列は破棄される。破棄せずに自動的に引き継いでくれる。リダイレクトするときに、クエリー文字列も引き継いでほしいことが多いのでよく指定する。ほぼ常につける。
- R|redirect: 外部リダイレクト、HTTPリダイレクトを行う。これを指定しない場合、内部リダイレクト (URLは変わらない)。R=のあとに有効なHTTPステータスコードを指定できる。302=temp (デフォルト) /301=permanent/303=seeotherのシンボリック名がある。
- NC|nocase: Patternのマッチの大文字小文字を無視する。
- B (escape backreferences): 変換前に非英数字をエスケープする。後方参照時に基本的に使う。URLのマッピング前に、URL内のエスケープを解除する。したがって、後方参照時に、エスケープが解除される。このフラグを適用すると、後方参照内の英数字以外がエスケープされる。例えば、検索フォームでx & y/zを入力すると、アドレスバーやリクエストはエスケープしてくれる。が、後方参照はエスケープを解除してしまうので、BがないとURLにx&y/zがそのまま登場して不正なURLになる。
- PT|passthrogh: Alias/ScriptAlias/Redirectを解釈したい場合に使用。
L(100%) > QSA(90%) > R(70%) > NC(50%) > B(40%) > PT(20%)
あまり使わない。
- E|env: 環境変数を設定する。 [E=VAR:VAL] # 環境変数VARにVALを代入。 [E=VAR] # 環境変数VARを空で定義。 [E=!VAR] # 環境変数VARを解除。
- UnsafeAllow3F: 基本は使わない。Apache v2.2までは、URLクエリー文字列内部に?がある場合、バックリファレンスで?がそのままだった。が、v2.4からはエンコードして%3Fにしている。この動きが困る場合だけつける。レガシー互換用。本来ならアプリで対応すべき内容。
[L,QSA] をデフォルトフラグに思っておくとよい。R/NC/B/PTは状況に応じて、状況にマッチしたら必須になる。
RewriteCond
RewriteCond TestString CondPattern [flags]
RewriteCondはルールの条件 (if文相当) の定義指令。RewriteRuleの直前に配置する。
RewriteRuleで使用可能な変数をテストしてRewriteRuleで書き換えるかどうか振り分ける。
例
# 1. ファイルが存在しない場合のみリライト
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php [L]
# 2. HTTPS接続を強制
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# 3. 特定のUser-Agentをブロック
RewriteCond %{HTTP_USER_AGENT} (malicious-bot|spammer) [NC]
RewriteRule .* - [F]
# 4. ホットリンク防止
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?example\.com/ [NC]
RewriteRule \.(jpg|png|gif)$ - [NC,F,L]
後方参照
backreferenceという構文。Pattern/TestString部分で丸括弧で囲んだ部分を、Substitution/CondPatternでも参照可能。N=0-9の数字で、RewriteRuleは$N、RewriteCondは%Nで参照。N=0はマッチ全体。
RewriteRuleの場合、[B]オプションを指定して、原則エスケープする。
変数
| HTTP headers: | connection & request: | |
|---|---|---|
| HTTP_ACCEPT
HTTP_COOKIE HTTP_FORWARDED HTTP_HOST HTTP_PROXY_CONNECTION HTTP_REFERER HTTP_USER_AGENT |
AUTH_TYPE
CONN_REMOTE_ADDR CONTEXT_PREFIX CONTEXT_DOCUMENT_ROOT IPV6 PATH_INFO QUERY_STRING REMOTE_ADDR REMOTE_HOST REMOTE_IDENT REMOTE_PORT REMOTE_USER REQUEST_METHOD SCRIPT_FILENAME |
|
| server internals: | date and time: | specials: |
| DOCUMENT_ROOT
SCRIPT_GROUP SCRIPT_USER SERVER_ADDR SERVER_ADMIN SERVER_NAME SERVER_PORT SERVER_PROTOCOL SERVER_SOFTWARE |
TIME_YEAR
TIME_MON TIME_DAY TIME_HOUR TIME_MIN TIME_SEC TIME_WDAY TIME |
API_VERSION
CONN_REMOTE_ADDR HTTPS IS_SUBREQ REMOTE_ADDR REQUEST_FILENAME REQUEST_SCHEME REQUEST_URI THE_REQUEST |
特によく使うものは以下。
- REQUEST_FILENAME: リクエストされたファイルのサーバー上の絶対パス。
- REQUEST_URI: /index.htmlのようなリクエストURIのパス部分。URLクエリーはQUERY_STRINGにある。
CondPattern
CondPatternはTestStringに対する正規表現 (PCRE) が基本。ただし、いくつかの追加の構文が使用可能。
- !文字の前置でCondPatternの否定になる。
- 辞書比較演算子が使用可能。
- <
- >
- =
- <=
- >=
- 数値比較演算子が使用可能。
- -eq
- -ge
- -gt
- -le
- -lt
- -ne
- ファイル属性テスト。
- -d: ディレクトリー判定。
- -f: ファイル判定。
- -F: 内部リクエスト経由のファイル判定。サーバー性能に影響ある。
- -l/-h/-L: シンボリックリンクの判定。-lt/-leとの混同防止で-h/-Lも使用可能。
- -s: ファイル判定+0超過ファイル。
- -U
- -x: 実行権限
- TestStringが特殊値exprの場合、CondPatternはap_exprとみなす。
ファイル属性テストの-d/-fはよく使う。
Flags
RewriteCondの第3引数にフラグを指定できる。これは以下の3種だけ指定可能で、CondPatternに作用する。
- nocase|NC (No Case): 大文字小文字の違いを無視。
- ornext|OR (OR next condition): RewriteCondを複数記載時に、デフォルトのANDではなくORで判断する。
- novary|NV (No Vary): 条件にHTTPヘッダーを使用した場合、このフラグはレスポンスのVaryヘッダーに使用ヘッダーの追加を抑制する。あまり使わない。
ORをよく使う。
Debug
RewriteRuleは条件が複雑になりがちで、デバッグが重要。いくつか方法がある。
Log Level alert rewrite:trace3
mod_rewriteはLogLevelでのログ用にtrace1-trace8 (debug-emergに対応?) までのログレベルを用意している。
trace8=debug未満では、何のログも出力しない。2超過は性能が落ちるのでデバッグ用にだけ使う。
auth
認証、承認、アクセス制御 - Apache HTTP サーバ バージョン 2.4
Apache HTTP Serverで実現可能な認証機能が複数ある。
mod_authn_core と mod_authz_core がコア機能。
mod_authz_core
- mod_authz_core - Apache HTTP Server Version 2.4
- Upgrading to 2.4 from 2.2 - Apache HTTP Server Version 2.4
- https://grok.com/share/c2hhcmQtMw%3D%3D_affdef93-e636-4f23-a274-e5f07be71b9d
アクセス制御の指令がいくつかある。Apache 2.2まで使用されていた、Allow/Deny/Order/Satisfyがあったのだけど、2.4でこれが整理されて、別の記法が推奨になった。
対応関係
対応関係を整理する。
昔の記法はシンプルだが、複数組み合わせた複雑な論理がしにくく、評価順序による予期せぬ動作が発生しやすかった。
新しい記法だと、認証プロバイダー (例: ip/host/user/group/all) で定義でき、<RequreAll> (初期値)のOR、<RequireAll> のAND、<RequreNone> NOTで複雑な組み合わせが可能になり、Satisfyも不要になった。
| シナリオ | 古い記法 (2.2以前) | 新しい記法 (2.4以降) | 説明 |
|---|---|---|---|
| すべて許可 | Order allow,denyAllow from all
|
Require all granted
|
無条件でアクセスを許可。 |
| すべて拒否 | Order deny,allowDeny from all
|
Require all denied
|
無条件でアクセスを拒否。 |
| 特定IPからのみ許可(他拒否) | Order deny,allowDeny from allAllow from 192.168.1.1
|
Require ip 192.168.1.1
|
IPアドレス(またはサブネット: 192.168.1)を指定。部分一致可能。
|
| 特定ドメインからのみ許可(他拒否) | Order deny,allowDeny from allAllow from example.com
|
Require host example.com
|
ホスト名やドメインを指定。サブドメインも対応(例: .example.com)。
|
| すべて許可だが特定IPを拒否 | Order allow,denyAllow from allDeny from 192.168.1.1
|
<RequireAll>Require all grantedRequire not ip 192.168.1.1</RequireAll>
|
否定には<RequireAll>を使い、AND論理で制限。複数拒否も追加可能。
|
| 認証とIP制限の両方が必要(AND) | Order deny,allowDeny from allAllow from 192.168.1.1Satisfy allAuthType BasicAuthName "Secure"AuthBasicProvider fileAuthUserFile /path/to/usersRequire valid-user
|
AuthType BasicAuthName "Secure"AuthBasicProvider fileAuthUserFile /path/to/users<RequireAll>Require valid-userRequire ip 192.168.1.1</RequireAll>
|
Satisfy allを<RequireAll>で置き換え。認証ディレクティブは共通。
|
| 認証かIP制限のどちらかでOK(OR) | Order deny,allowDeny from allAllow from 192.168.1.1Satisfy anyAuthType BasicAuthName "Secure"AuthBasicProvider fileAuthUserFile /path/to/usersRequire valid-user
|
AuthType BasicAuthName "Secure"AuthBasicProvider fileAuthUserFile /path/to/usersRequire valid-userRequire ip 192.168.1.1
|
デフォルトでOR論理(<RequireAny>相当)。明示的に<RequireAny>を使ってもOK。
|
| グループ認証とIP拒否の組み合わせ | Order allow,denyAllow from allDeny from bad.example.comAuthType BasicAuthName "Secure"AuthBasicProvider fileAuthUserFile /path/to/usersAuthGroupFile /path/to/groupsRequire group adminSatisfy all
|
AuthType BasicAuthName "Secure"<br>AuthBasicProvider fileAuthUserFile /path/to/usersAuthGroupFile /path/to/groups<RequireAll>Require group adminRequire all grantedRequire not host bad.example.com</RequireAll>
|
複雑な論理はコンテナで表現。<RequireNone>で複数のNOTも可能(例: <RequireNone> Require host bad1 Require host bad2 </RequireNone>)。
|
デフォルトがORなので、<RequireAll>でAND条件にするのが基本。
特定IP/hostのみ除外はよく使うと思われる。
<RequireAll> Require all granted Require not ip 192.168.1.1 </RequireAll>
Require
- mod_authz_user - Apache HTTP Server Version 2.4
- mod_authz_host - Apache HTTP Server Version 2.4
- mod_authz_groupfile - Apache HTTP Server Version 2.4
httpd v2.4で刷新された認証指令。非常に重要。
Require [not] <entity-name> [<entity-name> ...] <argument>
上記のような書式。<entity-name> (プロバイダー) が複数あって、これで識別する。
- Require all granted: 全員許可
- Require all deniede: 全員禁止。
- Require env <env-var> [<env-var> ...]: いずれかの環境変数がある場合許可。
- Require method <http-method> [<http-method>...]: 指定したHTTPメソッドのみ許容。
- Require expr <expression>: <expression> がtrueの場合許容。
- Require user <userid> [<userid>...]: 指定したユーザーのみ。
- Require group <group-name> [<group-name>...]: 指定したグループのみ。
- Require valid-user: 有効なユーザーのみ (パスワードファイルに記載のあるユーザーのみ)
- Require ip <ip> [<ip>...]: 指定したipのみ。ip/netmaskやip/CIDRの表記も可能。
- Require host <host-name> [<host-name>...]: 指定ホストのみ。
- Require forward-dns <>
- Require local: ローカルのみ。
Basic
一番基本的な認証機能では、<Directory>指令か、.htaccessで定義する。
以下の流れで認証設定する。
- htpasswdでパスワードを作成
- <Directive>/.htaccessで保護対象パスを指定。
- 認証方式とパスワードファイルの指定
htpasswd
htpasswd - Manage user files for basic authentication - Apache HTTP Server Version 2.4
最初にパスワードファイルを作成する。認証プロバイダーによって作成方法が異なる。
Basic認証では、htpasswdコマンドで作る。httpd付属のパスワード作成ソフト。
htpasswd [option] <passwordfile> <username>
- 引数
- <passwordfile>: 作成するパスワードファイルのパス。
- <username>: パスワードのユーザー名。
- オプション
- -c: create。パスワードファイルを新規作成する。上書きするので初回だけ実行すること。
例:
htpasswd -c /usr/local/apache/passwd/passwords rbowen
htpasswdを実行するとパスワードの入力が要請されるので、入力する。
ログイン前に確認されないように、パスワードファイルは、Webからアクセス不能な場所 (documentroot外部) に配置する。
.htaccess
パスワードファイルを作成したら、設定で参照する。
httpd.confの<Directory> セクションか、.htaccessで以下の内容を記載する。
AuthType Basic AuthName "Restricted Files" # (Following line optional) AuthBasicProvider file AuthUserFile /usr/local/apache/passwd/passwords Require user rbowen
指令の内容は以下の通り。
- AuthType: 認証方式。一般的なのはBasic。パスワードを暗号化せずにクライアントに送信するので、HTTPS必須。
- AuthName: 認証に使うRealm (領域) を指定。2種類の役割がある。1. パスワード入力ダイアログに表示する情報の一部としてWebブラウザーが使う。2. 認証領域の流用で使う。同じRealmの指定があれば、クライアントに保存された同じパスワードをWebブラウザーが自動入力しようとする。
- AuthBasicProvider: 認証プロバイダーの指定。初期値fileなのでAuthType Basicの場合省略可能尾。mod_authn_dbm/mod_authn_dbdなどDBを使う場合指定必須。
- AuthUserFile: htpasswdで作成したパスワードファイルのパスを指定。リクエストのたびにこのプレーンテキストを検査する。ユーザー数が数百を超えると遅延を感じる。その場合、mod_authn_dbmのAuthDBMUserFileでDBファイルを指定したりする。
- Require: アクセス可能なユーザーを指定する。
Requireはいくつか指定方法がある。ユーザーを指定する方式だと、複数ユーザーを追加する場合、都度修正が必要になる。
グループの指定か、valid-userで複数ユーザーを管理できる。
AuthGroupFileで以下のようなユーザー名を列挙したグループを定義する。
GroupName: rbowen dpitts sungo rshersey
続いて、htpasswdに上記のユーザーを追加する。
htpasswd /usr/local/apache/passwd/passwords dpitts
最後に、Require group GroupNameでグループを指定する。
AuthType Basic AuthName "By Invitation Only" # Optional line: AuthBasicProvider file AuthUserFile /usr/local/apache/passwd/passwords AuthGroupFile /usr/local/apache/passwd/groups Require group GroupName
これで複数ユーザーをグループファイルに外だしできる。
他に、Require valid-userを指定すると、パスワードファイル記載のどのユーザーでも承認する。
パスワードファイルがグループも兼ねるイメージ。ユーザーが少ないなら、Require valid-userがシンプル。
[サーバーIPがブラックリストに載ってメール送信エラーになるのを解除する方法]
MailHog: Go言語製のメールサーバーソフト。
Debian
PHP8
[How To Install PHP 8.0 on Debian 11/10/9 | ComputingForGeeks](https://computingforgeeks.com/how-to-install-php-on-debian-linux/)
Debian 11の場合、PHP 8には外部リポジトリーが必要なので追加する。
sudo apt update
sudo apt install -y lsb-release ca-certificates apt-transport-https software-properties-common gnupg2
PHPパッケージを追加する。
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list
wget -qO - https://packages.sury.org/php/apt.gpg | sudo apt-key add -
sudo apt update
これでPHP8を参照できるので、インストールする。
sudo apt install php8.2
[How to Switch between Multiple PHP Version on Debian 12/11/10 – TecAdmin](https://tecadmin.net/switch-between-multiple-php-version-on-debian/)
インストールしたら、PHPのバージョンを切り替える。
a2dismod php7.4
a2enmod php8.2
sudo systemctl restart apache2
php 8.2にするとこういうエラー。
[Sat Sep 02 11:31:02.558029 2023] [php:error] [pid 25644] [client 133.106.38.37:57181] PHP Fatal error: Uncaught Error: Undefined constant "DB_DATAOBJECT_ERROR_NODATA" in /var/www/gnusocial/public/index.php:104\nStack trace:\n#0 [internal function]: handleError()\n#1 {main}\n thrown in /var/www/gnusocial/public/index.php on line 104
念のためdockerで起動を試みましたが、同じくトップ画面を開くと同じエラーになります。
<https://notabug.org/gnusocialjp/gnusocial/src/main/docker/development> にDockerでの起動方法があります。`docker compose up -d` を実行するだけでlocalhostでアクセスできます。
私とあなたとの環境の違いを排除したいので、dockerのインストールだけ頑張って、それでdockerでも簡単に動作確認してくれませんか?
alternative
Ref: DebianAlternatives - Debian Wiki.
OS内でバージョン違いのプログラムを管理するための仕組みがある。それがupdate-alternativesコマンド。
sudo update-alternatives --display vi
sudo update-alternatives --config vi
オプションとコマンド名を指定することで、現在の実体と更新ができる。
XAMPP
ポート番号変更
XAMPP Control PanelのConfigから変更可能。
phpmyadminはConfigのphpmyadminで、Servers.portを追加する。
