1. Overview
PostgreSQL is a great open source database, not only because it supports lot of database features, but also because it supports different network setup. For example, you can set it up on an IPv6 enabled network in just a few steps. This blog will demonstrate how to setup PostgreSQL on an IPv6 network in Linux.
Before we dive into the detail, let’s discuss a little bit IPv6. IPv6 was developed by the Internet Engineering Task Force (IETF) in late 1998 and was intended to replace IPv4. With the IPv4 address exhaustion issue, after about two decades, IPv6 now is finally coming into the real picture. Below is the state of IPv6 Deployment in 2018:
1 | * Over 25% of all Internet-connected networks advertise IPv6 connectivity. |
If you check your home internet modem/router and most likely you will find the IPv6 is already enabled. There are many documents and RFCs explain IPv6 in much more detail. For example, IP Version 6 Addressing Architecture
defined in RFC 4291. In this blog, I will just explain some simple concepts which is required in this demo.
2. Setup IPv6 network
Link-local address
Not like IPv4, all the interface of an IPv6 enabled host require a link-local address. The link-local address will always start with the prefix fe80:: and it is generated during TCP/IP stack boot up on that interface. The interesting part is that link-local address doesn’t request a DHCP server or any manual configuration. The link-local can be set to derive from the MAC address of the interface, in this case, if you know the MAC of the interface then you can create the link-local address by simply copy and paste the MAC to a link-local calculator.
Global address
However, there is a limitation as the name indicated, it only works between the hosts which are directly connected. To allow the communication cross the internet or multiple routers, the host needs to have a global address. There are many different ways to setup a global IPv6 address. Here, we introduce three typical ways: Manually, DHCPv6 and SLAAC.
To manually setup an IPv6 global address, you can use either
ip
orifconfig
. For example,1
2
3sudo ip -6 addr add 2020:1:0:0::db1/64 dev eth0
sudo ifconfig eth0 inet6 add 2020:1:0:0::db1/64Since IPv6 allows the HEX characters, you can make your own customized IPv6 address for fun. For example, configure a PostgreSQL server with IPv6 address like,
:db:feed
,:da7a:ba5e
,:db1
,:db2
etc,.Stateless address autoconfiguration (SLAAC) requires to have a router which broadcast the
router advertisement
periodically. The router should also response torouter solicitation
request from any host machine. Once the host receive therouter advertisement
, it will use theprefix
to generate the global IPv6 address automatically. Below is an example,
Install theRouter Advertisement Daemon (radvd)
on PostgreSQL server side,1
sudo apt-get install radvd
then configure the radvd conf file, for example,
1
2
3
4
5
6
7
8
9
10interface eno1
{
AdvSendAdvert on;
AdvManagedFlag off;
AdvOtherConfigFlag on;
prefix 2020:1:0:0::/64
{
AdvAutonomous on;
};
};Configure a new IPv6 address on Postgres server for radvd daemon to use
1
sudo ip -6 addr add 2020:1:0:0::db1/64 dev eno1
Then start the
radvd
daemon,sudo radvd -l /etc/radvd.conf
Now, if you check the ip address on the client machine side, you should see something like below,1
2
3
4
5
6
7
8
9enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.20.14.27 netmask 255.255.255.0 broadcast 172.20.14.255
inet6 2020:1::8dcf:b8be:dbcc:26c6 prefixlen 64 scopeid 0x0<global>
inet6 fe80::8005:8b22:cd7d:ee39 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:29:ab:c9 txqueuelen 1000 (Ethernet)
RX packets 118 bytes 38615 (38.6 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 181 bytes 26919 (26.9 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0where,
2020:1::8dcf:b8be:dbcc:26c6
is the global address generated after receive therouter advertisement
.Stateful IPv6 address is done via a DHCPv6 server. The setup is similar to the IPv4 DHCP server setup. Below is an example on an Ubuntu machine,
1 | sudo apt-get install isc-dhcp-server |
After the DHCP Server has been installed, edit the configuration file for IPv6 address assignment.
1 | sudo vim /etc/dhcp/dhcpd6.conf |
and add below information,
1 | ddns-update-style none; |
Configure a new IPv6 address on Postgres server for DHCPv6 server to use
1 | sudo ip -6 addr add 2020:2:0:0::db1/64 dev eno1 |
1 | sudo dhcpd -6 -d -cf /etc/dhcp/dhcpd6.conf eth0 |
On the client machine side, run a dhcp request for IPv6 manually. sudo dhclient -6 enp0s3
, and then perform an ip address check.
1 | enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 |
where, 2020:2::1004
is the global IPv6 address assigned by the DHCPv6 server.
3. Connetivity test using ping6
- PostgreSQL server
- Network interface: eno1
- link-local: fe80::1c79:293f:1b6e:c826
- IPv6 global address(SLAAC): 2020:1::db1
- IPv6 global address(DHCPv6): 2020:2::db1
- psql client IPs
- Network interface: enp0s3
- link-local: fe80::8005:8b22:cd7d:ee39
- IPv6 global address generated(SLAAC): 2020:1::8dcf:b8be:dbcc:26c6
- IPv6 global address assigned(DHCPv6): 2020:2::1004
ping6 test from server to client
1 | $ ping6 fe80::8005:8b22:cd7d:ee39%eno1 |
ping6 test from client to server
1 | $ ping6 fe80::1c79:293f:1b6e:c826%enp0s3 |
4. Configure PostgreSQL for IPv6
Edit the postgresql.conf file to allow Postgres listen on different interfaces
1 | listen_addresses = '*' |
Edit the host-based authentication file to allow client machine to connect with different source IPs.
1 | # IPv6 local connections: |
psql client connect to Postgres server using link-local address with interface name
1 | $ psql -d postgres -U david -h fe80::1c79:293f:1b6e:c826%enp0s3 |
psql client connect to Postgres server using global address(Stateless address)
1 | $ psql -d postgres -U david -h 2020:1::db1 |
psql client connect to Postgres server using global address(Stateful address)
1 | $ psql -d postgres -U david -h 2020:2::db1 |
5. Typical errors
Using link-local to connect Postgres without the interface name
1 | $ psql -d postgres -U david -h fe80::1c79:293f:1b6e:c826 |
psql client using a wrong global address as source address
1 | $ psql -d postgres -h 2020:2::db1 |
This is due to multiple IPv6 global addresses available on the same interface. In this case, the application, i.e. psql
should have an option to select the preferred IPv6, otherwise, the kernel will pick up the IPv6 global address based on predefined policy and rules. Please check Source Address Selection for details. A simple solution is the remove other global IPv6 addresses, and disable the corresponding service
i.e. radvd
or DHCPv6
server.
6. Summary
We demonstrated how to setup a simple IPv6 network with one Postgres server and one psql client. To enable the IPv6 configuration is pretty simple on PostgreSQL side, but some the basic IPv6 knowledge is required.
Ref: [Configuring IPv6 addresses] (https://www.tldp.org/HOWTO/Linux+IPv6-HOWTO/ch06s02.html)