User Tools

Site Tools


bdnog11:netsec:bind-implementing-dnssec

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
bdnog11:netsec:bind-implementing-dnssec [2020/01/11 18:40]
Muhammad Moinur Rahman created
bdnog11:netsec:bind-implementing-dnssec [2020/01/14 12:34] (current)
Muhammad Moinur Rahman
Line 9: Line 9:
 **Note:** **Note:**
 In the steps below, we are using  ​ In the steps below, we are using  ​
-<​code>​  +<​code>​groupXX.net : our domain ​  
- groupXX.net : our domain ​  +db.groupXX.net : zone file for the domain  ​
- db.groupXX.net : zone file for the domain  ​+
  
- KgroupXX.net.+005+12345.key/​private = ZSK generated ​  +KgroupXX.net.+005+12345.key/​private = ZSK generated ​  
- KgroupXX.net.+005+67890.key/​private = KSK generated  ​+KgroupXX.net.+005+67890.key/​private = KSK generated  ​
 </​code>​ </​code>​
  
 ===== Steps ===== ===== Steps =====
  
-#####A. DNSSEC Validation.  ​+==== A. DNSSEC Validation ​====
 To allow your recursive DNS servers to validate DNSSEC-signed zones. To allow your recursive DNS servers to validate DNSSEC-signed zones.
  
-1. Update the DNS configuration. ​Add options in the configuration file `named.confto allow DNSSEC.+  - Update the DNS configuration. ​Change ​options in the configuration file ''/​etc/​bind/​named.conf.options'' ​to allow DNSSEC. ​These options must be enabled for this lab to success. This option is required only for LAB purpose and not applicable to real life:\\ <​code>​ 
 +dnssec-validation yes;</​code>​\\ **dnssec-enable** allows named to respond to DNS requests from DNSSEC-aware clients. The default is yes, but is best added in the `named.conf` so you know how to turn it off.\\ If `dnssec-validation` is set to auto, it defaults to the DNS root zone as the trust anchor.\\ If set to yes, a trust anchor must be explicitly configured using the trusted-keys option in ''/​etc/​bind/​named.conf.local''​.\\ <​code>​ 
 +trusted-keys { 
 + . 257 3 8 "​AwEAAeBVrjcVk2End+jIb/​0b5vRZJlQVgh2nspHrcDISSyeslhEiLWUr W9M8Bl/​LrUM0PYbfzkzhwtDayPm3Pz1hJN4cdr/​zXcjgG/​iuOZzXuAK+ GJmhEbM7QS1Tw7YrZLPO8OjqpnSt+vZirfsfCR44KtN9klrx6YFKrFt0 jB6C4gP4S955RyViqLnhNQfW3sq6LIkiUhpVgO82X0GHfe7FFCgqVxG+ 9nmaTu3M6mE9bsiAjuHyxlc+je8Ll12n56cpCMU+f+46hRSSDH6vtMUl sYaP2rvzjn1Mo1txtTLL8K0eXtHPYIaH6mDU8gcfPNFX+7mdECqMbs7B y0JQRykIHtgDTa9pCCIamrpquXvuAIQSAsnZ6ENzpPLRiaLCU92lCrYm +xL2RwQ4i3Y1sbPVfn6D73OWockfGf+Yc6CSxBCk8LvDM5LKtlN7CvkO DF8Jd9hajAL32ZVF2GlW6ps5+9coE0zJgkaWpNicMczIvL1WYtb+hmaK yR48cPDjdgnnezHifHix3C74zpdL4QmN10muzyGqULUKqYZOXiMQff5i TMtFO5MwAFrAfwmgfw+o+NAryhRwFqWaY0h4z8TTCh3rVRYR5PfOzFcd aoewfzOm90XihvoqRrajaEK1W6F+IS/​3UVEo4YR7M8mdZK1QF+g94bg0 4yCZkSGN8Z+xnu0p";​ 
 +};</​code>​ 
 +  - Change the root-hint to the lab root server. This part is also required for this lab only and not required in real life. Create a file named lab-root.hints using the command ''​vi /​etc/​bind/​lab-root.hints''​ with the following contents:<​code>​. 8600000 IN NS X.ROOT-SERVER.LOC. 
 +X.ROOT-SERVER.LOC. IN A 192.168.30.51</​code>​ 
 +  - Change the ''​zone "​."''​ block in ''/​etc/​bind/​named.conf.default-zones''​ to reflect the following<​code>​zone "​."​ { 
 + type hint; 
 + file "/​etc/​bind/​lab-root.hints";​ 
 +};</​code>​ 
 +  - Reload bind with ''​systemctl reload named''​
  
- These options must be enabled: 
-  
- dnssec-enable yes; 
- dnssec-validation yes|auto; 
  
- `dnssec-enable` allows named to respond to DNS requests from DNSSEC-aware clientsThe default is yes, but is best added in the `named.conf` so you know how to turn it off. +==== B. Signing ​the zone ==== 
- +  Generate ​the key pair in ''​/etc/bind/master''​ directory. This command generates the ZSK.<​code>​dnssec-keygen –a <​algorithm>​ –b <​keysize>​ -n ZONE <​groupXX>​</​code> ​example: ​<​code>​dnssec-keygen -a RSASHA256 -b 1024 -n ZONE groupXX.net</​code>​The defaults are RSASHA1 for the algorithm, with 1024 bits for ZSK and 2048 bits for KSK. Since these are all defaults, we can just issue the command:<​code>​dnssec-keygen -n ZONE groupXX.net</​code>​This will generate two file. Now generate KSK. This command generates the KSK<​code>​dnssec-keygen -a <​algorithm>​ -b <​keysize>​ -f KSK -n ZONE <​groupXX>​</​code>​Or simply<​code>​dnssec-keygen -a RSASHA256 -b 1024 -f KSK  -n ZONE groupXX.net</​code>​ 
- If `dnssec-validation` is set to auto, it defaults to the DNS root zone as the trust anchor. ​ +  ​- ​Include the public DNSKEYs in the zone file. You can either copy the entire file or reference to it using the $INCLUDE directive. Note that you are including only the public portion (.key) into the zone file. The private portion (.private) must be kept secure.<​code>​cat Kgroup*.key >> db.groupXX.net</​code>​OR<​code>​ 
-  +$INCLUDE “K<​groupXX>​.+005+<​id_of_zsk>​.key” 
- If set to yes, a trust anchor must be explicitly configured using the trusted-keys option.  +$INCLUDE “K<​groupXX>​.+005+<​id_of_ksk>​.key”</​code>​ 
- +  ​- ​Sign the zone using the secret keys. The syntax is:<​code>​dnssec-signzone -o <​zonename>​ -N INCREMENT -f <​output-file>​ -t -k <​KSKfile>​ <​zonefile>​ <​ZSKfile>​</​code>​example:<​code>​dnssec-signzone -o groupXX.net -N INCREMENT -f db.groupXX.net.signed -t -k KgroupXX.net.+005+12345 db.groupXX.net KgroupXX.net.+005+67890</​code>​\\ ​`dnssec-signzone` does the following things: 
- trusted-keys { +    ​- ​Takes the public keys from the KgroupXX.net.+005+*.key) and appends them as DNSKEY records to the zone. (This is what the -S flag does)   
- // parent zone +    ​- ​Signs the DNSKEY record of the ZSK with the KSK   
- . 257 3 5 “<​key-here>​”;​ +    ​- ​Puts all the records in the zone in canonical (alphabetical) order   
- }; +    ​- ​Generates a NSEC records for each record and interleaves them into the ordered zonefile ​  
- +    ​- ​Creates RRSIG records (signatures) for all the records in the zone by signing them with the ZSK.   
-2. For ​the lab, we will use trusted-keys. A file containing the root’s public ​key (`http://192.168.30.254/dns/​trusted-keys`) will be provided. Copy this into your `named.conf` +  ​- ​This creates a new file named ''​groupXX.net.signed'' ​which contains `RRSIG` records for each DNS record. If we don't add the ''​–f'' ​option output will automatically append a `.signed` in the zonefile.<​code>​<​db.groupXX.net>​.signed</​code>​After successful signing it will give some output<​code>​
- +
-#####​B. Signing the zone. +
- +
-1. Generate the key pair. This command generates the ZSK. +
- +
- dnssec-keygen ​-r /​dev/​urandom ​–a <​algorithm>​ –b <​keysize>​ -n ZONE <​groupXX>​ +
- +
- +
- example: +
-  +
- dnssec-keygen ​-r /​dev/​urandom ​-a RSASHA256 -b 1024 -n ZONE groupXX.net +
- +
- The defaults are RSASHA1 for the algorithm, with 1024 bits for ZSK and 2048 bits for KSK. Since these are all defaults, we can just issue the command: +
- +
- dnssec-keygen ​-r /​dev/​urandom ​-n ZONE groupXX.net +
-  +
- This will generate two file. +
- +
- Now generate KSK. This command generates the KSK +
- +
- dnssec-keygen -a <​algorithm>​ -b <​keysize>​ -f KSK -n ZONE <​groupXX>​ +
- +
- Or simply +
- +
- dnssec-keygen -r /​dev/​urandom ​-f KSK -n ZONE groupXX.net +
- +
-  +
-2. Include the public DNSKEYs in the zone file. +
- +
- You can either copy the entire file or reference to it using the \$INCLUDE directive. To do the latter, simply add the lines below. Note that you are including only the public portion (.key) into the zone file. The private portion (.private) must be kept secure. +
-  +
- $INCLUDE “K<​groupXX>​.+005+<​id_of_zsk>​.key” +
- $INCLUDE “K<​groupXX>​.+005+<​id_of_ksk>​.key” +
- +
-3. Sign the zone using the secret keys. The syntax is: +
- +
- dnssec-signzone -o <​zonename>​ -N INCREMENT -f <​output-file>​ -t \   +
- -k <​KSKfile>​ <​zonefile>​ <​ZSKfile>​ +
- +
- example: +
-  +
- dnssec-signzone -o groupXX.net -N INCREMENT -f db.groupXX.net.signed -t +
- -k KgroupXX.net.+005+12345 db.groupXX.net KgroupXX.net.+005+67890 +
- +
- `dnssec-signzone` does the following things: ​  +
- 1. Takes the public keys from the KgroupXX.net.+005+*.key) and appends them as DNSKEY records to the zone. (This is what the -S flag does)   +
- 2. Signs the DNSKEY record of the ZSK with the KSK   +
- 3. Puts all the records in the zone in canonical (alphabetical) order   +
- 4. Generates a NSEC records for each record and interleaves them into the ordered zonefile ​  +
- 4. Creates RRSIG records (signatures) for all the records in the zone by signing them with the ZSK.   +
- +
- This creates a new file named `groupXX.net.signedwhich contains `RRSIG` records for each DNS record. If we don't add the `–foption output will automatically append a `.signed` in the zonefile. ​ +
- +
- <​db.groupXX.net>​.signed +
- +
- After successful signing it will give some output +
- +
  Verifying the zone using the following algorithms: RSASHA1.  Verifying the zone using the following algorithms: RSASHA1.
  Zone fully signed:  Zone fully signed:
  Algorithm:​ RSASHA1: KSKs: 1 active, 0 stand-by, 0 revoked  Algorithm:​ RSASHA1: KSKs: 1 active, 0 stand-by, 0 revoked
-                    ​ZSKs: 1 active, 0 stand-by, 0 revoked+                ​ZSKs: 1 active, 0 stand-by, 0 revoked
  db.groupXX.net.signed  db.groupXX.net.signed
  Signatures generated: ​                      15  Signatures generated: ​                      15
Line 110: Line 59:
  Signing time in seconds: ​                0.006  Signing time in seconds: ​                0.006
  Signatures per second: ​               2423.654  Signatures per second: ​               2423.654
- Runtime in seconds: ​                     0.014 + Runtime in seconds: ​                     0.014</​code>​ 
- +  ​- ​The output file is bigger than the original zone file. Check with the commands ​''​ls -al'' ​or ''​wc''​.
- The output file is bigger than the original zone file. Check with the commands ​`ls -alor `wc`. +
-  +
-#####​C. Publishing the zone.+
   
-1. Reconfigure to load the signed zone. Edit `named.confand point to the signed zone. For example: +==== C. Publishing the zone ==== 
- +  - Reconfigure to load the signed zone. Edit ''​named.conf.local'' ​and point to the signed zone. For example:<​code>​ 
- zone “<​groupXX>​” { +zone “<​groupXX>​” { 
- type master; + type master; 
- file “db.groupXX.net”;​ + // file “db.groupXX.net”;​ 
- file “db.groupXX.net.signed”;​ + file “db.groupXX.net.signed”;​ 
- }; +};</​code>​Change the file to point to the signed zone.  
- +  ​- ​Start/​Reload named service. Check if for the DNSKEY record using dig on the same server.<​code>​dig DNSKEY groupXX.net. @localhost +multiline</​code>​Check for the presence of RRSIG records.<​code>​dig ns.groupXX.net. @localhost +multiline +dnssec A</​code>​ 
- Change the file to point to the signed zone.  +  ​- ​When we ran the ''​dnssec-signzone'' ​command apart from the ''​.signed'' ​zone file, a file named ''​dsset-groupXX.net'' ​was also created, this contains the DS records. Push the DS record up to your parent domain. Open the file ''​dsset-<​yourdomain>​'' ​(ex: ''​dsset-groupXX.net''​). This contains your DS records (see example below).<​code>​ 
- +groupXX.net. IN DS 4297 5 1 C5A8C518B2208463F87CB30E35F247DD7EACCDB1 
-2. Start/​Reload named service. Check if for the DNSKEY record using dig on the same server. +groupXX.net. IN DS 4297 5 2 27E89E4A769F6C6BC889BB6F2E98374CA835D2B8C750D5505F32144E 1E79B881</​code>​Send this to your parent zone (for the lab, it’s the gTLD server). The parent zone will then include the DS record in their zonefile. The ''​$INCLUDE'' ​statement can be used at this stage.<​code>​$INCLUDE “dsset-groupXX.net.”</​code>​In the class, securely send the file to the instructors. You may then check if it has been successfully added using dig.<​code>​dig @nameserver +noadditional DS groupXX.net | grep DS</​code>​ 
- +  ​- ​For slave servers, the configuration is simple. In the configuration file, add in the options section:<​code>​dnssec-enable yes; 
- dig DNSKEY groupXX.net. @localhost +multiline +dnssec-validation auto | yes;</​code>​Then edit the zone section to point to the new signed zonefile. After reload, verify that this file exists in the folder specified in the config.<​code>​ 
- +zone “<​groupXX>​” { 
- Check for the presence of RRSIG records. + type slave; 
-  + masters { X.X.X.X; }; 
- dig groupXX.net. @localhost +multiline +dnssec A + // file “db.groupXX.net”;​ 
-  + file “db.groupXX.net.signed”;​ 
-3. When we ran the `dnssec-signzonecommand apart from the `.signedzone file, a file named `dsset-groupXX.netwas also created, this contains the DS records. Push the DS record up to your parent domain. Open the file `dsset-<​yourdomain>​(ex: `dsset-groupXX.net`). This contains your DS records (see example below). +};</​code>​ 
- +  ​- ​Check if DNSSEC is working using the dig command. The output should show an `RRSIG` next to the record you asked.<​code>​dig @localhost +dnssec +multiline groupXX.net 
- groupXX.net. IN DS 4297 5 1 C5A8C518B2208463F87CB30E35F247DD7EACCDB1 +dig @localhost +trace +dnssec groupXX.net</​code>​Also check for the `AD` bit in the message header flags. It should look something like:<​code>​;; ->>​HEADER<<​- opcode: QUERY, status: NOERROR, id: 40679 
- groupXX.net. IN DS 4297 5 2 27E89E4A769F6C6BC889BB6F2E98374CA835D2B8C750D5505F32144E 1E79B881 +;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1</​code>​
- +
- Send this to your parent zone (for the lab, it’s the gTLD server). The parent zone will then include the DS record in their zonefile. The $INCLUDE statement can be used at this stage. +
- +
- $INCLUDE “dsset-groupXX.net.” +
- +
- In the class, securely send the file to the instructors. You may then check if it has been successfully added using dig. +
- +
- dig @nameserver +noadditional DS groupXX.net | grep DS +
-  +
-3. For slave servers, the configuration is simple. In the configuration file, add in the options section: +
- +
- dnssec-enable yes; +
- dnssec-validation auto | yes; +
- +
- Then edit the zone section to point to the new signed zonefile. After reload, verify that this file exists in the folder specified in the config. +
- +
- zone “<​groupXX>​” { +
- type slave; +
- masters { X.X.X.X; }; +
- file “db.groupXX.net”;​ +
- file “db.groupXX.net.signed”;​ +
- }; +
- +
-4. Check if DNSSEC is working using the dig command. The output should show an `RRSIG` next to the record you asked. +
- +
- dig @localhost +dnssec +multiline groupXX.net +
- dig @localhost +trace +dnssec groupXX.net +
- +
- Also check for the `AD` bit in the message header flags. It should look something like: +
- +
- ;; ->>​HEADER<<​- opcode: QUERY, status: NOERROR, id: 40679 +
- ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 +
- +
-#####​D. Signing the reverse zones.+
  
 +==== D. Signing the reverse zones. ====
 The steps to sign the reverse zones are similar to the instructions in items B and C. Using the IP block assigned to you, create the reverse zones and sign them accordingly. The steps to sign the reverse zones are similar to the instructions in items B and C. Using the IP block assigned to you, create the reverse zones and sign them accordingly.
- 
 Sample steps as follows using reverse domain for block `192.168.100.0/​24`. Sample steps as follows using reverse domain for block `192.168.100.0/​24`.
  
-1. Generate the keys. +  - Generate the keys.<​code>​dnssec-keygen –a <​algorithm>​ –b <​keysize>​ –n ZONE 100.168.192.in-addr.arpa 
 +dnssec-keygen –a <​algorithm>​ –b <​keysize>​ –f KSK –n ZONE 100.168.192.in-addr.arpa</​code>​ 
 +  - Sign the zone<​code>​dnssec-signzone -o 100.168.192.in-addr.arpa -N INCREMENT -f <​output-file>​ -t -k K100.168.192.in-addr.arpa.+005+12345 db.192.168.100 K100.168.192.in-addr.arpa.+005+67890</​code>​ 
 +  - Publish the signed zone<​code>​zone “100.168.192.in-addr.arpa” { 
 + type master; 
 + // file “db.groupXX.net”;​ 
 + file “db.192.168.100.signed”;​ 
 +};</​code>​ 
 +  - Verify using dig command. <​code>​dig @localhost +dnssec +multiline 1.100.168.192.in-addr.arpa 
 +dig –x @localhost 192.168.100.1</​code>​
  
- dnssec-keygen –r /​dev/​urandom –a <​algorithm>​ –b <​keysize>​ \  
- –n ZONE 100.168.192.in-addr.arpa 
- 
- dnssec-keygen –r /​dev/​urandom –a <​algorithm>​ –b <​keysize>​ \ 
- –f KSK –n ZONE 100.168.192.in-addr.arpa 
- 
-2. Sign the zone 
- 
- dnssec-signzone -o 100.168.192.in-addr.arpa -N INCREMENT -f <​output-file>​ -t -k \ 
- K100.168.192.in-addr.arpa.+005+12345 db.192.168.100 K100.168.192.in-addr.arpa.+005+67890 
- 
-3. Publish the signed zone 
- 
- zone “100.168.192.in-addr.arpa” { 
- type master; 
- # file “db.groupXX.net”;​ 
- file “db.192.168.100.signed”;​ 
- }; 
- 
-4. Verify using dig command. ​ 
- 
- dig @localhost +dnssec +multiline 1.100.168.192.in-addr.arpa 
- dig –x @localhost 192.168.100.1 
- 
- 
-#####​E. NSEC and NSEC3  ​ 
  
 +==== E. NSEC and NSEC3  ====
 NSEC records are created to prove the non-existence of a record. It builds a linked list of all the records in the zone file. The problem with this is it allows anyone to list the zone content. This is called “zone walking.” Some tools, like the ldns-walk (included in the LDNS library), can be used to do exactly this.  NSEC records are created to prove the non-existence of a record. It builds a linked list of all the records in the zone file. The problem with this is it allows anyone to list the zone content. This is called “zone walking.” Some tools, like the ldns-walk (included in the LDNS library), can be used to do exactly this. 
- 
 NSEC3 can be used to provide more security. It uses a hashing algorithm to output a “hash” to replace the real domain names. This makes it difficult for an attacker, but not totally impossible. NSEC3 can be used to provide more security. It uses a hashing algorithm to output a “hash” to replace the real domain names. This makes it difficult for an attacker, but not totally impossible.
- 
 In the steps above, NSEC was used by default. Let us re-do the key generation and signing this time using NSEC3. In the steps above, NSEC was used by default. Let us re-do the key generation and signing this time using NSEC3.
- +  - Using NSEC3 to generate keys. To do this, you may use `NSEC3RSASHA1` as your algorithm. The easier way to do this is to use `-3` option instead. This option allows a few other algorithms such as `RSASHA256` and `RSAHSHA512` but sets `NSEC3RSASHA1` as default.<​code>​dnssec-keygen -3 groupXX.net 
-1. Using NSEC3 to generate keys.   +dnssec-keygen -f ksk -3 groupXX.net</code
-To do this, you may use `NSEC3RSASHA1` as your algorithm. The easier way to do this is to use `-3` option instead. This option allows a few other algorithms such as `RSASHA256` and `RSAHSHA512` but sets `NSEC3RSASHA1` as default. +  ​- ​Sign the zone with a salt.<​code>​dnssec-signzone -A -3 <​salt>​ -o <​zonename>​ -N INCREMENT -f <​output-file>​ -t -k <​KSKfile>​ <​zonefile>​ <​ZSKfile>​>/​code>​The salt is a random hexadecimal number appended to the domain before hashing. It’s a public data that is part of the NSEC3PARAM record. It must be changed once in a while or on regular intervals. To generate the salt, you can use either of these:<​code>​date | sha1sum | cut –b 1-16 
- +head –c 1000 /dev/random | sha1sum | cut –b 1-16</​code>​Example:<​code>​dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) -o groupXX.net -N INCREMENT -f <​output-file>​ -t -k KgroupXX.net.+005+12345 db.groupXX.net KgroupXX.net.+005+67890</​code>​To use NSEC3 without a salt, simply use a single `-` (dash).<​code>​dnssec-signzone -A -3 - -o groupXX.net -N INCREMENT -f <​output-file>​ -t -k KgroupXX.net.+005+12345 db.groupXX.net KgroupXX.net.+005+67890</​code>​ 
- dnssec-keygen ​-r /​dev/​random ​-3 <groupXX> +  - View the signed zonefile (''​cat /etc/bind/db.groupXX.net.signed|grep NSEC''​). Notice that you now have NSEC3 records added with a hash value of the records in the ''​RDATA''​.
- dnssec-keygen -f ksk -r /​dev/​random ​-3 <groupXX+
-  +
-2. Sign the zone with a salt.   +
- +
- dnssec-signzone -A -3 <​salt>​ -o <​zonename>​ -N INCREMENT ​+
- -f <​output-file>​ -t -k <​KSKfile>​ <​zonefile>​ <​ZSKfile>​ +
- +
- The salt is a random hexadecimal number appended to the domain before hashing. It’s a public data that is part of the NSEC3PARAM record. It must be changed once in a while or on regular intervals. +
-  +
- To generate the salt, you can use either of these: +
-  +
- date | sha1sum | cut –b 1-16 +
- head –c 1000 /dev/random | sha1sum | cut –b 1-16 +
- +
- Example: +
- +
- dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b +
- 1-16) -o groupXX.net -N INCREMENT -f <​output-file>​ -t -k \  +
- KgroupXX.net.+005+12345 db.groupXX.net KgroupXX.net.+005+67890 +
- +
- To use NSEC3 without a salt, simply use a single `-` (dash). ​ +
-  +
- dnssec-signzone -A -3 - -o groupXX.net -N INCREMENT -f <​output-file>​ -t -k \  +
- KgroupXX.net.+005+12345 db.groupXX.net KgroupXX.net.+005+67890 +
-  +
-3. Open ​the signed zonefile (`db.groupXX.net.signed`). Notice that you now have NSEC3 records added with a hash value of the records in the `RDATA`.+
bdnog11/netsec/bind-implementing-dnssec.1578746413.txt.gz · Last modified: 2020/01/11 18:40 by Muhammad Moinur Rahman