Docker + Kerberos認証入門

「Dockerを使ってKerberosの環境を作ろう!」という内容です。Kerberos認証のことは参考書でちょっと読んだ程度で全然わかってないので、手を動かしながら勉強したいなと思った次第です。

目次


環境

単一ホスト上に合計3つのDockerコンテナを立てます。それぞれサービス、クライアント、KDCの役割があります。クライアントがサービスにSSHで接続する時、Kerberos認証をかけ、ログインまでできるようにするのが到達目標です。

以下、今回作成するコンテナです。

  • サービス(ホスト名: myservice)
  • クライアント(ホスト名: myclient)
  • KDC(ホスト名: mykdc)

また全てのコンテナはcentos:7.3.1611のイメージを使用して作り、新たに定義したネットワークkrb_networkに繋ぎます。DNSは使用しません。ちなみにDocker for Macを使ってます。

コンテナの起動まで

Kerberos用のネットワークの定義

コンテナに静的IPを割り当てたかったんですけどDockerのデフォルトのブリッジネットワークではそれができないので、新たにネットワークを作ってそこでIPを割り当てることにしました。

$ docker network create --subnet=192.168.1.0/24 krb_network

コンテナ作成

$ docker run -itd --name service1 -e TZ=Asia/Tokyo --net=krb_network --ip=192.168.1.10 --hostname myservice.mydomain.com --add-host=myclient.mydomain.com:192.168.1.11 --add-host=mykdc.mydomain.com:192.168.1.12 centos:7.3.1611

$ docker run -itd --name client1 -e TZ=Asia/Tokyo --net=krb_network --ip=192.168.1.11 --hostname myclient.mydomain.com --add-host=myservice.mydomain.com:192.168.1.10 --add-host=mykdc.mydomain.com:192.168.1.12 centos:7.3.1611 

$ docker run -itd --name kdc1 -e TZ=Asia/Tokyo --net=krb_network --ip=192.168.1.12 --hostname mykdc.mydomain.com --add-host=myservice.mydomain.com:192.168.1.10 --add-host=myclient.mydomain.com:192.168.1.11 centos:7.3.1611

このdocker runコマンドでは以下のようなことをやっています。

タイムゾーンは別に変更しなくてもいいです。

確認

コンテナがちゃんと動いているか

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
27e8658076c9        centos:7.3.1611     "/bin/bash"         5 minutes ago       Up 5 minutes                            kdc1
ec5a5306a0c3        centos:7.3.1611     "/bin/bash"         5 minutes ago       Up 5 minutes                            client1
db937ce4d851        centos:7.3.1611     "/bin/bash"         5 minutes ago       Up 5 minutes                            service1

hostsファイルと時刻の確認 (以下はmykdcで確認した場合)

$ docker attach kdc1 
[root@mykdc /]# cat /etc/hosts
127.0.0.1   localhost
::1    localhost ip6-localhost ip6-loopback
fe00::0    ip6-localnet
ff00::0    ip6-mcastprefix
ff02::1    ip6-allnodes
ff02::2    ip6-allrouters
192.168.1.10    myservice.mydomain.com
192.168.1.11    myclient.mydomain.com
192.168.1.12    mykdc.mydomain.com mykdc
[root@mykdc /]# date
Mon Jul 17 10:03:45 JST 2017
[root@mykdc /]# 

Kerberos関係のパッケージのインストール

krb5-workstationのインストール

myserviceとmyclientで行います

[root@myclient /]# yum -y install krb5-workstation

krb5-serverのインストール

mykdcで行います

[root@mykdc /]#  yum -y install krb5-server

/etc/krb5.confの編集

全てのコンテナで編集し、以下のようにします。default_ccache_name = KEYRING:persistent:%{uid}コメントアウトも忘れずに。

/etc/krb5.conf

(省略)

[libdefaults]
 dns_lookup_realm = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true
 rdns = false
# default_realm = EXAMPLE.COM                                                                                                                                  
 default_realm = MYDOMAIN.COM
# default_ccache_name = KEYRING:persistent:%{uid}

[realms]
# EXAMPLE.COM = {                                                                                                                                              
#  kdc = kerberos.example.com                                                                                                                                  
#  admin_server = kerberos.example.com                                                                                                                         
# }                                                                                                                                                            

 MYDOMAIN.COM = {
  kdc = mykdc.mydomain.com
  admin_server = mykdc.mydomain.com
 }

[domain_realm]
# .example.com = EXAMPLE.COM
# example.com = EXAMPLE.COM
.mydomain.com = MYDOMAIN.COM
mydomain.com = MYDOMAIN.COM

KDCの設定

各種設定ファイルの編集

mykdcで/var/kerberos/krb5kdc/kdc.conf/var/kerberos/krb5kdc/kadm5.aclの編集をします。

/var/kerberos/krb5kdc/kdc.conf

[kdcdefaults]
 kdc_ports = 88
 kdc_tcp_ports = 88

[realms]
# EXAMPLE.COM = {                                                                                                                                              
  MYDOMAIN.COM = {
  #master_key_type = aes256-cts                                                                                                                                
  acl_file = /var/kerberos/krb5kdc/kadm5.acl
  dict_file = /usr/share/dict/words
  admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
  supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal des-hmac-sh\
a1:normal des-cbc-md5:normal des-cbc-crc:normal
 }

/var/kerberos/krb5kdc/kadm5.acl

# */admin@EXAMPLE.COM     *
*/admin@MYDOMAIN.COM *  

Kerberosデータベースの作成

[root@mykdc /]# kdb5_util create -s
Loading random data
Initializing database '/var/kerberos/krb5kdc/principal' for realm 'MYDOMAIN.COM',
master key name 'K/M@MYDOMAIN.COM'
You will be prompted for the database Master Password.
It is important that you NOT FORGET this password.
Enter KDC database master key: 
Re-enter KDC database master key to verify: 

root/adminプリンシパル作成

[root@mykdc /]# kadmin.local
Authenticating as principal root/admin@MYDOMAIN.COM with password.
kadmin.local:  addprinc  root/admin
WARNING: no policy specified for root/admin@MYDOMAIN.COM; defaulting to no policy
Enter password for principal "root/admin@MYDOMAIN.COM": 
Re-enter password for principal "root/admin@MYDOMAIN.COM": 
Principal "root/admin@MYDOMAIN.COM" created.
kadmin.local:  exit
[root@mykdc /]# 

KDC起動

ではKDC管理サーバーとKDCサーバーを起動しましょう

[root@mykdc /]# kadmind
[root@mykdc /]# krb5kdc

出力が何もなくてめっちゃ不安になったので、プロセスが動いているか、何のポートが開いているかを確認しました。

ssnetstatも使えなかったので、とりあえず追加でnet-toolsをインストールしました。

[root@mykdc /]# ps ax
  PID TTY      STAT   TIME COMMAND
    1 pts/0    Ss     0:00 /bin/bash
   85 ?        Ss     0:00 kadmind
   87 ?        Ss     0:00 krb5kdc
   95 pts/0    R+     0:00 ps ax
[root@mykdc /]# netstat -atun
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:88              0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.11:41085        0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:749             0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:464             0.0.0.0:*               LISTEN     
tcp6       0      0 :::88                   :::*                    LISTEN     
tcp6       0      0 :::749                  :::*                    LISTEN     
tcp6       0      0 :::464                  :::*                    LISTEN     
udp        0      0 0.0.0.0:88              0.0.0.0:*                          
udp        0      0 127.0.0.11:50525        0.0.0.0:*                          
udp        0      0 0.0.0.0:464             0.0.0.0:*                          
udp6       0      0 :::88                   :::*                               
udp6       0      0 :::464                  :::*   

OKですね。

サービスプリンシパルの作成

mysericeのコンテナで設定します。

[root@myservice /]# kadmin -p root/admin
Authenticating as principal root/admin with password.
Password for root/admin@MYDOMAIN.COM: 
kadmin:  addprinc -randkey host/myservice.mydomain.com
WARNING: no policy specified for host/myservice.mydomain.com@MYDOMAIN.COM; defaulting to no policy
Principal "host/myservice.mydomain.com@MYDOMAIN.COM" created.
kadmin:  ktadd host/myservice.mydomain.com
Entry for principal host/myservice.mydomain.com with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/myservice.mydomain.com with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/myservice.mydomain.com with kvno 2, encryption type des3-cbc-sha1 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/myservice.mydomain.com with kvno 2, encryption type arcfour-hmac added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/myservice.mydomain.com with kvno 2, encryption type camellia256-cts-cmac added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/myservice.mydomain.com with kvno 2, encryption type camellia128-cts-cmac added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/myservice.mydomain.com with kvno 2, encryption type des-hmac-sha1 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/myservice.mydomain.com with kvno 2, encryption type des-cbc-md5 added to keytab FILE:/etc/krb5.keytab.
kadmin:  exit

klistでKerberos のキーテーブルを確認します。

[root@myservice /]# klist -e -k /etc/krb5.keytab 
Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
   2 host/myservice.mydomain.com@MYDOMAIN.COM (aes256-cts-hmac-sha1-96) 
   2 host/myservice.mydomain.com@MYDOMAIN.COM (aes128-cts-hmac-sha1-96) 
   2 host/myservice.mydomain.com@MYDOMAIN.COM (des3-cbc-sha1) 
   2 host/myservice.mydomain.com@MYDOMAIN.COM (arcfour-hmac) 
   2 host/myservice.mydomain.com@MYDOMAIN.COM (camellia256-cts-cmac) 
   2 host/myservice.mydomain.com@MYDOMAIN.COM (camellia128-cts-cmac) 
   2 host/myservice.mydomain.com@MYDOMAIN.COM (des-hmac-sha1) 
   2 host/myservice.mydomain.com@MYDOMAIN.COM (des-cbc-md5) 

ユーザープリンシパルの作成

どこかのコンテナ内で以下のコマンドを実行します。

[root@myclient /]# kadmin -p root/admin
Authenticating as principal root/admin with password.
Password for root/admin@MYDOMAIN.COM: 
kadmin:  addprinc user1
WARNING: no policy specified for user1@MYDOMAIN.COM; defaulting to no policy
Enter password for principal "user1@MYDOMAIN.COM": 
Re-enter password for principal "user1@MYDOMAIN.COM": 
Principal "user1@MYDOMAIN.COM" created.
kadmin:  exit
[root@myclient /]# 

TGTの取得

myclientで行います。kinitコマンドでTGT(Ticket Granting Ticket)を取得します

[root@myclient /]# kinit user1
Password for user1@MYDOMAIN.COM: 
[root@myclient /]# 

klistでチケットを表示してみます。

[root@myclient /]# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: user1@MYDOMAIN.COM

Valid starting     Expires            Service principal
07/17/17 11:08:28  07/18/17 11:08:28  krbtgt/MYDOMAIN.COM@MYDOMAIN.COM

SSH接続まで

ログイン用ユーザー追加

myserviceでsshでログインするユーザーを作成します。ここで作成するユーザーはさっき作成したユーザープリンシパルと同じ名前にしてください。

 [root@myservice /]# adduser user1  

SSHサーバーのインストール

openssh-serverをインストールします。

[root@myservice /]# yum -y install openssh-server

このままsshdを実行するとCould not load host keyのエラーが発生するので鍵を作ります。

[root@myservice /]# ssh-keygen -A
ssh-keygen: generating new host keys: RSA1 RSA DSA ECDSA ED25519 

次に/etc/ssh/sshd_configを編集します。

/etc/ssh/sshd_config

(省略)
# Kerberos options
KerberosAuthentication yes
#KerberosOrLocalPasswd yes
KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes

# GSSAPI options
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
#GSSAPIEnablek5users no
(省略)

sshdを実行してサーバーを立てます。

[root@myserver /]# /usr/sbin/sshd

SSHクライアントのインストール

myclientで行います

[root@myclient /]# yum -y install openssh-clients

SSH接続

オプションで-o GSSAPIAuthentication=yesをつけてsshを実行します(オプションつけなくてもログインできるかも)

[root@myclient /]# ssh -o GSSAPIAuthentication=yes user1@myservice.mydomain.com
Last login: Mon Jul 17 11:09:37 2017 from myclient.mydomain.com
[user1@myservice ~]$ cat /etc/hostname
myservice.mydomain.com
[user1@myservice ~]$ 

ログインに成功しました〜!再度チケットを表示してみましょう。

[root@myclient /]# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: user1@MYDOMAIN.COM

Valid starting     Expires            Service principal
07/17/17 11:08:28  07/18/17 11:08:28  krbtgt/MYDOMAIN.COM@MYDOMAIN.COM
07/17/17 11:09:37  07/18/17 11:08:28  host/myservice.mydomain.com@MYDOMAIN.COM
[root@myclient /]# 

新たなチケットが追加されています。

これでDockerを使ったKerberos環境の構築を終わりたいと思います。お疲れ様でした。

参考