These are instructions for adding PQConnect support to your existing server, to protect connections from client machines that have installed PQConnect. These instructions also cover PQConnect connections from your server.
Prerequisites: root on a Linux server (Arch, Debian, Gentoo, Raspbian, Ubuntu); ability to edit DNS entries for the server name.
Quick start
Here is how to download, install, and run the PQConnect server software. Start a root shell and run the following commands:
cd /root
wget -m https://www.pqconnect.net/pqconnect-latest-version.txt
version=$(cat www.pqconnect.net/pqconnect-latest-version.txt)
wget -m https://www.pqconnect.net/pqconnect-$version.tar.gz
tar -xzf www.pqconnect.net/pqconnect-$version.tar.gz
cd pqconnect-$version
scripts/install-pqconnect
scripts/create-first-server-key
scripts/start-server-under-systemd
Then edit the DNS entries for your server name,
following the instructions printed out by create-first-server-key
.
This is what lets PQConnect clients
detect that your server supports PQConnect.
To also run the PQConnect client software:
scripts/start-client-under-systemd
This has to be after install-pqconnect
but can be before
start-server-under-systemd
.
The client and server run as independent
pqconnect-client
and pqconnect-server
services.
Testing
The following steps build confidence that your new PQConnect server installation is properly handling PQConnect clients and non-PQConnect clients. (If you are also running the PQConnect client software, also try the quick client test and the detailed client test.)
After start-server-under-systemd
,
follow the instructions printed out by create-first-server-key
,
but apply those instructions to a new testing-pqconnect
server name in DNS
pointing to the same IP address,
without touching your normal server name.
On another machine running the
PQConnect client software:
Test that dig testing-pqconnect.your.server
sees a 10.*
address
instead of the server's actual public address.
Test that ping -c 30 testing-pqconnect.your.server
works and sees a 10.*
address.
On the server,
run journalctl -xeu pqconnect-server
and look for a key exchange
with a timestamp matching
when the PQConnect client first accessed the server.
Optionally,
run a network sniffer on the server's public network interface
to see that the client's pings are arriving as UDP packets rather than ICMP packets.
Test the server's normal services from the client machine
and, for comparison, from a machine that isn't running PQConnect yet.
Note that web servers will typically give 404 responses
for the testing-pqconnect
server name
(because that isn't the server's normal name),
but you can still see that the web server is responding.
Many other types of services will work independently of the name.
Finally,
move the testing-pqconnect
configuration in DNS
to your normal server name,
and test again from both client machines.
PQConnect ports
The PQConnect server needs clients to be able to reach it on two UDP ports: a crypto-server port (42424 by default) and a key-server port (42425 by default). You may wish to pick other ports: for example, ports below 1024 for port security, or ports that avoid restrictions set by external firewalls.
To set, e.g., crypto-server port 624 and key-server port 584, run
scripts/change-server-cryptoport 624
scripts/change-server-keyport 584
before running start-server-under-systemd
,
and edit your DNS records to use the pq1
name
printed out by the last script.
If you are running the PQConnect client software:
The PQConnect client uses port 42423 by default.
To set port 33333,
replace
pqconnect-client
with
pqconnect-client -p 33333
in scripts/run-client-core
.
Server-in-a-bottle mode
The PQConnect server software supports a "server-in-a-bottle mode"
aimed at the following common situation:
You are running multiple virtual machines (VMs) on one physical machine (the host).
The VMs are managed by a hypervisor that tries to
isolate
each VM,
to protect the other VMs and the host.
The VMs communicate on a private network inside the host.
The host uses network-address translation
(NAT: e.g., SNAT
or MASQUERADE
with iptables
,
along with 1
in /proc/sys/net/ipv4/ip_forward
)
to resend outgoing network traffic from the VMs
to the Internet,
so that all of the VMs appear as the same IP address publicly.
Each VM is providing services on some ports on the public IP address:
e.g., the host is forwarding IMAP to one VM,
forwarding SMTP to another VM, etc.
What server-in-a-bottle mode does is run a PQConnect server in its own VM to protect connections to all of the other VMs (and to any services that you are running outside VMs). Compared to running PQConnect in each VM, server-in-a-bottle mode has the following advantages: PQConnect is installed just once on the machine; there are only two new ports to configure for the machine, instead of two new ports per VM; to the extent that the hypervisor isolates VMs, the other VMs are protected against potential issues in the PQConnect software.
The steps to set up server-in-a-bottle mode are as follows.
Create a VM.
Create and start a new persistent VM
(called pqserver
, for example)
running an OS compatible with the PQConnect software
(for example, Debian),
following your favorite procedure to create a new VM.
Give the VM its own address within the internal network.
Ensure connectivity.
Test that this VM can contact another VM
via the public IP address and port for the other VM.
(The whole point here is to have PQConnect protecting traffic
that it will deliver to the other VMs.)
If this test does not work,
presumably the port-forwarding configuration
is only for traffic arriving from the Internet;
add forwarding rules that also apply to traffic from this VM,
and try this test again.
You can do this without configuring anything outside the VM:
just copy the host's port-forwarding configuration into this VM,
adjust as necessary (for, e.g., the VM having different network-interface names,
and for copying any PREROUTING
rules to OUTPUT
rules),
and set up a script to copy and adjust any subsequent changes to the port-forwarding configuration.
Choose ports. Choose two public ports for PQConnect. Double-check that you are not using these ports for anything else: for example, you don't want to accidentally cut off your existing SSH server on port 22. For concreteness, these instructions take crypto-server port 624 and key-server port 584.
Forward packets for those ports into the VM.
You'll want to be super-careful for this next step:
this step is working outside the VMs
(e.g., working on dom0
under Xen).
This step assumes that the host is using iptables
for packet management.
Run the following
both from the command line now
and in a boot script to apply after reboot:
publicip=203.0.113.113
pqserver=192.168.100.94
for port in 584 624
do
for chain in PREROUTING OUTPUT
do
iptables -t nat -A $chain -p udp \
-d $publicip --dport $port -j DNAT \
--to-destination $pqserver:$port
done
done
Replace 203.0.113.113
with the host's public IP address,
and replace 192.168.100.94
with the VM's address on the host-internal network.
This iptables
command configures DNAT
so that UDP packets (-p udp
)
destined to these two ports (--dport $port
)
on the public IP address (-d $publicip
)
are resent to the same ports on the VM.
Run PQConnect in the VM. Inside the VM, follow the quick-start installation of the PQConnect server software, but run
scripts/change-server-cryptoport 624
scripts/change-server-keyport 584
echo 203.0.113.113 > /etc/pqconnect/config/host
right before running start-server-under-systemd
.
As before, replace 203.0.113.113
with the host's public IP address.
This sets up the server to run on the specified ports inside the VM (you can also use ports different from the public ports if you want, as long as you forward the public ports appropriately), and to forward decrypted packets to the public IP address.
Forward decrypted packets out of the VM.
Inside the VM,
install iptables
for packet management,
and run the following
(with enX0
replaced by the VM's name for its network interface),
both from the command line now
and in a boot script to apply after reboot:
sysctl -w net.ipv4.ip_forward=1
for proto in tcp udp icmp
do
iptables -t nat -A POSTROUTING -p $proto \
-s 10.42.0.0/16 -o enX0 -j MASQUERADE \
--to-ports 40000-50000
done
This iptables
rule arranges for PQConnect's decrypted packets
to be delivered to dom0
in a way that allows PQConnect to see replies to those packets.
Specifically, the PQConnect server software
chooses various 10.42.*
addresses to send decrypted packets to the public IP address;
this rule will rewrite those packets
as coming from 192.168.100.94
(using port numbers to track the original addresses),
and will undo this rewriting for packets sent in reply.
The 10.42
is a default in the PQConnect server software;
it's used only inside the VM,
so it isn't an address you have to change for your configuration.
Test.
Now test PQConnect
using a new testing-pqconnect
server name.
Then edit DNS to announce PQConnect support
on whichever names are used for the services provided by this machine.
If the DNS names for some VMs are managed by other people,
let those people know that they can enable PQConnect support
for those names by simply modifying the DNS entries.
You don't have to upgrade all of the names at once.
Client-in-a-bottle mode
The PQConnect client software supports a "client-in-a-bottle mode" that runs in a VM to protect outgoing connections from the whole machine, analogous to the server-in-a-bottle mode for the server software. Documentation coming soon!
Version: This is version 2025.01.01 of the "For sysadmins" web page.