gRPC Authenticationの翻訳

grpc.io のdeepl翻訳

私がわかっていなかった点としてgRPCのTLSを使用した認証により、クライアントをどうやって認証するのだ?という点。 ただこれは私の認識違いで、gRPCのTLSを使用した認証は、クライアント側でサーバーの認証を行うもの。 言われてみればその通り。 クライアントが正しいかどうかを検証するしか考えていなかった。

Overview

gRPCは、さまざまな認証メカニズムと連携するように設計されており、gRPCを使って他のシステムと安全に通信することができます。gRPCでは、Googleトークンベースの認証機能を備えたSSL/TLSや、Googleトークンベースの認証機能を備えていないSSL/TLSを使用することもできますし、gRPCが提供するコードを拡張して独自の認証システムを組み込むこともできます。

また、gRPCはシンプルな認証APIを提供しており、チャンネルの作成やコールの際に、必要な認証情報をすべてCredentialsとして提供することができます。

サポートされている認証メカニズム

gRPCには、以下の認証メカニズムが組み込まれています。

  • SSL/TLS:gRPCにはSSL/TLSが統合されており、サーバーを認証し、クライアントとサーバーの間で交換されるすべてのデータを暗号化するために、SSL/TLSの使用が促進されます。オプションで、クライアントが相互認証のための証明書を提供する仕組みも用意されています。
  • ALTS:アプリケーションがGoogle Cloud Platform(GCP)上で動作している場合、gRPCはトランスポートセキュリティメカニズムとしてALTSをサポートしています。詳細については、以下の言語別ページのいずれかを参照してください。ALTS in C++, ALTS in Go, ALTS in Java, ALTS in Python.
  • Googleとのトークンベースの認証:gRPCは、メタデータベースの認証情報をリクエストやレスポンスに添付するための汎用的なメカニズム(以下で説明)を提供します。gRPCを介してGoogle APIにアクセスする際にアクセストークン(通常はOAuth2トークン)を取得するための追加サポートが、特定の認証フローに対して提供されています:これがどのように機能するかは、以下のコード例で確認できます。GoogleSSL/TLS なしでの接続を許可しませんし、ほとんどの gRPC 言語の実装では、暗号化されていないチャンネルで認証情報を送信することはできません。

注意 Google の認証情報は、Google のサービスへの接続にのみ使用してください。Google が発行した OAuth2 トークンを Google 以外のサービスに送信すると、このトークンが盗まれ、クライアントが Google サービスになりすますために使用される可能性があります。

Authentication API

gRPCは、Credentialsオブジェクトという統一されたコンセプトに基づいたシンプルな認証APIを提供しています。このAPIは、gRPCチャネル全体または個々のコールを作成する際に使用できます。

クレデンシャルの種類

クレデンシャルには 2 つのタイプがあります。

  • チャンネル クレデンシャル: SSL クレデンシャルなど、チャンネルに添付される。
  • コールクレデンシャル: コール(C++ではClientContext)に添付されるもの。

また、これらをCompositeChannelCredentialsで組み合わせることもできます。これにより、たとえば、チャネルのSSL詳細と、チャネルで行われる各コールのコール資格情報を指定することができます。CompositeChannelCredentials は、ChannelCredentials と CallCredentials を関連付けて、新しい ChannelCredentials を作成します。その結果、チャンネルで行われる各通話ごとに、合成されたCallCredentialsに関連する認証データが送信されます。

たとえば、SslCredentials と AccessTokenCredentials から ChannelCredentials を作成することができます。この結果をChannelに適用すると、そのChannel上の各コールに対して適切なアクセストークンが送信されます。

個々の CallCredentials は、CompositeCallCredentials を使用して構成することもできます。結果のCallCredentialsを通話で使用すると、2つのCallCredentialsに関連する認証データの送信が開始されます。

Using client-side SSL/TLS

次に、サポートされている認証メカニズムの1つでクレデンシャルがどのように動作するかを見てみましょう。これは、クライアントがサーバを認証し、すべてのデータを暗号化するだけという、最もシンプルな認証シナリオです。この例はC++で書かれていますが、APIはすべての言語で同様です。他の言語でSSL/TLSを有効にする方法は、以下の「例」セクションでご覧いただけます。

// Create a default SSL ChannelCredentials object.
auto channel_creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
// Create a channel using the credentials created in the previous step.
auto channel = grpc::CreateChannel(server_name, channel_creds);
// Create a stub on the channel.
std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
// Make actual RPC calls on the stub.
grpc::Status s = stub->sayHello(&context, *request, response);

ルートCAの変更やクライアント証明書の使用などの高度なユースケースでは、ファクトリーメソッドに渡されるSslCredentialsOptionsパラメータで対応するオプションを設定できます。

Using Google token-based authentication

gRPC アプリケーションは、シンプルな API を使用して、さまざまな展開シナリオで Google との認証に使用できるクレデンシャルを作成できます。ここではC++を使った例を紹介していますが、他の言語での例は「例」のセクションでご覧いただけます。

auto creds = grpc::GoogleDefaultCredentials();
// Create a channel, stub and make RPC calls (same as in the previous example)
auto channel = grpc::CreateChannel(server_name, creds);
std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
grpc::Status s = stub->sayHello(&context, *request, response);

このチャンネル資格情報オブジェクトは、サービスアカウントを使用するアプリケーションだけでなく、Google Compute Engine(GCE)で動作するアプリケーションでも機能します。前者の場合、サービスアカウントのプライベートキーは、環境変数GOOGLE_APPLICATION_CREDENTIALSで指定されたファイルから読み込まれます。この鍵は、対応するチャネルの各発信RPCに添付されるベアラートークンの生成に使用されます。

GCEで実行されるアプリケーションでは、VMのセットアップ時に、デフォルトのサービスアカウントとそれに対応するOAuth2スコープを構成できます。ランタイムには、このクレデンシャルが認証システムとの通信を処理してOAuth2アクセストークンを取得し、対応するチャネルの各発信RPCに添付します。

Extending gRPC to support other authentication mechanisms

クレデンシャル・プラグインAPIにより、開発者は独自のタイプのクレデンシャルをプラグインすることができます。これは以下のように構成されています。

MetadataCredentialsPlugin抽象クラスには、開発者が作成したサブクラスで実装する必要のある、純粋仮想のGetMetadataメソッドが含まれています。
MetadataCredentialsFromPlugin関数: MetadataCredentialsPluginからCallCredentialsを生成します。

以下は、カスタムヘッダに認証チケットを設定する、シンプルなクレデンシャルプラグインの例です。

class MyCustomAuthenticator : public grpc::MetadataCredentialsPlugin {
 public:
  MyCustomAuthenticator(const grpc::string& ticket) : ticket_(ticket) {}

  grpc::Status GetMetadata(
      grpc::string_ref service_url, grpc::string_ref method_name,
      const grpc::AuthContext& channel_auth_context,
      std::multimap<grpc::string, grpc::string>* metadata) override {
    metadata->insert(std::make_pair("x-custom-auth-ticket", ticket_));
    return grpc::Status::OK;
  }

 private:
  grpc::string ticket_;
};

auto call_creds = grpc::MetadataCredentialsFromPlugin(
    std::unique_ptr<grpc::MetadataCredentialsPlugin>(
        new MyCustomAuthenticator("super-secret-ticket")));

gRPCの内部では、SSL/TLSを他の暗号化メカニズムに切り替えることもできます。

Examples

これらの認証メカニズムは、gRPCがサポートするすべての言語で利用可能です。以下のセクションでは、上記の認証・認可機能が各言語でどのように表示されるかを示します。

Go

Base case - no encryption or authentication

Client:

conn, _ := grpc.Dial("localhost:50051", grpc.WithInsecure())
// error handling omitted
client := pb.NewGreeterClient(conn)
// ...

Server:

s := grpc.NewServer()
lis, _ := net.Listen("tcp", "localhost:50051")
// error handling omitted
s.Serve(lis)

With server authentication SSL/TLS

Client:

creds, _ := credentials.NewClientTLSFromFile(certFile, "")
conn, _ := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(creds))
// error handling omitted
client := pb.NewGreeterClient(conn)
// ...

Server:

creds, _ := credentials.NewServerTLSFromFile(certFile, keyFile)
s := grpc.NewServer(grpc.Creds(creds))
lis, _ := net.Listen("tcp", "localhost:50051")
// error handling omitted
s.Serve(lis)

pythonのdatetimeのtimezone

pythonのdatetimeモジュールはタイムゾーンがない文字列から生成した場合、ローカルタイムとして扱われる

from datetime import datetime, timezone

print(datetime.now())

dt_rfc3339 = datetime.fromisoformat("2021-03-19T11:30:00+00:00")
print("dt_rfc3339: ", dt_rfc3339, dt_rfc3339.tzinfo)


dt = datetime.fromisoformat("2021-03-19T11:30:00")
print("dt_no_tz:   ", dt, dt.tzinfo)

dt_replace_utc = dt.replace(tzinfo=timezone.utc)

print("replace:    ", dt_replace_utc, dt_replace_utc.tzinfo)

dt_astimezone = dt.astimezone(tz=timezone.utc)
print("astimezone: ", dt_astimezone, dt_astimezone.tzinfo)

実行結果

dt_rfc3339:  2021-03-19 11:30:00+00:00 UTC
dt_no_tz:    2021-03-19 11:30:00 None
replace:     2021-03-19 11:30:00+00:00 UTC
astimezone:  2021-03-19 02:30:00+00:00 UTC # astimezoneを使用するとtimezone(JSTで9時間)分ずれてしまう

RDBにおいてDATETIME型として保存されているものでタイムゾーンが含まれないが、

内部でUTCとして扱っている場合、replace(tzinfo=datetime.timezone.utc)を使用してUTCに変換すると良い。

code

github.com

    def astimezone(self, tz=None):
        if tz is None:
            tz = self._local_timezone()
        elif not isinstance(tz, tzinfo):
            raise TypeError("tz argument must be an instance of tzinfo")

        mytz = self.tzinfo
        if mytz is None:
            mytz = self._local_timezone()
            myoffset = mytz.utcoffset(self)
        else:
            myoffset = mytz.utcoffset(self)
            if myoffset is None:
                mytz = self.replace(tzinfo=None)._local_timezone()
                myoffset = mytz.utcoffset(self)

        if tz is mytz:
            return self

        # Convert self to UTC, and attach the new time zone object.
        utc = (self - myoffset).replace(tzinfo=tz)

        # Convert from UTC to tz's local time.
        return tz.fromutc(utc)
   def replace(self, year=None, month=None, day=None, hour=None,
                minute=None, second=None, microsecond=None, tzinfo=True,
                *, fold=None):
        """Return a new datetime with new values for the specified fields."""
        if year is None:
            year = self.year
        if month is None:
            month = self.month
        if day is None:
            day = self.day
        if hour is None:
            hour = self.hour
        if minute is None:
            minute = self.minute
        if second is None:
            second = self.second
        if microsecond is None:
            microsecond = self.microsecond
        if tzinfo is True:
            tzinfo = self.tzinfo
        if fold is None:
            fold = self.fold
        return type(self)(year, month, day, hour, minute, second,
                          microsecond, tzinfo, fold=fold)

環境

python-3.8.2

mac vscode F11を押すとデスクトップが表示されてしまう

Mac catalinaではF11がmission controlにより「デスクトップを表示」に割り当てられている

そのためvscodeでステップイン実行を行おうとすると、デスクトップが表示されてしまう

対策

「設定」「キーボード」「ショートカット」「Mission Control」「デスクトップを表示」のチェックボックスを外す

blog.stedplay.com

Setting up Netatalk 3.1

Chapter 3. Setting up Netatalk翻訳(deepl) netatalk.sourceforge.net

AFPファイルサーバーのセットアップ

AFP(Apple Filing Protocol)は、Apple Macintoshがファイルサービスに使用するプロトコルです。このプロトコルは長年にわたって進化してきました。このプロトコルの最新の変更点は「AFP 3.4」と呼ばれるもので、OS X Lion(10.7)のマイナーリリースで追加された。

afpdデーモンは、Appleクライアントにファイルサービスを提供します。設定ファイルはafp.confのみです。これは ini スタイルの設定構文を使用します。

Netatalk 3.1 で Spotlight のサポートが追加されました。Spotlight をサポートした Netatalkコンパイルする方法については、このセクションを参照してください。

Mac OS X 10.5 (Leopard) では、AFP 上の Time Machine バックアップのサポートが追加されました。2つの新しい機能により、バックアップはサーバのキャッシュだけでなく、回転しているディスクにも書き込まれます。ホストオペレーティングシステムによって、このキャッシュフラッシュの扱いが異なります。ボリュームをTime Machineターゲットにするには、ボリュームオプション "time machine = yes "を使用してください。

Netatalk 2.1 以降、UNIX シンボリックリンクがサーバー上で使用できるようになりました。つまり、サーバー側で解決されるのではなく、クライアント側で解決することになり、クライアントのファイルシステムビュー内のどこかを指すリンクになります。

afp.conf

afp.confはAFPファイルサーバーとそれが提供するAFPボリュームの動作と設定を決定するためにafpdが使用する設定ファイルです。

afp.confはいくつかのセクションに分かれています。

  • [Global]
    • グローバルセクションでは、一般的なサーバオプションを定義します。
  • [Homes]
    • ホームセクションでは、ユーザーのホームボリュームを定義します。

Global または Homes と呼ばれないセクションは、AFP ボリュームとして解釈されます。

Homesセクションを定義してユーザーホームを共有する場合は、すべてのユーザーホームの親ディレクトリへのパスを含む単純な文字列または正規表現を指定することができます。

例:

[Homes]
basedir regex = /home

これでAFPサーバーにログインしているユーザーは、パスが/home/NAMEであるユーザーボリュームを利用できるようになります。 より複雑な設定としては、大量のユーザーホームを持つサーバーで、2つの異なるファイルシステムに分割されている場合などが考えられます。

  • /RAID1/home
  • /RAID2/morehomes

以下の設定が必要です。

[Homes]
basedir regex = /RAID./.*homes

basedir正規表現シンボリックリンクが含まれている場合は、正規化された絶対パスを設定します。/homeが/usr/homeにリンクしている場合。

[Homes]
basedir regex = /usr/home

利用可能なオプションの詳細な説明は afp.conf(5) の man ページを参照してください。

CNID backends

SMBやNFSのような他のプロトコルとは異なり、AFPプロトコルはほとんどの場合、ファイルやディレクトリをパスではなくIDで参照します(IDはCNIDとも呼ばれ、カタログノードIDを意味します)。典型的なAFPリクエストでは、ディレクトリIDとファイル名を使用します。例えば、Macの "Aliases "は基本的にIDで動作します(最近のAFPクライアントでは絶対パスにフォールバックされます)。ただし、これはFinderのみに適用され、アプリケーションには適用されません)。)

AFPボリューム内のすべてのファイルは一意のファイルIDを持たなければならず、IDは仕様によれば、決して再利用されないものでなければならず、IDは32ビットの数字である(ディレクトリIDは同じIDプールを使用しています)。そのため、40億個のファイル/フォルダがAFPボリュームに書き込まれると、IDプールは枯渇し、新しいファイルを書き込むことができなくなります。泣き言はやめてください。)

Netatalk はホストファイルシステム内のファイルやフォルダに ID をマッピングする必要があります。これを実現するために、いくつかの異なる CNID バックエンドが利用可能で、afp.conf(5) 設定ファイルの cnid スキームオプションで選択することができます。CNID バックエンドは基本的に ID <-> 名前のマッピングを格納するデータベースです。

CNID データベースはデフォルトで /var/netatalk/CNID にあります。

dbd と呼ばれるコマンドラインユーティリティがあり、CNID データベースの検証、修復、再構築に使用できます。

Note

netatalkで作業する際には、CNIDに関連して覚えておくべきことがいくつかあります。

  • vol dbnest = yes "が設定されていない限り、ボリュームをネストしないでください。
  • CNIDバックエンドはデータベースなので、afpdはファイルサーバとデータベースのミックスになります。
  • ファイルシステム上の空き容量がなくなると、データベースが壊れてしまいます。これを回避するには、vol dbpathオプションを使用してデータベースファイルを別の場所に置くか、クオータを使用している場合は、CNIDデータベースフォルダがクオータなしのuser/groupによって所有されていることを確認してください。
  • NFS経由でマウントされたボリュームのCNIDデータベースには注意してください。いずれにせよ、これはかなり大胆な決定ですが、データベースをそこに置くことは、データベースの破損などのトラブルを招くことになります。NFS マウントされたボリュームを使用しなければならない場合は、vol dbpath ディレクティブを使用してローカルディスクにデータベースを置くようにしてください。

cdb

"並行(concurrent)データベース"バックエンドは、Berkeley DB をベースにしています。このバックエンドでは、複数の afpd デーモンが CNID データベースに直接アクセスします。1つのボリュームに対して複数のafpdプロセスがアクティブな場合、アクセスを同期させるためにBerkeley DBロックが使用されます。欠点は、単一の afpd プロセスがクラッシュするとデータベースが破損する可能性があることです。

dbd

CNID データベースへのアクセスは cnid_dbd デーモンプロセスに制限されています。データベースが破損する確率は実質的にゼロです。 これは Netatalk 2.1 以降のデフォルトのバックエンドです。

tdb

tdbはもう一つの永続的なCNIDデータベースで、SambaのTrivial Databaseである。ユーザーボリュームのためにcdbの代わりに使うことができます。 重要なこと 共有されておらず、複数のクライアントから一度にアクセスされるボリュームにのみ使用してください。

このバックエンドは、プライマリデータベースを開くことができない場合のフォールバックとして内部的に(インメモリCNIDデータベースとして)使用されます。これはもちろん、再起動時に CNID が消えてしまうことを意味します。

last

最後のバックエンドはインメモリのtdbデータベースです。これは永続的ではありません。netatalk 3.0からは自動的に読み取り専用モードになります。これはCD-ROMなどに便利です。

mysql

CNID backend using a MySQL server.

Charsets/Unicode

なぜユニコードなのか?

内部的には、コンピュータは文字や文章については何も知らず、数字だけを知っています。したがって、各文字には番号が割り当てられています。文字セットは、しばしば文字セットやコードページと呼ばれ、数字と文字の間のマッピングを定義します。

2つ以上のコンピュータシステムがお互いに通信する必要がある場合、同じ文字セットを使用する必要があります。1960年代には、ASCII(情報交換のための米国標準コード)の文字セットが米国規格協会によって定義されました。ASCIIの元の形式は128文字を表し、英語のアルファベットと数字をカバーするのに十分以上の文字数でした。今日まで、ASCIIはコンピュータで使用される標準的な文字スキームとなっています。

後のバージョンでは、より国際的な流暢さを演出するために256文字が定義され、若干難解なグラフィカルな文字も含まれるようになりました。このエンコーディングモードを使用すると、各文字は正確に1バイトになります。明らかに、256文字では、さまざまな言語で使用されているすべての文字を1つの文字セットにマッピングするにはまだ十分ではありませんでした。

その結果、ローカライズされた文字セット、例えばISO-8859文字セットなどが後に定義されるようになりました。ほとんどのオペレーティング・システム・ベンダーは、ニーズを満たすために独自の文字セットを導入しました。127よりも大きな番号が割り当てられた文字は、拡張文字と呼ばれていました。これらの文字セットは、異なる文字に同じ番号を使用したり、その逆を行ったりして、別の文字と衝突します。

これらの文字セットのほとんどすべてが256文字を定義しており、最初の128(0〜127)の文字マッピングはASCIIIと同じである。その結果、異なるコードページを使用するシステム間の通信は、事実上ASCII文字セットに制限されていました。

この問題を解決するために、新しいより大きな文字セットが定義されました。より多くの文字マッピングのためのスペースを確保するために、これらの文字セットは、1つの文字を格納するために少なくとも2バイトを使用します。したがって、それらはマルチバイト文字セットと呼ばれています。

1つの標準化されたマルチバイト文字セット符号化方式は、ユニコードとして知られています。マルチバイト文字セットを使用する大きな利点は、1つだけで済むことです。彼らが通信しているときに2台のコンピュータが同じ文字セットを使用していることを確認する必要はありません。

アップルが使用する文字セット

過去には、アップルのクライアントは、ネットワークを介して通信するために、シングルバイトの文字セットを使用していました。長年にわたり、Apple は多くのコードページを定義してきましたが、欧米のユーザーは MacRoman のコードページを使用している可能性が高いでしょう。 Apple が定義したコードページには以下のようなものがあります。

  • MacArabic, MacFarsi
  • MacCentralEurope
  • MacChineseSimple
  • MacChineseTraditional
  • MacCroation
  • MacCyrillic
  • MacDevanagari
  • MacGreek
  • MacHebrew
  • MacIcelandic
  • MacJapanese
  • MacKorean
  • MacRoman
  • MacRomanian
  • MacThai
  • MacTurkish

Mac OS XやAFP3からは、UTF-8が使用されています。UTF-8はASCIIと互換性のある方法でUnicode文字をエンコードしており、各Unicode文字は1~6のASCII文字にエンコードされています。したがって、UTF-8は実際には文字セットそのものではなく、Unicode文字セットのエンコーディングです。

物事を複雑にするために、Unicode はいくつかの正規化形式を定義しています。samba はほとんどの Unix ツールが好むプリコンポーズ Unicode を使用していますが、Apple はデコンポーズ正規化を使用することにしました。

例えば、ドイツ語の文字 'ä' を考えてみましょう。プリコンポーズ正規化を使うと、Unicode はこの文字を 0xE4 にマップします。デコンポーズ正規化では、'ä'は実際には0x61と0x308の2つの文字にマッピングされます。0x61 は「a」のマッピングで、0x308 は「COMBINING DIAERESIS」のマッピングです。

Netatalkでは、プリコンポーズされたUTF-8をUTF8、デコンポーズされたUTF-8をUTF8-MACと呼んでいます。

afpd and character sets

新しいAFP 3.xクライアントと古いAFP 2.xクライアントを同時にサポートするために、afpdは使用される様々な文字セット間で変換できる必要があります。AFP 3.xクライアントは常にUTF8-MACを使用し、AFP 2.xクライアントはAppleのコードページを使用します。

この記事を書いている時点では、netatalkは以下のAppleのコードページをサポートしています。

afpd は 3 つの異なる文字セットオプションを扱います。

  • unix 文字セット

    • これは、お使いのオペレーティングシステムで内部的に使用されるコードページです。指定されていない場合、デフォルトは UTF8 です。LOCALE が指定され、システムが Unix ロケールをサポートしている場合、 afpd はコードページを検出しようとします。 afpd はこのコードページを使用して設定ファイルを読み込んでいるので、 ボリューム名やログインメッセージなどに拡張文字を使用できます。
  • mac の文字セット

    • すでに述べたように、古いMac OSクライアント(AFP 2.2まで)では、afpdとの通信にコードページを使用しています。しかし、AFP プロトコルでクライアントが使用するコードページをネゴシエートするサポートはありません。特に指定がない場合、afpd は MacRoman コードページが使用されていると仮定します。クライアントがMacCyrillicなどの別のコードページを使用している場合は、明示的に設定する必要があります。
  • vol 文字セット

    • これは afpd がディスク上のファイル名に使用する文字セットを定義します。デフォルトでは、Unix の文字セットと同じです。iconv がインストールされていれば、iconv が提供する任意の文字セットを使うことができます。

      afpd は unix ファイルシステム上でファイルを保存する際に、拡張 macintosh 文字や unix ファイル名では不正な文字を保存する方法を必要とします。以前のバージョンでは CAP エンコーディングと呼ばれるものを使用していました。例えば、Apple ロゴ (MacRoman: 0xF0) は :f0 として保存されていました。いくつかの特殊文字も同様に :xx 記法に変換されます。もし usedots が指定されていない場合は、先頭のドット '.' は :2e としてエンコードされます。

      このバージョンでは、ファイル名のデフォルトエンコーディングに UTF8 を使用していますが、'/' は ':' に変換されます。欧米のユーザにとっては、vol charset = ISO-8859-15という設定も便利です。

      mac の文字セットから選択した vol charset に変換できない文字がある場合、mac で -50 のエラーが表示されます。注意: 可能な限り、デフォルトの UTF8 ボリュームフォーマットを使用してください。

Authentication

AFP authentication basics

アップルは、AFPクライアントとサーバー間の認証を目的とした「ユーザー認証モジュール」(User Authentication Modules:UAMs)という柔軟なモデルを選択した。AFPクライアントが最初にAFPサーバーに接続すると、サーバーが提供するUAMのリストを要求し、クライアントがサポートする最も強力な暗号化機能を持つものを選択する。 いくつかのUAMは、Appleによって開発されたものもあれば、サードパーティの開発者によって開発されたものもあります。

NetatalkによってサポートされるUAM

Netatalkは、以下のものをデフォルトでサポートしています。

  • "No User Authent" UAM (認証なしのゲストアクセス)
  • "Cleartxt Passwrd" UAM (パスワード暗号化なし)
  • "ランドナム交換"/"2ウェイランドナム交換 "UAM(弱パスワード暗号化、別パスワード保存
  • "DHCAST128" UAM(より強力なパスワード暗号化)
  • "DHX2" UAM (DHCAST128後継機)

他にもオプションのUAMも存在します。

  • "PGPuam 1.0" UAM (Mac OS X以前のクライアント用のPGPベースの認証。これを動作させるには、PGPuam クライアントも必要です) この UAM を利用できるようにするには、configure スイッチに "--enable-pgp-uam" を追加する必要があります。
  • "Kerberos IV"/"AFS Kerberos" UAM (Kerberos v4 ベースの認証と AFS ファイルサーバの使用に適しています) コンパイル時に"--enable-krb4-uam "を使用して、このUAMのビルドを有効にしてください。
  • "Client Krb v2" UAM (Kerberos V、OS Xクライアントの "シングルサインオン "シナリオに適しています。) "--enable-krbV-uam "はこのUAMを使用する機能を提供します。

グローバルセクションで "uam list "を定義することで、どのUAMを有効にするかを設定することができます。afpdは、どのUAMを使用しているかをログに記録し、問題が発生した場合は起動時にnetatalk.logまたはsyslogに記録します。

サーバで利用可能な特定のUAMがあるからといって、自動的にクライアントが利用できるわけではない。クライアント側のサポートも必要である。Mac OS < Xの古いMacintoshでは、AppleShareクライアント3.8.x以降、DHCAST128のサポートがあります。

OS Xでは、AFPクライアントをより饒舌にするためのクライアントサイドのテクニックが存在しますので、使用するUAMをネゴシエートしながら何が起こっているかを見ることができます。このヒントと比較してみてください。

どのUAMを有効化するか?

それは主にあなたのニーズとサポートしなければならないMac OSのバージョンの種類に依存します。基本的には、パスワード暗号化の強さから、可能な限りDHCAST128とDHX2を使用するようにしてください。

  • 本当にサーバーのボリュームにゲストアクセスを供給する必要がない限り、それが誤って不正アクセスにつながる可能性があるので、"No User Authent "を無効にすることを確認してください。ゲストアクセスを有効にしなければならない場合は、アクセスコントロールを使用してボリュームごとにこれを強制するように注意してください。

  • ClearTxt Passwrd" UAM は、パスワードが暗号化されていない状態で有線で送信されるため、聞こえが悪いです。サーバー側とクライアント側の両方でこれを避けるようにしてください。注意: Mac OS 8/9 のクライアントに NetBoot サービスを提供したい場合は uams_cleartext.so が必要です。

  • Randnum exchange」/「2-Way Randnum exchange」は暗号化に56ビットDESしか使わないので、これも避けるべきです。もう一つの欠点は、パスワードをサーバ上のクリアテキストに保存しなければならないことと、PAM シナリオや古典的な /etc/shadow に統合されていないことです (クライアントがこれらの UAM を使用する場合は afppasswd(1) ユーティリティを使用してパスワードを個別に管理しなければなりません)。

  • "DHCAST128 "または "DHX2 "は、より強力な暗号化とPAM統合を組み合わせているので、ほとんどの人にとって良い妥協点になるはずです。

  • Kerberos V ("Client Krb v2") UAMを使用すると、Kerberosチケットを使用して実際のシングルサインオンシナリオを実装することが可能です。パスワードはネットワーク経由では送信されません。その代わりに、ユーザパスワードは appleshare サーバのサービスチケットを復号化するために使用されます。サービスチケットには、クライアント用の暗号化キーと暗号化されたデータが含まれています(これは appleshare サーバだけが解読できます)。サービスチケットの暗号化された部分はサーバに送られ、ユーザの認証に使用されます。afpd サービスプリンシパル検出が実装されているため、この認証方法は中間者攻撃に対して脆弱です。

異なる UAM の技術的な意味合いについてのより詳細な概要については、Apple の File Server Security のページをご覧ください。

特定のUAMで異なる認証ソースを使用する

uams_cleartext.so、uams_dhx.so、uams_dhx2.so といった異なる認証「バックエンド」を使用する機能を提供している UAM もあります。uams_cleartext.so は uams_passwd.so や uams_pam.so にシンボリックリンクすることができます。 so または uams_pam.so、 uams_dhx.so は uams_dhx_passwd.so または uams_dhx_pam.so、 uams_dhx2.so は uams_dhx2_passwd.so または uams_dhx2_pam.so のいずれかにシンボリックリンクすることができます。

なので、NetatalkのUAMsフォルダ(デフォルトの/etc/netatalk/uams/あたり)でこのようになっていれば、次のようになります。

uams_clrtxt.so -> uams_pam.so
uams_dhx.so -> uams_dhx_pam.so
uams_dhx2.so -> uams_dhx2_pam.so

とすると、PAM、そうでなければ古典的な Unix パスワードを使用していることになります。PAM を使用する主な利点は、LDAPNIS などを介して集中認証のシナリオで Netatalk を統合できることです。このようなシナリオでユーザのログイン認証情報を保護するには、問題のUAMが提供する暗号化の強さにも依存することを常に念頭に置いてください。したがって、「ClearTxt Passwrd」や「Randnum exchange」のような弱いUAMをネットワークから完全に排除することを考えてください。

Netatalk UAM概要表

よく使われているUAMの概要を少しご紹介します。

表 3.1. Netatalk UAMの概要

UAM No User Authent Cleartxt Passwrd (2-Way) Randnum exchange DHCAST128 DHX2 Client Krb v2
password length guest access max. 8 characters max. 8 characters max. 64 characters max. 256 characters Kerberos tickets
Client support built-in into all Mac OS versions built-in in all Mac OS versions except 10.0. Has to be activated explicitly in recent Mac OS X versions built-in into almost all Mac OS versions built-in since AppleShare client 3.8.4, available as a plug-in for 3.8.3, integrated in Mac OS X' AFP client built-in since Mac OS X 10.2 built-in since Mac OS X 10.2
Encryption Enables guest access without authentication between client and server. Password will be sent in cleartext over the wire. Just as bad as it sounds, therefore avoid at all if possible (note: providing NetBoot services requires the ClearTxt UAM) 8-byte random numbers are sent over the wire, comparable with DES, 56 bits. Vulnerable to offline dictionary attack. Requires passwords in clear on the server. パスワードは128ビットSSLで暗号化され、ユーザーはサーバーに対して認証されますが、その逆ではありません。そのため、中間者攻撃には弱いです。 パスワードは、CBC モードで CAST 128 の libgcrypt を使って暗号化されます。ユーザはサーバに対して認証されますが、その逆は認証されません。そのため、中間者攻撃には弱いです。 パスワードはネットワーク経由では送信されません。サービス主検知方式のため、この認証方式は中間者攻撃に弱い。
Server support uams_guest.so uams_cleartxt.so uams_randnum.so uams_dhx.so uams_dhx2.so uams_gss.so
Password storage method None Either /etc/passwd (/etc/shadow) or PAM Passwords stored in clear text in a separate text file Either /etc/passwd (/etc/shadow) or PAM Either /etc/passwd (/etc/shadow) or PAM At the Kerberos Key Distribution Center*

Kerberosの概要を見てみましょう。

SSH トンネリング

トンネリングやVPNのようなものは、一般的にAFP認証やUAMとは何の関係もありません。しかし、Appleが「Allow Secure Connections Using SSH」というオプションを導入したことで、両者を混同しがちな人が多いので、ここではそれについても触れておきます。

AFPセッションを手動でトンネリングする

これは、「AFP over TCP」を話すAFPサーバーが最初にネットワークに登場したときから機能しています。リモートサーバーのAFPポートを548とは別のローカルポートにトンネルし、その後、ローカルでこのポートに接続するだけです。OS Xでは、これは次のようにして行うことができます。

ssh -l $USER $SERVER -L 10548:127.0.0.1:548 sleep 3000

トンネルを確立した後、"サーバへの接続 "ダイアログで "afp://127.0.0.1:10548 "を使用します。ローカルAFPクライアントはMacのローカルポート10548に接続し、リモートサーバーのAFPポート(デフォルトの548を使用しています)にSSHで転送されます。

この種のトンネルは、「本物の」VPNを使用する能力がなくても、インターネットを介して弱い認証メカニズムを提供するAFPサーバにアクセスしたい場合には、理想的なソリューションとなります。ssh の "-C" スイッチを使ってデータを圧縮することができることと、トンネルのエンドポイントが AFP クライアントとサーバの両方と異なる場合があることに注意してください (詳細については SSH のドキュメントと比較してください)。

トンネル化されたAFP接続を自動的に確立する

Mac OS X 10.2から10.4まで、Appleは「サーバへの接続」ダイアログに「SSHを使ったセキュアな接続を許可する」チェックボックスを追加しました。その背景にある考え方。サーバがSSHで連絡が取れることを知らせると、Mac OS XのAFPクライアントはトンネルを確立しようとし、AFPトラフィックをすべて自動で通過させる。

しかし、この機能が初めて動作するようになったのは Mac OS X 10.3 のリリースまででした...部分的には。SSHトンネルが確立できない場合、AFPクライアントは無言で暗号化されていないAFP接続を試みるようになりました。

Netatalkのafpdは、グローバルセクションで "advertise ssh "と "fqdn "の両方のオプションが設定されている場合、SSHトンネルされたAFPリクエストを処理できることを報告します(設定を変更したときにafpdを再起動した後、asip-status.pl(1)で二重に確認してください)。しかし、このオプションを全く使いたくない理由がいくつかあります。

  • (SSH のように) TCP 上に TCP をトンネルするのは最良のアイデアではありません。IP 層に基づいた VPN のようなより良いソリューションが存在します。

  • このSSHはAFP認証メカニズムに直接統合された通常のUAMではなく、その代わりにクライアントがトンネルを確立しようとするかどうかをシグナリングする単一のフラグを使っているので、何かがうまくいかないときに何が起こっているのかを見るのが難しくなります。

  • すべての接続試行がローカルホストから行われているように見えるので、macusers のような Netatalk ツールでどのマシンがログオンしているかを制御することはできません。

  • 一方で、すべてのAFPセッションがSSHで暗号化されているかどうかを確認したい場合は、afpdへのアクセスをローカルホストのみに制限しなければなりません(TCPラッパー)。

  • ... 10.2 - 10.3.3 を使用している場合は、期待していたのとは逆の結果になります: 暗号化されていない可能性のある AFP 通信 (ログオン認証情報を含む) がネットワーク上で行われ、トンネルの確立に失敗したという通知もありません。Appleはこの問題をMac OS X 10.3.4までは修正していませんでした。

  • SSH経由ですべてのAFPセッションを暗号化すると、Netatalkサーバの負荷が大幅に高くなる可能性があります。

ACL Support

AFPのACLサポートは、Solarisおよび派生プラットフォーム上のZFS ACLLinux上のPOSIX 1e ACLに実装されています。

Configuration

基本的な動作モードでは、何も設定する必要はありません。Netatalkはその場でACLを読み取り、有効なパーミッションを計算し、それをUARightsパーミッションビットと呼ばれるビットを介してAFPクライアントに送信します。Macの場合、Finderはこれらのビットを使用してFinderウィンドウのパーミッションを調整します。例:UNIXモードが読み取り専用で、ACLによりユーザーに書き込みアクセス権が与えられているフォルダでは、有効な読み取り/書き込み権限が表示されます。パーミッションマッピングがない場合、Finder は読み取り専用のアイコンを表示し、ユーザーはそのフォルダへの書き込みができなくなります。

デフォルトでは、認証されたユーザの有効なパーミッションは、UNIX モードではなく、前述の UARightspermission 構造にのみマッピングされます。この動作は設定オプションの map acls で調整できます。

しかし、Finder の "Get Info" ウィンドウでもターミナルでも ACL を見ることはできませんが、これは OS XACL がどのように設計されているかに起因しています。クライアントで ACL を表示させたい場合は、クライアントとサーバの両方を認証ドメイン (LDAP, OpenDirectory などのディレクトリサービス) の一部にするように設定しなければならないので、物事はより複雑になります。理由は、OS X では ACL は uid や gid だけでなく UUID にバインドされているからです。そのため、afpd は、UNIX の uid と gidOS X の UUID にマッピングされたサーバ側 ACL を返すことができるように、すべてのファイルシステムの uid と gid を UUID にマッピングできなければなりません。

Netatalk は、LDAP クエリを使用してディレクトリサーバに問い合わせを行うことができます。ディレクトリサーバが既にユーザやグループのUUID属性を提供している場合(Active Directory、Open Directory)、または未使用の属性をディレクトリサーバに再利用(または新規追加)する場合(OpenLDAPなど)があります。

詳細は以下の通りです。

  1. Solaris/ZFS の場合: ZFS ボリューム Netatalk で使用したいボリュームの ZFS ACL know を設定する必要があります。
aclinherit = passthrough
aclmode = passthrough

このノブが何をするのか、どのように適用するのかについては、ホストの ZFS のドキュメント (例: man zfs) を参照してください。

  1. 認証領域

サーバーとクライアントは、IDデータが共通のソースから来るセキュリティアソシエーションの一部でなければなりません。DarwinACLはUUIDに基づいており、AFP 3.2のACL仕様もそうです。したがって、IDデータのソースは、UUIDがASCII文字列として格納されているユーザーとグループごとに属性を提供しなければなりません。言い換えれば

  • UUIDを何らかの属性で保存するOpen DirectoryサーバーまたはLDAPサーバーが必要です。
  • クライアントがこのサーバーを使用するように設定されている必要があります
  • サーバは nsswitch と PAM を介してこのサーバを使用するように設定されている必要があります。
  • afp.confのACLのための特別なLDAPオプションを使用して、NetatalkLDAP検索クエリを介してユーザーとグループのUUIDを取得できるようにNetatalkを設定します。

OS X ACLs

Mac OS Xでは、従来のUNIX権限モデルを強力に拡張したアクセス制御リスト(ACL)を提供しています。ACLとは、特定のユーザやグループに対する一連の権限を明示的に付与または拒否するアクセス制御エントリ(ACE)の順序付きリストのことです。

ユーザーやグループのIDに縛られているUNIX権限とは異なり、ACLはUUIDに縛られています。このため、オブジェクトの ACL にアクセスするには、サーバとクライアントが UUID とユーザ/グループ ID を変換する共通のディレクトリサービスを使用する必要があります。

ACLUNIXパーミッションの相互作用は、かなり単純な方法で行われます。ACLはオプションであるため、UNIXパーミッションはアクセス制御のためのデフォルトのメカニズムとして機能します。オブジェクトのUNIXパーミッションを変更しても、そのオブジェクトのACLはそのままで、ACLを変更しても、そのオブジェクトのUNIXパーミッションは変更されません。アクセスチェックを行っている間、OS X は最初にオブジェクトの ACL を検査し、要求された権利がすべて付与されたか、要求された権利が ACE によって明示的に拒否されたか、またはリストの最後に達するまで ACE を順に評価します。ACLがない場合や、ACLによって付与されたパーミッションが要求を満たすのに十分でない場合、OS Xは次にオブジェクトのUNIXパーミッションを評価します。したがって、ACLは常にUNIXパーミッションよりも優先されます。

ZFS ACLs

ZFSACLOS XACL と密接に一致しています。どちらもほとんど同じ細かいパーミッションと継承設定を提供しています。

POSIX ACL

概要

OS X や NFSv4 ACL と比較して、Posix ACL は、従来の UNIX パーミッションの制限を克服するための、異なる、汎用性の低いアプローチを表しています。実装は、廃止された Posix 1003.1e 標準に基づいています。 標準では、2種類のACLを定義しています。ファイルとディレクトリは、アクセスチェックのために参照されるアクセスACLを持つことができます。ディレクトリは、アクセスチェックとは無関係のデフォルトのACLを持つこともできます。デフォルトの ACL を持つディレクトリ内に新しいオブジェクトが作成されると、デフォルトの ACL がアクセス ACL として新しいオブジェクトに適用されます。サブディレクトリは親からデフォルト ACL を継承します。それ以上の継承制御のメカニズムはありません。 Posix ACLOS X ACL の間のアーキテクチャの違いは、特に以下の点に関係しています。

  • 細かい粒度のパーミッションモデルがない。UNIXパーミッションと同様に、Posix ACLは読み取り、書き込み、実行のパーミッションのみを区別しています。
  • ACL内のエントリは順番がありません。
  • Posix ACLは権限のみを付与することができます。エントリによって明示的に権利を拒否する方法はありません。
  • UNIX の権限は、特別なエントリとして ACL に統合されています。

Posix 1003.1eでは、6種類の異なるタイプのACLエントリを定義しています。最初の3つのタイプは、標準的なUNIX権限を統合するために使用されます。これらは最小限の ACL を形成し、その存在は必須であり、ACL 内では各タイプの 1 つのエントリしか許可されません。

  • ACL_USER_OBJ: 所有者のアクセス権。
  • ACL_GROUP_OBJ: 所有者グループのアクセス権。
  • ACL_OTHER: 全員のアクセス権。

残りのエントリタイプは、従来のアクセス権モデルを拡張したものです。

  • ACL_USER: 特定のユーザーにアクセス権を付与します。
  • ACL_GROUP: 特定のグループにアクセス権を付与します。
  • ACL_MASK: ACL_GROUP_OBJ、ACL_USER、およびACL_GROUPタイプのエントリによって付与されるアクセス権の最大値を制限します。その名が示すように、このエントリはマスクとして動作します。ACLごとに1つのACL_MASKエントリだけが許可されます。ACLACL_USERまたはACL_GROUPエントリを含む場合、ACL_MASKエントリも存在しなければならず、そうでない場合はオプションです。

ACLを認識しないアプリケーションとの互換性を維持するために、Posix 1003.1eでは、オブジェクトのUNIXパーミッションを取得または操作するシステムコールとユーティリティのセマンティクスが変更されています。オブジェクトが最小のACLしか持っていない場合、UNIX権限のグループ権限ビットは、ACL_GROUP_OBJエントリの値に対応します。

しかし、ACLACL_MASKエントリが含まれている場合、それらのシステムコールやユーティリティの動作は異なる。UNIXパーミッションのグループパーミッションのビットは、ACL_MASKエントリの値に対応している。

POSIX ACLからOS X ACLへのマッピング

クライアントがオブジェクトの ACL を読みたい場合、afpd は Posix ACL を同等の OS X ACL にマップします。オブジェクトの ACL を書き込むには、afpd は OS X ACLPosix ACL にマップする必要があります。Posix ACLアーキテクチャ上の制限のため、正確なマッピングを見つけることは通常不可能であり、マッピング処理の結果は元のACLのセマンティックの近似値になります。

  • afpd は、Posix アーキテクチャ内で表現できないため、一連のパーミッションを拒否するエントリを黙って破棄します。
  • Posix ACL内のエントリは順序がないので、順序を維持することは不可能です。
  • 継承制御も同様に厳しい制限を受けます。
    • only_inherit フラグが設定されているエントリは、ディレクトリのデフォルト ACL の一部にしかなりません。
    • file_inherit, directory_inherit, limit_inherit のうち少なくとも一つのフラグが設定されているエントリは、 ディレクトリのアクセスとデフォルトの ACL の一部になりますが、それらが継承に課す制限は無視されます。
  • Posix側に細かい粒度のパーミッションモデルがないため、通常は許可されるパ ーミッションが増えることになります。

OS XクライアントはPosix 1003.1e特有のUNIXパーミッションACL_MASKの関係を認識していないため、afpdは互換性の問題を避けるためにこの機能をクライアントに公開せず、Appleのリファレンス実装であるAFPと同じ方法で*UNIXパーミッションACLを扱います。オブジェクトのUNIXパーミッションが要求されると、afpdは適切なグループ権限を計算し、FPUnixPrivs構造体の "permissions "と "ua_permissions "メンバーを介して、呼び出し元に所有者と全員のアクセス権とともに結果を返します(Apple Filing Protocol Reference、181ページ参照)。オブジェクトのパーミッションを変更すると、afpd は常に ACL_USER_OBJ、ACL_GROUP_OBJ、および ACL_OTHERS を更新します。ACL_MASK エントリも存在する場合、afpd はその値を再計算し、新しいグループ権限が有効になり、ACL_USER または ACL_GROUP タイプの既存のエントリがそのまま維持されるようにします。

Filesystem Change Events

Netatalk には、気の利いたファイルシステム変更イベントメカニズムが含まれており、 afpd プロセスは、特定のファイルシステムイベントについて興味のあるリスナーに UDP ネットワークデータグラムで通知します。

UDP パケットのフォーマットと、リスナーでの使用方法を示す C アプリケーションの例については、Netatalk のソースファイル bin/misc/fce.c を参照してください。

現在サポートされている FCE イベントは以下のとおりです。

利用可能なシンプルな設定オプションの詳細は afp.conf を参照してください。

スポットライト

バージョン3.1以降、NetatalkはSpotlight検索をサポートしています。Netatalkメタデータストア、インデクサ、検索エンジンとして Gnome Tracker を使用します。

設定

スポットライトオプションを使用して、スポットライトとインデックスをグローバルに、または数量単位で有効にすることができます。

警告

一旦Spotlightが1つのボリュームで有効になると、Spotlightが無効になっている他のすべてのボリュームは検索できなくなります。

スポットライト機能を有効にするには、dbus-daemonバイナリをインストールする必要があります。dbus-daemonへのパスは--with-dbus-daemonオプションの "configure "で決定されます。

dbus-daemonバイナリが他のパスにインストールされている場合、パスを指定するためにグローバルオプションのdbus daemonを使用する必要があります。

dbus daemon = /opt/csw/bin/dbus-daemon

制限と備考

Solaris では、FEN ファイルイベント通知システムが使用されています。このSolarisサブシステムがどのような制限やリソース消費をするかは不明です。

したがって、ライブのファイルシステム監視を無効にして、代わりに Tracker に定期的にファイルシステムの変更をスキャンさせることを推奨する。

サーバ上での Tracker コマンドラインツールの使用

Netatalk が起動している必要があり、コマンドは root で実行され、いくつかの環境変数が設定されている必要があります (PREFIX を調整して Netatalk がインストールされているベースディレクトリを指すようにしてください)。

# cat .tracker_profile
PREFIX="/"
export XDG_DATA_HOME="$PREFIX/var/netatalk/"
export XDG_CACHE_HOME="$PREFIX/var/netatalk/"
export DBUS_SESSION_BUS_ADDRESS="unix:path=$PREFIX/var/netatalk/spotlight.ipc"
# . .tracker_profile
#

OpenCSW から Tracker を使用する場合は、PATH も更新する必要があります。

Querying Tracker status

Recent Tracker:

# tracker daemon

Old Tracker:

# tracker-control -S

Stop Tracker

Recent Tracker:

# tracker daemon -t

Old Tracker:

# tracker-control -t

Start Tracker

Recent Tracker:

# tracker daemon -s

Old Tracker:

# tracker-control -s

Reindex directory

Recent Tracker:

# tracker index -f PATH

Old Tracker:

# tracker-control -f PATH

Query Tracker for information about a file or directory

Recent Tracker:

# tracker info PATH

Old Tracker:

# tracker-info PATH

Search Tracker

Recent Tracker:

# tracker search QUERY

Old Tracker:

# tracker-search QUERY

Advanced Tracker コマンドライン設定

Tracker は、gsettings コマンドで変更できる Gnome dconf バックエンドを介して設定を保存する。

Gnome dconf の設定はユーザごとの設定なので、Netatalk が root として Tracker プロセスを実行すると、設定は root ユーザコンテキストに保存され、これらの設定の読み込みや変更は root として実行され、Netatalk が実行されていなければならない (そして再び、上記のように環境が設定されていなければならない)。

# gsettings list-recursively | grep Tracker
org.freedesktop.Tracker.Writeback verbosity 'debug'
...

以下のリストでは、いくつかの重要な Tracker オプションとそのデフォルト設定について説明します。

org.freedesktop.Tracker.Miner.Files index-recursive-directories

このオプションは、Tracker がインデックスを作成するディレクトリを制御します。Netatalk ボリュームの Spotlight オプションの設定を反映して Netatalk によって自動的に設定されるので、このオプションを手動で変更しないでください。

org.freedesktop.Tracker.Miner.Files enable-monitors true

この値は、Tracker が変更のために設定されたすべてのパスを監視するかどうかを制御する。ファイルシステムの変更のバックエンド (Linux では FAM、Solaris では FEN) に依存して、この機能は信頼性が低いので、これを無効にして、代わりに Tracker 自体の定期的なクロールに頼る方が安全かもしれません。オプションの crawling-interval も参照してください。

org.freedesktop.Tracker.Miner.Files crawling-interval -1

ファイルシステムがデータベースの最新の状態にあるかどうかをチェックするための日数間隔、最大値は365、デフォルトは-1です。 -2 = クローリングは完全に無効化され、-1 = クローリングは起動時に発生する可能性があります。

サポートされているメタデータ属性

次の表に、サポートされている Spotlight のメタデータ属性を示します。 表 3.2. サポートされている Spotlight のメタデータ属性

Description Spotlight Key
Name kMDItemDisplayName, kMDItemFSName
Document content (full text search) kMDItemTextContent
File type _kMDItemGroupId, kMDItemContentTypeTree
File modification date kMDItemFSContentChangeDate, kMDItemContentModificationDate, kMDItemAttributeChangeDate
Content Creation date kMDItemContentCreationDate
The author, or authors, of the contents of the file kMDItemAuthors, kMDItemCreator
The name of the country where the item was created kMDItemCountry
Duration kMDItemDurationSeconds
Number of pages kMDItemNumberOfPages
Document title kMDItemTitle
The width, in pixels, of the contents. For example, the image width or the video frame width kMDItemPixelWidth
The height, in pixels, of the contents. For example, the image height or the video frame height kMDItemPixelHeight
The color space model used by the document contents kMDItemColorSpace
The number of bits per sample kMDItemBitsPerSample
Focal length of the lens, in millimeters kMDItemFocalLength
ISO speed kMDItemISOSpeed
Orientation of the document. Possible values are 0 (landscape) and 1 (portrait) kMDItemOrientation
Resolution width, in DPI kMDItemResolutionWidthDPI
Resolution height, in DPI kMDItemResolutionHeightDPI
Exposure time, in seconds kMDItemExposureTimeSeconds
The composer of the music contained in the audio file kMDItemComposer
The musical genre of the song or composition kMDItemMusicalGenre

参考文献

  1. エムディーアイアイ
  2. トラッカー

Netatalk の起動と停止

Netatalk ディストリビューションには、コンパイル前の "configure" スクリプトに与えられたオプションに応じて調整された、いくつかのオペレーテ ィングシステム固有の起動スクリプトテンプレートが付属しています。現在、RedHat (sysv 形式), RedHat (systemd 形式), SUSE (sysv 形式), SUSE (systemd 形式), Debian (sysv 形式), Debian (systemd 形式), Gentoo, NetBSD, Solaris 用のテンプレートが提供されています。configure」にシステムタイプを指定することで、生成されたスタートアップスクリプトをインストールするかどうかを選択できます。自動的にスタートアップスクリプトをインストールするには、利用可能な --with-init-style オプションのいずれかを "configure" に指定してください。

Linux ディストリビューションの新しいリリースは常に登場しており、上記の他のシステムのスタートアップ手順も変更される可能性があるので、やみくもにスタートアップスクリプトをインストールするのではなく、まずそれを見て、自分のシステムで動作するかどうかを確認することをお勧めします。Linux ディストリビューションRPMBSD パッケージなど、固定されたセットアップの一部として Netatalk を使用している場合は、おそらく適切に設定されているでしょう。そのため、以下の内容は Netatalk を自分でコンパイルした場合に適用されます。

以下のデーモンは、どのような起動スクリプト機構を使用しても起動する必要があります。 - netatalk さらに、設定ファイルafp.confが適切な場所にあることを確認してください。

hls.jsのログ解析

v0.14.7にて説明します。適時最新版にするなり、所望のバージョンで確認をお願いします。

hls.jsのデバッグログを出力する

Hlsオブジェクトを生成する際に引数にconfigを渡す。そのconfigdebug変数にtrueを代入すれば良い。

config.debug = true;

そうすると、JS consoleにログが出力されるようになる

JS consoleはchromeであればdeveloper toolsから確認できる

詳細は以下を参照のこと

hls.js/API.md at v0.14.17 · video-dev/hls.js · GitHub

hls.jsのデバッグログを読み解く

logを有効にしても意味がわからないと理解できない。

結論から先に書くとhls.js/API.md at v0.14.17 · video-dev/hls.js · GitHub を読むこと

以下は、調べた際の途中経過。

source codeをgrepするとlogの出力箇所を探すことができるが、なんとなくしかわからない

例えば以下のようなログを調べる場合について説明する

[log] > Parsed video,PTS:[3.985,4.985],DTS:[2.985/3.985],nb:30,dropped:0

まず使用しているリビジョンのsource codeを取得し、Parsedgrepする。 そうすると、何個か引っかかるが、今回はhttps://github.com/video-dev/hls.js/blob/v0.14.17/src/controller/stream-controller.js#L1019

class StreamController extends BaseStreamController {

...

  onFragParsingData (data) {
    const fragCurrent = this.fragCurrent;
    const fragNew = data.frag;
...
      if (data.hasVideo === true) {
        frag.addElementaryStream(ElementaryStreamTypes.VIDEO);
      }

      logger.log(`Parsed ${data.type},PTS:[${data.startPTS.toFixed(3)},${data.endPTS.toFixed(3)}],DTS:[${data.startDTS.toFixed(3)}/${data.endDTS.toFixed(3)}],nb:${data.nb},dropped:${data.dropped || 0}`);

      // Detect gaps in a fragment  and try to fix it by finding a keyframe in the previous fragment (see _findFragments)
      if (data.type === 'video') {
        frag.dropped = data.dropped;

onFragParsingDataといった関数で呼ばれているため、この関数名でgrepをする。しかし見つからない。

???

onFragParsingDataといった関数はStreamController classで定義されている。 このclassのコンストラクタにおいてEvent.FRAG_PARSING_DATAというそれっぽいのが宣言されている。

class StreamController extends BaseStreamController {
  constructor (hls, fragmentTracker) {
    super(hls,
      Event.MEDIA_ATTACHED,
      Event.MEDIA_DETACHING,
      Event.MANIFEST_LOADING,
      Event.MANIFEST_PARSED,
      Event.LEVEL_LOADED,
      Event.LEVELS_UPDATED,
      Event.KEY_LOADED,
      Event.FRAG_LOADED,
      Event.FRAG_LOAD_EMERGENCY_ABORTED,
      Event.FRAG_PARSING_INIT_SEGMENT,
      Event.FRAG_PARSING_DATA, //☆
      Event.FRAG_PARSED,
      Event.ERROR,
      Event.AUDIO_TRACK_SWITCHING,
      Event.AUDIO_TRACK_SWITCHED,
      Event.BUFFER_CREATED,
      Event.BUFFER_APPENDED,
      Event.BUFFER_FLUSHED);

この定義は events.js https://github.com/video-dev/hls.js/blob/v0.14.17/src/events.js#L93にて定義されている。 そしていつ起こるかのがきちんと書いてある

  FRAG_PARSING_DATA: 'hlsFragParsingData',
  // fired when fragment parsing is completed - data: { id : demuxer id, frag: fragment object }

ここまで書いてAPI.mdのruntimeの章にきちんといつ起こるかが書いてあるため参照すると良い hls.js/API.md at v0.14.17 · video-dev/hls.js · GitHub

参考までに調べようとしていたFRAG_PARSING_DATAの説明は以下のようになっている

Hls.Events.FRAG_PARSING_DATA - fired when moof/mdat have been extracted from fragment

    data: { id: demuxer id, frag : fragment object, moof : moof MP4 box, mdat : mdat MP4 box, startPTS : PTS of first sample, endPTS : PTS of last sample, startDTS : DTS of first sample, endDTS : DTS of last sample, type : stream type (audio or video), nb : number of samples }

moof/mdatがfragramentから取り出されたときに起きることがわかる

さらにPTS:[3.985,4.985]は[startPTS,endPTS], nb:はサンプル数ということがわかる

tmux.confの意味

今まで、俺が考えた最強のtmux.confであったり、おすすめtmux.confを使ってきたが、なんとなくしか意味がわかっておらず、メンテナンスするには限界がきた。 そこで理解が曖昧な物に関して備忘録的にまとめる。

ただ以下のmanを読むのが好ましい。 man7.org

bindとbind-keysの違い

bind h select-pane -L

bindはbind-keysのエイリアス

setとbindは?

set -g status-fg white

setはset-optionのエイリアス -gはglobalの意味

つまりsetはオプションの変更、bindはkeyへの割当

bindの後のkey(e.g. -T)は大文字小文字を識別するか?

setwは?

set-window-optionのエイリアス

bind-keyの構文

bind-key [-nr] [-N note] [-T key-table] key command [arguments]
                   (alias: bind)
             Bind key key to command.  Keys are bound in a key table.
             By default (without -T), the key is bound in the prefix key
             table.  This table is used for keys pressed after the
             prefix key (for example, by default ‘c’ is bound to
             new-window in the prefix table, so ‘C-b c’ creates a new
             window).  The root table is used for keys pressed without
             the prefix key: binding ‘c’ to new-window in the root table
             (not recommended) means a plain ‘c’ will create a new
             window.  -n is an alias for -T root.  Keys may also be
             bound in custom key tables and the switch-client -T command
             used to switch to them from a key binding.  The -r flag
             indicates this key may repeat, see the repeat-time option.
             -N attaches a note to the key (shown with list-keys -N).

             To view the default bindings and possible commands, see the
             list-keys command.

keyをコマンドにバインドします。 keyはkey tableにバインドされます。 デフォルトでは (-T を指定しない場合)、キーはprefix key tableにバインドされます。このtableは、prefix keyの後に押されたkeyに使用されます (例えば、デフォルトでは 'c' はprefix tableの new-window にバインドされているので、'C-b c' はnew-windowを生成します)。 root tableは、prefix keyなしで押されたkeyに使用されます。 root talbeの new-window に 'c' をバインドすると (推奨されません)、単純な 'c' で新しいウィンドウが作成されます。 -n は -T root のエイリアスです。 keyはcustom key tableにバインドすることもでき、switch-client -Tコマンドを使ってキーバインドからcustom key tablesに切り替えることができます。 - r フラグは、このキーが繰り返し使用できることを示します。 -N は、キーにメモを付けます (list-keys -N で表示されます)。

既定のバインディングと可能なコマンドを表示するには、 list-keys コマンドを参照してください。

bind -T copy-mode-vi v send -X begin-selection

bind-keyを行う

-T copy-mode-viとあるため、copy-mode-viという名前が付いているtableにバインドする

keyはv

commandはsend -X begin-selection.

つまり、prefixの後にvが押された場合に、send -X begin-selectionを行う。このbind設定はvi-copy-modeと行ったkey tableに保存する。

プロバイダを選ぶ時に覚えておくと良い事

プロバイダの変更を検討したためその備忘録

  • 同じ1Gを謳っているプロバイダでも全然違う
  • 地域によって全然違う

仕組みを押さえておく

以下2つくらいを眺めておくと良い

notoken.hatenadiary.com

diary.sorah.jp

twitterで「プロバイダ名 地域」検索して確かめる

googleによる検索はアフィリエイトとか、広告しか出てこない。