はじめに
Verticaではクライアントとの通信をSSL/TLSを使用して暗号化することができます。認証の方式としては、サーバ認証と相互認証の2種類があり、こちらの記事では、相互認証を使用したSSL/TLS通信の設定方法をご紹介します。相互認証を使用すると、クライアント証明書を保持しているクライアントのみが対象のDBユーザに接続できるようになり、クライアント‐サーバ間の接続をよりセキュアに保つことができます。
設定に必要なファイル
相互認証方式のSSL/TLS通信を行うには以下のファイルが必要となります。・サーバ証明書(自己署名証明書でも可)
・ルート証明書
・サーバの秘密鍵
・クライアント証明書
・クライアントの秘密鍵
設定方法
構文
サーバ証明書、秘密鍵、ルート証明書の登録
OSのdbadminユーザから以下のコマンドにて、Verticaへサーバ証明書とサーバの秘密鍵、ルート証明書を登録します。
admintools -t set_ssl_params -d <データベース名> -p <パスワード> -k <サーバの秘密鍵> -c <サーバ証明書> -a <ルート証明書>
VerticaデータベースのSSL/TLS通信の有効化
Verticaデータベースへdbadminユーザにて接続した後、以下のSQLコマンドを実行します。
ALTER DATABASE <データベース名> SET EnableSSL = 1;
Verticaデータベースの相互認証モードの設定
Verticaデータベースへdbadminユーザにて接続した後、以下のSQLコマンドを実行します。
# 認証設定の作成
CREATE AUTHENTICATION <認証名> METHOD ‘tls’ HOST TLS ‘接続元IP CIDR’;
# DBユーザへの認証の付与
GRANT AUTHENTICATION <認証名> TO;
CREATE AUTHENTICATION <認証名> METHOD ‘tls’ HOST TLS ‘接続元IP CIDR’;
# DBユーザへの認証の付与
GRANT AUTHENTICATION <認証名> TO
注意点
クライアント証明書を作成するときは、Common Name(CN)に接続対象のDBユーザ名を必ず含めてください。設定例
以下に自己署名証明書を使用した設定例を記載します。正規の証明書を保持している場合は手順「1. サーバ証明書(自己署名)の作成」と「5. クライアント証明書(自己署名)の作成」はスキップしてください。なお、OSコマンドの詳細についてはマニュアル等でご確認ください。
サーバ証明書の設定
1. サーバ証明書(自己署名)の作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#-- 1-1. サーバの秘密鍵を生成します $ openssl genrsa -out server.key Generating RSA private key, 2048 bit long modulus ............................................................................+++ .....+++ e is 65537 (0x10001) #-- 1-2. 証明書署名要求を生成します。 $ openssl req -new -nodes -key ./server.key -out ./server.csr -config ./openssl.cnf -batch ※事前にopenssl.cnf(opensslの設定ファイル)を用意しておく必要があります。(サンプルは欄外参照) #-- 1-3. 自己署名証明書を作成します。 $ openssl x509 -req -days 365 -in ./server.csr -signkey ./server.key -out ./server.crt Signature ok subject=/C=JP/ST=Not Applicable/L=Not Applicable/O=CompanyName Getting Private key |
## openssl.cnfのサンプル
######################################################################
[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
######################################################################
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = JP
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Not Applicable
localityName = Locality Name (eg, city)
localityName_default = Not Applicable
0.organizationName = Organization Name (eg, company)
0.organizationName_default = CompanyName
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default =
commonName = Common Name (eg, your website’s domain name)
commonName_max = 64
######################################################################
[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
######################################################################
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = JP
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Not Applicable
localityName = Locality Name (eg, city)
localityName_default = Not Applicable
0.organizationName = Organization Name (eg, company)
0.organizationName_default = CompanyName
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default =
commonName = Common Name (eg, your website’s domain name)
commonName_max = 64
2. サーバの秘密鍵とサーバ証明書の検証
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#-- 2-1. 証明書とキーが一致していることを確認します。md5チェックサムが一致することを確認してください。 $ openssl x509 -noout -modulus -in ./server.crt | openssl md5 (stdin)= 7daaf458fa49da3628e34bb6067b7e34 $ openssl rsa -noout -modulus -in ./server.key | openssl md5 (stdin)= 7daaf458fa49da3628e34bb6067b7e34 #-- 2-2. 証明書の有効期限が切れていないことを確認します。 $ openssl x509 -noout -text -in ./server.crt | grep -e "Before" -e "After" Not Before: Aug 29 15:50:19 2021 GMT Not After : Aug 29 15:50:19 2022 GMT #-- 2-3. サーバ証明書が有効であることを確認します。 $ openssl verify -verbose -CAfile root.crt server.crt server.crt: OK ※自己署名証明書を使用する場合は、事前に"cp -p ./server.crt ./root.crt"を実行して証明書を複製します。 #-- 2-4. サーバ証明書がSSLサーバで許可されていることを確認します。 $ openssl x509 -noout -purpose -in ./server.crt | grep "SSL server" SSL server : Yes <== ★Yesであること SSL server CA : Yes (WARNING code=3) Netscape SSL server : Yes Netscape SSL server CA : Yes (WARNING code=3) #-- 2-5. ルート認証局(CA)がSSLサーバCA証明書であることを確認します。 $ openssl x509 -noout -purpose -in ./root.crt | grep "SSL server CA" SSL server CA : Yes (WARNING code=3) <== ★Yesであること Netscape SSL server CA : Yes (WARNING code=3) #-- 2-6. 秘密鍵のパーミッションを変更します。 $ chmod 600 ./server.key #-- 2-7. 秘密鍵にパスワードが必要ないことを確認します。 $ ssh-keygen -y -f ./server.key ssh-rsa AAAAB3<省略>i4m9ngAUmVOaoE+X1iNkD2IcNhYr8O3+Wfl6BDD6sw5OrTlEA6jh ※パスワードの入力を求められる場合は、手順に誤りがある可能性があります。手順に漏れがないか確認してください。 |
3. サーバ証明書と秘密鍵をVerticaに登録
1 2 3 4 5 6 7 8 |
#-- 3-1. サーバ証明書とサーバの秘密鍵の所有者と権限を設定します。 $ chown dbadmin:verticadba ./server.key ./server.crt $ chmod 600 ./server.key ./server.crt #-- 3-2. admintoolsを使用してサーバ証明書、秘密鍵、ルート証明書を登録します。 $ admintools -t set_ssl_params -d verticadb -p verticadb -k ./server.key -c ./server.crt -a ./root.crt SSL configuration parameters set successfully |
4. VerticaのSSL接続を有効化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#-- 4-1. データベースに接続し、SSL接続を有効化します。 $ vsql -d verticadb -w password dbadmin=> ALTER DATABASE verticadb SET EnableSSL = 1; ALTER DATABASE #-- 4-2. 設定変更後の確認を行います。 dbadmin=> \x Expanded display is on. dbadmin=> SELECT node_name, parameter_name, current_value, default_value FROM vs_configuration_parameters dbadmin-> WHERE parameter_name in ('EnableSSL', 'SSLCertificate', 'SSLPrivateKey', 'SSLCA');" -[ RECORD 1 ]--+----------------------------------------------------------------------------- node_name | v_verticadb_node0001 parameter_name | EnableSSL current_value | 1 <==★1であること default_value | 0 -[ RECORD 2 ]--+----------------------------------------------------------------------------- node_name | v_verticadb_node0001 parameter_name | SSLCA current_value | -----BEGIN CERTIFICATE-----MIIDJ<省略>c2kTrntOr/+ss-----END CERTIFICATE----- <== ★登録されていること default_value | -[ RECORD 3 ]--+----------------------------------------------------------------------------- node_name | v_verticadb_node0001 parameter_name | SSLCertificate current_value | -----BEGIN CERTIFICATE-----MIIDJ<省略>c2kTrntOr/+ss-----END CERTIFICATE----- <== ★登録されていること default_value | -[ RECORD 4 ]--+----------------------------------------------------------------------------- node_name | v_verticadb_node0001 parameter_name | SSLPrivateKey current_value | -----BEGIN RSA PRIVATE KEY-----MIIEo<省略>qjwWd-----END RSA PRIVATE KEY----- <== ★登録されていること default_value | ※複数ノードで構成されている場合、ノードごとに出力されます。 dbadmin=> \q #-- 4-3. データベースを再起動します。 $ admintools -t stop_db -d verticadb -p password -F Database verticadb stopped successfully $ admintools -t start_db -d verticadb -p password -i Starting nodes: v_verticadb_node0001 (10.1.1.1) Starting Vertica on all nodes. Please wait, databases with a large catalog may take a while to initialize. Node Status: v_verticadb_node0001: (DOWN) Node Status: v_verticadb_node0001: (DOWN) Node Status: v_verticadb_node0001: (UP) Database verticadb: Startup Succeeded. All Nodes are UP |
相互認証モードの設定
5. クライアント証明書(自己署名)の作成
以下の実行例ではDBユーザ「testuser」に接続するための証明書、秘密鍵の生成を行っています。ファイル名はDBユーザ名にあわせて変更してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#-- 5-1. サーバの秘密鍵を生成します $ openssl genrsa -out testuser.key Generating RSA private key, 2048 bit long modulus ..........................................+++ .................+++ e is 65537 (0x10001) #-- 5-2. 証明書署名要求を生成します。なお、Common NameはDBユーザ名に設定します。 $ openssl req -new -out testuser.csr -key testuser.key <中略> Common Name (eg, your name or your server’s hostname) []:testuser <== ★DBユーザ名を入力 Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: #-- 5-3. ユーザ証明書を作成します。 $ openssl x509 -CA root.crt -CAkey root.key -days 3650 -req -in testuser.csr -out testuser.crt Signature ok subject=/C=JP/L=Default City/O=Default Company Ltd/CN=testuser Getting CA Private Key ※シリアル管理ファイル(root.srl)が不足している場合は、以下のコマンドで作成します。 $ openssl x509 -serial -noout -in root.crt | sed -e 's/.*=//' > root.srl |
6. クライアント証明書の検証
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#-- 6-1. 証明書がSSLクライアント証明書であることを確認します。 $ openssl x509 -noout -purpose -in testuser.crt | grep "SSL client" SSL client : Yes <== ★Yesであること SSL client CA : No #-- 6-2. 証明書のCommon Nameを表示し、DBユーザ名と一致することを確認します。 $ openssl x509 -noout -issuer -subject -dates -in testuser.crt issuer= /C=JP/ST=Not Applicable/L=Not Applicable/O=CompanyName subject= /C=JP/L=Default City/O=Default Company Ltd/CN=testuser <== ★DBユーザ名と一致すること notBefore=Aug 29 16:28:40 2021 GMT notAfter=Aug 27 16:28:40 2031 GMT <== ★ログインは左記の日付範囲内である必要があります #-- 6-3. root.crtがクライアント証明書の署名に使用されていることを確認します。 $ openssl verify -CAfile root.crt testuser.crt testuser.crt: OK |
7. ユーザ証明書と秘密鍵の配置
※以下はvsqlを使用する際の設定方法です。JDBC、ODBCクライアントを使用した接続は参考情報の「Configuring TLS for JDBC and ODBC clients」を参照してください。
1 2 3 4 5 6 7 8 9 |
#-- 7-1. .vsqlディレクトリを作成します。 $ mkdir -p ~/.vsql #-- 7-2. ユーザ証明書と秘密鍵を配置します。 $ cp testuser.crt ~/.vsql/client.crt $ cp testuser.key ~/.vsql/client.key #-- 7-3. ファイルのパーミッションを変更します。 $ chmod 600 ~/.vsql/client.key ~/.vsql/client.crt |
8. 相互認証モードの構成
1 2 3 4 5 6 7 8 |
#-- 8-1. データベースにdbadminユーザで接続し、「SSLCert」という名称で認証設定を作成します。 $ vsql -d verticadb -w password dbadmin=> CREATE AUTHENTICATION SSLCert METHOD 'tls' HOST TLS '0.0.0.0/0'; CREATE AUTHENTICATION #-- 8-2. 対象のDBユーザに認証設定を付与します。 dbadmin=> GRANT AUTHENTICATION SSLCert to testuser; GRANT AUTHENTICATION |
9. 相互認証接続の確認
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#-- 9-1. データベースに接続し、相互認証が有効であることを確認します。 $ vsql -h 10.1.1.1 -U testuser SSL connection (cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, protocol: TLSv1.2) <== ★SSL/TLS通信を行う旨のメッセージが表示されること ※適切なクライアント証明書を持たないクライアントから対象DBユーザに接続した場合、以下のエラーメッセージが表示されます。 vsql: FATAL 2248: Authentication failed for username "testuser" #-- 9-2. 認証状態を確認します。 dbadmin=> SELECT user, authentication_method, ssl_state FROM sessions WHERE session_id = current_session(); current_user | authentication_method | ssl_state --------------+-----------------------+----------- testuser | TLS | Mutual <== ★Mutual(相互認証)であること dbadmin=> \q |
以上で設定は完了です。
参考情報
・Vertica-クライアント間通信を暗号化(SSL/TLS)する方法(サーバ認証)http://vertica-tech.ashisuto.co.jp/ssl-tls_connection_servermode/
・TLS Authentication
https://www.vertica.com/docs/10.1.x/HTML/Content/Authoring/Security/ClientAuth/ConfiguringTLSAuthentication.htm
・Implementing Client Self-Authentication
https://www.vertica.com/docs/10.1.x/HTML/Content/Authoring/Security/ClientAuth/ImplementingClientSelfAuthentication.htm
・Using Mutual Mode SSL Server Authentication with Vertica: Validating Your SSL Key and Certificate
https://www.vertica.com/kb/Using-Mutual-Mode-SSL-Server-Authentication-with-Vertica/Content/BestPractices/Using-Mutual-Mode-SSL-Server-Authentication-with-Vertica.htm
・Configuring TLS for JDBC and ODBC clients
https://www.vertica.com/docs/10.1.x/HTML/Content/Authoring/Security/TLS/ConfiguringTLS.htm