□PowerDNSでDNSSECの実装
□PowerDNSでDNSSECの実装
http://www.nic.ad.jp/ja/newsletter/No43/0800.html
http://dnssec.jp/
http://www.furelo.jp/wordpress/?p=93
DNSSECで必要なレコードは
DNSKEY ゾーンを署名する秘密鍵に対応する公開鍵
RRSIG リソースレコードの電子署名
DS DNSKEYのハッシュ値
NSEC 不存在との旨の回答に署名するためのリソースレコード
NSEC3 NSECのゾーン名をハッシュ値で示したもの
署名に用いる鍵は…
ゾーンに署名するゾーン署名鍵ZSK(Zone Signing Key)
ゾーン署名鍵ZSKに署名する鍵署名鍵KSK(Key SigningKey)
鍵署名鍵KSKは、ゾーン署名鍵ZSKを署名するものです。
鍵署名鍵KSKについて公開鍵のハッシュ値を求め、その値をDSとします。
親ゾーンには、鍵署名鍵KSKのDSを登録することになります。
ゾーンの更新があるたびに親ゾーンにDSを再登録するとなると更新の負荷が
高まりますが、このように鍵を二つに分ける運用をすることで、鍵署名鍵KSK
の更新があったときにのみ、親ゾーンにDSを再登録すればよくなります。
鍵署名鍵KSKの更新は、長くとも1~2年程度の間隔で行うことが推奨されて
います。
…だそうです。
・PowerDNSでDNSSECを使う場合のテーブル生成
alter table records add ordername VARCHAR(255);
alter table records add auth bool;
create index orderindex on records(ordername);
drop table domainmetadata;
create table domainmetadata (
id SERIAL PRIMARY KEY,
domain_id INT REFERENCES domains(id) ON DELETE CASCADE,
kind VARCHAR(16),
content TEXT
);
ALTER SEQUENCE domainmetadata_id_seq CYCLE;
drop table cryptokeys;
create table cryptokeys (
id SERIAL PRIMARY KEY,
domain_id INT REFERENCES domains(id) ON DELETE CASCADE,
flags INT NOT NULL,
active BOOL,
content TEXT
);
GRANT ALL ON domainmetadata TO hogehoge;
GRANT ALL ON domainmetadata_id_seq TO hogehoge;
GRANT ALL ON cryptokeys TO hogehoge;
GRANT ALL ON cryptokeys_id_seq TO hogehoge;
ALTER SEQUENCE cryptokeys_id_seq CYCLE;
drop table tsigkeys;
create table tsigkeys (
id SERIAL PRIMARY KEY,
name VARCHAR(255),
algorithm VARCHAR(255),
secret VARCHAR(255)
);
create unique index namealgoindex on tsigkeys(name, algorithm);
GRANT ALL ON tsigkeys TO hogehoge;
GRANT ALL ON tsigkeys_id_seq TO hogehoge;
alter table records alter column type type VARCHAR(10);
ALTER SEQUENCE tsigkeys_id_seq CYCLE;
・DNSSECもろもろの設定
…えーと、Googleせんせーに和訳してもらうと、どうもコマンドポチポチで
DNSSEC関連は自動設定されるみたい…ほんと?と言うわけでサンプルデータ
をいれてみる。
INSERT INTO domains (name, type) values (‘test.com’, ‘NATIVE’);
INSERT INTO records (domain_id, name, content, type,ttl,prio)
VALUES (1,’test.com’,’localhost ahu@ds9a.nl 1′,’SOA’,86400,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio)
VALUES (1,’test.com’,’dns-us1.powerdns.net’,’NS’,86400,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio)
VALUES (1,’test.com’,’dns-eu1.powerdns.net’,’NS’,86400,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio)
VALUES (1,’www.test.com’,’199.198.197.196′,’A’,120,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio)
VALUES (1,’mail.test.com’,’195.194.193.192′,’A’,120,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio)
VALUES (1,’localhost.test.com’,’127.0.0.1′,’A’,120,NULL);
INSERT INTO records (domain_id, name, content, type,ttl,prio)
VALUES (1,’test.com’,’mail.test.com’,’MX’,120,25);
ちゃんと入ったら、テストでいれた test.com について確認してみようと思う。
dig +dnssec test.com @localhost
としても、最初は何にも出てこないわけだが、
> ; <<>> DiG 9.7.3-P3-RedHat-9.7.3-8.P3.el6_2.3 <<>> +dnssec test.com @localhost
> ;; global options: +cmd
> ;; Got answer:
> ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34569
> ;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
> ;; WARNING: recursion requested but not available
>
> ;; OPT PSEUDOSECTION:
> ; EDNS: version: 0, flags: do; udp: 2800
> ;; QUESTION SECTION:
> ;test.com. IN A
>
> ;; AUTHORITY SECTION:
> test.com. 86400 IN SOA localhost. ahu.ds9a.nl. 1 600 180 600 300
>
> ;; Query time: 251 msec
> ;; SERVER: 192.168.100.200#53(192.168.100.200)
> ;; WHEN: Tue Jun 19 16:29:02 2012
> ;; MSG SIZE rcvd: 93
>
pdnssec secure-zone test.com
pdnssec rectify-zone test.com
とすると、必要な情報が設定されるらしい…Σ(゜Д゜;エーッ! まぢ?
実行前にDBの中を見ても、
psql -d hogehoge_db -U hogehoge
として、
select * from cryptokeys;select * from domainmetadata;select * from tsigkeys;
としても
> id | domain_id | flags | active | content
> —-+———–+——-+——–+———
> (0 行)
>
> id | domain_id | kind | content
> —-+———–+——+———
> (0 行)
>
> id | name | algorithm | secret
> —-+——+———–+——–
> (0 行)
>
なんだけど、ほんとかなぁ?
ではまずPowerDNSに「gpgsql-dnssec」を追記する。
> #
> # PostgreSQL Setting
> #
> launch=gpgsql
> gpgsql-host=192.168.100.200
> gpgsql-user=hogehoge
> gpgsql-password=areare
> gpgsql-port=5432
> gpgsql-dbname=hogehoge_db
> gpgsql-dnssec
特にパラメーターはないのでこれだけ。
でもって再起動。
/etc/init.d/pdns-server restart
で、先ほどのコマンドを実行する。
pdnssec secure-zone test.com
pdnssec rectify-zone test.com
とすると
> # pdnssec secure-zone test.com
> Zone test.com secured
> Adding NSEC ordering information
> # pdnssec rectify-zone test.com
> Adding NSEC ordering information
だそうだ…ちなみにcryptokeysにいろいろ追加されるだけで、NSECが追加
された読みたいなメッセージだけど、recordsには何も追加されていない。
この時点で
dig +dnssec test.com @localhost
とすると、ちゃんとNSECとRRSIGレコードが出てくる。
> ; <<>> DiG 9.7.3-P3-RedHat-9.7.3-8.P3.el6_2.3 <<>> +dnssec test.com @localhost
> ;; global options: +cmd
> ;; Got answer:
> ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24821
> ;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
> ;; WARNING: recursion requested but not available
>
> ;; OPT PSEUDOSECTION:
> ; EDNS: version: 0, flags: do; udp: 2800
> ;; QUESTION SECTION:
> ;test.com. IN A
>
> ;; AUTHORITY SECTION:
> test.com. 86400 IN SOA localhost. ahu.ds9a.nl. 1 600 180 600 300
> test.com. 86400 IN RRSIG SOA 8 2 86400 20120628000000 20120614000000 54244 test.com. kQMmHoqA1Mnl/apjeI5pudWYFHUjQS1ebEOyPHsfpoQoVI62Kfb5nOus 8OWBm9zzjhO3xgDtYEuVU1dX2lzHG8HG9S9Zz6eL3l9puLAwgW4d7pJM XHnJ66KP/CLVLcKvC3vgPsl5m5027LHPbnBg5+mHfarTpvuZsQao91f5 vyE=
> test.com. 86400 IN NSEC localhost.test.com. NS SOA MX RRSIG NSEC DNSKEY
> test.com. 86400 IN RRSIG NSEC 8 2 86400 20120628000000 20120614000000 54244 test.com. oi8Q4O1ajl/9RD39fEvLzsEs9XAcDyrwmEJUFsY+NE54qTcfuIagkQyT kA2jfZV3IIJkXosBbtIATclk3pudpW9UjSdZ+Dmcmk9JLRXkWWOvqwPV ocgIob3Vw+MmzuSk6MoEkjg2kPNGWUg/nJdGtXDFx9/MKzD+7CuM1JMB Iu4=
>
> ;; Query time: 7 msec
> ;; SERVER: 127.0.0.1#53(127.0.0.1)
> ;; WHEN: Tue Jun 19 16:52:05 2012
> ;; MSG SIZE rcvd: 470
さらに本当にOKなのかどうか確認する。
pdnssec show-zone 012345.jp | grep ‘KSK DNSKEY =’ | sed ‘s/KSK DNSKEY = //’ > trusted-keys
として、鍵署名鍵KSKを取り出して、コレを元に確認してみる…
dig +dnssec +sigchase +trusted-key=./trusted-keys test.com @localhost
> ;; NO ANSWERS: no more
> We want to prove the non-existence of a type of rdata 1 or of the zone:
> We have a NSEC for this zone :OK
> OK the NSEC said that the type doesn’t exist
> prove_nx: OK type does not exist
> ;; An NSEC prove the non-existence of a answers, Now we want validate this NSEC
> ;; NO ANSWERS: no more
>
>
> Launch a query to find a RRset of type DNSKEY for zone: test.com.
>
> ;; DNSKEYset that signs the RRset to chase:
> test.com. 300 IN DNSKEY 256 3 8 AwEAAZ4LKu7PO1WBI9B4hPeo3dWzEiqcnGAxSncBjydsSmpHdMmtklJc asHATqzKlhNsqum3lZYuxPPiR0n3KIu+kNjggY/XINYA3PsGP+2+FCAE JbnhIzcqsZNXYbkAYbFnKz6bdtiT9nMC4fSPrdhzgM6PdH0iM5L6WLyg /0WQ391L
> test.com. 300 IN DNSKEY 257 3 8 AwEAAZtnwM7sb3FSiTt1t5Ix91WtCWofad+1QLNKexKFoLmNIf2IGCq3 gNOJKdTD4W7l8bh1hU9A2irCo/iLvgM8NtsXZDts2HNLik81yeFnwYD1 GIYQYfiRErljRauTSrDwkfB+z5nOSIFDF8pO8duu+ZD/iHlsHZDLvegk gH6QjR/mjKb7SwGfOmScnGrDpnLp8QdI/EcDFKPkBhWujpgp6vPoHR4q G0ZFbqTHrmCuCudpP99PEV8h9rW3aTY+eElf+bhsbIzzjrJLUKLfQYNY ee0xqq5bRYK2qN++/vAr6jGpj/j7hx6cUOgSYvD1+d63tXceHUp5xs8I ePKwN2e83f0=
> test.com. 300 IN DNSKEY 256 3 8 AwEAAbMBM20qU96CJwxyMvXsmGCuMG/HbZRx5WvvC9n5wkBs7yk4bpfi mWZtqSpcxk97ZURS26h+PLmfymYOzVLMuF4fFoGldqeMapoIpHBMX652 p22mTZ9HGkHqfzyVQ/wdumM01er47T0KQHjSyfWljTS+Qvy6rBk7Aruw st6UVoBt
>
>
> ;; RRSIG of the DNSKEYset that signs the RRset to chase:
> test.com. 300 IN RRSIG DNSKEY 8 2 300 20120628000000 20120614000000 32294 test.com. JXClxY+5S70YeEqYy6iOVcN8KdzcB3VsuFAyi1hbY1Ix7aMm+Hl4sxy+ ldEkuVxesWs2AtxyywFRRZA8IM6HG3TvRP2dxyA8yDKsfKuWFSFLSADe bQzyhHao7m/FngRZTr64pxlrdxMTdBnGCK3WZq4wlXpGakHO+fPLDcc5 RpJca4TXN06rvjeXKTJeO+TEydLuQw8zu9XbgvPEDJJdjG2jTXJp5ZT6 S5jAAOuxf0NH1ny60PVEYQg/MCCz4f5UKmqKailgKuADWBeUf8LK9PTb hDXi43SxHxBSxVUyswbAYX8LsZ8XhJayjzvwwMiyfoKqgAeKMUklXfl1 UXM+3Q==
>
>
>
> Launch a query to find a RRset of type DS for zone: test.com.
> ;; NO ANSWERS: no more
>
> ;; WARNING There is no DS for the zone: test.com.
>
>
>
> ;; WE HAVE MATERIAL, WE NOW DO VALIDATION
> ;; VERIFYING NSEC RRset for test.com. with DNSKEY:54244: success
> ;; OK We found DNSKEY (or more) to validate the RRset
> ;; Ok, find a Trusted Key in the DNSKEY RRset: 32294
> ;; VERIFYING DNSKEY RRset for test.com. with DNSKEY:32294: success
>
> ;; Ok this DNSKEY is a Trusted Key, DNSSEC validation is ok: SUCCESS
という感じで、SUCCESSになったからOKってことかな?
すげー簡単じゃん、どうしよー?
追伸:
JPRSにDNSSECの署名鍵として登録するのは以下のこの部分です。
> # pdnssec show-zone test.com > Zone has NSEC semantics > Zone is not presigned > keys: > ID = 1 (KSK), tag = 41431, algo = 8, bits = 2048 Active: 1 > KSK DNSKEY = test.com IN DNSKEY 257 3 8 AwEAAaAranAUTTF2fqMAgC0o2fATpuO8XBfzSqT/HJBoNibomCEMAdeDfHdZFe8HyLCPZAXWlsy+n8yIQgac9VYf7DJtFOc0FkrLujInLdyVtYks3o44wOTSq1qfib+0x2YgS/j+cDU6OKgDVSzN2pd8Q4bsb9OkieUd0QvWbMQVP5c/HpJckGKXQ4FsqouoUIurqe4elMdyDXbe28PokH180AGRbHM5lvawghd1JPCzmR9MwBubH1hR7lyz87ugzAJLruPb85VBYSFK1eUiSmzTHIYePrUw2W8Xf0IRTPlRwygsdSqKesjTBGh2Wg3N8tMqQ6f0ew2ZM8zARhoRRpstRq8= > DS = test.com IN DS 41431 8 1 307571944166292803abb805590b51a78f790f8d > DS = test.com IN DS 41431 8 2 a73f4201b967791afff20a46b29f6f46469e216e7d7937d24fb807652a4436d9 > > ID = 2 (ZSK), tag = 60066, algo = 8, bits = 1024 Active: 1 > ID = 3 (ZSK), tag = 34536, algo = 8, bits = 1024 Active: 0 >
二行ありますが、それぞれを署名鍵1、署名鍵2として登録したらいけました。:-)