To test mutual SSL (two-way SSL)
authentication using curl, you need to set up a server that requires client certificates for access, and then use curl to make
requests to this server with the appropriate client certificate.
Here’s a step-by-step guide for setting up and
testing mutual SSL with curl:
1. Generate Certificates
If you haven’t already, you need to generate the necessary certificates. Here’s a brief overview:
a. Create a CA (Certificate Authority):
bash
# Generate CA private key
openssl genpkey -algorithm RSA -out ca.key
# Generate CA certificate
openssl req -x509 -new -nodes -key ca.key -sha256 -days 365 -out ca.crt
b. Generate a server certificate:
# Generate server private key
openssl genpkey -algorithm RSA -out server.key
# Generate server CSR
openssl req -new -key server.key -out server.csr
# Sign the server CSR with the CA certificate
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256
c. Generate a client certificate:
bash
# Generate client private key
openssl genpkey -algorithm RSA -out client.key # Generate client CSR
openssl req -new -key client.key -out client.csr
# Sign the client CSR with the CA certificate
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 -sha256
2. Set Up the Server
For this example, let’s assume you’re using an Nginx server. Configure it to use mutual SSL:
Nginx configuration (e.g., /etc/nginx/nginx.conf or a server block configuration file):
nginx
bash
For this example, let’s assume you’re using an Nginx server. Configure it to use mutual SSL:
Nginx configuration (e.g., /etc/nginx/nginx.conf or a server block configuration file):
nginx
server {
listen 443 ssl;
# Path to your server certificate and private key
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
# Path to CA certificate for verifying client certificates
ssl_client_certificate /etc/ssl/certs/ca.crt;
ssl_verify_client on;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
After updating the configuration, restart Nginx:
sudo systemctl restart nginx
Configure Apache
a. Copy Certificates to Apache Directories:
Place your certificates and keys in a secure directory, for example:
bash
sudo cp server.crt /etc/ssl/certs/
sudo cp server.key /etc/ssl/private/
sudo cp ca.crt /etc/ssl/certs/
sudo cp client.crt /etc/ssl/certs/
sudo cp client.key /etc/ssl/private/
b. Edit Apache Configuration:
You need to configure Apache to use the server certificate and to request a client certificate. This is typically done in a virtual host configuration file or in the main Apache configuration file.
For Ubuntu/Debian, edit the file /etc/apache2/sites-available/000-default.conf. For RHEL/CentOS, edit /etc/httpd/conf.d/ssl.conf or a similar file.
Add or update the following directives:
apache
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/html
# Enable SSL
SSLEngine on
# Server Certificate
SSLCertificateFile /etc/ssl/certs/server.crt
SSLCertificateKeyFile /etc/ssl/private/server.key
# CA Certificate
SSLCACertificateFile /etc/ssl/certs/ca.crt
# Request a client certificate
SSLVerifyClient require
SSLVerifyDepth 1
# Additional SSL settings
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:!aNULL:!MD5
SSLHonorCipherOrder on
# DocumentRoot settings
<Directory /var/www/html>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
c. Enable SSL Module and Site Configuration:
On Debian/Ubuntu:
bash
sudo a2enmod ssl
sudo a2ensite default-ssl
On RHEL/CentOS: You might already have SSL enabled; just ensure the configuration file is included and correctly set.
d. Restart Apache:
Apply the configuration changes by restarting Apache:
bash
sudo systemctl restart apache2 # For Debian/Ubuntu
sudo systemctl restart httpd # For RHEL/CentOS
3. Test with curl
Use curl to make a request to the server with mutual SSL:
curl -v https://your-server-domain/ --cert client.crt --key client.key --cacert ca.crt
Explanation:
--cert
client.crt: Specifies the client certificate to use.
--key
client.key: Specifies the private key associated with the client
certificate.
--cacert
ca.crt: Specifies the CA certificate used to verify the server's
certificate.
Example output:
plaintext
* Trying <server-ip>...
* TCP_NODELAY set
* Connected to your-server-domain (<server-ip>) port 443 (#0)
* schannel: SSL/TLS connection with your-server-domain port 443 (step 1/3)
* schannel: setting hostname via SNI
* schannel: SSL/TLS connection with your-server-domain port 443 (step 2/3)
* schannel: SSL/TLS connection with your-server-domain port 443 (step 3/3)
* Server certificate:
* subject:CN=your-server-domain
* start date:Sep 1 00:00:00 2024 GMT
* expire date: Sep 1 00:00:00 2025 GMT
* subjectAltName: host "your-server-domain" matched cert's "your-server-domain"
* issuer: CN=My CA
* SSL certificate verify ok.
> GET / HTTP/1.1
> Host: your-server-domain
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.18.0
< Date: Mon, 02 Sep 2024 00:00:00 GMT
< Content-Type: text/html
< Content-Length: 612
< Last-Modified: Mon, 02 Sep 2024 00:00:00 GMT
< Connection: keep-alive
< ETag: "5f2e3b7d-264"
< Accept-Ranges: bytes
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style> /* Add some basic styling here */</style></head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and working.</p>
</body>
</html>
* Connection #0 to host your-server-domain left intact If curl successfully connects and retrieves content, mutual SSL is working correctly. If there are issues, check both server and client logs for troubleshooting.
If curl successfully connects and retrieves content, mutual SSL is working correctly. If there are issues, check both server and client logs for troubleshooting.