-
Notifications
You must be signed in to change notification settings - Fork 0
/
autoCertif
executable file
·282 lines (242 loc) · 11.9 KB
/
autoCertif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
#!/bin/bash
# AUTHORS
# Froissart Kévin : [email protected]
# Bourdin Maxence : [email protected]
# Version 1.1
# 03/march/2020
# USAGE:
# chmod +x ./autoCertif
# sudo ./autoCertif
# sudo ./autoCertif clean
# sudo ./autoCertif init
# sudo ./autoCertif --help
################## DECLARE FUNCTIONS ##################
# Cette méthode permet de vérifier si l'utilisateur est root
checkRoot() {
if [ $(id -u) -ne 0 ]; then
printf "Script must be run as root. Try 'sudo ./autoCertif'\n"
exit 1
fi
}
# Cette méthode permet de vérifier si tous les paquets requis sont installés
checkNeededPackages() {
lst="expect openssl apache2"
for items in $lst
do
type -P $items &>/dev/null || {
echo -en "\n Package \"$items\" is not installed!"
echo -en "\n Install now? y/n: "
read ops
case $ops in
[Yy]* ) sudo apt-get install $items ;;
*) echo -e "\n Exiting..."
exit 1 ;;
esac
}
done
}
# Cette méthode affiche les informations entrés par l'utilisateur dans le fichier certificat.cfg
informationCorrect() {
printf "\n\n"
echo "Country name = "$countryName
echo "State or province name = "$stateOrProvinceName
echo "Locality name = "$localityName
echo "Organization name = "$organizationName
echo "Organizational Unit Name = "$organizationUnitName
echo "Common name = "$commonName
echo "Email Address = "$email
echo "Public IP = "$publicIp
while true; do
printf "\n\n"
read -p "Are these informations correct ? y/n " yn
case $yn in
[Yy]* ) break;;
[Nn]* ) printf "Please edit certificat.cfg to match expected informations\n";
printf "Try 'sudo ./autoCertif init' if file missing or corrupted\n";
exit 0;;
* ) echo "Please answer yes or no.";;
esac
done
}
# Cette méthode permet de lire le fichier certificat.cfg afin d'en récupérer son contenu
readConfigFile() {
fichier=$(cat certificat.cfg)
fichier=$(echo $fichier | tr ' ' '=');
countryName=$(echo $fichier | awk -F '=' '{print $2}')
stateOrProvinceName=$(echo $fichier | awk -F '=' '{print $4}')
localityName=$(echo $fichier | awk -F '=' '{print $6}')
organizationName=$(echo $fichier | awk -F '=' '{print $8}')
organizationUnitName=$(echo $fichier | awk -F '=' '{print $10}')
commonName=$(echo $fichier | awk -F '=' '{print $12}')
email=$(echo $fichier | awk -F '=' '{print $14}')
publicIp=$(echo $fichier | awk -F '=' '{print $16}')
informationCorrect
}
# Cette méthode demande à l'utilisateur d'entrer un mot de passe
informationQuerry() {
read -s -p "Enter a PEM pass phrase (4-20 length) = " PEMpassword
passwordLength
}
# Cette méthode permet de vérifier la longueur du mot de passe
passwordLength() {
if [ ${#PEMpassword} -gt 20 ]; then
printf "Password is too long\n"
printf "Password's lenght must be between 4 and 20 !\n"
informationQuerry;
elif [ ${#PEMpassword} -lt 4 ]; then
printf "Password is too short\n"
printf "Password's lenght must be between 4 and 20 !\n"
informationQuerry;
fi
}
# Cette méthode permet de modifier les informations présentes dans le fichier ca.cnf
changeInfo() {
sed -i 's/dir = .\/demoCA/dir = .\/CA/g' CA/ca.cnf
sed -i 's/countryName_default = AU/countryName_default = '$countryName'/g' CA/ca.cnf
sed -i 's/tateOrProvinceName_default = Some-State/tateOrProvinceName_default = '$stateOrProvinceName'/g' CA/ca.cnf
sed -i 's/0.organizationName_default = Internet Widgits Pty Ltd/0.organizationName_default = '$organizationName'/g' CA/ca.cnf
sed -i 's/#organizationalUnitName_default =/organizationalUnitName_default = '$organizationUnitName'/g' CA/ca.cnf
printf "Config file: updated\n"
}
# Cette méthode permet de générer le fichier certificat.cfg
editConfigFile() {
if touch certificat.cfg && echo -e "countryName=\nStateOrProvinceName=\nlocalityName=\norganizationName=\norganizationUnitName=\ncommonName=\nemail=\nmachinePublicIp=\n" > certificat.cfg; then
printf "certificat.cfg has been initialised and is ready to be modified\n"
fi
}
# Cette méthode permet de modifier les fichiers de configuration d'apache
editApache() {
for file in $1
do
sed -i 's/#LoadModule ssl_module modules\/mod_ssl.so/LoadModule ssl_module modules\/mod_ssl.so/g' $file
if grep -ozqs -P "Listen 443 https\s<VirtualHost \*:80>\s\tServerName www.example.com\s\tDocumentRoot \"/usr/local/apache2/htdocs\"\s</VirtualHost>\s<VirtualHost \*:443>\s\tServerName ssl.example.com\s\tSSLEngine On\s\tSSLCertificateFile \"/opt/apache2/ssl/webserver.cert\"\s\tSSLCertificateKeyFile \"/opt/apache2/ssl/webserver.key\"\s\tDocumentRoot \"/usr/local/apache2/htdocs\"\s</VirtualHost>\s" $file; then
printf "$file is already up to date\n"
else
sed -i 's/Listen 80/#Listen 80/g' $file
if $(echo $file | grep "httpd.conf"); then
sed -i '/httpd-vhosts.conf/a Listen 80 http\nListen 443 https\n<VirtualHost *:80>\n\tServerName www.example.com\n\tDocumentRoot \"/usr/local/apache2/htdocs\"\n</VirtualHost>\n<VirtualHost *:443>\n\tServerName ssl.example.com\n\tSSLEngine On\n\tSSLCertificateFile \"/opt/apache2/ssl/webserver.cert\"\n\tSSLCertificateKeyFile \"/opt/apache2/ssl/webserver.key\"\n\tDocumentRoot \"/usr/local/apache2/htdocs\"\n</VirtualHost>\n' $file
printf "$file has been updated\n"
else
sudo sed -ie 's/SSLCertificateFile \/etc\/ssl\/certs\/ssl-cert-snakeoil.pem/SSLCertificateFile \/etc\/ssl\/certs\/webserver.cert/g' /etc/apache2/sites-enabled/default-ssl.conf # "$(locate default-ssl.conf)"
sudo sed -ie 's/SSLCertificateKeyFile \/etc\/ssl\/private\/ssl-cert-snakeoil.key/SSLCertificateKeyFile \/etc\/ssl\/private\/webserver.key/g' /etc/apache2/sites-enabled/default-ssl.conf #"$(locate default-ssl.conf)"
sudo sed -ie 's/SSLEngine Off/SSLEngine On/g' /etc/apache2/sites-enabled/default-ssl.conf #"$(locate default-ssl.conf)"
fi
fi
done
}
######################## GO ########################
# Si l'utlisateur est root le programme continue
checkRoot
# On vérifie les paramètres
# S'il y a plus d'un paramètre on renvoie une erreur
if [ "$#" -gt 1 ]; then
printf "Illegal number of parameters\n"
exit 2;
# Si le paramètre est "--help" on affiche l'aide
elif [ "$1" = "--help" ]; then
printf "\n Program must be run as sudo\n"
printf " It is mandatory to complete certificat.cfg\n"
printf " Config file openssl.cnf is also needed to run the program\n"
printf " Try 'sudo ./autoCertif' to create self-signed certificates,\n"
printf " a pre-built architechture to store the generated files\n"
printf " and to configure apache2 files\n"
printf " Try 'sudo ./autoCertif clean' to flush the architechture\n"
printf " Try 'sudo ./autoCertif init' to initialize the config file\n"
printf "\n"
exit 0;
# Si le paramètre est "clean" on efface l'architecture CA
elif [ "$1" = "clean" ]; then
if rm -R --force CA > /dev/null 2>&1; then
printf "Architecture: cleaned\n"
else sudo rm -R CA > /dev/null 2>&1
printf "Architecture: cleaned\n"
fi
exit 0;
# Si le paramètre est "init" on créé le fichier certificat.cfg
elif [ "$1" = "init" ]; then
editConfigFile
exit 0;
# S'il n'y a qu'un paramètre et qu'il est inconnu on renvoie une erreur
elif [ "$#" -eq 1 ]; then
printf "Illegal argument, try './autoCertif --help'\n"
exit 1;
fi
# Pour continuer on vérifie si tous les paquets sont installés
checkNeededPackages
# On lit le fichier certificat.cfg afin d'en récupérer son contenu
readConfigFile
# L'utilisateur confirme si les informations lues sont correctes
informationQuerry
# On créer l'architecture de fichier et initialise les fichiers nécéssaires à la création des certificats
mkdir CA && mkdir CA/newcerts && mkdir CA/certrequests && mkdir CA/private
echo "01" > CA/serial && touch CA/index.txt && echo "Architecture: done"
cp openssl.cnf CA/ca.cnf
# On met à jour le fichier de configuration ca.cnf
changeInfo
# On créé le certificat ainsi que sa clé privée
/usr/bin/expect <<EOD
spawn sudo openssl req -new -x509 -extensions v3_ca -newkey rsa:4096 -keyout CA/private/cakey.pem -out CA/cacert.pem -config CA/ca.cnf
expect {Enter PEM pass phrase:} {send "${PEMpassword}\n"}
expect {Verifying - Enter PEM pass phrase:} {send "${PEMpassword}\n"}
expect -re {Country Name \(2 letter code\) [^:]*:} {send ".\n"}
expect -re {State or Province Name \(full name\) [^:]*:} {send ".\n"}
expect -re {Locality Name \(eg, city\) [^:]*:} {send "${localityName}\n"}
expect -re {Organization Name \(eg, company\) [^:]*:} {send ".\n"}
expect -re {Organizational Unit Name \(eg, section\) [^:]*:} {send ".\n"}
expect -re {Common Name \(e.g. server FQDN or YOUR name\) [^:]*:} {send "${commonName}\n"}
expect -re {Email Address [^:]*:} {send "${email}\n"}
expect eof
EOD
printf "\n\nCertificate and private key succesfully created\n\n"
# On émet la requête de certificat CSR
/usr/bin/expect <<EOD
spawn sudo openssl req -new -nodes -newkey rsa:2048 -keyout CA/private/webserver.key -out CA/certrequests/webserver.csr -config CA/ca.cnf
expect -re {Country Name \(2 letter code\) [^:]*:} {send ".\n"}
expect -re {State or Province Name \(full name\) [^:]*:} {send ".\n"}
expect -re {Locality Name \(eg, city\) [^:]*:} {send "${localityName}\n"}
expect -re {Organization Name \(eg, company\) [^:]*:} {send ".\n"}
expect -re {Organizational Unit Name \(eg, section\) [^:]*:} {send ".\n"}
expect -re {Common Name \(e.g. server FQDN or YOUR name\) [^:]*:} {send "${publicIp}\n"}
expect -re {Email Address [^:]*:} {send "${email}\n"}
expect -re {A challenge password [^:]*:} {send "${PEMpassword}\n"}
expect -re {An optional company name [^:]*:} {send "\n"}
expect eof
EOD
printf "\n\nCertificate Signing Request successfully created\n\n"
# On créé finalement le certificat pour apache
/usr/bin/expect <<EOD
spawn sudo openssl ca -config CA/ca.cnf -policy policy_anything -out CA/newcerts/webserver.cert -infiles CA/certrequests/webserver.csr
expect {Enter pass phrase for ./CA/private/cakey.pem:} {send "${PEMpassword}\n"}
expect -re {Sign the certificate\? [^:]*:} {send "y\n"}
expect -re {1 out of 1 certificate requests certified, commit\? [^:]*} {send "y\n"}
expect eof
EOD
printf "\nCertificate succesfully signed\n\n"
#openssl x509 -in CA/newcerts/webserver.cert -noout -text
# On vérifie si le certificat est valable
sudo openssl verify -CAfile CA/cacert.pem CA/newcerts/webserver.cert
# On copie les fichiers nécéssaires au fonctionnement du module SSL d'apache
if sudo locate -q ssl/private/ > /dev/null 2>&1; then
if sudo cp CA/private/webserver.key /etc/ssl/private/ && sudo cp CA/newcerts/webserver.cert /etc/ssl/certs/; then
printf "\nFiles succesfully added to apache2\n"
fi
else
if mkdir -p /opt/apache2/ssl && cp CA/private/webserver.key /opt/apache2/ssl/ && cp CA/newcerts/webserver.cert /opt/apache2/ssl/; then
printf "\nFiles succesfully added to apache2\n"
fi
fi
# On active le module SSL
if sudo a2enmod ssl > /dev/null 2>&1; then
printf "\nApache ssl module has been enabled\n"
fi
# On met à jour les fichiers de configuration d'apache
editApache "$(locate httpd.conf)"
editApache "$(locate 000-default.conf)"
# On redémarre apache
if sudo apachectl stop > /dev/null 2>&1 && sudo apachectl start > /dev/null; then
printf "\napache2 has been restarted and is ready for use\n"
fi
printf "\n You can access your server at http://$publicIp/ using port 80\n"
printf " Or using port 443 at https://$publicIp/\n"
printf " To access https://$publicIp/ please import\n $PWD/CA/cacert.pem\n"
printf " to your Web Browser.\n\n\n"