SSHテンプレートのスマートな使用例





SSH証明書は 非常に強力なツールです。当初、認証センターでstep-ca



ユーザー証明書とホスト証明書を使用した認証のための最小限の機能セットのみを実装していました。次にX.509証明書テンプレートを追加しました。昨年8月には、バージョン0.15.2のSSHテンプレートを追加しました 。最後に、この機能を文書化し、それについて話す準備ができました。



SSH証明書のテンプレートは、X.509テンプレートと同じように機能します。つまり、Goで記述されたJSONファイルです text/template



。これらは、発行するSSH証明書を構成するために使用されます step-ca



。これらのテンプレートとは何か、およびそれらをどのように使用できるかを見てみましょう。



デフォルトでは、カスタムSSH証明書テンプレートは次のようになります。



{
	"type": {{ toJson .Type }},
	"keyId": {{ toJson .KeyID }},
	"principals": {{ toJson .Principals }},
	"extensions": {{ toJson .Extensions }},
	"criticalOptions": {{ toJson .CriticalOptions }}
}
      
      





そして、これがこのパターンを使用して発行されたSSH証明書です。



$ step ssh inspect id_ct-cert.pub
id_ct-cert.pub:
        Type: ecdsa-sha2-nistp256-cert-v01@openssh.com user certificate
        Public key: ECDSA-CERT SHA256:iczSh1XiBBE36yfJcDidgp6fqY3qWx1RtEwFfAN9jDs
        Signing CA: ECDSA SHA256:MKwRQ/SDKk/pCJbbCk5bfhZACjSjv7uZXLyc5n4Wx6k
        Key ID: "carl@smallstep.com"
        Serial: 2831574724231262409
        Valid: from 2020-11-17T16:48:11 to 2020-11-18T08:49:11
        Principals:
                carl
                carl@smallstep.com
        Critical Options: (none)
        Extensions:
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc
      
      





これにより、ユーザーcarl



(または carl@smallstep.com



)は、SSHCAを信頼する任意のSSHホストに対して認証できます 証明書には、いくつかの基本的な拡張機能が含まれています。



  • permit-x11-forwarding



    :X11転送(を使用ssh -X



    )を有効にして、ローカルディスプレイでリモートX11プログラムを実行します。

  • permit-agent-forwarding



    :エージェントのリダイレクト(を使用ssh -A



    )により、ローカルSSHエージェントからリモートホストにキーを転送できます(SSHエージェントの詳細については、こちらを参照してください)。

  • permit-port-forwarding



    :ローカルからリモートポート(ssh -L



    )またはリモートからローカル(ssh -R



    へのポート転送(トンネリング)を許可します

  • permit-pty



    :非常に重要な拡張機能。コンソールでインタラクティブセッションを開きたい場合は、ホストがpty(pseudo-tty)を割り当てる必要があります。それ以外の場合、対話性は提供されません。たとえば、GitHubでSSH認証をテストするには、実行できますssh -T git@github.com



    -T



    ptyリクエストを無効にします)。

  • permit-user-rc



    :接続後に個人用RCファイルを実行します(~/.ssh/rc



    リモートホストにあります)。


ユーザー証明書とホスト証明書は拡張機能と重要なパラメーターをサポートしますが、OpenSSHはホスト証明書の組み込み拡張機能や重要なパラメーターを定義していません。したがって、最も興味深いのはすべてユーザー証明書で発生するため、この記事ではそれらのみを検討します。



証明書テンプレートの例



デフォルトのテンプレートにいくつか変更を加えましょう。



エージェントとポートフォワーディングの禁止

ユーザーが要塞ホストを介して内部ホストに接続している場合は 、セキュリティ上の理由からポート転送を無効にすることをお勧めしますユーザーがMySQL本番サーバーからローカルホストにトラフィックをリダイレクトすることは望ましくありません。同様に、エージェントのリダイレクトにはセキュリティリスクが伴い ますSSH証明書からこれら2つの拡張機能を削除するだけのテンプレートを次に示します。



{
	"type": {{ toJson .Type }},
	"keyId": {{ toJson .KeyID }},
	"principals": {{ toJson .Principals }},
	"extensions": {
           "permit-x11-forwarding": "",
           "permit-pty": "",
           "permit-user-rc": ""
  },
	"criticalOptions": {{ toJson .CriticalOptions }}
}
      
      





force-commandディレクティブの埋め込み

ForceCommand



対話型端末の代わりにホスト上で代替コマンドを実行するサーバー側SSHD構成ディレクティブです。ただし、同じ効果でforce-command



、証明書直接埋め込むことができ ます-セクションに Critical Options:



これは、たとえばリモートシステムでタスクを開始するなど、1つのコマンドのみを実行する必要があるサービスアカウントに役立ちます。



アドレスによる接続の制限

証明書の範囲を制限するために、許可されたIPアドレス(CIDRブロック)のリストを証明書に埋め込むことができます。



これはsource-address



、との 両方を使用する証明書テンプレートです force-command







{
	"type": {{ toJson .Type }},
	"keyId": {{ toJson .KeyID }},
	"principals": {{ toJson .Principals }},
	"extensions": {{ toJson .Extensions }},
	"criticalOptions": {
		"force-command": "echo \"Hello World\"",
		"source-address": "10.20.30.0/24,1.1.1.1/32"
	}
}
      
      





これは通常の例ですが、ここではIPリストは厳密に固定されており、変更されません。また、通常、ユーザーごとに異なるアドレスリストを使用する必要があります。やってみよう…



ユーザーごとに異なる値を挿入します

明らかに、ユーザーにアドレス範囲を編集する権利を与えることはできません。したがって、動的な値は信頼できるソースから取得する必要があります。



これを行うには step-ca



、OpenID Connect(OIDC)プロバイダーを介して、このユーザーの証明書に追加するCIRDアドレスブロックを含むトークンにカスタムクレームを追加するようにOAuthプロバイダーを構成できます。



OIDCプロバイダーは、step-caにSSH証明書を発行するのに最適な方法です。SSHDIYシングルサインオンの記事で は、信頼できるOAuthプロバイダーからのIDトークンを使用して短期SSH証明書を発行するようにSSHCAを構成する方法について説明しました。もし step-ca



信頼できるOAuthクライアントとして構成さemail



れ、IDトークンからフィールドを読み取り、 そこからSSH証明書プリンシパルのリストを取得します(たとえば、フィールドのcarl@smallstep.com



証明書carl



フィールドによって生成さ れます carl@smallstep.com



)。



ただし、OIDCでは、トークンからテンプレートを介してIDやその他のフィールドを読み取ることができます ここから本当の魔法が始まります。したがって、IDプロバイダー側​​のユーザーディレクトリに別のフィールドを追加し、 source_address



それをIDトークンに反映します。次に、SSHテンプレートを使用して、トークンの値を証明書に入力できます。テンプレートは次のとおりです。



{
	"type": {{ toJson .Type }},
	"keyId": {{ toJson .KeyID }},
	"principals": {{ toJson .Principals }},
	"extensions": {{ toJson .Extensions }},
{{ if .Token.source_address }}
	"criticalOptions": {
		"source-address": "{{ .Token.source_address }}"
	}
{{ else }}
	"criticalOptions": {{ toJson .CriticalOptions }}
{{ end }}
}
      
      





証明書によるGitHub認証

カスタムクレームの別の例を見てみましょう。 GitHub EnterpriseCloudまたはGitHubEnterprise Serverを使用して、SSH証明書を使用するようにGitHubを構成できます。具体的には、GitHub はSSH認証局を信頼します。ただし、すべてが機能するためには、login@github.com



GitHubでユーザー名を指定する拡張子持つユーザーごとに個別のSSH証明書を作成する必要があり ます。この拡張機能を使用すると、証明書はユーザーをGitHubEnterpriseに対して認証します。そして、それは素晴らしいことです。同じ証明書を使用すると、SSH経由でサーバーに接続し、コードをGitHubにプッシュすることができます。



カスタムGitHub拡張機能をサポートする証明書テンプレートは次のとおりです。



{
	"type": {{ toJson .Type }},
	"keyId": {{ toJson .KeyID }},
	"principals": {{ toJson .Principals }},
	"criticalOptions": {{ toJson .CriticalOptions }},
{{ if .Token.ghu }}
	"extensions": {
	  "login@github.com": {{ toJson .Token.ghu }}
	}
{{ else }}
	"extensions": {{ toJson .Extensions }}
{{ end }}
}
      
      





テンプレートを使用するには、個別の要件ghu



(「GitHubユーザー名」)をOIDC識別トークンに追加する必要があります OAuthプロバイダーを使用してこのカスタムクレームを作成する方法を詳しく見てみましょう。



IDプロバイダーへのアプリケーションの登録

すべてのIDプロバイダーが個々の要件をサポートしているわけではありませんが、サポートしている場合、プロセスは非常に似ています。Oktaでどのように行われるかを次に示します。



  1. OAuthアプリをOktaに追加し、SSHのDIY SSOのstep-ca



    記事で説明されているように、OIDCプロバイダーと信頼します





  2. Oktaユーザーディレクトリに新しいフィールドを追加します(たとえばGitHub Username





  3. たとえば、短い名前でOIDCトークンに個別の要件を追加しますghu





  4. 次に、テストユーザーのフィールドに入力し、要件を確認します。OktaにはIDトークンテストツールがあります。またはstep



    、OAuthフロー全体を検証するために使用できます



    OIDC_ENDPOINT="https://[your organization].okta.com/oauth2/default/.well-known/openid-configuration"
    CLIENT_ID="[your OAuth client ID]"
    CLIENT_SECRET="[your OAuth client secret]"
    step oauth --oidc --provider $OIDC_ENDPOINT \
        --client-id $CLIENT_ID --client-secret $CLIENT_SECRET \
        --listen=":10000" --bare |
    step crypto jwt inspect --insecure
          
          





  5. 最後に、 step-ca



    このパターンを使用します。プロバイダー構成は、テンプレートファイルを参照する必要があります。



    {
      "provisioners": [
        {
          "type": "OIDC",
          "name": "Okta",
          "clientID": "[your OAuth client ID]",
          "clientSecret": "[your OAuth client secret]",
          "configurationEndpoint": "https://[your organization].okta.com/oauth2/default/.well-known/openid-configuration",
          "listenAddress": ":10000",
          "options": {
            "ssh": {
                "templateFile": "templates/certs/ssh/github.tpl"
            }
          }
        },
          ...
      ]
    }
          
          





次は何ですか



すべてのパラメーターと変数について詳しく説明するSSHテンプレートに関するセクションをドキュメントに追加しました



不明な点がございましたら、お 気軽にお問い合わせください



All Articles