Next.jsをCloudflareWorkersにデプロイしたらAPI が呼べなくなった...

今回はタイトル通りの内容に出くわしてしまったので、備忘録として記事を記載します。

現象

OpenNext(@opennextjs/cloudflare)を使ってNext.jsアプリをCloudflare Workersにデプロイしました。
Server Componentから別のWorkerで動いているAPIをfetchしようとしたところ、HTTP 404が返ってきました。

// Server Component 内
const res = await fetch('https://my-api.username.workers.dev/data');
// → 404 Not Found

不思議なことに、同じURLをcurlで叩くと正常に200が返ってきました。

curl https://my-api.username.workers.dev/data
# → 正常にレスポンスが返る

原因

レスポンスボディを確認するとerror code: 1042というCloudflare特有のエラーが含まれていました。
これはCloudflare Workers間のfetch制限によるものです。
同じ*.workers.devサブドメイン上にあるWorkerから別の Workerへのfetchリクエストは、セキュリティ上の理由(無限ループ防止など)でブロックされます。

解決策: Service Binding を使う

Cloudflareでは、Workers間の通信にはService Bindingを使います。
これにより、ネットワークを経由せず直接Workerを呼び出せます。

  1. wrangler.jsoncにService Bindingを追加
{
  "name": "my-web",
  "services": [
    {
      "binding": "API",
      "service": "my-api"  // 呼び出したい Worker の名前
    }
  ]
}
  1. OpenNextのgetCloudflareContextを使って呼び出す
import { getCloudflareContext } from '@opennextjs/cloudflare';

async function fetchFromAPI(path: string): Promise<Response> {
  try {
    const { env } = await getCloudflareContext({ async: true });
    if (env?.API) {
      // Service Binding 経由で呼び出し
      return env.API.fetch(new Request(`https://api${path}`));
    }
  } catch {
    // ローカル開発環境ではフォールバック
  }
  return fetch(`${API_BASE_URL}${path}`);
}
  1. デプロイ結果
Your Worker has access to the following bindings:
env.API (my-api)    Worker

これでServer ComponentからAPIを正常に呼び出せるようになりました。

まとめ

方法 同一 workers.dev 間 カスタムドメイン
通常の fetch ❌ エラー 1042 ✅ 可能
Service Binding ✅ 可能 ✅ 可能

Next.js on Cloudflare WorkersでAPIを分離している場合、Service Bindingは必須です。
ローカル開発時はgetCloudflareContextが使えないため、フォールバック処理も忘れずに。

他にもカスタムドメインを設定する方法やクライアントサイドでfetchする方法もあるみたいでしたが、 SSRを活かしつつ追加コストなしで解決できるService Bindingが良いかなと感じました。

参考

i18nとは?

はじめに

こんにちは!あめくです!
今日はアプリケーションを作成する際に出てきた言葉「i18n」が何かを調べてみました。

i18nとは

さまざまな地域、言語、文化が異なるターゲットオーディエンスに簡単に適応できるようにシステムを設計することを国際化対応(Internationalization) と呼びます。
国際化対応のInternationalizationの先頭のiと語尾のn、その間に18文字あるため「i18n」と略されるそうです。

対象項目

一般的な国際化の対象項目があるみたいで下記の項目が対象になってるそうです!

  • 文字セット(標準の文字コードなど)
  • 文字の方向性(左から右へ、右から左へ、左に向かって上から下へ、他)
  • 文言
  • 書式
  • 日時情報の時差
  • 通貨情報

i18nl10nの違い

i18n を調べてみると l10n という言葉もありました。
l10n は何かというとLocalization(ローカライゼーション)の略だそうです。
i18n と同じ略し方で、Lとnの間に10文字あるので「l10n」となります。

i18n は国際化で多言語対応できる「仕組み・設計」を作ることでしたが、 l10n は地域化で特定の言語・地域向けに「実際に翻訳・調整」することを言うそうです。

終わりに

アプリケーションをリリースするプラットフォームに日本語圏外が含まれていたり、他の言語でも対応したいと思った際に i18n 対応を考慮しておいても良いかなと感じました。
アプリ側のフレームワークやライブラリに i18n に対応したものがあったりするみたいなので、それを利用するのも良いかと思います!

今回は個人でアプリケーションを開発する際に英語で対応できないかなと思った際に i18n という言葉が出てきたので、調べて記事にしてみました。

もし何かありましたらコメントなどいただけると嬉しいです!

参考

Internationalization (i18n) 国際化と地域化

CSSのword-breakを使ってみた

はじめに

こんにちは!あめくです!
今回はCSSを用いて改行したいことがあったので、 word-break について調べてみました。

word-breakとは

word-breakとは、テキストがコンテンツボックスから溢れる場合に、ブラウザが改行するかどうかを指定することができるCSSプロパティです。
単語や文字がコンテナの端に達した時にどう改行するかを決定します。

主な値と動作

ベースのCSSを下記のように設定して動作確認してみたいと思います!

    <style>
      div {
        width: 200px;
        border: 1px solid #ccc;
        padding: 10px;
        margin: 10px;
      }
    </style>

normal(デフォルト値)

既定の改行規則を使用します。
言語ごとに定められた標準的な改行ルールに沿って改行されるみたいです。

  • CSSの設定方法
.example {
  word-break: normal;
}

表示の確認

<div style="word-break: normal;">
  Verylongwordwithoutspaces
  これは日本語のテキストです。
</div>

Verylongwordwithoutspaces: 単語の途中では切らない
これは日本語のテキストです。: 日本語なので文字ごとに改行できる

日本語・中国語・韓国語(CJK)の場合下記の制限があります。

  • 文字ごとに改行可能: ほぼすべての文字境界で改行できる
  • 禁則処理あり: 句読点などは行頭・行末禁則に従う
  • 英単語は分割しない: 混在する英単語は単語単位

break-all

CJK (中国語、台湾語、日本語、韓国語) 以外のテキストにおいて、単語中などでの文字の改行に関する禁則処理を解除し、どの文字の間でも改行するようにします。

  • CSSの設定方法
.example {
  word-break: break-all;
}

表示の確認

<div style="word-break: break-all;">
  Verylongwordwithoutspaces ← 途中で改行
  これは日本語のテキストです。
</div>

単語の途中で改行されることがあり、単語の意味が分かりにくくなったり、日本語の「。」が行頭に来ることもあるので、注意が必要です。
レイアウト優先ではみ出しを絶対に防ぎたいときに使えますね!

keep-all

CJK テキストの改行を許可しません。 CJK 以外のテキストについては normal と同じ挙動となります

  • CSSの設定方法
.example {
  word-break: keep-all;
}

表示の確認

<div style="word-break: keep-all;">
  これは 日本語の テキストです。 ← スペースでのみ改行
</div>

単語をまとまりとして扱い改行するため、読みやすさ優先で単語や文節をバラバラにしたくないときに使う設定になります。
狭いスペースでははみ出しやすかったり、日本語では改行位置が少なくなるということから注意が必要です。
特にレスポンシブデザインで問題になることもありそうです。

他の値

他にも break-word があるみたいですが、こちらは非推奨になってます。
長い単語のみ途中で改行することができる値ですが overflow-wrap: break-word; を使用することをお勧めします!

まとめ

今回はCSSで改行するための機能を見てみました。
ブラウザ上で改行するにもいろんな制約があることを知り、ただ改行するだけでなくどの値を設定するかで単語の扱い方が変わることを知ることができました。

CSSはまだまだ奥が深いので、新しいプロパティを知った際には備忘録として記事にしていきたいと思います。

この記事を見て何かございましたら、コメントなどしていただけると嬉しいです!

参考

MDN word-break

CSSの!importantとは?使い方と注意点

はじめに

こんにちはあめくです!

自分はCSSが苦手ということもあり、全体のCSSを加味して一部を変更するのがとても苦手です。
今回はCSSの!importantを使って優先順位を変更する機会があったので、記事として残したいと思います。

!importantとは

CSSの優先順位を 最優先 にする修飾子です。

通常の優先順位を無視して、そのスタイルを強制的に適用します。

使い方

要素 {
  プロパティ: 値 !important;
}
input {
    border: 1px solid red !important;
    color: blue !important;
    padding: 10px !important;
}

!important はプロパティの値の後かつセミコロンの前に書きます。

実際の使用例

私の場合、他社サイトの上に画面を作成する必要があり、自分が作成した画面のHTMLが他社サイトのCSSの影響を受けてしまいました。

/* 他社サイトのCSS */
input {
    border: 2px solid #ccc;
    padding: 5px;
}

/* 自分のスタイルを確実に適用 */
.my-input {
    border: 1px solid #000 !important;
    padding: 10px !important;
}

このように!importantを使うことで、他社サイトのCSSに影響されずに自分のスタイルを適用できました。

優先順位について

CSSの基本的な優先順位は以下の通りです。

IDセレクタ(優先度:高) > クラスセレクタ(優先度:中) > 要素セレクタ(優先度:低)

しかし、!important はこれらの順位を無視して最優先となります。
(ただし、複数の!importantがある場合は通常の優先順位ルールに従います)

!importantの問題点

デバッグが困難になる

みなさんお分かりかと思いますが、どこかで!importantが使われているとなぜスタイルが適用されないのか分かりにくくなります。

優先順位の混乱

無闇に!importantを用いるとどこでデバッグが困難になることもそうですが、正しい優先順位でCSSが適用されないということもあり、 管理不能に陥る可能性があります。

もしクラスの順序を変えたり適切なクラス名をつけたりと正しい優先順位で設定できるのであれば、!importantを用いずに設定するのが好ましいです!

まとめ

今回は!importantについて調べた内容を記事にさせていただきました。
自分の対応で、他社サイトの上に画面を作成することがあり、自分が作成した画面のHTMLが他社サイトのCSSの影響を受けることがありました。
そのため、今回の!importantを使用することがありどのように使うのか気になったため調べました。

もし!importantを使用せずにCSSの優先順位だけで対応できるならその方が良いということもわかりました。 ただ、使うのが危ない修飾子ではあるものの時にはとても役にたつものでもあります。

適切に使用するととても便利な修飾子なので、覚えておくのは損がない機能だと思いました!

ここまで読んでいただきありがとうございました!何かあればコメントいただけると嬉しいです。

参考

MDNの!important

【初心者向け】レインボーテーブル攻撃とは?簡単にまとめてみた

はじめに

ハッシュ値に関して調べていたら レインボーテーブル攻撃 という文言に初めて出会いました!
厨二心をくすぐられる名称だったので、調べてみました。

レインボーテーブルとは

Wikipediaによると

レインボーテーブル (rainbow table) は、ハッシュから平文を得るために使われるテクニックの一つである。
特殊なテーブルを使用して表引きを行うことで、時間と空間のトレードオフを実現している。

とのことです!

要するに ハッシュ値と対応する平文を大量に格納したデータ構造 と覚えておけば良さそうですね!

このデータ構造を使った攻撃が「レインボーテーブル攻撃」です。

参考: Wiki

レインボーテーブル攻撃

レインボーテーブル攻撃とは、レインボーテーブルの構造を利用し不正に取得したハッシュ値から元の平文を導き出す攻撃手法となります。

攻撃の流れ

  1. ハッシュ値の不正取得: 攻撃者がデータベースへの侵入などにより、ユーザーのパスワードのハッシュ値を入手します。
  2. レインボーテーブルとの照合: 入手したハッシュ値をレインボーテーブルと照合し、対応する平文を探します。
  3. 平文の特定: テーブル内に一致するハッシュ値があれば、元のパスワード(平文)が判明します。

なぜ効果的なのか

通常、ハッシュ値から平文を求めるには考えられるすべてのパスワードを1つずつハッシュ化して照合する「総当たり攻撃」が必要です。
しかし、レインボーテーブルを使えば事前に計算されたデータを参照するだけで済むため、攻撃時間を大幅に短縮できます。

特に、短いパスワードや一般的なパスワード(例: password123, qwertyなど)は、 レインボーテーブルに含まれている可能性が高く、瞬時に解読されてしまうリスクがあります。

レインボーテーブル攻撃を防ぐ方策

レインボーテーブル攻撃を防ぐためには、以下のような対策が有効です。

ソルト(Salt)の使用

ソルトとは、ハッシュ化する前の平文にランダムな文字列を付加する手法です。
たとえ同じパスワードでも、ユーザーごとに異なるソルトを使用することで異なるハッシュ値が生成されます。
これにより、事前に計算されたレインボーテーブルが使用できなくなります。

例:

  • password → ハッシュ化 → 5f4dcc3b5aa765d61d8327deb882cf99
  • password + ソルトabc123 → ハッシュ化 → 異なるハッシュ値

ストレッチング(繰り返しハッシュ化)

ハッシュ化を複数回繰り返すことで、計算コストを高める手法です。
攻撃者がレインボーテーブルを作成する際の計算時間が大幅に増加するため、攻撃を困難にします。

適切なハッシュ関数の選択

パスワードのハッシュ化には、MD5SHA-1のような高速なハッシュ関数ではなく 意図的に計算コストが高く設計された専用のハッシュ関数を使用すべきです。

推奨されるハッシュ関数

MD5SHA-1は高速であるがゆえに、攻撃者が総当たり計算を短時間で行えてしまうためパスワード用途には不向きだそうです。

ハッシュ化と暗号化の違い

ハッシュ化と同様に連想されるものに 暗号化 があります。混合されやすい内容ですが、下記のような違いがあります。

  • 暗号化:適切な鍵があれば暗号化されたデータを元に戻せる(復号可能)。
  • ハッシュ化:一方向性を持ち、理論上元のデータには戻せない。

まとめ

今回ハッシュ値について調べてたら、知らない攻撃手法が出てきました。
ハッシュ値は一方向性を持つため、データの復元ができないから安心という気持ちを持つかと思います。
ただ、レインボーテーブル攻撃という手法があるため、一概に安心ではないことがわかりました。

セキュリティ関連は安心するものではなく、安心と思われる内容にこと注意すべきだと改めて感じました。

ここまで読んでいただきありがとうございます。
もし何か間違いなどありましたらご指摘をコメントにていただけると嬉しいです!

参考

whoisコマンドの使い方:ドメイン情報を簡単に調べる方法(初級者向け)

最近ドメインに関する情報を調べたいと思ったので、今回はLinuxMacのコマンドで利用できる whois コマンドに関して記事を書きたいと思います!

今回は基本的な使い方をメインで紹介できればと思います。

whoisとは?

whoisコマンドとはドメイン名やIPアドレスの登録情報を調べるコマンドです。

「このウェブサイトは誰ば運営しているのだろうか?」「このドメインはいつ登録されたの??」

といった疑問を解決・確認できる便利なコマンドです。

インストール方法

調べたところ、一部Linux(Ubuntu)ではwhoisコマンドが利用できないみたいで、下記のコマンドのように一度インストール必要がある場合があります。

$ apt install whois

私の環境はMacなのですが、Macはデフォルトでこのコマンドが利用できます。

基本的な使い方

ドメイン名を調べる

この方法は一番シンプルな方法です。 調べたいドメイン名を下記のように指定するだけで良いです。

$ whois example.com

このコマンドを実行すると下記のような情報が取得できます。

$ whois example.com
% IANA WHOIS server
% for more information on IANA, visit http://www.iana.org
% This query returned 1 object

domain:       EXAMPLE.COM

organisation: Internet Assigned Numbers Authority

created:      1992-01-01
source:       IANA

IPアドレスを調べる

ドメイン名同様、IPアドレスを指定することで調べることができます。

$ whois 8.8.8.8
$ whois 8.8.8.8
% IANA WHOIS server
% for more information on IANA, visit http://www.iana.org
% This query returned 1 object

refer:        whois.arin.net

inetnum:      8.0.0.0 - 8.255.255.255
organisation: Administered by ARIN
status:       LEGACY

whois:        whois.arin.net

changed:      1992-12
source:       IANA

# whois.arin.net

NetRange:       8.8.8.0 - 8.8.8.255
CIDR:           8.8.8.0/24
NetName:        GOGL
NetHandle:      NET-8-8-8-0-2
Parent:         NET8 (NET-8-0-0-0-0)
NetType:        Direct Allocation
OriginAS:
Organization:   Google LLC (GOGL)
RegDate:        2023-12-28
Updated:        2023-12-28
Ref:            https://rdap.arin.net/registry/ip/8.8.8.0



OrgName:        Google LLC
OrgId:          GOGL
Address:        1600 Amphitheatre Parkway
City:           Mountain View
StateProv:      CA
PostalCode:     94043
Country:        US
RegDate:        2000-03-30
Updated:        2019-10-31
Comment:        Please note that the recommended way to file abuse complaints are located in the following links.
Comment:
Comment:        To report abuse and illegal activity: https://www.google.com/contact/
Comment:
Comment:        For legal requests: http://support.google.com/legal
Comment:
Comment:        Regards,
Comment:        The Google Team
Ref:            https://rdap.arin.net/registry/entity/GOGL


OrgTechHandle: ZG39-ARIN
OrgTechName:   Google LLC
OrgTechPhone:  +1-650-253-0000
OrgTechEmail:  [email protected]
OrgTechRef:    https://rdap.arin.net/registry/entity/ZG39-ARIN

OrgAbuseHandle: ABUSE5250-ARIN
OrgAbuseName:   Abuse
OrgAbusePhone:  +1-650-253-0000
OrgAbuseEmail:  [email protected]
OrgAbuseRef:    https://rdap.arin.net/registry/entity/ABUSE5250-ARIN

これでGoogleDNSサーバーの情報が分かります。

どんな情報がわかるのか

whoisコマンドで確認できる主な情報

google.com で確認してみたいと思います!

$ whois google.com
$ whois google.com
% IANA WHOIS server
% for more information on IANA, visit http://www.iana.org
% This query returned 1 object

refer:        whois.verisign-grs.com

domain:       COM

organisation: VeriSign Global Registry Services
address:      12061 Bluemont Way
address:      Reston VA 20190
address:      United States of America (the)

contact:      administrative
name:         Registry Customer Service
organisation: VeriSign Global Registry Services
address:      12061 Bluemont Way
address:      Reston VA 20190
address:      United States of America (the)
phone:        +1 703 925-6999
fax-no:       +1 703 948 3978
e-mail:       [email protected]

contact:      technical
name:         Registry Customer Service
organisation: VeriSign Global Registry Services
address:      12061 Bluemont Way
address:      Reston VA 20190
address:      United States of America (the)
phone:        +1 703 925-6999
fax-no:       +1 703 948 3978
e-mail:       [email protected]

nserver:      A.GTLD-SERVERS.NET 192.5.6.30 2001:503:a83e:0:0:0:2:30
nserver:      B.GTLD-SERVERS.NET 192.33.14.30 2001:503:231d:0:0:0:2:30
nserver:      C.GTLD-SERVERS.NET 192.26.92.30 2001:503:83eb:0:0:0:0:30
nserver:      D.GTLD-SERVERS.NET 192.31.80.30 2001:500:856e:0:0:0:0:30
nserver:      E.GTLD-SERVERS.NET 192.12.94.30 2001:502:1ca1:0:0:0:0:30
nserver:      F.GTLD-SERVERS.NET 192.35.51.30 2001:503:d414:0:0:0:0:30
nserver:      G.GTLD-SERVERS.NET 192.42.93.30 2001:503:eea3:0:0:0:0:30
nserver:      H.GTLD-SERVERS.NET 192.54.112.30 2001:502:8cc:0:0:0:0:30
nserver:      I.GTLD-SERVERS.NET 192.43.172.30 2001:503:39c1:0:0:0:0:30
nserver:      J.GTLD-SERVERS.NET 192.48.79.30 2001:502:7094:0:0:0:0:30
nserver:      K.GTLD-SERVERS.NET 192.52.178.30 2001:503:d2d:0:0:0:0:30
nserver:      L.GTLD-SERVERS.NET 192.41.162.30 2001:500:d937:0:0:0:0:30
nserver:      M.GTLD-SERVERS.NET 192.55.83.30 2001:501:b1f9:0:0:0:0:30
ds-rdata:     19718 13 2 8acbb0cd28f41250a80a491389424d341522d946b0da0c0291f2d3d771d7805a

whois:        whois.verisign-grs.com

status:       ACTIVE
remarks:      Registration information: http://www.verisigninc.com

created:      1985-01-01
changed:      2023-12-07
source:       IANA

# whois.verisign-grs.com

   Domain Name: GOOGLE.COM
   Registry Domain ID: 2138514_DOMAIN_COM-VRSN
   Registrar WHOIS Server: whois.markmonitor.com
   Registrar URL: http://www.markmonitor.com
   Updated Date: 2019-09-09T15:39:04Z
   Creation Date: 1997-09-15T04:00:00Z
   Registry Expiry Date: 2028-09-14T04:00:00Z
   Registrar: MarkMonitor Inc.
   Registrar IANA ID: 292
   Registrar Abuse Contact Email: [email protected]
   Registrar Abuse Contact Phone: +1.2086851750
   Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited
   Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
   Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited
   Domain Status: serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited
   Domain Status: serverTransferProhibited https://icann.org/epp#serverTransferProhibited
   Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited
   Name Server: NS1.GOOGLE.COM
   Name Server: NS2.GOOGLE.COM
   Name Server: NS3.GOOGLE.COM
   Name Server: NS4.GOOGLE.COM
   DNSSEC: unsigned
   URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/
>>> Last update of whois database: 2025-11-02T10:47:16Z <<<

# whois.markmonitor.com

Domain Name: google.com
Registry Domain ID: 2138514_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.markmonitor.com
Registrar URL: http://www.markmonitor.com
Updated Date: 2024-08-02T02:17:33+0000
Creation Date: 1997-09-15T07:00:00+0000
Registrar Registration Expiration Date: 2028-09-13T07:00:00+0000
Registrar: MarkMonitor, Inc.
Registrar IANA ID: 292
Registrar Abuse Contact Email: [email protected]
Registrar Abuse Contact Phone: +1.2086851750
Domain Status: clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)
Domain Status: clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)
Domain Status: clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)
Domain Status: serverUpdateProhibited (https://www.icann.org/epp#serverUpdateProhibited)
Domain Status: serverTransferProhibited (https://www.icann.org/epp#serverTransferProhibited)
Domain Status: serverDeleteProhibited (https://www.icann.org/epp#serverDeleteProhibited)
Registrant Organization: Google LLC
Registrant Country: US
Registrant Email: Select Request Email Form at https://domains.markmonitor.com/whois/google.com
Tech Email: Select Request Email Form at https://domains.markmonitor.com/whois/google.com
Name Server: ns3.google.com
Name Server: ns4.google.com
Name Server: ns2.google.com
Name Server: ns1.google.com
DNSSEC: unsigned
URL of the ICANN WHOIS Data Problem Reporting System: http://wdprs.internic.net/
>>> Last update of WHOIS database: 2025-11-02T10:46:00+0000 <<<

1. ドメインの基本情報

分かること

  • ドメイン名: Domain Name: google.com
  • 登録日: Creation Date: 1997-09-15T07:00:00+0000
  • 有効期限: Registrar Registration Expiration Date: 2028-09-13T07:00:00+0000
  • 最終更新日: Updated Date: 2019-09-09T15:39:04Z

2. 所有者情報

分かること

  • 組織名(会社名など): Registrant Organization: Google LLC
  • 国名: Registrant Country: US
  • 連絡先情報: Registrant Email: Select Request Email Form at https://domains.markmonitor.com/whois/google.com

WHOIS 情報の中には 所有者(Registrant)情報 が含まれていますが、現在は 個人情報保護の観点からマスク(非公開化)されています。 今回の場合だと、連絡先情報は直接は記載がなく、「Select Request Email Form at ...」と書かれてます。実際のメールアドレスは非公開(問い合わせフォーム経由)になっています。

3. ドメイン管理会社(レジストラ

分かること

  • どこでドメインを登録したか: Registrar: MarkMonitor, Inc.
  • 登録会社の連絡先:
Registrar Abuse Contact Email: [email protected]
Registrar Abuse Contact Phone: +1.2086851750

4. DNSサーバー情報

分かること

  • どのネームサーバーを使っているか:
   Name Server: NS1.GOOGLE.COM
   Name Server: NS2.GOOGLE.COM
   Name Server: NS3.GOOGLE.COM
   Name Server: NS4.GOOGLE.COM

いろいろな使い方

必要な情報だけを表示

そのまま使用するとたくさんの情報が表示されます。
全部の情報は多すぎるので、欲しい情報だけ抽出することも可能です。

下記のコマンドで、特定の文字列を検索してその行だけ出力できます。
※ name serverの箇所を他の文字に変えることで、検索対象の文字を変更することが可能。

$ whois google.com | grep -i "name server"

コマンドの実際の動き

  1. whois example.com
    example.comWHOIS情報を取得 (登録者、登録日、有効期限、DNS情報などが含まれる)
  2. | パイプ
    → 出力を次のコマンド grep に渡す
  3. grep -i "name server"
    → 「name server」という文字列を(大文字小文字を区別せず)検索し、その行だけ表示

怪しいサイトをチェック

フィッシングサイトかも?と思ったら whois コマンドを用いて下記の項目を確認

  • 登録日が最近(数日前とか)
  • 所有者情報が全部隠されている
  • 聞いたことない登録会社

結果をファイルに保存

WHOIS情報をdomain_info.txtというファイルに書き出すことが可能 ※ domain_info.txtは任意のファイル名を指定してください。

$ whois example.com > domain_info.txt

まとめ

whoisコマンドは、たった1行でドメインの情報が分かる便利なツールです。

ドメインの有効期限をチェックしたい、サイトの運営者を確認したい、怪しいサイトを調べたい、DNSサーバーを確認したい 上記のようなことを確認したい場合にとても便利です!

思ったより簡単に使えるコマンドなので、まずは自分の知っているサイトで気軽に試してみてください!

ここまで読んでいただきありがとうございました!もし何かあればコメントなどいただけると嬉しいです!

「ユニットエコノミクス」とは?【LTV・CAC・計算方法を解説】

エンジニアだけどユニットエコノミクスを考えてみた。

こんにちは!普段はエンジニアでソフトウェアのコードをガリガリ書いているあめくです!

いつもは技術的なことを記事にしてますが、 今回はマーケティング用語で特にSaasサブスクリプション型ビジネスで用いられるユニットエコノミクスとは何なのか調べてみました。

ユニットエコノミクスとは

ユニットエコノミクスとは主にサブスクリプション型のビジネスにおいて使われる、事業の経済性を表す管理会計の指標の一つだそうです。

ユニットエコノミクスが適正であればその事業は健全な状態とされ、この状態を「ユニットエコノミクスが成立した状態」といいます。

「LTV(顧客生涯価値)」と「CAC(顧客獲得コスト)」という2つの指標

※ LTVはCLV(Customer Lifetime Value)と言われることもあります。

ユニットエコノミクスの算出には、「LTV(顧客生涯価値)」と「CAC(顧客獲得コスト)」という2つの指標が用いられます。

LTV(顧客生涯価値)

LTVとは「Life Time Value」の頭文字を取ったマーケティング用語であり、 一人の顧客が取引を始めてから終了するまでの期間に、企業にもたらす利益の総額を指します。 「顧客生涯価値」とも呼ばれます。

なぜLTVが重要なのか

  • マーケティング投資の判断基準:新規顧客獲得にいくらまでコストをかけられるかの指標になります
  • 収益性の高い顧客の特定:どの顧客セグメントに注力すべきかが分かります
  • ビジネスの持続可能性:長期的な収益予測が可能になります

LTVの基本的な計算式

最もシンプルな計算方法:

LTV = 平均購入単価 × 購入頻度 × 継続期間

計算例

  • 平均購入単価:5,000円
  • 平均年間購入回数:4回
  • 平均継続年数:3年 の場合
LTV = 5,000円 × 4回 × 3年 = 60,000円

他の計算方法

利益率を考慮した式:

LTV = (平均購入単価 × 購入頻度 × 継続期間) × 利益率

サブスクリプションビジネスでよく使われる式:

LTV = 月額収益 × 粗利率 ÷ 月次解約率

LTVを向上させる方法

  • 購入単価を上げる:アップセル、クロスセル
  • 購入頻度を増やす:リピート施策、メルマガ
  • 継続期間を延ばす:顧客満足度向上、ロイヤルティプログラム
  • 解約率を下げる:カスタマーサポートの充実

CAC(顧客獲得コスト)

CACとは「Customer Acquisition Cost」の頭文字を取ったマーケティング用語であり、 新規顧客を1人獲得するために必要なコストの平均値を指します。
マーケティングやビジネスの効率性を測る重要な指標です。
「顧客獲得コスト」とも呼ばれます。

CACの基本的な計算式

CAC = マーケティング・営業コストの合計 ÷ 獲得した新規顧客数

計算例

  • 月間マーケティング費用:100万円
  • 月間営業費用:50万円
  • 獲得した新規顧客数:50人
CAC = (100万円 + 50万円) ÷ 50人 = 30,000円

→ 1人の新規顧客を獲得するのに30,000円かかっている

CACに含めるコスト

含めるべき項目

  • 広告費:リスティング、SNS広告、ディスプレイ広告など
  • 人件費:マーケティング・営業チームの給与
  • ツール費用:MA、CRM、分析ツールなど
  • 制作費:クリエイティブ、LP制作費
  • イベント費:展示会、セミナー開催費

期間の設定

  • 通常は月次または年次で計算
  • 計算期間を統一することが重要

ユニットエコノミクスの計算式

ユニットエコノミクスの計算式は以下のように求めます。

ユニットエコノミクス = LTV ÷ CAC

計算例

ケース1:健全なビジネス

  • LTV:60,000円
  • CAC:20,000円
ユニットエコノミクス = 60,000円 ÷ 20,000円 = 3.0

→ 獲得コストの3倍の価値を顧客から得られる

ケース2:危険なビジネス

  • LTV:15,000円
  • CAC:20,000円
ユニットエコノミクス = 15,000円 ÷ 20,000円 = 0.75

→ 顧客を獲得するほど赤字になる

健全性の判断基準

比率 評価 状態
3以上 優良 健全で拡大可能
2〜3 良好 改善の余地あり
1〜2 要注意 収益性が低い
1未満 危険 ビジネスモデルの再検討が必要

一般的にSaaSなどのサブスクリプションモデルで健全なユニットエコノミクスは「3以上」が目安と言われているそうです。 もしこの数値が1を下回れば、かけた顧客獲得コストよりも収益が下回るので赤字になります。
したがって、LTVまたはCACの改善が必要です。

ユニットエコノミクスが「10」や「20」のように高い場合、一見すると黒字で費用対効果も優れています。
しかし、サブスクリプションビジネスの成長には顧客数の拡大が不可欠です。
もっと積極的に顧客獲得に投資していれば、より多くの顧客を獲得でき結果として売上も伸びていた可能性があります。
つまり、ユニットエコノミクスが高すぎるということは、投資余力があるのに成長機会を逃している状態とも言えます。

まとめ

仕事では基本的に開発をメインとして携わってますが、マーケティングに関する知識を学ぶことで自分が開発しているサービスがどのように売り出されてるのかを知ることができ、開発からは見えない面白さがたくさん見えてきました。

今回ユニットエコノミクスを学んで、自分が開発している機能が 「LTV向上」や「CAC削減」にどう貢献しているのか考えるように なりました。
例えば、ユーザー体験の改善は解約率を下げLTVを 高めることに繋がります。開発とビジネス指標が繋がった瞬間でした。

エンジニアとして開発だけでなくいろんな側面からソフトウェアを見る必要があると思いますが、今回はマーケティングの観点で考えてみました。
また何か面白い内容があれば自分の備忘録としてメモがてら記事にしたいと思います。

何かおかしな点などあればコメントなどいただけると嬉しいです!
ここまで読んでいただきありがとうございました!

参考