-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge PR #85 from usit-gd/feature-public-client-ca
This PR takes care of 2 issues: - It automates the upgrading process of the client CA certificate, making it easy to upgrade, and "documenting" (in the form of code) how to do it. #27 - It publishes a bundle with the currently active CA certificates on the web server, facilitating 3rd party use. #32 See also: https://github.com/usit-gd/nivlheim/wiki/Client-certificates
- Loading branch information
Showing
10 changed files
with
227 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,7 +45,7 @@ sub getpassword(); | |
# Options with default values | ||
my %defaultopt = ( | ||
'config' => '/etc/nivlheim/client.conf:/usr/local/etc/nivlheim/client.conf', # configuration file | ||
'ca_file' => '/var/nivlheim/nivlheimca.crt:/var/www/nivlheim/CA/nivlheimca.crt' | ||
'ca_file' => '/var/nivlheim/nivlheimca.crt' | ||
. ':/etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-bundle.crt' | ||
. ':/etc/pki/tls/certs/ca-bundle.crt:/usr/local/et/ssl/cert.pem', | ||
'cert_file' => '/var/nivlheim/my.crt', | ||
|
@@ -62,7 +62,7 @@ my $NAME = 'nivlheim_client'; | |
my $AUTHOR = 'Øyvind Hagberg'; | ||
my $CONTACT = '[email protected]'; | ||
my $RIGHTS = 'USIT/IT-DRIFT/GD/GID, University of Oslo, Norway'; | ||
my $VERSION = '0.10.1'; | ||
my $VERSION = '0.12.1'; | ||
|
||
# Usage text | ||
my $USAGE = <<"END_USAGE"; | ||
|
@@ -494,15 +494,13 @@ sub ssl_connect($$$) { | |
my ($hostname, $port, $use_client_cert) = @_; | ||
|
||
if (!-r $opt{cert_file} || !-r $opt{key_file}) { $use_client_cert = 0; } | ||
my $commonName; | ||
if ($real_ca_file =~ m!/nivlheimca\.crt$!) { | ||
$commonName = "localhost"; | ||
} else { | ||
$commonName = $hostname; | ||
|
||
my $verify_mode = IO::Socket::SSL::SSL_VERIFY_PEER(); | ||
if ($hostname eq 'localhost') { | ||
$verify_mode = IO::Socket::SSL::SSL_VERIFY_NONE(); | ||
} | ||
if ($opt{debug}) { | ||
print "hostname=$hostname port=$port\n"; | ||
print "commonName=$commonName use_client_cert=$use_client_cert\n"; | ||
print "hostname=$hostname port=$port use_client_cert=$use_client_cert\n"; | ||
#$IO::Socket::SSL::DEBUG = 3; | ||
} | ||
|
||
|
@@ -542,9 +540,9 @@ sub ssl_connect($$$) { | |
# We have a connection - try to start SSL | ||
if (my $ssl = IO::Socket::SSL->new_from_fd( | ||
$socket->fileno(), | ||
SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_PEER(), | ||
SSL_verify_mode => $verify_mode, | ||
SSL_verifycn_scheme => 'http', | ||
SSL_verifycn_name => $commonName, | ||
SSL_verifycn_name => $hostname, | ||
SSL_ca_file => $real_ca_file, | ||
SSL_ca_path => '', | ||
SSL_use_cert => $use_client_cert ? 1 : 0, | ||
|
@@ -560,8 +558,7 @@ sub ssl_connect($$$) { | |
} | ||
else { | ||
# Negotiation failed | ||
warn("Could not establish SSL connection: $! $@\n") | ||
if $opt{debug}; | ||
warn("Could not establish SSL connection: $! $@\n"); | ||
} | ||
$socket->close(); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -82,7 +82,7 @@ Requires: perl(Sys::Syslog) | |
%package server | ||
Summary: Server components of Nivlheim | ||
Group: Applications/System | ||
Requires: perl, openssl, httpd, mod_ssl, systemd | ||
Requires: perl, openssl, httpd, mod_ssl, systemd, cronie | ||
Requires: postgresql, postgresql-server, postgresql-contrib | ||
Requires: unzip, file | ||
Requires: perl(Archive::Tar) | ||
|
@@ -190,6 +190,7 @@ install -p -m 0755 server/setup.sh %{buildroot}%{_localstatedir}/nivlheim/ | |
install -p -m 0755 server/cgi/processarchive %{buildroot}/var/www/cgi-bin/ | ||
install -p -m 0644 server/nivlheim.service %{buildroot}%{_unitdir}/%{name}.service | ||
install -p -m 0644 -D client/cronjob %{buildroot}%{_sysconfdir}/cron.d/nivlheim_client | ||
install -p -m 0755 -D server/client_CA_cert.sh %{buildroot}%{_sysconfdir}/cron.daily/client_CA_cert.sh | ||
rm -rf server/website/mockapi server/website/templates server/website/libs | ||
cp -a server/website/* %{buildroot}%{_localstatedir}/www/html/ | ||
install -p -m 0644 ../jquery-3.3.1/dist/jquery.min.js %{buildroot}%{_localstatedir}/www/html/libs/jquery-3.3.1.min.js | ||
|
@@ -244,6 +245,7 @@ rm -rf %{buildroot} | |
%config(noreplace) %{_sysconfdir}/httpd/conf.d/nivlheim.conf | ||
%config %{_sysconfdir}/nivlheim/openssl_ca.conf | ||
%config(noreplace) %{_sysconfdir}/nivlheim/server.conf | ||
%{_sysconfdir}/cron.daily/client_CA_cert.sh | ||
%{_unitdir}/%{name}.service | ||
%{_sbindir}/nivlheim_service | ||
%dir /var/log/nivlheim | ||
|
@@ -263,6 +265,9 @@ rm -rf %{buildroot} | |
%systemd_postun_with_restart %{name}.service | ||
|
||
%changelog | ||
* Mon Mar 11 2019 Øyvind Hagberg <[email protected]> - 0.12.2-20190311 | ||
- New cron job that maintains the client CA certificates | ||
|
||
* Tue Dec 11 2018 Øyvind Hagberg <[email protected]> - 0.11.0-20181211 | ||
- Include 3rd party javascript and css libraries in the rpm file | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#!/bin/bash | ||
|
||
# This script is a part of Nivlheim. | ||
# It is used to create CA certificates that are used for signing | ||
# client certificates. | ||
# | ||
# It is intended to be run without parameters, as a cron job. | ||
# It will check the expiry date of the existing CA certificate, | ||
# and replace it with a new one when necessary. | ||
# | ||
# To make it easier for 3rd party software to verify client certificates, | ||
# a new CA certificate will appear in the bundle https://<server>/clientca.pem | ||
# 3 weeks before it is actually put to use. | ||
|
||
|
||
if [ `whoami` != "root" ]; then | ||
echo "This script must be run as root." | ||
exit 1 | ||
fi | ||
|
||
# What operations to perform | ||
CREATE=0 | ||
ACTIVATE=0 | ||
VERBOSE=0 | ||
|
||
# Parameters may override normal operations | ||
while (( "$#" )); do | ||
if [[ "$1" == "--force-create" ]]; then | ||
CREATE=1 | ||
elif [[ "$1" == "--force-activate" ]]; then | ||
ACTIVATE=1 | ||
elif [[ "$1" == "--verbose" ]] || [[ "$1" == "-v" ]]; then | ||
VERBOSE=1 | ||
else | ||
echo "Unknown argument: $1" | ||
exit 1 | ||
fi | ||
shift | ||
done | ||
|
||
cd /var/www/nivlheim/CA | ||
|
||
# If the CA certificate will expire in less than 30 days, create a new one | ||
if [ ! -f nivlheimca.crt ] || ! openssl x509 -checkend 2592000 -noout -in nivlheimca.crt -enddate >/dev/null; then | ||
CREATE=1 | ||
fi | ||
|
||
# If the CA certificate will expire in less than 9 days, change to the new one | ||
if [ ! -f nivlheimca.crt ] || ! openssl x509 -checkend 777600 -noout -in nivlheimca.crt >/dev/null; then | ||
ACTIVATE=1 | ||
fi | ||
|
||
if [[ $CREATE -eq 1 ]]; then | ||
if [ ! -f new_nivlheimca.crt ] || [ ! -f new_nivlheimca.key ]; then | ||
[ $VERBOSE -eq 1 ] && echo "Creating a new CA certificate" | ||
|
||
# Generate a new certificate | ||
rm -f old_* | ||
openssl genrsa -out new_nivlheimca.key 4096 >/dev/null 2>&1 | ||
openssl req -new -key new_nivlheimca.key -out new_nivlheimca.csr -subj "/C=NO/ST=Oslo/L=Oslo/O=UiO/OU=USIT/CN=Nivlheim$RANDOM" | ||
openssl x509 -req -days 365 -in new_nivlheimca.csr -out new_nivlheimca.crt -signkey new_nivlheimca.key >/dev/null 2>&1 | ||
|
||
# Fix permissions | ||
chgrp apache new_nivlheimca.* | ||
chmod 640 new_nivlheimca.key | ||
|
||
# Show results | ||
[ $VERBOSE -eq 1 ] && openssl x509 -in new_nivlheimca.crt -noout -enddate | ||
|
||
# create a bundle with the old and the new CA | ||
cat nivlheimca.crt new_nivlheimca.crt > /var/www/html/clientca.pem | ||
else | ||
echo "Won't create a new CA certificate; One has already been created and is waiting" | ||
fi | ||
fi | ||
|
||
if [[ $ACTIVATE -eq 1 ]]; then | ||
if [ -f new_nivlheimca.crt ] && [ -f new_nivlheimca.key ]; then | ||
[ $VERBOSE -eq 1 ] && echo "Activating the new CA certificate" | ||
# Activate/change to the new CA certificate | ||
mv nivlheimca.key old_nivlheimca.key | ||
mv nivlheimca.csr old_nivlheimca.csr | ||
mv nivlheimca.crt old_nivlheimca.crt | ||
mv new_nivlheimca.key nivlheimca.key | ||
mv new_nivlheimca.csr nivlheimca.csr | ||
mv new_nivlheimca.crt nivlheimca.crt | ||
systemctl restart httpd | ||
else | ||
echo "There's no new CA certificate to activate" | ||
exit 1 | ||
fi | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#!/bin/bash | ||
|
||
echo "-------------- Testing creating/activating a new client CA certificate -----------" | ||
set -e | ||
|
||
# Clean/init everything | ||
sudo systemctl stop nivlheim | ||
sudo rm -f /var/log/nivlheim/system.log /var/nivlheim/my.{crt,key} \ | ||
/var/run/nivlheim_client_last_run /var/www/nivlheim/certs/* \ | ||
/var/www/nivlheim/queue/* | ||
echo -n | sudo tee /var/log/httpd/error_log | ||
sudo -u apache /var/nivlheim/installdb.sh --wipe | ||
sudo systemctl start nivlheim | ||
sleep 4 | ||
|
||
# Run the client. This will call reqcert and post | ||
if ! grep -s -e "^server" /etc/nivlheim/client.conf > /dev/null; then | ||
echo "server=localhost" | sudo tee -a /etc/nivlheim/client.conf | ||
fi | ||
curl -sS -X POST 'http://localhost:4040/api/v0/settings/ipranges' -d 'ipRange=127.0.0.0/24' | ||
sudo /usr/sbin/nivlheim_client | ||
if [[ ! -f /var/run/nivlheim_client_last_run ]]; then | ||
echo "The client failed to post data successfully." | ||
exit 1 | ||
fi | ||
|
||
# Create a new CA certificate | ||
sudo /etc/cron.daily/client_CA_cert.sh --force-create --verbose | ||
|
||
# Verify that the old client certificate still works | ||
if ! sudo curl -sSkf --cert /var/nivlheim/my.crt --key /var/nivlheim/my.key \ | ||
https://localhost/cgi-bin/secure/ping; then | ||
echo "The client cert didn't work after a new CA was created." | ||
exit 1 | ||
fi | ||
|
||
# Verify that the client doesn't ask for a new certificate yet | ||
OLDMD5=$(md5sum /var/nivlheim/my.crt) | ||
sudo /usr/sbin/nivlheim_client | ||
NEWMD5=$(md5sum /var/nivlheim/my.crt) | ||
if [[ "$OLDMD5" != "$NEWMD5" ]]; then | ||
echo "The client got get a new certificate before the new CA was activated." | ||
exit 1 | ||
fi | ||
|
||
# Ask for a new certificate, verify that they are still being signed with the old CA cert | ||
A=`openssl x509 -in /var/nivlheim/my.crt -noout -issuer_hash` | ||
sudo rm -f /var/nivlheim/my.* /var/run/nivlheim_client_last_run | ||
sudo /usr/sbin/nivlheim_client | ||
if [[ ! -f /var/run/nivlheim_client_last_run ]]; then | ||
echo "The client failed to run the second time." | ||
exit 1 | ||
fi | ||
B=`openssl x509 -in /var/nivlheim/my.crt -noout -issuer_hash` | ||
if [[ "$A" != "$B" ]]; then | ||
echo "After creating a new CA cert, it was used for issuing even before it was activated." | ||
exit 1 | ||
fi | ||
|
||
# Activate the new CA certificate | ||
sudo /etc/cron.daily/client_CA_cert.sh --force-activate --verbose | ||
|
||
# Verify that the old client certificate still works | ||
sudo cp /var/www/cgi-bin/ping /var/www/cgi-bin/secure/foo | ||
if ! sudo curl -sSkf --cert /var/nivlheim/my.crt --key /var/nivlheim/my.key \ | ||
https://localhost/cgi-bin/secure/foo; then | ||
echo "The client cert didn't work after a new CA was activated." | ||
exit 1 | ||
fi | ||
|
||
# Run the client again, verify that it asked for (and got) a new certificate | ||
# (because secure/ping should return 400) | ||
# and verify that it was signed with the new CA cert | ||
OLDMD5=$(md5sum /var/nivlheim/my.crt) | ||
sudo rm -f /var/run/nivlheim_client_last_run | ||
sudo /usr/sbin/nivlheim_client | ||
if [[ ! -f /var/run/nivlheim_client_last_run ]]; then | ||
echo "The client failed to run the third time." | ||
exit 1 | ||
fi | ||
NEWMD5=$(md5sum /var/nivlheim/my.crt) | ||
if [[ "$OLDMD5" == "$NEWMD5" ]]; then | ||
echo "The client didn't get a new certificate after the server got a new CA." | ||
exit 1 | ||
fi | ||
C=`openssl x509 -in /var/nivlheim/my.crt -noout -issuer_hash` | ||
if [[ "$B" == "$C" ]]; then | ||
echo "Still signing with the old CA cert, even after the new one was activated." | ||
exit 1 | ||
fi | ||
|
||
echo "Test result: OK" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters