###################################### DHCP ##############################################
~Dynamic Host Configuration Protocol

#### basic DHCP configuration:

# ***For testing purposes on virtualbox***: set one network interface on the SERVER to 
#  Internal Networking and configure it to have a static IP address of your choice (this
#  is the interface from which DHCP service will work); set another network interface on
#  the test-CLIENT also to Internal Networking, and configure that interface to receive 
#  automatic DHCP information.

### install DHCP
apt install isc-dhcp-server


##### basic IPv4 configuration:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## edit the DHCP's interface configuration file:
nano /etc/default/isc-dhcp-server     #specify the network card(s) from which DHCP will work, ex.:
INTERFACESv4="enp0s8" 

# let's assume, for this example, that we have a DNS configured for example.com, with a 
#  nameserver ns1.example.com, the DHCP server also works as router for this network and
#  its IP is 10.1.1.1/24

## edit the IPv4's DHCP configuration file:
nano /etc/dhcp/dhcpd.conf    #update the domain, DNS, subnetwork to distribute and router information:
option domain-name "example.com";                       #domain
option domain-name-servers ns1.example.com;             #DNS
subnet 10.1.1.0 netmask 255.255.255.0 {                 #subnetwork
  range 10.1.1.10 10.1.1.110;                           #range to distribute
  option routers 10.1.1.1;                              #router info
}                                                       #don't forget to uncomment this!

## restart DHCP service:
systemctl restart isc-dhcp-server                       #OR: service isc-dhcp-server restart

# to view the distributed IP registers:
cat /var/lib/dhcp/dhcpd.leases 

# to check if DHCP port is running (look for udp port 67):
netstat -awun


##### basic IPv6 configuration:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## edit the DHCP's interface configuration file:
nano /etc/default/isc-dhcp-server     #specify the network card(s) from which DHCP will work, ex.:
INTERFACESv6="enp0s8" 

# let's assume, for this example, that we have a DNS configured for example.com, with a 
#  nameserver ns1.example.com (2001:db8::12), the DHCP server also works as router (and
#  DNS) for this network and its IP is 2001:db8::12/64

## edit the IPv6's DHCP configuration file:
nano /etc/dhcp/dhcpd6.conf    #update the domain, DNS, subnetwork to distribute and router information:
#... ### some of the commented lines may help you find yourself in this file
# Global definitions for name server address(es) and domain search list
option dhcp6.name-servers 2001:db8::12;                  #DNS, make sure to use the IPv6 number here!
option dhcp6.domain-search "example.com";                #domain
#...
# The subnet where the server is attached
#  (i.e., the server has an address in this subnet)
subnet6 2001:db8::/64 {                                  #subnetwork
#       # Two addresses available to clients
#       #  (the third client should get NoAddrsAvail)
        range6 2001:db8::aaaa 2001:db8::fffa;            #range to distribute
#...
}                                                        #don't forget to uncomment this!

## restart DHCP service for IPv6:
systemctl restart isc-dhcp-server6

# to check if DHCP port is running (look for udp6 port 547):
netstat -awun

# to view the distributed IPv6 registers:
cat /var/lib/dhcp/dhcpd6.leases            #if you already have Router Advertisement correctly 
                                           # configured in your network, and the test-CLIENT is
                                           # already running waiting for an IPv6 attribution,
                                           # everything should be working and there would be
                                           # a new record on the dhcpd6.leases file. If not,
                                           # the next step is to configure a ROUTER 
                                           # ADVERTISEMENT (RA)!

####################################### RADVD ###########################################
~Router Advertisement Daemon

# RADVD is the router advertisement daemon for IPv6. It listens to router solicitations 
#  and sends router advertisements as described in "Neighbor Discovery for IP Version 6 (IPv6)"
#  (RFC 4861). With these advertisements hosts can automatically configure their addresses and 
#  some other parameters. They can also a default router based on these advertisements.

## Ubuntu Server 20.4 and more recent versions (tested up to 24.04) requires a RA (router 
##  advertisement) to make DHCP for IPv6 work correctly. RADVD will simulate that on this 
##  test-server.

### intstall radvd
apt install radvd 

# check if the service is ok:
systemctl status radvd

### usually /etc/radvd.conf does not exist or is empty... To fix this we're going to create 
### that configuration file
nano /etc/radvd.conf
## example of radvd.conf's content:
interface enp0s8
{
MinRtrAdvInterval 3;
MaxRtrAdvInterval 4;
AdvSendAdvert on;
AdvManagedFlag on;
#prefix 2001:db8:cafe:5000::/64
#{ AdvValidLifetime 14300; AdvPreferredLifetime 14200; }
#;
# those lines are commented so that radvd doesn't attribute a second IPv6 besides the one
#  our DHCP is providing. If you want radvd to attribute an IPv6 instead of DHCP, this is
#  a way to do it!
};

### restart the service, then check the status again:
systemctl restart radvd                             #OR: service radvd restart
systemctl status radvd

# if you want the warning about the IPv6 forwarding setting gone, do this:
nano /etc/sysctl.conf                               #uncomment the following line:
net.ipv6.conf.all.forwarding=1
# then, reboot the server or use this command:
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding

# and restart radvd again, all should be fine if you look at the status once more!!
systemctl restart radvd                             #OR: service radvd restart
systemctl status radvd
#########################################################################################

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EXTRAS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

##### Troubleshooting ERROR after DHCP for IPv6 configuration on UBUNTU 24.04:~~~~~~~~~~~~~~
systemctl status isc-dhcp-server6     #this command shows the following error:
Can't create PID file /run/dhcp-server6/dhcpd6.pid: Permission denied.

## on another terminal (T2), run:
journalctl -f 

## on your regular terminal (T1), restart the DHCP for IPv6 service:
systemctl restart isc-dhcp-server6

## check for more details of the error on T2, I found this:
audit: type=1400 audit(1715452530.661:118): apparmor="DENIED" operation="mknod" class="file" 
profile="/usr/sbin/dhcpd" name="/run/dhcp-server6/dhcpd6.pid" pid=3341 comm="dhcpd" 
requested_mask="c" denied_mask="c" fsuid=0 ouid=0

# similar error reported on bind at this link:
https://askubuntu.com/questions/172030/how-to-allow-bind-in-app-armor

### resolution:
nano /etc/apparmor.d/local/usr.sbin.dhcpd       #and add this line to it:
/run/dhcp-server6/dhcpd6.pid rw,
## then run:
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.dhcpd
## and restart the DHCP for IPv6 service again:
systemctl restart isc-dhcp-server6
systemctl status isc-dhcp-server6               #the error should be gone
#########################################################################################
      
	

~~~~~~~~~~DHCP Server Script:~~~~~~~~~~

ATTENTION: Always read a script before you run it!!!


To run a basic DHCP for IPv4 configuration script, run the following command line in your server's terminal:

     wget -nc https://www.maycke.com.br/guides/raw/dhcp_ipv4.sh && chmod 700 dhcp_ipv4.sh && sudo ./dhcp_ipv4.sh && sudo rm dhcp_ipv4.sh

#########################################################################################