Awesome .htaccess Snippets
.htaccess Snippetsを扱う資料や関連プロジェクトをまとめたAwesomeリストです。
目次
- 書き換えとリダイレクト
- セキュリティ
- すべてのアクセスを拒否
- 自分以外のアクセスを拒否
- スパマー以外のアクセスを許可
- 隠しファイルとディレクトリへのアクセスを拒否
- バックアップとソースファイルへのアクセスを拒否
- ディレクトリ一覧を無効化
- 画像の直リンクを無効化
- 特定ドメインの画像直リンクを無効化
- ディレクトリをパスワード保護
- ファイルをパスワード保護
- リファラーで訪問者をブロック
- 特定のUser-Agentをブロック
- サイトのフレーム表示を防止
- Content Security Policy(CSP)
- MIMEタイプスニッフィングを防止
- Referrer Policyを設定
- Permissions Policyを設定
- サーバー署名を削除
- パフォーマンス
- その他
書き換えとリダイレクト
注: mod_rewriteがインストールされ、有効になっていることを前提とします。
wwwを強制
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301,NC]汎用的にwwwを強制
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]これは_任意の_ドメインで機能します。出典
非wwwを強制
wwwと非wwwのどちらを使うべきかは今も議論が続いています。裸のドメインを好む場合は次の設定を使えます。
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]汎用的に非wwwを強制
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.
RewriteCond %{HTTPS}s ^on(s)|off
RewriteCond http%1://%{HTTP_HOST} ^(https?://)(www\.)?(.+)$
RewriteRule ^ %1%3%{REQUEST_URI} [R=301,L]HTTPSを強制
RewriteEngine on
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
# Note: It’s also recommended to enable HTTP Strict Transport Security (HSTS)
# on your HTTPS website to help prevent man-in-the-middle attacks.
# See https://developer.mozilla.org/en-US/docs/Web/Security/HTTP_strict_transport_security
<IfModule mod_headers.c>
# Remove "includeSubDomains" if you don't want to enforce HSTS on all subdomains
Header always set Strict-Transport-Security "max-age=31536000;includeSubDomains"
</IfModule>プロキシ背後でHTTPSを強制
サーバーの前段にTLS終端を行うプロキシがある場合に便利です。
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}末尾スラッシュを強制
RewriteCond %{REQUEST_URI} /+[^\.]+$
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]末尾スラッシュを削除
このスニペットは、実在するディレクトリを除き、末尾がスラッシュのパスをスラッシュなしのパスへリダイレクトします。たとえば https://www.example.com/blog/ を https://www.example.com/blog へ変換します。各ページに正規URLを設けることが推奨されるため、SEOでも重要です。
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [R=301,L]単一ページをリダイレクト
Redirect 301 /oldpage.html https://www.example.com/newpage.html
Redirect 301 /oldpage2.html https://www.example.com/folder/RedirectMatchでリダイレクト
RedirectMatch 301 /subdirectory(.*) https://www.newsite.com/newfolder/$1
RedirectMatch 301 ^/(.*).htm$ /$1.html
RedirectMatch 301 ^/200([0-9])/([^01])(.*)$ /$2$3
RedirectMatch 301 ^/category/(.*)$ /$1
RedirectMatch 301 ^/(.*)/htaccesselite-ultimate-htaccess-article.html(.*) /htaccess/htaccess.html
RedirectMatch 301 ^/(.*).html/1/(.*) /$1.html$2
RedirectMatch 301 ^/manual/(.*)$ https://www.php.net/manual/$1
RedirectMatch 301 ^/old-directory/(.*)$ /new-directory/$1
RedirectMatch 301 ^/z/(.*)$ https://static.askapache.com/$1単一ディレクトリのエイリアス
RewriteEngine On
RewriteRule ^source-directory/(.*) /target-directory/$1 [R=301,L]パスをスクリプトへ割り当て
FallbackResource /index.fcgiこの例では、あるディレクトリに index.fcgi があり、そのディレクトリ内でファイル名やディレクトリ名として解決できないリクエストを index.fcgi へ送ります。baz.foo/some/cool/path を baz.foo/index.fcgi(baz.foo へのリクエストにも対応)で処理しながら、baz.foo/css/style.css などを維持したい場合に便利です。元のパスは、スクリプト環境に公開されるPATH_INFO環境変数から取得できます。
RewriteEngine On
RewriteRule ^$ index.fcgi/ [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.fcgi/$1 [QSA,L]これはFallbackResourceディレクティブより効率が劣ります(mod_rewriteはFallbackResourceだけを扱うより複雑なため)が、より柔軟です。
サイト全体をリダイレクト
Redirect 301 / https://newsite.com/この方法ではリンクのパスを維持します。つまりwww.oldsite.com/some/crazy/link.htmlはwww.newsite.com/some/crazy/link.htmlになります。サイトを新しいドメインへ移転する場合に非常に便利です。出典
クリーンURLのエイリアス
このスニペットを使うと、example.com/users のような、example.com/users.php に代わるPHP拡張子なしの「クリーン」URLを利用できます。
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([^.]+)$ $1.php [NC,L]URLをリダイレクト対象から除外
このスニペットはURLをリダイレクト対象から除外します。たとえばリダイレクト規則を設定しつつ、検索エンジンが想定どおりアクセスできるようrobots.txtだけを除外できます。
RewriteEngine On
RewriteRule ^robots.txt - [L]セキュリティ
すべてのアクセスを拒否
Require all deniedでも、これによりあなたのコンテンツからもアクセスが遮られます!したがって紹介するのは…
自分以外のアクセスを拒否
Require all denied
Require ip xxx.xxx.xxx.xxxxxx.xxx.xxx.xxx is your IP. If you replace the last three digits with 0/12 for example, this will specify a range of IPs within the same network, thus saving you the trouble to list all allowed IPs separately. Source
もちろん、逆のバージョンもあります:
スパマー以外のアクセスを許可
Require all granted
Require not ip xxx.xxx.xxx.xxx
Require not ip xxx.xxx.xxx.xxy
隠しファイルとディレクトリへのアクセスを拒否
名前がドット.で始まる隠しファイルとディレクトリ(.htaccess、.htpasswd、.git、.hgなど)は、ほぼ常に保護すべきです。
RewriteCond %{SCRIPT_FILENAME} -d [OR]
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule "(^|/)\." - [F]代わりに「Not Found」エラーを返し、攻撃者へ手掛かりを与えない方法もあります。
RedirectMatch 404 /\..*$バックアップとソースファイルへのアクセスを拒否
これらのファイルはVi/Vimなどのテキスト/HTMLエディターが残す場合があり、公開されると重大なセキュリティリスクになります。
<FilesMatch "(\.(bak|config|dist|fla|inc|ini|log|psd|sh|sql|swp)|~)$">
Require all denied
</FilesMatch>ディレクトリ一覧を無効化
Options All -Indexes画像の直リンクを無効化
RewriteEngine on
# Remove the following line if you want to block blank referrer too
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(.+\.)?example.com [NC]
RewriteRule \.(jpe?g|png|gif|bmp|webp|avif|svg|ico)$ - [NC,F,L]
# If you want to display a “blocked” banner in place of the hotlinked image,
# replace the above rule with:
# RewriteRule \.(jpe?g|png|gif|bmp|webp|avif|svg|ico) https://example.com/blocked.png [R,L]特定ドメインの画像直リンクを無効化
特定の悪質なサイトからの画像直リンクだけを無効にしたい場合があります。
RewriteEngine on
RewriteCond %{HTTP_REFERER} ^https?://(.+\.)?badsite\.com [NC,OR]
RewriteCond %{HTTP_REFERER} ^https?://(.+\.)?badsite2\.com [NC,OR]
RewriteRule \.(jpe?g|png|gif|bmp|webp|avif|svg|ico)$ - [NC,F,L]
# If you want to display a “blocked” banner in place of the hotlinked image,
# replace the above rule with:
# RewriteRule \.(jpe?g|png|gif|bmp|webp|avif|svg|ico) https://example.com/blocked.png [R,L]ディレクトリをパスワード保護
まず、システム内の任意の場所に.htpasswdファイルを作成します。
htpasswd -c /home/fellowship/.htpasswd boromir次に、それを認証へ使用します。
AuthType Basic
AuthName "One does not simply"
AuthUserFile /home/fellowship/.htpasswd
Require valid-userファイルをパスワード保護
AuthName "One still does not simply"
AuthType Basic
AuthUserFile /home/fellowship/.htpasswd
<Files "one-ring.o">
Require valid-user
</Files>
<FilesMatch ^((one|two|three)-rings?\.o)$>
Require valid-user
</FilesMatch>リファラーで訪問者をブロック
特定のドメインをリファラーとして訪れたすべてのユーザーのアクセスを拒否します。 Source
RewriteEngine on
# Options +FollowSymlinks
RewriteCond %{HTTP_REFERER} somedomain\.com [NC,OR]
RewriteCond %{HTTP_REFERER} anotherdomain\.com
RewriteRule .* - [F]特定のUser-Agentをブロック
特定のUser-Agentによるサイトへのアクセスを遮断します。スクレイパーや悪質なボットのブロックに便利です。
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} BadBot [NC,OR]
RewriteCond %{HTTP_USER_AGENT} EvilScraper [NC]
RewriteRule .* - [F,L]サイトのフレーム表示を防止
特定のURIだけは許可しつつ、ウェブサイトがiframeタグ内へ埋め込まれることを防止します。
SetEnvIf Request_URI "/starry-night" allow_framing=true
Header set X-Frame-Options SAMEORIGIN env=!allow_framingContent Security Policy(CSP)
Content Security Policyヘッダーは、読み込みを許可する動的リソースを宣言し、クロスサイトスクリプティング(XSS)などのコードインジェクション攻撃を軽減します。
<IfModule mod_headers.c>
Header set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'"
</IfModule>用途に合わせてディレクティブを調整してください。利用可能な全ディレクティブはCSPリファレンスを参照してください。
MIMEタイプスニッフィングを防止
ブラウザーがリソースのMIMEタイプを推測(スニッフィング)することを防ぎます。ブラウザーはサーバーの指定を信頼し、想定タイプと一致しないリソースをブロックします。
<IfModule mod_headers.c>
Header set X-Content-Type-Options "nosniff"
</IfModule>Referrer Policyを設定
リクエストに含めるリファラー情報の量を制御します。完全なURLが外部サイトへ漏れるのを防ぎ、ユーザーのプライバシーを保護します。
<IfModule mod_headers.c>
Header set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>Permissions Policyを設定
カメラ、マイク、位置情報など、サイトが利用できるブラウザー機能を制限します。
<IfModule mod_headers.c>
Header set Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()"
</IfModule>サーバー署名を削除
ApacheがHTTPヘッダーやエラーページでバージョン番号とOS情報を公開するのを防ぎます。
ServerSignature Offパフォーマンス
テキストファイルを圧縮
<IfModule mod_deflate.c>
# Force compression for mangled headers.
# https://developer.yahoo.com/blogs/ydn/pushing-beyond-gzipping-25601.html
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
</IfModule>
</IfModule>
# Compress all output labeled with one of the following MIME-types
# (mod_filter is required for Apache 2.4)
<IfModule mod_filter.c>
AddOutputFilterByType DEFLATE application/atom+xml \
application/javascript \
application/json \
application/rss+xml \
application/x-font-ttf \
application/x-web-app-manifest+json \
application/xhtml+xml \
application/xml \
font/opentype \
image/svg+xml \
image/x-icon \
text/css \
text/html \
text/plain \
text/xml
</IfModule>
</IfModule>Expiresヘッダーを設定
Expires headers tell the browser whether they should request a specific file from the server or just grab it from the cache. It is advisable to set static content’s expires headers to something far in the future.
ファイル名ベースのキャッシュバスティングでバージョンを管理していない場合は、CSSやJSなどのキャッシュ期間を1週間程度へ短縮することを検討してください。出典
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"
# CSS
ExpiresByType text/css "access plus 1 year"
# Data interchange
ExpiresByType application/json "access plus 0 seconds"
ExpiresByType application/xml "access plus 0 seconds"
ExpiresByType text/xml "access plus 0 seconds"
# Favicon (cannot be renamed!)
ExpiresByType image/x-icon "access plus 1 week"
# HTML
ExpiresByType text/html "access plus 0 seconds"
# JavaScript
ExpiresByType application/javascript "access plus 1 year"
# Manifest files
ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"
# Media
ExpiresByType audio/ogg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType video/mp4 "access plus 1 month"
ExpiresByType video/ogg "access plus 1 month"
ExpiresByType video/webm "access plus 1 month"
# Web feeds
ExpiresByType application/atom+xml "access plus 1 hour"
ExpiresByType application/rss+xml "access plus 1 hour"
# Web fonts
ExpiresByType application/font-woff2 "access plus 1 month"
ExpiresByType application/font-woff "access plus 1 month"
ExpiresByType application/x-font-ttf "access plus 1 month"
ExpiresByType font/opentype "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
</IfModule>Cache-Controlヘッダーを設定
Cache-Control headers provide more fine-grained control over browser caching than Expires headers. You can use both together for maximum compatibility.
<IfModule mod_headers.c>
# Cache CSS and JS for 1 year
<FilesMatch "\.(css|js)$">
Header set Cache-Control "max-age=31536000, public"
</FilesMatch>
# Cache images for 1 month
<FilesMatch "\.(jpe?g|png|gif|webp|avif|svg|ico)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
# Cache fonts for 1 month
<FilesMatch "\.(woff2?|ttf|otf)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
# Do not cache HTML
<FilesMatch "\.(html|htm)$">
Header set Cache-Control "no-cache, no-store, must-revalidate"
</FilesMatch>
</IfModule>eTagを無効化
ETagヘッダーを削除すると、キャッシュとブラウザーはファイルを検証できなくなり、Cache-ControlとExpiresヘッダーに依存します。出典
<IfModule mod_headers.c>
Header unset ETag
</IfModule>
FileETag Noneその他
PHP変数を設定
php_value <key> <val>
# For example:
php_value upload_max_filesize 50M
php_value max_execution_time 240カスタムエラーページ
ErrorDocument 500 "Houston, we have a problem."
ErrorDocument 401 https://error.example.com/mordor.html
ErrorDocument 404 /errors/halflife3.htmlカスタムメンテナンスページ
特定のIPアドレスからのアクセスだけを許可し、その他すべてのトラフィックをメンテナンスページへリダイレクトします。
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^xxx\.xxx\.xxx\.xxx
RewriteCond %{REQUEST_URI} !/maintenance.html$ [NC]
RewriteCond %{REQUEST_URI} !\.(css|js|png|jpe?g|gif|svg|ico)$ [NC]
RewriteRule .* /maintenance.html [R=503,L]メンテナンス中もアクセスできるよう、xxx.xxx.xxx.xxxを自分のIPアドレスへ置き換えてください。
ダウンロードを強制
コンテンツを表示せず、ブラウザーにダウンロードさせたい場合があります。
<Files *.md>
ForceType application/octet-stream
Header set Content-Disposition attachment
</Files>この陰には陽があるのです:
ダウンロードを防止
コンテンツをダウンロードせず、ブラウザーに表示させたい場合があります。
<FilesMatch "\.(tex|log|aux)$">
Header set Content-Type text/plain
</FilesMatch>クロスドメインフォントを許可
CDNから配信されるウェブフォントは、CORSのためFirefoxで動作しない場合があります。このスニペットで解決できます。
<IfModule mod_headers.c>
<FilesMatch "\.(otf|ttc|ttf|woff|woff2)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>CORSを有効化
サイトでCross-Origin Resource Sharing(CORS)を有効にし、他のドメインからサーバーへのリクエストを許可します。
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type, Authorization"
</IfModule>特定のドメインに制限するには、* を https://example.com などのドメインへ置き換えます。
UTF-8を自動設定
テキストコンテンツは常にUTF-8でエンコードすべきです。
# Use UTF-8 encoding for anything served text/plain or text/html
AddDefaultCharset utf-8
# Force UTF-8 for a number of file formats
AddCharset utf-8 .atom .css .js .json .rss .vtt .xmlカスタムMIMEタイプを設定
Apacheが標準では認識しないファイル形式にカスタムMIMEタイプを定義します。
AddType application/manifest+json .webmanifest
AddType application/wasm .wasm
AddType application/x-ndjson .ndjson
AddType text/vtt .vtt別のPHPバージョンへ切り替え
共有ホスティングでは複数のPHPバージョンがインストールされていることがあり、サイトごとに特定バージョンを使いたい場合があります。次のスニペットでPHPバージョンを切り替えます。
AddHandler application/x-httpd-php84 .php
# Alternatively, you can use AddType
AddType application/x-httpd-php84 .phpWebP/AVIF画像を配信
元のjpg/pngと同じ名前のモダン形式画像(AVIFまたはWebP)があれば、代わりに配信します。ブラウザーが両方に対応する場合はAVIFを優先します。
RewriteEngine On
# Serve AVIF if supported and available
RewriteCond %{HTTP_ACCEPT} image/avif
RewriteCond %{DOCUMENT_ROOT}/$1.avif -f
RewriteRule (.+)\.(jpe?g|png)$ $1.avif [T=image/avif,E=accept:1]
# Otherwise, serve WebP if supported and available
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{DOCUMENT_ROOT}/$1.webp -f
RewriteRule (.+)\.(jpe?g|png)$ $1.webp [T=image/webp,E=accept:1]