Certificate Setup
Certificate-based authentication requires proper PKI infrastructure. This guide covers the certificate requirements, installation, and management for Linux EAP-TLS clients.
Certificate Types Required
EAP-TLS requires three certificate components on the client:
| Certificate | Purpose | Location |
|---|---|---|
CA Certificate |
Trust anchor for validating RADIUS server |
|
Client Certificate |
Proves client identity to RADIUS server |
|
Private Key |
Signs the TLS handshake |
|
Certificate Requirements
Client Certificate
The client certificate must meet these requirements:
| Attribute | Requirement |
|---|---|
Subject CN |
Hostname or machine identifier |
Subject Alternative Name (SAN) |
DNS name, optionally UPN |
Extended Key Usage (EKU) |
Client Authentication (1.3.6.1.5.5.7.3.2) |
Key Usage |
Digital Signature |
Key Size |
RSA 2048+ or ECDSA P-256+ |
Validity |
1 year typical |
Obtaining Certificates
From Internal PKI
If your organization runs an internal PKI (Active Directory Certificate Services, HashiCorp Vault PKI, etc.):
# Example: Request from Vault PKI
vault write pki_int/issue/eap-tls-client \
common_name="<hostname>.<domain>" \
alt_names="<hostname>.<domain>" \
ttl="8760h" \
-format=json > /tmp/cert.json
# Extract certificate
jq -r '.data.certificate' /tmp/cert.json > /etc/ssl/certs/<hostname>-eaptls.pem
# Extract private key
jq -r '.data.private_key' /tmp/cert.json > /etc/ssl/private/<hostname>-eaptls.key
# Extract CA chain
jq -r '.data.ca_chain[]' /tmp/cert.json > /etc/ssl/certs/ca-chain.pem
# Clean up
rm /tmp/cert.json
From SCEP/EST
For automated enrollment via SCEP or EST protocols:
# Generate CSR
openssl req -new -nodes \
-newkey rsa:2048 \
-keyout /etc/ssl/private/<hostname>-eaptls.key \
-out /tmp/<hostname>.csr \
-subj "/CN=<hostname>.<domain>"
# Submit CSR to SCEP server (example using sscep)
sscep enroll \
-u https://scep.example.com/certsrv/mscep/mscep.dll \
-c /tmp/ca.pem \
-k /etc/ssl/private/<hostname>-eaptls.key \
-r /tmp/<hostname>.csr \
-l /etc/ssl/certs/<hostname>-eaptls.pem
Manual Certificate Request
For manual enrollment:
# Generate private key
openssl genrsa -out /etc/ssl/private/<hostname>-eaptls.key 2048
# Generate CSR
openssl req -new \
-key /etc/ssl/private/<hostname>-eaptls.key \
-out /tmp/<hostname>.csr \
-subj "/CN=<hostname>.<domain>"
# View CSR for submission
cat /tmp/<hostname>.csr
Submit the CSR to your CA administrator and receive the signed certificate.
Installing Certificates
Directory Structure
# Create directories if needed
sudo mkdir -p /etc/ssl/certs
sudo mkdir -p /etc/ssl/private
Copy Certificates
# Copy CA chain
sudo cp ca-chain.pem /etc/ssl/certs/ca-chain.pem
# Copy client certificate
sudo cp <hostname>-eaptls.pem /etc/ssl/certs/<hostname>-eaptls.pem
# Copy private key
sudo cp <hostname>-eaptls.key /etc/ssl/private/<hostname>-eaptls.key
Set Permissions
Critical security step — private keys must be protected:
# CA chain - readable
sudo chmod 644 /etc/ssl/certs/ca-chain.pem
sudo chown root:root /etc/ssl/certs/ca-chain.pem
# Client certificate - readable
sudo chmod 644 /etc/ssl/certs/<hostname>-eaptls.pem
sudo chown root:root /etc/ssl/certs/<hostname>-eaptls.pem
# Private key - root only
sudo chmod 600 /etc/ssl/private/<hostname>-eaptls.key
sudo chown root:root /etc/ssl/private/<hostname>-eaptls.key
Verification
Verify Certificate Chain
# Verify client cert against CA chain
openssl verify -CAfile /etc/ssl/certs/ca-chain.pem \
/etc/ssl/certs/<hostname>-eaptls.pem
# Expected: /etc/ssl/certs/hostname-eaptls.pem: OK
Verify Key Matches Certificate
# Get certificate modulus
openssl x509 -in /etc/ssl/certs/<hostname>-eaptls.pem -noout -modulus | md5sum
# Get key modulus
openssl rsa -in /etc/ssl/private/<hostname>-eaptls.key -noout -modulus | md5sum
# Both hashes must match
Certificate Renewal
Monitor Expiration
Create a systemd timer to check certificate expiration:
# /etc/systemd/system/cert-check.service
[Unit]
Description=Check EAP-TLS certificate expiration
[Service]
Type=oneshot
ExecStart=/usr/local/bin/cert-check.sh
# /etc/systemd/system/cert-check.timer
[Unit]
Description=Weekly certificate expiration check
[Timer]
OnCalendar=weekly
Persistent=true
[Install]
WantedBy=timers.target
Check Script
#!/bin/bash
# /usr/local/bin/cert-check.sh
CERT="/etc/ssl/certs/<hostname>-eaptls.pem"
DAYS_WARNING=30
# Check if cert expires within warning period
if ! openssl x509 -in "$CERT" -noout -checkend $((DAYS_WARNING * 86400)); then
echo "WARNING: Certificate expires within $DAYS_WARNING days"
# Add notification logic (email, logging, etc.)
fi
Troubleshooting
Certificate Chain Incomplete
Symptom: RADIUS rejects with "certificate verify failed"
Solution: Ensure ca-chain.pem contains full chain:
# View chain
openssl crl2pkcs7 -nocrl -certfile /etc/ssl/certs/ca-chain.pem | \
openssl pkcs7 -print_certs -noout
# Should show: Root CA, then Intermediate CA(s)