When I send DNS request, I will get some response. At this time, I had some question if this answer come from cached information or not. Someone think like me.

 

When the DNS server can recurse (RA is set)

1. Even if the query is recursive or not, the DNS which recived refer to local cache to find out the A record.

2. If the DNS is not authoritative, it will be return cached.

 

Please Look at these Packets.

There are 2 answers. One is CNAME which has 300 TTL time, other is A which 30 TTL time. I try again. And then

Now, I can see CNAME which has 300 TTL time and A which 29 TTL time. 

In my test environment, I have DNS and GSLB. It has the role each like below. I dig to Authoritative DNS.

Thus, 

1. Authoritative DNS return the TTL time for CNAME. This is the configuration value. 

- In the response packet, Authoritative flag is set.

2. Authoritative DNS recurse to GSLB and cache the answer and return to client. So this TTL time will be counted down.

- In the response packet, Recursion Available is set. (The DNS can recurse)

 

The best way to find out the answer come from cached is watching "TTL time will be counted down or not".

 

This is the other case, I will try dig to "8.8.8.8" which is google DNS server. Even if there are lots of DNS server behind 8.8.8.8.

In this result above, Recursion Available is set, so the DNS is expected to cache answer. However, this is not Authoritative. Therefore, the CNAME and A should be counted down.

 

So far, I send recursive query. However, I want to see the same result with iterative query. In this post, I explained how to generate iterative query. I will use "dig +norecurse". Please note below

 

1. "dig with norecurse" show the result by DNS properies.

- Some DNS show the next query information, even if it has cached record.

- Some DNS show the cached answer.

- Some DNS show "server failed" result

 

Because of this, I did not recommend to use "dig with norecurse". Anyway, I will show when it works. I used same DNS server target.

When dig with no-recurse works, It show CNAME with counted TTL time down and A with counted TTL time down. With result, this DNS server has cached record value.

 

I have already told that different type of result can be shown with "norecurse" option. I will send query "www.google.com" to different DNS servers.

 

At first, Cached A record information is returned from DNS server. At this time, I can expect this DNS server has the cache. Please look at the next case,

There is no Answer field. There are next DNS server information to query. This is the reason why I do not recommend this norecursion option. Sometime, I can see the server fail like below.

This is my result. It is OK to use "norecurse" option for checking the cached return. However, it can can show different result what I do not expect. 

 

1. See the response packet field : RA is set

2. See the TTL time count down.

 

This is the prove to cached.

 

 

Reference

[ 1 ] superuser.com/questions/523917/dns-queries-returning-no-answer-section

[ 2 ] superuser.com/questions/681680/dns-making-iterative-requests/681710

[ 3 ] www.slashroot.in/difference-between-iterative-and-recursive-dns-query

[ 4 ] www.ateamsystems.com/tech-blog/using-dig-to-find-domain-dns-ttl/

Sometimes, I need to use "dig trace" command. I have known that it trace the DNS hop by hop. In this post, I will see the Packet level with this command.

 

1. First Packet of dig trace.

 

The first packet is look like. 

There are 3 properties. 

 

1. "Recursion Desired" is not set (I have alread posted about recursion and iterative flags.)

2. The request is not for A record. it is NS.

3. This request is for "root" domain such "dot ."

 

By 2 property. the DNS response NS answer. After then, the client start to send A and AAAA request to the same DNS.

In this case, Client send A and AAAA for m.root-servers.net. The DNS does not response. After 5 second, it will retry.

In the result, I can see "couldn't get address for m.root-server.net" (Anyway this is not normal case)

The below is normal case. It request A and AAAA requests to all of targets which the response of the first NS request.

There is the things important to see. In wireshark, I estimate the time from request and response. 

The client choose the fastest one. In this sample, it will be "198.97.190.53". 

 

2. Second Reqeust for target domain

 

I think this is first step for the domain what I lookup. I have known that "198.97.190.53" is the namesever for next step. Therefore, I send the A record request to this DNS server.

Please not that "This is A record request with no-recursion". The below is the response packet.

There is no answer field in this response. Also, this server does not recursion available and is not Authoritative.

The DNS response with "Authoritative nameserver" list to client. The client must request other DNS server to find out.

Client send the nameserver (8.8.8.8) to find out A record for this nameserver list received. This is almost same with first one.

During these step, the client also choose the fastest one. At this time, it is "210.101.60.1"

With this value, the client try again.

However, there is no answer filed at this time. There are "authoritative nameservers list" again. Client will repeate above step.

 

3. Finally Request for A record.

 

The client send the A record request without recursion to 211.188.180.21 name server. It response like below.

At this time, there is "answer filed". Becuse of this, dig trace will be stoped. However, this is not A record. It is CNAME record with "authoritative nameservers" for this CNAME.

(Please note that "Authoritative is set" even if the A record is not responsed.) This measn that CNAME is valuable like A record.

Client must repeat this CNAME domain request again. It is the same above step.

 

[ Reference ]

 

[ 1 ] createnetech.tistory.com/60

 

 

In the past, I posted "how to configure bind9". During writing, I did not understand fully the concept of the recursion, even if there are simple explain like others.

I will see the some packet in this post. It is much easier.

 

1. General DNS Standard Query (Default Reqeust)

 

Normally, the servers are set the "/etc/resolv.conf" file to customize DNS server. In my case, I set "8.8.8.8" as the resolver.

It is everything which I can do simply. And then I use without any recognization. This is the Request Packet

In DNS packet, there is flags field. "Recursion Desired is set". This is what I want to find. Because of this, the DNS server (the request packeted is received) will try to recurse. 

In the received packet, there are lot of informations. I can estimate DNS properites such as "Authoritative" and "Recursion option".

This is the Default Reqeust Packet. Therefore, the DNS will do recursion and caching.

 

2. No Recursion DNS Reqeust (Iterative Request)

 

At this time, I want to send "no recursion DNS request". I mean iterative request. The simple way is to use "dig" command with "norecursion". Please look the manual page.

I will try "dig +norecurse" like below.

That is so strange. There is no answer for A record. "This imply that there is no cached A record for this domain", Becuase this DNS server does not do recursion. If the DNS has the cached A record. It looks like below.

In this case, the DNS has the cached A record. It returned the response. Look at the packet.

With "norecursion", "Recursion desired flag" is not set. This is the important factor to understand. 

In the response, the flags values are same as the above. Please look at the Answer. This means that "DNS server (8.8.8.8) give me 2 types of answers, first is CNAME and second is A record for the CNAME". This A record is cached value. Because This DNS server can recursion by the flag.

 

Reference 

[ 1 ] help.fasthosts.co.uk/app/answers/detail/a_id/1276/~/what-is-recursive-dns-and-why-is-it-not-recommended%3F

 

How to upgrade DNSSEC for bind9?

 

In this post, I wrote how to configure DNS servers (Bind9). In this post, I will setup the DNSSEC to enforce DNS secrutiy from the attacker. In fact, I am not friendly with DNS element. So I will follow this instruction.

 

1. Pre-requisite 

 

I need DNS servers (master, slave and caching). I can build from this instruction simply.

 

2. Edit Master DNS server configuration

 

At first, I need to update master DNS server configuration to enable DNSSEC function. Open "/etc/bind/named.conf.option" and update like below (red text)

# cat /etc/bind/named.conf.options

options {

        directory "/var/cache/bind";

        recursion no;

        listen-on port 53 { 10.10.0.124; };

        allow-transfer { none; };

        dnssec-enable yes;

        dnssec-validation yes;

        dnssec-lookaside auto;

        auth-nxdomain no;    # conform to RFC1035

        listen-on-v6 { any; };

};

DNSSEC required the ZSK KEY (Zone Signing Key) and KSK KEY (Key Signing Key). Both key are called as DNSKEY. I have to generated these. To generate encryption key, I need entropy algorithm. "havedged" is good solution for this.

# apt-get install haveged

Now, I can generate. Please note that Key files should be located on the same directory of zone files.

# cd /var/cache/bind/zones

After run command to geneate, I can see the 2 files like below. These file are Zone Signing Key.

dnssec-keygen -a NSEC3RSASHA1 -b 2048 -n ZONE db.g.crenet.com            

Generating key pair......+++ ...............+++

K%2Fvar%2Fcache%2Fbind%2Fzones%2Fdb.g.crenet.com.+007+49394

 

root@master:/var/cache/bind/zones# ls

Kg.crenet.com.+007+01898.key

Kg.crenet.com.+007+01898.private

Now I will create Key Signing Key like below. After running, I can another 2 files.

dnssec-keygen -f KSK -a NSEC3RSASHA1 -b 4096 -n ZONE g.crenet.com

Generating key pair............................++ .........................................................................++

K%2Fvar%2Fcache%2Fbind%2Fzones%2Fdb.g.crenet.com.+007+56676

 

root@master:/var/cache/bind/zones# ls

Kg.crenet.com.+007+01898.key  Kg.crenet.com.+007+01898.private  Kg.crenet.com.+007+33324.key  Kg.crenet.com.+007+33324.private

All of these step are for creating signed zone file. Therefore, I will update zone file from now. Open zone file what I make secure and Include the key files above.

root@master:/var/cache/bind/keys# cat ../zones/db.g.crenet.com

$TTL    30

@       IN      SOA     g.crenet.com. admin.g.crenet.com. (

                              3         ; Serial

                         604800         ; Refresh

                          86400         ; Retry

                        2419200         ; Expire

                         604800 )       ; Negative Cache TTL

;

        IN      NS      ns1.g.crenet.com.

        IN      NS      ns2.g.crenet.com.

ns1.g.crenet.com. IN A 10.10.0.124

ns2.g.crenet.com. IN A 10.10.0.225

;

www.g.crenet.com. IN A 10.10.0.10

$INCLUDE /var/cache/bind/keys/Kg.crenet.com.+007+01898.key

$INCLUDE /var/cache/bind/keys/Kg.crenet.com.+007+33324.key

Now, I am ready to sign the zone file. I will run "dnssec-signzone -3 <salt> -A -N INCREMENT -o <zonename> -t <zonefilename>". "<Salt>" value is the random number. I can generate like below

# head -c 1000 /dev/random | sha1sum | cut -b 1-16

643f8a18458c3fbd

With this value, I can complete the command above

# cd ../zones

# dnssec-signzone -3  643f8a18458c3fbd -A -N INCREMENT -o g.crenet.com -t db.g.crenet.com
Verifying the zone using the following algorithms: NSEC3RSASHA1.
Zone fully signed:
Algorithm: NSEC3RSASHA1: KSKs: 1 active, 0 stand-by, 0 revoked
                         ZSKs: 1 active, 0 stand-by, 0 revoked
db.g.crenet.com.signed
Signatures generated:                       12
Signatures retained:                         0
Signatures dropped:                          0
Signatures successfully verified:            0
Signatures unsuccessfully verified:          0
Signing time in seconds:                 0.017
Signatures per second:                 685.910
Runtime in seconds:                      0.023

 

# ls
db.g.crenet.com         dsset-g.crenet.com.           Kg.crenet.com.+007+01898.private  Kg.crenet.com.+007+33324.private
db.g.crenet.com.signed  Kg.crenet.com.+007+01898.key  Kg.crenet.com.+007+33324.key

"db.g.crenet.com.signed" and "dsset-g.crenet.com." files are created. I will update to target this signed zone file in "named.conf.local"

# cat /etc/bind/named.conf.local

zone g.crenet.com {

   type master;

   file "/var/cache/bind/zones/db.g.crenet.com.signed";

   allow-transfer { 10.10.0.225; };

};

Service restart and dig the DNS query with this Master DNS server.

# service bind9 restart

# dig DNSKEY g.crenet.com @10.10.0.124 +multiline

; <<>> DiG 9.10.3-P4-Ubuntu <<>> DNSKEY g.crenet.com @10.10.0.124 +multiline
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31480
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;g.crenet.com.          IN DNSKEY

;; ANSWER SECTION:
g.crenet.com.           30 IN DNSKEY 257 3 7 (
                                AwEAAZxSkIvePjPUR+SDp7Dyf9NUVdVN2x250Ipqf/Oj
                                JFbq3Wl6b+97lZtSCkQIwa4llL6BHtXMfWWY70qx8hn6
                                q3lBVXR4XQcsloe16YHDucO8x5MW+o+l61yspKeEj4ZH
                                rb9msIW0AY4vGKj6xofTza/RFI2iiBiLzrCelgYWP2IG
                                hemeYMfUP3y0RNnsNB9ozh8O1uA2PocTwDaKWqkI0a41
                                Up/Ea41VKy97ZZgz2duafCkWrrFOAGMbR6M1+P3Glay5
                                Sj1vLHt1jUcCKk7RnjvlMTuZ74jGu/8IcotMZsna8nwe
                                jZB4Scm4Y/gr1xo+5CkJ9lzsdz8oMHAdwNE+CqDag24C
                                7gisB81zl1qtNOuSlVGO1TPdriH+Y3da+kCfNj6Q+vLi
                                rtoNlY6/WfmYtr9KzhnthDkoz3HVCJguv2ThUL62La2Z
                                GHyFtYeiyQ0Oa7y6z0VtrQZ/qn/BwmnWqDOCdQLqu7m4
                                k4zqoknGZ1BbUK77DQ1R08yfOYTbIOJlHHHgGuVWHAIo
                                XrhjbwQYvNXtFgCn+w60zB8uxQcctIX2PiOj0WRtOJkN
                                5mcrL5sYGNVETQ3k73MzE0WAOUTpQQoT+uD8OnTSaw3p
                                dHB12PL+swVQKn/LzBxhXCn9/A39vOUkJ7PyYkfn2Ej/
                                aLNb5+F5LIDB57UqPv5I2T4p0rYr
                                ) ; KSK; alg = NSEC3RSASHA1; key id = 33324
g.crenet.com.           30 IN DNSKEY 256 3 7 (
                                AwEAAcDZ5SCeLN0IhLoRKm/BKVPRJuc/ufMXOJivmXHH
                                O4oRLXFwTq1Xe+TLN+cRmOQiBCO3FTN1rMgNxgts7u6u
                                /RVTZnBNvKdcLVbayzE3fsMQrXxFho3fg5zEsF2xORve
                                K+f5fUWxfNl/cduzz6PplU82xznhMyYvrirGV2SN6v7w
                                IP+eZNqUyrcaUdBWCv3t+jZnTWdd4zOPkkv1EGSG0mMR
                                memYJIL66M2eFl4uQyShAqjzVWOpTyDWeKaaB4R2GB0g
                                LiKNZuiIUr+5V+Lmk/a3qsd26DGu3wU2z/MApwPucrLF
                                0vDdGocpS1Vk6Da7QgcI7ZNQnJWmMa/z7FeBbb8=
                                ) ; ZSK; alg = NSEC3RSASHA1; key id = 1898

Now, The DNSSEC in master DNS server is worked.

 

3. Edit Slave DNS server configuration

 

There is not complicated. Just enable "named.conf.option" in Slave DNS server.

# cat /etc/bind/named.conf.options

options {

        directory "/var/cache/bind";

        recursion no;

        listen-on port 53 { 10.10.0.225; };

        dnssec-enable yes;

        dnssec-validation yes;

        dnssec-lookaside auto;

        auth-nxdomain no;    # conform to RFC1035

        listen-on-v6 { any; };

};

Also, change file value in "named.conf.local" of Slave DNS server.

# cat /etc/bind/named.conf.local

zone g.crenet.com {

   type slave;

   file "db.g.crenet.com.signed";

   masters { 10.10.0.124; };

};

Now, I have restart bind9 and reload zone file. I can see downloaded file which is signed.

# service bind9 restart

# rndc reload

server reload successful

 

# ls

db.g.crenet.com  db.g.crenet.com.signed  managed-keys.bind  managed-keys.bind.jnl

4. Edit Caching DNS server configuration

 

I have alread update this file to work DNSSEC function. Please check "/etc/bind/named.conf.option" file.

# cat /etc/bind/named.conf.options

acl trusted {

   178.128.21.101;

   10.10.0.204;

   10.10.0.124;

   10.10.0.225;

};

options {

        directory "/var/cache/bind";

        recursion yes;                 # enables resursive queries

        allow-recursion { trusted; };  # allows recursive queries from "trusted" clients

        listen-on port 53 { 10.10.0.204; };   # ns1 private IP address - listen on private network only

        allow-transfer { none; };      # disable zone transfers by default

        dnssec-enable yes;

        dnssec-validation yes;

        dnssec-lookaside auto;

        dump-file "/var/cache/bind/dumps/named_dump.db";

        auth-nxdomain no;    # conform to RFC1035

        listen-on-v6 { any; };

};

 

5. Configure DS records with the registrar.

 

When I create Signed zone file, "dsset-g.crenet.com" file is also generated which include "DS" record. 

# cat dsset-g.crenet.com.

g.crenet.com.           IN DS 33324 7 1 CFE9B08DB55C9EF23AAE19979FB2A48467C1061E

g.crenet.com.           IN DS 33324 7 2 1245F5EB80E7A2F6CE9A64A9C69A94EFBC800D60EA4065B96B7FF501 AB6816D2

To publish this DNS server with DNSSEC, I have to offer these DS record to my DNS registrar. (DNS registrar mean the represtative compay which has the role to register DNS, such as GoDaddy or Gabia.

 

Reference 

[ 1 ] https://createnetech.tistory.com/46

[ 2 ] https://www.digitalocean.com/community/tutorials/how-to-setup-dnssec-on-an-authoritative-bind-dns-server--2 

 

How to configure DNS bind9 configuration in Ubuntu

 

Recently, I need to learn about DNS system. In fact, I have not considered about this system so far. To understand about this as the begineer. I will memorize how to configure simply.

 

1. Pre-requisite.

I have four servers with Ubuntu 16.04 in AWS. Each server has the Public IP address.

 

2. Installation of bind9 packages

 

In fact, I do not know anything at this time. I need some instructions. I will follow this instruction basically. At first I need to update hosts name.

# hostname ns1

hostname ns2

hostname ns3

And I will update repository and install the bind packages like below. I will repeate this step in each servers, ns2 and ns3 also.

# apt-get update

sudo apt-get install bind9 bind9utils bind9-doc

Installation is completed. I can see the directory and files under /etc/bind directory.

# ls /etc/bind
bind.keys  db.127  db.empty  db.root     named.conf.default-zones  named.conf.options  zones.rfc1918
db.0       db.255  db.local  named.conf  named.conf.local          rndc.key

 

3. Configuration Primary DNS Server

 

At first, I will edit "named.conf.options". In this file, I will add some options to work well as the DNS server. This configuration is not applied to only primary. I will edit all of servers. 

# For Caching DNS server

acl "trusted" {
        10.10.0.72;
        10.10.0.99;
        10.10.0.39;
}

options {
        directory "/var/cache/bind";

        recursion yes;
        allow-recursion { trusted; };
        listen-on port 53 { 10.10.0.72; };
        allow-transfer { 10.10.0.99; 10.10.0.39; }; 
        forwarders {
                8.8.8.8;
                8.8.4.4;
        };
};

# For Authoritative DNS servers

options { 
        directory "/var/cache/bind"; 

        recursion no;  
        listen-on port 53 { 10.10.0.72; }; 
        allow-transfer { 10.10.0.99; 10.10.0.39; }; 
};

In above, there is "acl" field. It is the represatative name for allow-recursion. "recursion yes" means enable the recurive query from other DNS servers which is defined in "allow-recursion". In this instrucion, It shows what the recursive query is.

In this instruction, it is more simple contexts comparing with "iterative request".

If I do not want to use this recursion, I can change to "recursion no;" In my case, my authoritative DNS servers will be end of step for Domain. So I will disable the recursion. "allow-transfer { 10.10.0.99; 10.10.0.39; };" means transfering zone file to listed DNS servers which are refered as slave servers. 

# Master DNS (Authoritative DNS) server

options {
        directory "/var/cache/bind";

        recursion no;
        listen-on port 53 { 10.10.0.72; };
        allow-transfer { 10.10.0.99; 10.10.0.39; };

        dnssec-validation auto;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };
};

# Slave DNS (Authoritative DNS) servers

options {
        directory "/var/cache/bind";

        recursion no;
        listen-on port 53 { 10.10.0.72; };

        dnssec-validation auto;

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };
};

After these configurations, I can check the configuration is correct or not.

# service bind9 restart

# # named-checkconf named.conf.options

If I do not get any answer or failed message, It works correct. In above, I defined "allow-transfer" like "allow-transfer { 10.10.0.99; 10.10.0.39; };". This parameter is the global value. Therefore, it is applied for all of zone files. It need to be limited sometimes. In the instructionallow-transfer { none; }; is recommended.

# Master DNS (Authoritative DNS) server

options { 
        directory "/var/cache/bind"; 

        recursion no; 
        listen-on port 53 { 10.10.0.72; }; 
        allow-transfer { none };

        dnssec-validation auto; 

        auth-nxdomain no;    # conform to RFC1035 
        listen-on-v6 { any; }; 
}; 

# Slave DNS (Authoritative DNS) servers

options { 
        directory "/var/cache/bind"; 

        recursion no; 
        listen-on port 53 { 10.10.0.72; }; 

        dnssec-validation auto; 

        auth-nxdomain no;    # conform to RFC1035 
        listen-on-v6 { any; }; 
}; 

I will define "allow-transfer" in "named.conf.local" individually in every zone difinition. I will edit the "named.conf.local". It looks like below.

# Master DNS (Authoritative DNS) server

zone "dizigo.shop" {
    type master;
    file "/etc/bind/zones/db.dizigo.shop";
    allow-transfer { 10.10.0.99; 10.10.0.39; };
};
zone "10.10.in-addr.arpa" {
    type master;
    file "/etc/bind/zones/db.10.10";
    allow-transfer { 10.10.0.99; 10.10.0.39; };
};

# Slave DNS (Authoritative DNS) servers 

zone "dizigo.shop" {
    type slave;
    file "db.dizigo.shop";
    masters { 10.10.0.72; };
};
zone "10.10.in-addr.arpa" {
    type slave;
    file "db.10.10";
    masters { 10.10.0.72; };
};

In above, I defined "forward zone" and "reverse zone". (Please this does not mean zone file) I suppose the one of 10.10.0.0/16 ip addresses will be mapped with Domain. In this file, It show how many zone file are existed and the each properties. I wrote 2 types of configuration for master and slave. In this "master", I can define "allow-transfer { 10.10.0.99; 10.10.0.39; };" in each zone definition. (Even if I will explain later in this post) In "slave", I can define "masters" as the source.

I will locate the zone file under "/etc/bind/zones". If you do not have zone directory, I need to create before.

# mkdir -r /etc/bind/zones

After these configurations, I can check the configuration is correct or not.

# service bind9 restart

# named-checkconf named.conf.local

named-checkconf

 

3. Createing the Forward and reverse zone files.

 

Under the "/etc/bind" directory, there is the sample file for these.

# Forward zone file sample

root@ns1:/etc/bind# cat /etc/bind/db.local
$TTL    604800
@       IN      SOA     localhost. root.localhost. (
                              2         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      localhost.
@       IN      A       127.0.0.1
@       IN      AAAA    ::1

# Reverse zone file sample 

root@ns1:/etc/bind# cat /etc/bind/db.127
$TTL    604800
@       IN      SOA     localhost. root.localhost. (
                              1         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      localhost.
1.0.0   IN      PTR     localhost.

I will copy and edit this files for my zone file. This step is depends on your environments. It will be different from me

# cp db.local /etc/bind/zones/db.dizigo.shop

# cp db.127 /etc/bind/zones/db.10.10

Open the forward zone file and edit at first. It looks like below.

$TTL    60

@       IN      SOA     ns1.dizigo.shop admin.dizigo.shop. (

                              3         ; Serial

                         604800         ; Refresh

                          86400         ; Retry

                        2419200         ; Expire

                         604800 )       ; Negative Cache TTL

 

; name servers - NS records

       IN      NS      ns1.dizigo.shop.

       IN      NS      ns2.dizigo.shop.

       IN      NS      ns3.dizigo.shop.

 

; name servers - A records

ns1.dizigo.shop.       IN     A    10.10.0.72

ns2.dizigo.shop.       IN     A    10.10.0.99

ns3.dizigo.shop.       IN     A    10.10.0.39

 

; sample - A records

www.dizigo.shop.       IN     A    10.128.100.101

ftp.dizigo.shop.       IN     A    10.128.200.101 

I edit the TTL time for caching. If there is the caching DNS server in front of these authoritative DNS servers, the Caching server does not ask again during this time. I will adjust for 60 seconds. Serail number is increased. Every time, I edit zone file, I have to increase this number. This number is used for the slave servers to determince download zone file or not. I added all of name servers in end of SOA field.  For reverse zone file, it is similar with forward zone file. It looks like below.

$TTL    60
@       IN      SOA      ns1.dizigo.shop. admin.dizigo.shop. (
                              2         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL

; name servers - NS records
       IN      NS      ns1.dizigo.shop.
       IN      NS      ns2.dizigo.shop.
       IN      NS      ns3.dizigo.shop.

; PTR Records
72.0      IN   PTR  ns1.dizigo.shop.
99.0      IN   PTR  ns2.dizigo.shop.
39.0      IN   PTR  ns3.dizigo.shop.

Most of values are same. Add all of name servers end of SOA field, then add PTR records. After all of these, I can check my configuration.

# named-checkconf

# named-checkzone dizigo.shop ./zones/db.dizigo.shop

zone dizigo.shop/IN: loaded serial 3

OK

 

# named-checkzone 10.10.in-addr.arpa ./zones/db.10.10

zone 10.10.in-addr.arpa/IN: loaded serial 2

OK

If there are no errors, I will restart the daemon.

# service bind9 restart

 

4. Configuration Secondary(Slave) DNS Server

 

I will do these on ns2 and ns3 in my case. It is almost same as the master DNS server. I have already written above. For "named.conf.options",

# Slave DNS (Authoritative DNS) servers

options { 
        directory "/var/cache/bind"; 

        recursion no; 
        listen-on port 53 { 10.10.0.72; }; 

        dnssec-validation auto; 

        auth-nxdomain no;    # conform to RFC1035 
        listen-on-v6 { any; }; 
}; 

For "named.conf.local",

# Slave DNS (Authoritative DNS) servers 

zone "dizigo.shop" { 
    type slave; 
    file "db.dizigo.shop"; 
    masters { 10.10.0.72; }; 
}; 
zone "10.10.in-addr.arpa" { 
    type slave; 
    file "db.10.10"; 
    masters { 10.10.0.72; }; 
}; 

In this "named.conf.local", the file field is not a certain path. Now, I have slave DNS servers.

 

5. Verfication the Master and Slave DNS server.

 

Before I verify this. I need to download zone file from master to slave. On slaves, I run this command.

rndc reload
server reload successful


# ls -la /var/cache/bind/
total 24
drwxrwxr-x  2 root bind 4096 Sep 11 19:20 .
drwxr-xr-x 10 root root 4096 Sep 11 08:52 ..
-rw-r--r--  1 bind bind  411 Sep 11 19:12 db.10.10
-rw-r--r--  1 bind bind  420 Sep 11 19:12 db.dizigo.shop
-rw-r--r--  1 bind bind  821 Sep 11 19:20 managed-keys.bind
-rw-r--r--  1 bind bind  512 Sep 11 19:20 managed-keys.bind.jnl

In the /var/cache/bind/, I can see the zone file downloaded. Now I can Domain lookup from remote clients.

# dig +short ns2.dizigo.shop @54.180.126.68
10.10.0.99
# dig +short ns1.dizigo.shop @13.125.70.251
10.10.0.72

 

6. Create Caching DNS server without zone file (Only Forwarding caching DNS server)

 

Now, I create the Caching DNS server in front of Authoritative DNS servers. I will refere this instruction. Most of steps are similar with above. I have already written above. 

# For Caching DNS server

acl "trusted" { 
        10.10.0.72; 
        10.10.0.99; 
        10.10.0.39; 
} 

options { 
        directory "/var/cache/bind"; 

        recursion yes; 
        allow-recursion { trusted; }; 
        listen-on port 53 { 10.10.0.72; }; 
        allow-transfer { 10.10.0.99; 10.10.0.39; }; 
        forwarders { 
                8.8.8.8; 
                8.8.4.4; 
        }; 
};

In the instrucion, there is another term, "allow-query". This is same with "allow-recursion". So In my case I will use again in this post. I need to define "forwarders" which point to DNS server whiech handdle the recursive query. In my case, the authoritative DNS servers are listed in here

At this time, I want to make this Caching server to work as forwarder (This server does not response against the query reqeust itself). So I will add "forward only;" option. Final thing I need to edit is dnssec. In fact, I do not know what this is exactly. Anyway, this part make the server and client more secure. So, the my configuration of "named.conf.opiton" look like below.

acl trusted {

        10.10.0.37;

        178.128.21.101;

        49.174.202.137;

};

options {

        recursion yes;                 # enables resursive queries

        allow-recursion { trusted; };  # allows recursive queries from "trusted" clients

        listen-on port 53 { 10.10.0.37; };   # ns1 private IP address - listen on private network only

        allow-transfer { none; };      # disable zone transfers by default

        forwarders {

               10.10.0.99;

               10.10.0.72;

        };

        forward only;

        dnssec-enable yes;

        dnssec-validation yes;

        auth-nxdomain no;    # conform to RFC1035

        listen-on-v6 { any; };

};

After this configuration, I need to check the configuration with "named-checkconf" and restart bind

# named-checkconf

# service bind9 restart

 

7. Verfication of Caching server (Clean cached DB)

 

In this blog, there is the way to view cahce status. 

# Run Command

# rndc dumpdb -cache

 

# Log messages (Error)

Sep 13 14:38:25 cache kernel: [195574.027929] audit: type=1400 audit(1568385505.800:83): apparmor="DENIED" operation="mknod" profile="/usr/sbin/named" name="/named_dump.db" pid=25682 comm="named" requested_mask="c" denied_mask="c" fsuid=112 ouid=112
Sep 13 14:38:25 cache named[25678]: received control channel command 'dumpdb -cache'
Sep 13 14:38:25 cache named[25678]: could not open dump file 'named_dump.db': permission denied

This error happend due to permission of file location which is created by the command. Therefore, I need to re-define the path for the dump file in the configuration. Please read this instruction.

acl trusted {

        10.10.0.37;

        178.128.21.101;

        49.174.202.137;

};

options {

        recursion yes;                 # enables resursive queries

        allow-recursion { trusted; };  # allows recursive queries from "trusted" clients

        listen-on port 53 { 10.10.0.37; };   # ns1 private IP address - listen on private network only

        allow-transfer { none; };      # disable zone transfers by default

        forwarders {

               10.10.0.99;

               10.10.0.72;

        };

        forward only;

        dnssec-enable yes;

        dnssec-validation yes;

        dump-file "/var/cache/bind/dumps/named_dump.db";

        auth-nxdomain no;    # conform to RFC1035

        listen-on-v6 { any; };

};

"dump-file "/var/cache/bind/dumps/named_dump.db";" is added int the configuration. After then, check configuration and restart. (Please note that the file should be located under /var/cache/bind directory)

# Run Command

# rndc dumpdb -cache

 

# /var/cache/bind/dumps# ls
named_dump.db

I can see the file created. I can also read this file. The result look like below

# cat named_dump.db

;

; Start view _default

;

;

; Cache dump of view '_default' (cache _default)

;

$DATE 20190913145755

; authanswer

www.dizigo.shop.        56      IN A    10.128.100.101

;

; Address database dump

;

; [edns success/4096 timeout/1432 timeout/1232 timeout/512 timeout]

; [plain success/timeout]

;

;

; Unassociated entries

;

;       10.10.0.99 [srtt 232] [flags 00004000] [edns 1/0/0/0/0] [plain 0/0] [udpsize 512] [ttl 1796]

;       10.10.0.72 [srtt 29] [flags 00000000] [edns 0/0/0/0/0] [plain 0/0] [ttl 1796]

;

; Bad cache

;

;

; Start view _bind

;

;

; Cache dump of view '_bind' (cache _bind)

;

$DATE 20190913145755

;

; Address database dump

;

; [edns success/4096 timeout/1432 timeout/1232 timeout/512 timeout]

; [plain success/timeout]

;

;

; Unassociated entries

;

;

; Bad cache

;

; Dump complete

If I want to clean this db and caching. I can run like below. Flush and service restarted are necessary.

# rndc flush

# service bind9 restart

 

8. Create Caching DNS server with zone file (Delegating sub-domain)

 

Please note that I can not delegate other domain. I can only delegate sub-domain. For example, "some-name.origin-domain.com --> some-domain.com" is not possible.  "some-name.origin-domain.com --> some-name.sub-domain.origin-domain.com" is only possible

Because of above, I use another name "ozigo.shop". (So far, I used "dizigo.shop")

 

I will follow this instruction. Caching DNS server can have zone file and handle the query directly. For this, I will do some of changes. First I will remove "forward only;" and "forwarders". Therefore  "named.conf.option" is look like below

acl trusted {

        10.10.0.37;

        178.128.21.101;

        49.174.202.137;

};

options {

        recursion yes;                 # enables resursive queries

        allow-recursion { trusted; };  # allows recursive queries from "trusted" clients

        listen-on port 53 { 10.10.0.37; };   # ns1 private IP address - listen on private network only

        allow-transfer { none; };      # disable zone transfers by default

        dnssec-enable yes;

        dnssec-validation yes;

        dump-file "/var/cache/bind/dumps/named_dump.db";

        auth-nxdomain no;    # conform to RFC1035

        listen-on-v6 { any; };

};

And then, I need other configuration file and zone file, "named.conf.local" and "zone file included sub-domain"

# cat named.conf.local

zone "ozigo.shop" {

    type master;

    file "/etc/bind/zones/db.ozigo.shop";

};

I used "$ORIGIN" term to seperate zone between ozigo.shop and ns.ozigo.shop. The red text show how to delegate sub-domain reqursion. The request query for "ns.ozigo.shop" will be sent to "ns1.ns.ozigo.shop" which has 10.10.0.72 IP address.  The authoritative DNS which has zone file will be like below.

root@cache:/var/cache/bind/zones# cat db.crenet.com
$ORIGIN crenet.com.
$TTL    10
@       IN      SOA     crenet.com. admin.crenet.com. (
                              3         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
        IN      NS      ns1.crenet.com.
ns1.crenet.com. IN A 10.10.0.204

;
www.crenet.com. IN CNAME www.g.crenet.com.

$ORIGIN g.crenet.com.
@       IN      NS      ns1.g.crenet.com.
        IN      NS      ns2.g.crenet.com.
ns1.g.crenet.com. IN A 10.10.0.124
ns2.g.crenet.com. IN A 10.10.0.225

# cat zones/db.ns.ozigo.shop

$TTL    60

@       IN      SOA     ns1.ns.ozigo.shop. admin.ns.ozigo.shop. (

                              3         ; Serial

                         604800         ; Refresh

                          86400         ; Retry

                        2419200         ; Expire

                         604800 )       ; Negative Cache TTL

; name servers - NS records

       IN      NS      ns1.ns.ozigo.shop.

; name servers - A records

ns1.ns.ozigo.shop.       IN     A    10.10.0.72

; sample - A records

recursion.ns.ozigo.shop.  IN     A    200.200.200.200

My final goal is looking up "recursion.ozigo.shop". When I try to dig from remote client, the result should be like below.

# dig recursion.ns.ozigo.shop @54.180.154.199

; <<>> DiG 9.11.3-1ubuntu1.8-Ubuntu <<>> recursion.ns.ozigo.shop @54.180.154.199

;; global options: +cmd

;; Got answer:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46798

;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2

;; OPT PSEUDOSECTION:

; EDNS: version: 0, flags:; udp: 4096

;; QUESTION SECTION:

;recursion.ns.ozigo.shop.       IN      A

;; ANSWER SECTION:

recursion.ns.ozigo.shop. 60     IN      A       200.200.200.200

;; AUTHORITY SECTION:

ns.ozigo.shop.          60      IN      NS      ns1.ns.ozigo.shop.

;; ADDITIONAL SECTION:

ns1.ns.ozigo.shop.      60      IN      A       10.10.0.72

;; Query time: 104 msec

;; SERVER: 54.180.154.199#53(54.180.154.199)

;; WHEN: Fri Sep 13 20:31:49 UTC 2019

;; MSG SIZE  rcvd: 102

 

9. TroubleShooting.

 

When I can meet some errors like below during checking zone file configuration in cache server.

# named-checkzone crenet.com db.crenet.com

zone crenet.com/IN: getaddrinfo(ns1.g.crenet.com) failed: Temporary failure in name resolution

zone crenet.com/IN: getaddrinfo(ns2.g.crenet.com) failed: Temporary failure in name resolution

zone crenet.com/IN: loaded serial 3

OK

In my case, I update /etc/resolv.conf file like below. I update the nameserver with my local private IP address.

# cat /etc/resolv.conf  

nameserver 10.10.0.204

 

Reference

 

[ 1 ] https://www.digitalocean.com/community/tutorials/how-to-configure-bind-as-a-private-network-dns-server-on-ubuntu-18-04

[ 2 ] https://kifarunix.com/configure-bind-as-slave-dns-server-on-ubuntu-18-04/

[ 3 ] https://help.fasthosts.co.uk/app/answers/detail/a_id/1276/~/what-is-recursive-dns-and-why-is-it-not-recommended%3F

[ 4 ] https://www.slashroot.in/difference-between-iterative-and-recursive-dns-query

[ 5 ] https://help.fasthosts.co.uk/app/answers/detail/a_id/1276/~/what-is-recursive-dns-and-why-is-it-not-recommended%3F

[ 6 ] https://www.digitalocean.com/community/tutorials/how-to-configure-bind-as-a-caching-or-forwarding-dns-server-on-ubuntu-14-04

[ 7 ] https://linuxconfig.org/how-to-view-and-clear-bind-dns-server-s-cache-on-linux 

[ 8 ] https://bugzilla.redhat.com/show_bug.cgi?id=112350

[ 9 ] http://www.zytrax.com/books/dns/ch9/delegate.html

 

How to install self-signed certification on Windows 2012 R2 for RDP?


Recently, I have some issue about the RDP security. I try to find out how to use my own certification. Please note that it is not recommend that I use self-signed certification. Because it can make more complex trouble. However, I do not have any certification. So I will use self-signed certification for this post.


1. Pre-requisite


Before I start this post. I need to prepare the self-signed certification. In this post, I will write how to create certification with openssl. In addition, I need to merge and covert from "cert (crt)" to "pfx". In windows, the matched private key is necessary according to certification which I want to insert. 


# create CSR (Certificate Signing Request) file

openssl req -new -key crenet-pri.pem -out crenet.csr


# create certificate file

openssl x509 -req -days 365 -in crenet.csr -signkey crenet-pri.pem -out crenet.crt


# create "pfx" file 

openssl pkcs12 -export -in crenet.crt -inkey crenet-pri.pem -out crenet.pfx


2. Install certification feature and Import certificate file.


Run "mmc" and open the console. In here, I can install and configure the certification.



There is nothing at first. I need to install the certification. 



I need to follow "File > Add/Remove Snap-ins"



And choose the what I want to install. In my case, Certificates is chosen. After "Add the Certificate for Snap-in". I can see the menu like below. Select "Computer account".



Select "Local computer"



After finishing the above steps, I can see the "Certificates" category on the left of side. In "Certificates > Personal > All Tasks > Import", I can see my self-signed certificate.



Now, I can start the "Certificate Import Wizard". Click "Next"



There is the form to insert the path for certificate which is the "pfx" file.



Input the optional values if I used the values.



Select the location which the certificate is located in. In this case, "Personal" is used.



Now I can check all of information.



Click Finish. I can check the certification which is located in Personal like below.



Now, I have done to insert my certificate.


3. Check the certification status and activate the certification.


After installation and import process above, I can check the detail of certification which is installed with "double click".  If it is status is good. I can see the comment "You have a private key that corresponds to this certificate".



Now, self-signed certification is imported with correct steps and status. Now, I need to check "Thumbprint" to activate and covert this certification from default. In Details, I can see the "Thumbprint" like below.




This value of "Thumbprint" is necessary. This value is used with command line below. There are two types of command. In my case, I will use "Command mode"


# Command mode 

wmic /namespace:\\root\cimv2\TerminalServices PATH Win32_TSGeneralSetting Set SSLCertificateSHA1Hash="THUMBPRINT" 


# Powershell mode

$path = (Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -Filter "TerminalName='RDP-tcp'").__path Set-WmiInstance -Path $path -argument @{SSLCertificateSHA1Hash="THUMBPRINT"}


In the CMD, I can run like below and I will confirm that "Update is successful".



4. Access the Remote Desktop

 

Now, I will access and I can confirm the certification is changed like below.


 

Basically, RDP is encrypted by TLS. With the steps above. It is more customized.



I can see the TLS handshake by the wireshark packets.


5. (Optional) Enforce the RDP data and connection encryption level.


In this post. there are several steps to make more secure RDP connection. In the middle of contents, "Local Group Policy Editor" are used to enhance the security. Run "gpedit.msc" at first.



In "Computer Configuration > Administrative Templates > Windows Components > Remote Desktop Services > Remote Desktop Session Host > Security", there are several parameter which I have to change.


1. Set Client Connection Encryption Level (Enable/High Level)

2. Require Secure RPC communication. (Enable)

3. Require Use of Specific Security Layer for Remote (RDP) connections. (Enable/SSL)

4. Require user authentication for remote connections by using Network Level Authentication (Enable)



Reference 


[ 1 ] https://www.geocerts.com/support/how-to-export-import-ssl-certificate-between-windows-servers 

[ 2 ] https://www.youtube.com/watch?v=qDwF0_ax6_w

[ 3 ] http://createnetech.tistory.com/12?category=679927

[ 4 ] https://www.ssl.com/how-to/create-a-pfx-p12-certificate-file-using-openssl/

[ 5 ] https://www.howtogeek.com/175087/how-to-enable-and-secure-remote-desktop-on-windows/ 

How to use etcd (multi-machine cluster TLS/SSL security mode) in Ubuntu?


From this post, I run multi-machine cluster basic mode. Now, I will run multi-machine cluster with TLS/SSL security. I am not the security engineer. I am not friendly about TLS/SSL concepts. I studied about key and chain concept before, however it still difficult to understand it. In this documentation, there are 2 things required,  a unique key pair (member.crt, member.key) and shared cluster CA certificate (ca.crt). In this post, I address how to create these.


1. Overview the command for multi-machine cluster with TLS/SSL.


From this documentation, the commands are look like below.


etcd --name infra0 --initial-advertise-peer-urls https://172.22.0.96:2380 \

  --listen-peer-urls https://172.22.0.96:2380 \

  --listen-client-urls https://172.22.0.96:2379,https://127.0.0.1:2379 \

  --advertise-client-urls https://172.22.0.96:2379 \

  --initial-cluster-token etcd-cluster-1 \

  --initial-cluster infra0=https://172.22.0.96:2380,infra1=https://172.22.0.33:2380,infra2=https://172.22.0.133:2380 \

  --initial-cluster-state new \

  --client-cert-auth --trusted-ca-file=/path/to/ca-client.crt \

  --cert-file=/path/to/infra0-client.crt --key-file=/path/to/infra0-client.key \

  --peer-client-cert-auth --peer-trusted-ca-file=ca-peer.crt \

  --peer-cert-file=/path/to/infra0-peer.crt --peer-key-file=/path/to/infra0-peer.key


etcd --name infra1 --initial-advertise-peer-urls https://172.22.0.33:2380 \

  --listen-peer-urls https://172.22.0.33:2380 \

  --listen-client-urls https://172.22.0.33:2379,https://127.0.0.1:2379 \

  --advertise-client-urls https://172.22.0.33:2379 \

  --initial-cluster-token etcd-cluster-1 \

  --initial-cluster infra0=https://172.22.0.96:2380,infra1=https://172.22.0.33:2380,infra2=https://172.22.0.133:2380 \

  --initial-cluster-state new \

  --client-cert-auth --trusted-ca-file=/path/to/ca-client.crt \

  --cert-file=/path/to/infra1-client.crt --key-file=/path/to/infra1-client.key \

  --peer-client-cert-auth --peer-trusted-ca-file=ca-peer.crt \

  --peer-cert-file=/path/to/infra1-peer.crt --peer-key-file=/path/to/infra1-peer.key


etcd --name infra2 --initial-advertise-peer-urls https://172.22.0.133:2380 \

  --listen-peer-urls https://172.22.0.133:2380 \

  --listen-client-urls https://172.22.0.133:2379,https://127.0.0.1:2379 \

  --advertise-client-urls https://172.22.0.133:2379 \

  --initial-cluster-token etcd-cluster-1 \

  --initial-cluster infra0=https://172.22.0.96:2380,infra1=https://172.22.0.33:2380,infra2=https://172.22.0.133:2380 \

  --initial-cluster-state new \

  --client-cert-auth --trusted-ca-file=/path/to/ca-client.crt \

  --cert-file=/path/to/infra2-client.crt --key-file=/path/to/infra2-client.key \

  --peer-client-cert-auth --peer-trusted-ca-file=ca-peer.crt \

  --peer-cert-file=/path/to/infra2-peer.crt --peer-key-file=/path/to/infra2-peer.key 


From command line above, there is something unknown like below. I need certificate. However, I do not know how and what can I obtain these.


  --client-cert-auth --trusted-ca-file=/path/to/ca-client.crt \

  --cert-file=/path/to/infra2-client.crt --key-file=/path/to/infra2-client.key \

  --peer-client-cert-auth --peer-trusted-ca-file=ca-peer.crt \

  --peer-cert-file=/path/to/infra2-peer.crt --peer-key-file=/path/to/infra2-peer.key  


"cfssl" can do for these. In this Git link, there are introduction about "cfssl" like below.


This demonstrates using Cloudflare's cfssl to easily generate certificates for an etcd cluster. 


2. Download and install the "cfssl"


In this documentation, there are installation guide and usage


mkdir ~/bin

curl -s -L -o ~/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64

curl -s -L -o ~/bin/cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64

chmod +x ~/bin/{cfssl,cfssljson} 

export PATH=$PATH:~/bin 


It is so simple. I verify the version.


# cfssl version

Version: 1.2.0

Revision: dev

Runtime: go1.6


3. Create root certificate (CA).


In the command, there are 2 root certificate, ca-client.crt and ca-peer.crt. It will be shared between all hosts. Thus, I create these certificate on single host and copy into others. To create root certificate, I need 2 files, "config.json" and "csr.json". The contents is here.


# vi ca-client-config.json

{

  "signing": {

    "default": {

        "usages": [

          "signing",

          "key encipherment",

          "server auth",

          "client auth"

        ],

        "expiry": "8760h"

    }

  }

}


# vi ca-client-csr.json

{ "CN": "CA Client", "key": { "algo": "ecdsa", "size": 384 }, "names": [ { "O": "Honest Achmed's Used Certificates", "OU": "Hastily-Generated Values Divison", "L": "San Francisco", "ST": "California", "C": "US" } ] }


I create "ca-client-config.json" and "ca-client-csr.json" for ca-client certificate. I have to create more for ca-peer certificate. CN name should be different.


# vi ca-peer-config.json

{

  "signing": {

    "default": {

        "usages": [

          "signing",

          "key encipherment",

          "server auth",

          "client auth"

        ],

        "expiry": "8760h"

    }

  }

}


# vi ca-peer-csr.json

{ "CN": "CA Peer", "key": { "algo": "ecdsa", "size": 384 }, "names": [ { "O": "Honest Achmed's Used Certificates", "OU": "Hastily-Generated Values Divison", "L": "San Francisco", "ST": "California", "C": "US" } ] }


Now, I can generate with files above. Please, note that I will obtain some files which is named "ca.csr", "ca-key.pem" and "ca.pem"


# cfssl gencert -initca ca-client-csr.json | cfssljson -bare ca-client -

# cfssl gencert -initca ca-peer-csr.json | cfssljson -bare ca-peer -


I can verify this is normally good or not. 


# openssl x509 -noout -text -in ca-client.pem

# openssl x509 -noout -text -in ca-peer.pem


It's good. I can generate intermediate certification with this certificate. Therefore I need to copy these files into other hosts. I move files on each directory like below. (I create these directory on every hosts)


# mkdir ~/cert/clientm

# cp ca-client* ~/cert/client/

# ls ~/cert/client/

ca-client-key.pem ca-client.pem ca-client-config.json


# mkdir ~/cert/peer

# cp ca-peer* ~/cert/peer/

# ls ~/cert/peer/

ca-peer-key.pem  ca-peer.pem 

 

In this documentation, there are several security models. Example 2 (Red) and Example 3(Blue) are matched with the command above.


etcd --name infra0 --initial-advertise-peer-urls https://172.22.0.96:2380 \

  --listen-peer-urls https://172.22.0.96:2380 \

  --listen-client-urls https://172.22.0.96:2379,https://127.0.0.1:2379 \

  --advertise-client-urls https://172.22.0.96:2379 \

  --initial-cluster-token etcd-cluster-1 \

  --initial-cluster infra0=https://172.22.0.96:2380,infra1=https://172.22.0.33:2380,infra2=https://172.22.0.133:2380 \

  --initial-cluster-state new \

  --client-cert-auth --trusted-ca-file=/path/to/ca-client.crt \

  --cert-file=/path/to/infra0-client.crt --key-file=/path/to/infra0-client.key \

  --peer-client-cert-auth --peer-trusted-ca-file=ca-peer.crt \

  --peer-cert-file=/path/to/infra0-peer.crt --peer-key-file=/path/to/infra0-peer.key 


At first, In example 2, I need server to run "etcd" and I need client certificate to get response. And second, In example 3, I need peer certificate to communicate between hosts.


4. Create server, client and peer certificate.


Look at this post, there are way to generate each certificate. I create server certificate. To create, I need to "server.json" file. In this Git, there are sample JSON file. For server.json, hosts information are most important.


IP's currently in the config should be replaced/added with IP addresses of each cluster node, please note 127.0.0.1 is always required for loopback  


# cat server.json

{

  "CN": "infra0-client",

  "hosts": [

    "172.22.0.96",

    "127.0.0.1"

  ],

  "key": {

    "algo": "ecdsa",

    "size": 384

  },

  "names": [

    {

      "O": "autogenerated",

      "OU": "etcd cluster",

      "L": "the internet"

    }

  ]

}


# cat server.json

{

  "CN": "infra1-client",

  "hosts": [

    "172.22.0.33",

    "127.0.0.1"

  ],

  "key": {

    "algo": "ecdsa",

    "size": 384

  },

  "names": [

    {

      "O": "autogenerated",

      "OU": "etcd cluster",

      "L": "the internet"

    }

  ]

}


# cat server.json { "CN": "infra2-client", "hosts": [ "172.22.0.133", "127.0.0.1" ], "key": { "algo": "ecdsa", "size": 384 }, "names": [ { "O": "autogenerated", "OU": "etcd cluster", "L": "the internet" } ] }


I will generate server certificate. Please note that the command above use the name "infra-client", however, this is server certification, it is not client certificate.


# cfssl gencert -ca=client/ca-client.pem -ca-key=client/ca-client-key.pem -config=client/ca-client-config.json -profile=server server.json | cfssljson -bare infra0-client

# mv infra0-client* client/


# cfssl gencert -ca=client/ca-client.pem -ca-key=client/ca-client-key.pem -config=client/ca-client-config.json -profile=server server.json | cfssljson -bare infra1-client

# mv infra1-client* client/


# cfssl gencert -ca=client/ca-client.pem -ca-key=client/ca-client-key.pem -config=client/ca-client-config.json -profile=server server.json | cfssljson -bare infra2-client

# mv infra2-client* client/


"-profile=server" option makes server certificate. Next, I create the peer certificate. Also I need "peer.json" file. This file is similar with "server.json". However, CommonName (CN) should be different.


# cat peer.json

{

  "CN": "infra0-peer",

  "hosts": [

    "172.22.0.96",

    "127.0.0.1"

  ],

  "key": {

    "algo": "ecdsa",

    "size": 384

  },

  "names": [

    {

      "O": "autogenerated",

      "OU": "etcd cluster",

      "L": "the internet"

    }

  ]

}


# cat peer.json

{

  "CN": "infra1-peer",

  "hosts": [

    "172.22.0.33",

    "127.0.0.1"

  ],

  "key": {

    "algo": "ecdsa",

    "size": 384

  },

  "names": [

    {

      "O": "autogenerated",

      "OU": "etcd cluster",

      "L": "the internet"

    }

  ]

}


# cat peer.json { "CN": "infra2-peer", "hosts": [ "172.22.0.133", "127.0.0.1" ], "key": { "algo": "ecdsa", "size": 384 }, "names": [ { "O": "autogenerated", "OU": "etcd cluster", "L": "the internet" } ] }


I generate peer certificate with peer.json file above. "-profile=peer" is adopted at this time.


# cfssl gencert -ca=peer/ca-peer.pem -ca-key=peer/ca-peer-key.pem -config=peer/ca-peer-config.json -profile=peer peer.json | cfssljson -bare infra0-peer

# mv infra0-peer* peer/


# cfssl gencert -ca=peer/ca-peer.pem -ca-key=peer/ca-peer-key.pem -config=peer/ca-peer-config.json -profile=peer peer.json | cfssljson -bare infra1-peer

# mv infra1-peer* peer/


# cfssl gencert -ca=peer/ca-peer.pem -ca-key=peer/ca-peer-key.pem -config=peer/ca-peer-config.json -profile=peer peer.json | cfssljson -bare infra2-peer

# mv infra2-peer* peer/


I create server certificate and peer certificate. Therefore, I can run "etcd" with both certificate. However, I need client certificate to obtain response. I will use same root certificate of the server. I need "client.json" file.


# cat client.json { "CN": "infra0", "hosts": [""], "key": { "algo": "ecdsa", "size": 384 }, "names": [ { "O": "autogenerated", "OU": "etcd cluster", "L": "the internet" } ] }


# cat client.json
{
  "CN": "infra1",
  "hosts": [""],
  "key": {
    "algo": "ecdsa",
    "size": 384
  },
  "names": [
    {
      "O": "autogenerated",
      "OU": "etcd cluster",
      "L": "the internet"
    }
  ]
}

# cat client.json
{
  "CN": "infra2",
  "hosts": [""],
  "key": {
    "algo": "ecdsa",
    "size": 384
  },
  "names": [
    {
      "O": "autogenerated",
      "OU": "etcd cluster",
      "L": "the internet"
    }
  ]
}


I generate peer certificate with client.json file above. "-profile=client" is adopted at this time.


# cfssl gencert -ca=client/ca-client.pem -ca-key=client/ca-client-key.pem -config=client/ca-client-config.json -profile=client client.json | cfssljson -bare infra0


# cfssl gencert -ca=client/ca-client.pem -ca-key=client/ca-client-key.pem -config=client/ca-client-config.json -profile=client client.json | cfssljson -bare infra1


# cfssl gencert -ca=client/ca-client.pem -ca-key=client/ca-client-key.pem -config=client/ca-client-config.json -profile=client client.json | cfssljson -bare infra2


5. Run etcd in security mode.


I ready all certificate to run in security mode. Final command looks like below.


etcd --name infra0 --initial-advertise-peer-urls https://172.22.0.96:2380 \

  --listen-peer-urls https://172.22.0.96:2380 \

  --listen-client-urls https://172.22.0.96:2379,https://127.0.0.1:2379 \

  --advertise-client-urls https://172.22.0.96:2379 \

  --initial-cluster-token etcd-cluster-1 \

  --initial-cluster infra0=https://172.22.0.96:2380,infra1=https://172.22.0.33:2380,infra2=https://172.22.0.133:2380 \

  --initial-cluster-state new \

  --client-cert-auth --trusted-ca-file=client/ca-client.pem \

  --cert-file=client/infra0-client.pem --key-file=client/infra0-client-key.pem \

  --peer-client-cert-auth --peer-trusted-ca-file=peer/ca-peer.pem \

  --peer-cert-file=peer/infra0-peer.pem --peer-key-file=peer/infra0-peer-key.pem


etcd --name infra1 --initial-advertise-peer-urls https://172.22.0.33:2380 \

  --listen-peer-urls https://172.22.0.33:2380 \

  --listen-client-urls https://172.22.0.33:2379,https://127.0.0.1:2379 \

  --advertise-client-urls https://172.22.0.33:2379 \

  --initial-cluster-token etcd-cluster-1 \

  --initial-cluster infra0=https://172.22.0.96:2380,infra1=https://172.22.0.33:2380,infra2=https://172.22.0.133:2380 \

  --initial-cluster-state new \

  --client-cert-auth --trusted-ca-file=client/ca-client.pem \

  --cert-file=client/infra1-client.pem --key-file=client/infra1-client-key.pem \

  --peer-client-cert-auth --peer-trusted-ca-file=peer/ca-peer.pem \

  --peer-cert-file=peer/infra1-peer.pem --peer-key-file=peer/infra1-peer-key.pem


etcd --name infra2 --initial-advertise-peer-urls https://172.22.0.133:2380 \

  --listen-peer-urls https://172.22.0.133:2380 \

  --listen-client-urls https://172.22.0.133:2379,https://127.0.0.1:2379 \

  --advertise-client-urls https://172.22.0.133:2379 \

  --initial-cluster-token etcd-cluster-1 \

  --initial-cluster infra0=https://172.22.0.96:2380,infra1=https://172.22.0.33:2380,infra2=https://172.22.0.133:2380 \

  --initial-cluster-state new \

  --client-cert-auth --trusted-ca-file=client/ca-client.pem \

  --cert-file=client/infra2-client.pem --key-file=client/infra2-client-key.pem \

  --peer-client-cert-auth --peer-trusted-ca-file=peer/ca-peer.pem \

  --peer-cert-file=peer/infra2-peer.pem --peer-key-file=peer/infra2-peer-key.pem


At this time, I do not know command line to put and get. However, there is sample curl command in this documentation (Example 2).


curl --cacert client/ca-client.pem --cert infra0.pem --key infra0-key.pem -L https://172.22.0.96:2379/v2/keys/foo -XPUT -d value=bar -v 


# curl --cacert client/ca-client.pem --cert infra0.pem --key infra0-key.pem -L https://172.22.0.96:2379/v2/keys/foo -XPUT -d value=bar -v * Trying 172.22.0.96... * Connected to 172.22.0.96 (172.22.0.96) port 2379 (#0) * found 1 certificates in client/ca-client.pem * found 592 certificates in /etc/ssl/certs * ALPN, offering http/1.1 * SSL connection using TLS1.2 / ECDHE_ECDSA_AES_128_GCM_SHA256 * server certificate verification OK * server certificate status verification SKIPPED * common name: infra0-client (matched) * server certificate expiration date OK * server certificate activation date OK * certificate public key: EC * certificate version: #3 * subject: L=the internet,O=autogenerated,OU=etcd cluster,CN=infra0-client * start date: Fri, 19 Oct 2018 16:34:00 GMT * expire date: Sat, 19 Oct 2019 16:34:00 GMT * issuer: C=US,ST=California,L=San Francisco,O=Honest Achmed's Used Certificates,OU=Hastily-Generated Values Divison,CN=CA Client * compression: NULL * ALPN, server did not agree to a protocol > PUT /v2/keys/foo HTTP/1.1 > Host: 172.22.0.96:2379 > User-Agent: curl/7.47.0 > Accept: */* > Content-Length: 9 > Content-Type: application/x-www-form-urlencoded > * upload completely sent off: 9 out of 9 bytes < HTTP/1.1 201 Created < Content-Type: application/json < X-Etcd-Cluster-Id: e3631873cee60c62 < X-Etcd-Index: 17 < X-Raft-Index: 26 < X-Raft-Term: 47 < Date: Fri, 19 Oct 2018 17:33:13 GMT < Content-Length: 90 < {"action":"set","node":{"key":"/foo","value":"bar","modifiedIndex":17,"createdIndex":17}}


# curl --cacert client/ca-client.pem --cert infra0.pem --key infra0-key.pem -L https://172.22.0.96:2379/v2/keys/foo

{"action":"get","node":{"key":"/foo","value":"bar","modifiedIndex":17,"createdIndex":17}}


I can see the result {"action":"set","node":{"key":"/foo","value":"bar","modifiedIndex":17,"createdIndex":17}}. It's works now.


6. Run automatic certificate mode


So far, I do so many step to run in security mode. It's is not simple. Because of this, etcd offers automatic certificate mode. In this mode, etcd create certificate automatically. "--auto-tls" and "--peer-auto-tls" are replaced instead of part for certificate.


etcd --name infra0 --initial-advertise-peer-urls https://172.22.0.96:2380 \

  --listen-peer-urls https://172.22.0.96:2380 \

  --listen-client-urls https://172.22.0.96:2379,https://127.0.0.1:2379 \

  --advertise-client-urls https://172.22.0.96:2379 \

  --initial-cluster-token etcd-cluster-1 \

  --initial-cluster infra0=https://172.22.0.96:2380,infra1=https://172.22.0.33:2380,infra2=https://172.22.0.133:2380 \

  --initial-cluster-state new \

  --auto-tls \

  --peer-auto-tls


etcd --name infra1 --initial-advertise-peer-urls https://172.22.0.33:2380 \

  --listen-peer-urls https://172.22.0.33:2380 \

  --listen-client-urls https://172.22.0.33:2379,https://127.0.0.1:2379 \

  --advertise-client-urls https://172.22.0.33:2379 \

  --initial-cluster-token etcd-cluster-1 \

  --initial-cluster infra0=https://172.22.0.96:2380,infra1=https://172.22.0.33:2380,infra2=https://172.22.0.133:2380 \

  --initial-cluster-state new \

  --auto-tls \

  --peer-auto-tls


etcd --name infra2 --initial-advertise-peer-urls https://172.22.0.133:2380 \

  --listen-peer-urls https://172.22.0.133:2380 \

  --listen-client-urls https://172.22.0.133:2379,https://127.0.0.1:2379 \

  --advertise-client-urls https://172.22.0.133:2379 \

  --initial-cluster-token etcd-cluster-1 \

  --initial-cluster infra0=https://172.22.0.96:2380,infra1=https://172.22.0.33:2380,infra2=https://172.22.0.133:2380 \

  --initial-cluster-state new \

  --auto-tls \

  --peer-auto-tls


In Example 4 of this documentation, "curl -k https://127.0.0.1:2379/v2/keys/foo -Xput -d value=bar -v" command is used. (This site also useful)


# curl -k -X "PUT" https://127.0.0.1:2379/v2/keys/seoul -d value='seoul'

{"action":"set","node":{"key":"/seoul","value":"seoul","modifiedIndex":18,"createdIndex":18}}


# curl -k https://127.0.0.1:2379/v2/keys/seoul

{"action":"get","node":{"key":"/seoul","value":"seoul","modifiedIndex":18,"createdIndex":18}}


# curl -k -X "DELETE" https://127.0.0.1:2379/v2/keys/seoul


Now, I can use with simple model.


Reference


[ 1 ] http://createnetech.tistory.com/16

[ 2 ] http://createnetech.tistory.com/14

[ 3 ] http://createnetech.tistory.com/12

[ 4 ] https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/clustering.md

[ 5 ] https://coreos.com/etcd/docs/latest/op-guide/security.html

[ 6 ] https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/security.md

[ 7 ] https://coreos.com/os/docs/latest/generate-self-signed-certificates.html

[ 8 ] https://github.com/etcd-io/etcd/tree/master/hack/tls-setup

[ 9 ] https://coreos.com/etcd/docs/latest/demo.html

[ 10 ] https://www.mkyong.com/web/curl-put-request-examples/

How to use etcd (multi-machine cluster basic mode) in Ubuntu?


Recently, I have found interesting solution. it is called as etcd. It is Distributed reliable key-value store. What is the key-value store?. It is similar with dictionary in Python. This etcd make dictionary items can be put and get on any hosts. 


1. Prerequesite


The etcd is used for cluster environment. Therefore, I will prepare 3 servers with ubuntu.


infra0     172.22.0.96 infra0.example.com

infra1     172.22.0.33 infra1.example.com

infra2     172.22.0.133 infra2.example.com 


2. Get etcd release 


I have ubuntu server. I need the etcd release for ubuntu. In this documentation. There is installation guide for Linux.


ETCD_VER=v3.3.10


# choose either URL

GOOGLE_URL=https://storage.googleapis.com/etcd

GITHUB_URL=https://github.com/etcd-io/etcd/releases/download

DOWNLOAD_URL=${GOOGLE_URL}


rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz

rm -rf /tmp/etcd-download-test


mkdir -p /tmp/etcd-download-test

curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz

tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download-test --strip-components=1

rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz


/tmp/etcd-download-test/etcd --version

ETCDCTL_API=3 /tmp/etcd-download-test/etcdctl version 


I will run this command on every hosts. "/tmp" directory is used in command above. However, In my case, I will change the directory "/home/ubunut"


# mkdir -p /home/ubuntu/etcd-download-test

# curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o 

# /home/ubuntu/etcd-${ETCD_VER}-linux-amd64.tar.gz

# tar xzvf /home/ubuntu/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /home/ubuntu/etcd-download-test --strip-components=1

# rm -f /home/ubuntu/etcd-${ETCD_VER}-linux-amd64.tar.gz 


I can check the installation version with both of commands.


/home/ubuntu/etcd-download-test/etcd --version

ETCDCTL_API=3 /home/ubuntu/etcd-download-test/etcdctl version 


# /home/ubuntu/etcd-download-test/etcd --version

etcd Version: 3.3.10

Git SHA: 27fc7e2

Go Version: go1.10.4

Go OS/Arch: linux/amd64


More efficient, I will export the directory in PATH environment.


# export PATH=$PATH:/home/ubuntu/etcd-download-test


# vi /root/.bashrc
PATH=$PATH:/home/ubuntu/etcd-download-test

# source /root/.bashrc


3. Running in multi-machine cluster basic mode


I can run in single standalone mode. The command line usage is here. At first, run in single mode


etcd


I can put and get data. "ETCDCTL_API=3" is important parameter. It should be exist.


# ETCDCTL_API=3 etcdctl put mykey "this is awesome"

OK

# ETCDCTL_API=3 etcdctl get mykey
mykey
this is awesome


Also I can see the result with JSON format like below. If I want to find more example of command usage, look this documentation.


# export ETCDCTL_API=3
# etcdctl --endpoints=localhost:2379 put foo "Hello World!"
OK

# etcdctl --endpoints=localhost:2379 get foo --write-out="json"
{"header":{"cluster_id":14841639068965178418,"member_id":10276657743932975437,"revision":3,"raft_term":2},"kvs":[{"key":"Zm9v","create_revision":3,"mod_revision":3,"version":1,"value":"SGVsbG8gV29ybGQh"}],"count":1}

# etcdctl --endpoints=localhost:2379 get foo
foo
Hello World!


Even if this single mode works, but etcd is more powerful in mult-machin cluster mode. Look this documentation. To run cluster mode, there are 2 things important. IP address to listen and announce and IP address for peer hosts


etcd --name infra0 --initial-advertise-peer-urls http://172.22.0.96:2380 \

  --listen-peer-urls http://172.22.0.96:2380 \

  --listen-client-urls http://172.22.0.96:2379,http://127.0.0.1:2379 \

  --advertise-client-urls http://172.22.0.96:2379 \

  --initial-cluster-token etcd-cluster-1 \

  --initial-cluster infra0=http://172.22.0.96:2380,infra1=http://172.22.0.33:2380,infra2=http://172.22.0.133:2380 \

  --initial-cluster-state new

etcd --name infra1 --initial-advertise-peer-urls http://172.22.0.33:2380 \

  --listen-peer-urls http://172.22.0.33:2380 \

  --listen-client-urls http://172.22.0.33:2379,http://127.0.0.1:2379 \

  --advertise-client-urls http://172.22.0.33:2379 \

  --initial-cluster-token etcd-cluster-1 \

  --initial-cluster infra0=http://172.22.0.96:2380,infra1=http://172.22.0.33:2380,infra2=http://172.22.0.133:2380 \

  --initial-cluster-state new

etcd --name infra2 --initial-advertise-peer-urls http://172.22.0.133:2380 \

  --listen-peer-urls http://172.22.0.133:2380 \

  --listen-client-urls http://172.22.0.133:2379,http://127.0.0.1:2379 \

  --advertise-client-urls http://172.22.0.133:2379 \

  --initial-cluster-token etcd-cluster-1 \

  --initial-cluster infra0=http://172.22.0.96:2380,infra1=http://172.22.0.33:2380,infra2=http://172.22.0.133:2380 \

  --initial-cluster-state new

  

For peer communicate, the 2380 port is used. For data communication, the 2379 port is used. Therefore, "127.0.0.1:2379" is necessary to request to localhost. However, this is not necessary to announce. These command above should be run on each host. After running, I can get the status of clustering.


# ETCDCTL_API=3 etcdctl --endpoints=172.22.0.96:2379,172.22.0.33:2379,172.22.0.133:2379 endpoint health

172.22.0.96:2379 is healthy: successfully committed proposal: took = 2.385219ms

172.22.0.133:2379 is healthy: successfully committed proposal: took = 2.847419ms

172.22.0.33:2379 is healthy: successfully committed proposal: took = 2.292504ms


Now, I have done everything to cluster multi-hosts. In multi-hosts environments, I put data into anywhere, I can get data from anywhere.


ETCDCTL_API=3 etcdctl --endpoints=172.22.0.96:2379 put foo "Hello World!"

OK


ETCDCTL_API=3 etcdctl --endpoints=172.22.0.133:2379 get foo

foo

Hello World!


Finally, I can use the "etcd" little.


 Reference


[ 1 ] https://github.com/etcd-io/etcd

[ 2 ] https://github.com/etcd-io/etcd/releases

[ 3 ] https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/clustering.md

[ 4 ] https://coreos.com/etcd/docs/latest/demo.html

How does create Intermediate certificate with openssl?  


It is difficult to understand this intermediate certificate. I wonder why this intermediate is necessary?. I have found this documentation over Internet


The purpose of using an intermediate CA is primarily for security. The root key can be kept offline and used as infrequently as possible. If the intermediate key is compromised, the root CA can revoke the intermediate certificate and create a new intermediate cryptographic pair. 


I studied about the chain concept. I focused if the encryption with private key of root certificate and decryption with public key of child certificate are possible, reverse versa?. (The answer is "Not Possible"). The reason is to hide the root CA for security. 


1. Prerequisite


This is the default directory structure to generate intermediate certificate.


# mkdir /root/ca


# cd /root/ca

# mkdir certs crl newcerts private

# chmod 700 private

# touch index.txt

# echo 1000 > serial


To generate "Key", "CSR" (Certificate Signing Reqeust) and. CRT (Certificate), I need configuration for each case, In reference documentation, there are 2 types of configuration for Root CA and Intermediate CA. At this time, I need Root CA configuration. It looks like below.


vi /root/ca/openssl.cnf


# OpenSSL root CA configuration file.
# Copy to `/root/ca/openssl.cnf`.

[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir               = /root/ca
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/index.txt
serial            = $dir/serial
RANDFILE          = $dir/private/.rand

# The root key and root certificate.
private_key       = $dir/private/ca.key.pem
certificate       = $dir/certs/ca.cert.pem

# For certificate revocation lists.
crlnumber         = $dir/crlnumber
crl               = $dir/crl/ca.crl.pem
crl_extensions    = crl_ext
default_crl_days  = 30

# SHA-1 is deprecated, so use SHA-2 instead.
default_md        = sha256

name_opt          = ca_default
cert_opt          = ca_default
default_days      = 375
preserve          = no
policy            = policy_strict

[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
# Options for the `req` tool (`man req`).
default_bits        = 2048
distinguished_name  = req_distinguished_name
string_mask         = utf8only

# SHA-1 is deprecated, so use SHA-2 instead.
default_md          = sha256

# Extension to add when the -x509 option is used.
x509_extensions     = v3_ca

[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name
localityName                    = Locality Name
0.organizationName              = Organization Name
organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name
emailAddress                    = Email Address

# Optionally, specify some defaults.
countryName_default             = GB
stateOrProvinceName_default     = England
localityName_default            =
0.organizationName_default      = Alice Ltd
organizationalUnitName_default  =
emailAddress_default            =

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection

[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always

[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning


There are lots of options in there. I can not explain all of things. For the reproduction of this test, I check the directory path at first.


[ CA_default ]

# Directory and file locations.

dir               = /root/ca


In this post, I create "/root/ca" directory before, therefore I do not need to change this value. However, it need to be changed if I want to work on other directory.

 

2. Create root key and root certificate


I generate RSA private key which is most used with "openssl genrsa" command. (Please, note that If there is no option like "-aes256", there is no process to enter the password)


# cd /root/ca

# openssl genrsa -aes256 -out private/ca.key.pem 4096


Enter pass phrase for ca.key.pem: secretpassword

Verifying - Enter pass phrase for ca.key.pem: secretpassword


# chmod 400 private/ca.key.pem


And then, I create Root CA certificate with the Private key which is generated earlier. (In this case, I do not use the CSR). The "-x509" option is the option which is necessary when I create certificate 


# cd /root/ca

# openssl req -config openssl.cnf -key private/ca.key.pem -new -x509 -days 7300 -sha256 -extensions v3_ca -out certs/ca.cert.pem


Enter pass phrase for ca.key.pem: secretpassword

You are about to be asked to enter information that will be incorporated

into your certificate request.

-----

Country Name (2 letter code) [XX]:GB

State or Province Name []:England

Locality Name []:

Organization Name []:Alice Ltd

Organizational Unit Name []:Alice Ltd Certificate Authority

Common Name []:Alice Ltd Root CA

Email Address []:


# chmod 444 certs/ca.cert.pem


In this case, Root CA is not changed for a long time. So "-days 7300" (almost 20 years) is defined. Because of this, the Private key of Root should be secret. I can see more detail information with "verification" command. In the result, I can see the "issuer" and "validity" information. Also I can see the certificate include the Public Key Info.


# openssl x509 -noout -text -in certs/ca.cert.pem

Certificate:

    Data:

        Version: 3 (0x2)

        Serial Number: 

    Signature Algorithm: sha256WithRSAEncryption

        Issuer: C=GB, ST=England, O=Alice Ltd, OU=Alice Ltd Certificate Authority, CN=Alice Ltd Root CA

        Validity

            Not Before: Oct 19 00:53:19 2018 GMT

            Not After : Oct 14 00:53:19 2038 GMT

        Subject: C=GB, ST=England, O=Alice Ltd, OU=Alice Ltd Certificate Authority, CN=Alice Ltd Root CA

        Subject Public Key Info:

            Public Key Algorithm: rsaEncryption

                Public-Key: (4096 bit)

                Modulus:

                Exponent: 65537 (0x10001)

        X509v3 extensions:

            X509v3 Subject Key Identifier:

            X509v3 Authority Key Identifier:

            X509v3 Basic Constraints: critical

                CA:TRUE

            X509v3 Key Usage: critical

                Digital Signature, Certificate Sign, CRL Sign

    Signature Algorithm: sha256WithRSAEncryption


Therefore, I can extract the Public key.


# mkdir public


openssl x509 -pubkey -in certs/ca.cert.pem -noout > public/pub.ca.cert.pem

-----BEGIN PUBLIC KEY-----

Something ................ xxxxxxxxxxxxxxxxxxxxxxx

-----END PUBLIC KEY-----


3. Create intermediate pair


To generate the Intermediate certificate, I need to make sub-directory under the root directory.


mkdir /root/ca/intermediate


# cd /root/ca/intermediate

# mkdir certs crl csr newcerts private

# chmod 700 private

# touch index.txt

# echo 1000 > serial

# echo 1000 > /root/ca/intermediate/crlnumber


"echo 1000 > /root/ca/intermediate/crlnumber" is used for tracking certificate revocation lists. In this post, I do not handle about this. I also need configuration for intermediate certificate. Most of the contents are same with Root's configuration. 5 things are different.


[ CA_default ]

dir               = /root/ca    ==>  /root/ca/intermediate

private_key       = $dir/private/ca.key.pem    ==> $dir/private/intermediate.key.pem

certificate       = $dir/certs/ca.cert.pem    ==> $dir/certs/intermediate.cert.pem

crl               = $dir/crl/ca.crl.pem    ==> $dir/crl/intermediate.crl.pem

policy            = policy_strict    ==> policy_loose


I generate RSA Private key. this key is independent with Root Private key. This intermediate certificate is usually not used for end-point such as the server and client. I think it is kinds of sub-Root certificate. (However, this is one of cases. I can use intermediate certificate on server and client also.)


# cd /root/ca

# openssl genrsa -aes256 -out intermediate/private/intermediate.key.pem 4096


Enter pass phrase for intermediate.key.pem: secretpassword

Verifying - Enter pass phrase for intermediate.key.pem: secretpassword


# chmod 400 intermediate/private/intermediate.key.pem


Now I need to generate certificate signing request (CSR) at this time. During this step, The Common Name must be different. CSR includes several information such as "common Name". I can create certificate without this CSR. (In the Root case, I did not create CSR at that time.


# cd /root/ca

# openssl req -config intermediate/openssl.cnf -new -sha256 -key intermediate/private/intermediate.key.pem -out intermediate/csr/intermediate.csr.pem


Enter pass phrase for intermediate.key.pem: secretpassword

You are about to be asked to enter information that will be incorporated

into your certificate request.

-----

Country Name (2 letter code) [XX]:GB

State or Province Name []:England

Locality Name []:

Organization Name []:Alice Ltd

Organizational Unit Name []:Alice Ltd Certificate Authority

Common Name []:Alice Ltd Intermediate CA

Email Address []:


Now, I will generate intermediate certificate with this CSR. Please, note that I will use root certificate and configuration to create intermediate


# cd /root/ca

# openssl ca -config openssl.cnf -extensions v3_intermediate_ca -days 3650 -notext -md sha256 -in intermediate/csr/intermediate.csr.pem -out intermediate/certs/intermediate.cert.pem

Using configuration from openssl.cnf

Enter pass phrase for /root/ca/private/ca.key.pem:

Check that the request matches the signature

Signature ok

Certificate Details:

        Serial Number: 4096 (0x1000)

        Validity

            Not Before: Oct 19 01:20:29 2018 GMT

            Not After : Oct 16 01:20:29 2028 GMT

        Subject:

            countryName               = GB

            stateOrProvinceName       = England

            organizationName          = Alice Ltd

            organizationalUnitName    = Alice Ltd Certificate Authority

            commonName                = Alice Ltd Intermediate CA

        X509v3 extensions:

            X509v3 Subject Key Identifier:

            X509v3 Authority Key Identifier:

            X509v3 Basic Constraints: critical

                CA:TRUE, pathlen:0

            X509v3 Key Usage: critical

                Digital Signature, Certificate Sign, CRL Sign

Certificate is to be certified until Oct 16 01:20:29 2028 GMT (3650 days)

Sign the certificate? [y/n]:y



1 out of 1 certificate requests certified, commit? [y/n]y

Write out database with 1 new entries

Data Base Updated


# chmod 444 intermediate/certs/intermediate.cert.pem


During creation, I can see the detail information. Also, I can see mote detail with "verification" command.


# #  openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem

Certificate:

    Data:

        Version: 3 (0x2)

        Serial Number: 4096 (0x1000)

    Signature Algorithm: sha256WithRSAEncryption

        Issuer: C=GB, ST=England, O=Alice Ltd, OU=Alice Ltd Certificate Authority, CN=Alice Ltd Root CA

        Validity

            Not Before: Oct 19 01:20:29 2018 GMT

            Not After : Oct 16 01:20:29 2028 GMT

        Subject: C=GB, ST=England, O=Alice Ltd, OU=Alice Ltd Certificate Authority, CN=Alice Ltd Intermediate CA

        Subject Public Key Info:

            Public Key Algorithm: rsaEncryption

                Public-Key: (4096 bit)

                Modulus:

                Exponent: 65537 (0x10001)

        X509v3 extensions:

            X509v3 Subject Key Identifier:

            X509v3 Authority Key Identifier:

            X509v3 Basic Constraints: critical

                CA:TRUE, pathlen:0

            X509v3 Key Usage: critical

                Digital Signature, Certificate Sign, CRL Sign

    Signature Algorithm: sha256WithRSAEncryption


This certificate also include the public key, therefore I can extract the public key from certificate


# mkdir intermediate/public


# openssl x509 -pubkey -in intermediate/certs/intermediate.cert.pem -noout > intermediate/public/pub.intermediate.cert.pem

-----BEGIN PUBLIC KEY-----

Something ........ xxxxxxxxxxxxxxxxxxxxxxxx

-----END PUBLIC KEY-----



4. Verify the intermediate certificate


I obtain "Private key", "CSR" and "Certificate" files for intermediate. I have some question how does this cert guarantee?. "openssl verfify -CAfile" command show intermediate cert is certified by root certificate

 

# openssl verify -CAfile certs/ca.cert.pem intermediate/certs/intermediate.cert.pem

intermediate/certs/intermediate.cert.pem: OK


4-1. [Optional] The relationship between Root Key and Intermediate Key.


Someone can think like me, the intermediate certificate inherit from the root certification. Therefore, I can encrypt with intermediate public key and decrypt with root private key or reverse versa. The answer is "No" (RSA operation error is happend)


# echo "welecom ssl world" > message


[ Intermediate public encrypt + Root private decrypt ]

# openssl rsautl -encrypt -inkey intermediate/public/pub.intermediate.cert.pem -pubin -in message -out encrypted-message

# openssl rsautl -decrypt -inkey private/ca.key.pem -in encrypted-message -out decrypted-message

RSA operation error


[ Root public encrypt + Intermediate private decrypt ]

# openssl rsautl -encrypt -inkey public/pub.ca.cert.pem -pubin -in message -out encrypted-message

# openssl rsautl -decrypt -inkey intermediate/private/intermediate.key.pem -in encrypted-message -out decrypted-message

RSA operation error



5. Create the certificate chain file


In the documentation, there are reason why the chain file is necessary. 


When an application (eg, a web browser) tries to verify a certificate signed by the intermediate CA, it must also verify the intermediate certificate against the root certificate.  


Thus, it is necessary to confirm if the intermediate certificate come from root certificate. To create chain, I will merge both certificate into single file.


# cat intermediate/certs/intermediate.cert.pem certs/ca.cert.pem > intermediate/certs/ca-chain.cert.pem

# chmod 444 intermediate/certs/ca-chain.cert.pem


6. Sign server and client certificates


Before, I do this step. I need to know what is difference between server certificate and client certificate. Before, I write this post, I only consider web server such as Apache. In this Apache case, the server certificate is necessary. Server certificate focus if this server is safe or not. Client certificate focus if my request to the server is safe or not. So usually, client certificate is doing after server certificate. In this post, I will handle server certificate. 


I think this intermediate certificate is kinds of sub-root certificate. So this intermediate should be hidden for the security. (Don't worry, if this intermediate certificate is stolen, I can delete and re-create with Root certificate again) Anyway, I can create certificate for end-point.


# cd /root/ca

# openssl genrsa -aes256 -out intermediate/private/www.example.com.key.pem 2048

# chmod 400 intermediate/private/www.example.com.key.pem


The reason why I use 2048 bit to create RSA key. Usually, the certificate for end-point should be short expiration day. So, 2048 bit is much efficient. After this, I create the CSR with private key. And I use intermediate configuration file to generate. (At this time, it looks like another intermediate certificate). Note that the Common Name cannot be the same as either your root or intermediate certificate.


# cd /root/ca

# openssl req -config intermediate/openssl.cnf -key intermediate/private/www.example.com.key.pem -new -sha256 -out intermediate/csr/www.example.com.csr.pem


Enter pass phrase for www.example.com.key.pem: secretpassword

You are about to be asked to enter information that will be incorporated

into your certificate request.

-----

Country Name (2 letter code) [XX]:US

State or Province Name []:California

Locality Name []:Mountain View

Organization Name []:Alice Ltd

Organizational Unit Name []:Alice Ltd Web Services

Common Name []:www.example.com

Email Address []:


Now, I will create the certificate. Please note, I used "server_cert" option, because I suppose I create certificate for web-server. However if I want the certificate for client, I use "user_cert"


To create a certificate, use the intermediate CA to sign the CSR. If the certificate is going to be used on a server, use the server_cert extension. If the certificate is going to be used for user authentication, use the usr_cert extension. Certificates are usually given a validity of one year, though a CA will typically give a few days extra for convenience. 


# cd /root/ca

# openssl ca -config intermediate/openssl.cnf -extensions server_cert -days 375 -notext -md sha256 -in intermediate/csr/www.example.com.csr.pem -out intermediate/certs/www.example.com.cert.pem

# chmod 444 intermediate/certs/www.example.com.cert.pem


I can verify this certificate. At this time, I do not verify with the certificate of the intermediate. I verify with ca-chain which are generated earlier.


openssl x509 -noout -text -in intermediate/certs/www.example.com.cert.pem

openssl verify -CAfile intermediate/certs/ca-chain.cert.pem intermediate/certs/www.example.com.cert.pem


I will deploy my web server with these certificate and chain. At this time, I do not need to merge again the ca-chain.cert.pem.


ca-chain.cert.pem

www.example.com.key.pem

www.example.com.cert.pem


I compare the configuration. In "-config" option of "openssl ca", it decide the "issuer". Therefore, intermediate's issuer is root and server's issuer is intermediate. In "extension" option, it decide the rule or type of certificate. Becuase of this, the server handle another type of intermediate certificate which is issued by (sub-root) intermediate certificate.



Therefore, the certification does not need to merge at this time. I do test again to check the relationship between intermediate certifications. In the result, I can not encrypt and decrypt. 


# openssl rsautl -encrypt -inkey intermediate/public/pub.www.example.com.cert.pem -pubin -in message -out encrypt-message

# openssl rsautl -decrypt -inkey intermediate/private/intermediate.key.pem -in encrypt-message -out decrypt-message

RSA operation error




Reference 


[ 1 ] https://jamielinux.com/docs/openssl-certificate-authority/index.html#openssl-certificate-authority

[ 2 ] https://jamielinux.com/docs/openssl-certificate-authority/appendix/root-configuration-file.html

[ 3 ] https://www.websecurity.symantec.com/security-topics/client-certificates-vs-server-certificates

How to use ECDSA?


Recently, I have some changes to know about "ECDSA" to signature the messages. I am not the security engineer. So, I can not explain all of things about this. Before, I read about this. I only think about the encryption and decryption. However, "ECDSA" shows another mechanism. Most of the documentations, "ECDSA" uses to sign and verfication. Let's think about RSA case, the RSA focus on "How can the file encrypt and decrypt". Therefore, encrypted-file is created and transferred to the destination. However, the ECDSA case is different. the ECDSA focus on "How can this message confirm to be same with others". Therefore, no encrypted-file is created, but the signature is generated. The destination has already known the message, it is verified with this signature. In this post, I will use "openssl" mainly. 


1. Create the Private key


In ECDSA algorithm, the concept of the private and public key. I can create a private key at first. With the private key, I can generate the signature for the some messages.


# openssl ecparam -genkey -name sect571r1 -out private.pem


Above, there is "name" field which has already defined. With "-list_curves" option, I can check what name is possible. In my case, "sect571r1" is one what I choose.


# openssl ecparam -list_curves

  secp112r1 : SECG/WTLS curve over a 112 bit prime field

  secp112r2 : SECG curve over a 112 bit prime field

  secp128r1 : SECG curve over a 128 bit prime field

  secp128r2 : SECG curve over a 128 bit prime field

  secp160k1 : SECG curve over a 160 bit prime field

  secp160r1 : SECG curve over a 160 bit prime field

  secp160r2 : SECG/WTLS curve over a 160 bit prime field

  secp192k1 : SECG curve over a 192 bit prime field

  secp224k1 : SECG curve over a 224 bit prime field

  secp224r1 : NIST/SECG curve over a 224 bit prime field

  secp256k1 : SECG curve over a 256 bit prime field

  secp384r1 : NIST/SECG curve over a 384 bit prime field

  secp521r1 : NIST/SECG curve over a 521 bit prime field

  prime192v1: NIST/X9.62/SECG curve over a 192 bit prime field

  prime192v2: X9.62 curve over a 192 bit prime field

  prime192v3: X9.62 curve over a 192 bit prime field

  prime239v1: X9.62 curve over a 239 bit prime field

  prime239v2: X9.62 curve over a 239 bit prime field

  prime239v3: X9.62 curve over a 239 bit prime field

  prime256v1: X9.62/SECG curve over a 256 bit prime field

  sect113r1 : SECG curve over a 113 bit binary field

  sect113r2 : SECG curve over a 113 bit binary field

  sect131r1 : SECG/WTLS curve over a 131 bit binary field

  sect131r2 : SECG curve over a 131 bit binary field

  sect163k1 : NIST/SECG/WTLS curve over a 163 bit binary field

  sect163r1 : SECG curve over a 163 bit binary field

  sect163r2 : NIST/SECG curve over a 163 bit binary field

  sect193r1 : SECG curve over a 193 bit binary field

  sect193r2 : SECG curve over a 193 bit binary field

  sect233k1 : NIST/SECG/WTLS curve over a 233 bit binary field

  sect233r1 : NIST/SECG/WTLS curve over a 233 bit binary field

  sect239k1 : SECG curve over a 239 bit binary field

  sect283k1 : NIST/SECG curve over a 283 bit binary field

  sect283r1 : NIST/SECG curve over a 283 bit binary field

  sect409k1 : NIST/SECG curve over a 409 bit binary field

  sect409r1 : NIST/SECG curve over a 409 bit binary field

  sect571k1 : NIST/SECG curve over a 571 bit binary field

  sect571r1 : NIST/SECG curve over a 571 bit binary field

  c2pnb163v1: X9.62 curve over a 163 bit binary field

  c2pnb163v2: X9.62 curve over a 163 bit binary field

  c2pnb163v3: X9.62 curve over a 163 bit binary field

  c2pnb176v1: X9.62 curve over a 176 bit binary field

  c2tnb191v1: X9.62 curve over a 191 bit binary field

  c2tnb191v2: X9.62 curve over a 191 bit binary field

  c2tnb191v3: X9.62 curve over a 191 bit binary field

  c2pnb208w1: X9.62 curve over a 208 bit binary field

  c2tnb239v1: X9.62 curve over a 239 bit binary field

  c2tnb239v2: X9.62 curve over a 239 bit binary field

  c2tnb239v3: X9.62 curve over a 239 bit binary field

  c2pnb272w1: X9.62 curve over a 272 bit binary field

  c2pnb304w1: X9.62 curve over a 304 bit binary field

  c2tnb359v1: X9.62 curve over a 359 bit binary field

  c2pnb368w1: X9.62 curve over a 368 bit binary field

  c2tnb431r1: X9.62 curve over a 431 bit binary field

  wap-wsg-idm-ecid-wtls1: WTLS curve over a 113 bit binary field

  wap-wsg-idm-ecid-wtls3: NIST/SECG/WTLS curve over a 163 bit binary field

  wap-wsg-idm-ecid-wtls4: SECG curve over a 113 bit binary field

  wap-wsg-idm-ecid-wtls5: X9.62 curve over a 163 bit binary field

  wap-wsg-idm-ecid-wtls6: SECG/WTLS curve over a 112 bit prime field

  wap-wsg-idm-ecid-wtls7: SECG/WTLS curve over a 160 bit prime field

  wap-wsg-idm-ecid-wtls8: WTLS curve over a 112 bit prime field

  wap-wsg-idm-ecid-wtls9: WTLS curve over a 160 bit prime field

  wap-wsg-idm-ecid-wtls10: NIST/SECG/WTLS curve over a 233 bit binary field

  wap-wsg-idm-ecid-wtls11: NIST/SECG/WTLS curve over a 233 bit binary field

  wap-wsg-idm-ecid-wtls12: WTLS curvs over a 224 bit prime field

  Oakley-EC2N-3:

        IPSec/IKE/Oakley curve #3 over a 155 bit binary field.

        Not suitable for ECDSA.

        Questionable extension field!

  Oakley-EC2N-4:

        IPSec/IKE/Oakley curve #4 over a 185 bit binary field.

        Not suitable for ECDSA.

        Questionable extension field!

  brainpoolP160r1: RFC 5639 curve over a 160 bit prime field

  brainpoolP160t1: RFC 5639 curve over a 160 bit prime field

  brainpoolP192r1: RFC 5639 curve over a 192 bit prime field

  brainpoolP192t1: RFC 5639 curve over a 192 bit prime field

  brainpoolP224r1: RFC 5639 curve over a 224 bit prime field

  brainpoolP224t1: RFC 5639 curve over a 224 bit prime field

  brainpoolP256r1: RFC 5639 curve over a 256 bit prime field

  brainpoolP256t1: RFC 5639 curve over a 256 bit prime field

  brainpoolP320r1: RFC 5639 curve over a 320 bit prime field

  brainpoolP320t1: RFC 5639 curve over a 320 bit prime field

  brainpoolP384r1: RFC 5639 curve over a 384 bit prime field

  brainpoolP384t1: RFC 5639 curve over a 384 bit prime field

  brainpoolP512r1: RFC 5639 curve over a 512 bit prime field

  brainpoolP512t1: RFC 5639 curve over a 512 bit prime field


2. Create the Public key


Now, I can create the public key with private key.


# openssl ec -in private.pem -pubout -out public.pem

read EC key

writing EC key


3. Sign the message


Before sign the message, I create message file like below.


# cat message

this is test message to check ecdsa with openssl


Now, I sign this message file with "openssl dgst" command.


openssl dgst -sha1 -sign private.pem message > message-sign.bin


In this case, I choose the "sha1" hashing algorithm. (Default, sha256) However, I can choose with more options.


# openssl dgst --help

unknown option '--help'

options are

-c              to output the digest with separating colons

-r              to output the digest in coreutils format

-d              to output debug info

-hex            output as hex dump

-binary         output in binary form

-hmac arg       set the HMAC key to arg

-non-fips-allow allow use of non FIPS digest

-sign   file    sign digest using private key in file

-verify file    verify a signature using public key in file

-prverify file  verify a signature using private key in file

-keyform arg    key file format (PEM or ENGINE)

-out filename   output to filename rather than stdout

-signature file signature to verify

-sigopt nm:v    signature parameter

-hmac key       create hashed MAC with key

-mac algorithm  create MAC (not neccessarily HMAC)

-macopt nm:v    MAC algorithm parameters or key

-engine e       use engine e, possibly a hardware device.

-md4            to use the md4 message digest algorithm

-md5            to use the md5 message digest algorithm

-ripemd160      to use the ripemd160 message digest algorithm

-sha            to use the sha message digest algorithm

-sha1           to use the sha1 message digest algorithm

-sha224         to use the sha224 message digest algorithm

-sha256         to use the sha256 message digest algorithm

-sha384         to use the sha384 message digest algorithm

-sha512         to use the sha512 message digest algorithm

-whirlpool      to use the whirlpool message digest algorithm


4. Verify the message 


I got some signature for message. Now I can my message which I have already gotten with this signature.


# cp message received-message


# openssl dgst -sha1 -verify public.pem -signature message-sign.bin received-message

Verified OK


If I change the contents in received-message file like below.


cat received-message

this is test message to check ecdsa with openssl

more information


# openssl dgst -sha1 -verify public.pem -signature message-sign.bin received-message
Verification Failure


I will get the verification failure


Reference


[ 1 ] https://superuser.com/questions/737574/openssl-ecdsa-sign-and-verify-file

[ 2 ] https://www.openssl.org/docs/man1.0.2/apps/ecparam.html

[ 3 ] https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations

+ Recent posts