#8 closed task (fixed)
Install phpMyAdmin on crin1 and enable encrypted connections from crin2
Reported by: | chris | Owned by: | chris |
---|---|---|---|
Priority: | major | Milestone: | Install and configure crin1 |
Component: | crin1 | Version: | |
Keywords: | Cc: | jenny, gillian | |
Estimated Number of Hours: | 5.5 | Add Hours to Ticket: | 0 |
Billable?: | yes | Total Hours: | 5.42 |
Description
The plan is to have Drupal on crin2 connecting to the MySQL server on crin1 using SSL/TLS and also have phpMyAdmin running on crin1 with HTTP Authentication.
See:
Change History (10)
comment:1 Changed 3 years ago by chris
- Summary changed from Install phpMyAdmin on crin1 and enable encrypted connections form crin2 to Install phpMyAdmin on crin1 and enable encrypted connections from crin2
comment:2 Changed 3 years ago by chris
- Add Hours to Ticket changed from 0 to 1.3
- Total Hours set to 1.3
comment:3 Changed 3 years ago by chris
- Add Hours to Ticket changed from 0 to 0.15
- Total Hours changed from 1.3 to 1.45
We don't need access to the edit the phpMyAdmin configuration so that was disabled, the final phpmyadmin.conf file:
<VirtualHost *:80> <IfModule mpm_itk_module> AssignUserID www-data www-data MaxClientsVHost 60 </IfModule> ServerName phpmyadmin.crin.org ServerAlias phpmyadmin.crin1.webarch.net <If "%{HTTP_HOST} == 'phpmyadmin.crin1.webarch.net'"> Redirect / https://phpmyadmin.crin1.webarch.net/ </If> <If "%{HTTP_HOST} == 'phpmyadmin.crin.org'"> Redirect / https://phpmyadmin.crin.org/ </If> </VirtualHost> <IfModule mod_ssl.c> <VirtualHost *:443> <IfModule mpm_itk_module> AssignUserID www-data www-data MaxClientsVHost 60 </IfModule> ServerName phpmyadmin.crin.org ServerAlias phpmyadmin.crin1.webarch.net SSLEngine on SSLCertificateFile /etc/ssl/cacert/crin1_cert.pem SSLCertificateKeyFile /etc/ssl/cacert/crin1_privatekey.pem SSLCACertificateFile /etc/ssl/cacert/cacert.pem DocumentRoot /usr/share/phpmyadmin <Directory /usr/share/phpmyadmin> Options FollowSymLinks DirectoryIndex index.php AuthType Digest AuthName "phpmyadmin" AuthDigestDomain /phpmyadmin AuthUserFile /etc/phpmyadmin/.htpasswd Require valid-user <IfModule mod_php5.c> <IfModule mod_mime.c> AddType application/x-httpd-php .php </IfModule> <FilesMatch ".+\.php$"> SetHandler application/x-httpd-php </FilesMatch> php_flag magic_quotes_gpc Off php_flag track_vars On php_flag register_globals Off php_admin_flag allow_url_fopen Off php_value include_path . php_admin_value upload_tmp_dir /var/lib/phpmyadmin/tmp php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/php-gettext/:/usr/share/javascript/:/usr/share/php/tcpdf/ </IfModule> </Directory> # Authorize for setup <Directory /usr/share/phpmyadmin/setup> # <IfModule mod_authz_core.c> # <IfModule mod_authn_file.c> # AuthType Basic # AuthName "phpMyAdmin Setup" # AuthUserFile /etc/phpmyadmin/htpasswd.setup # </IfModule> # Require valid-user # </IfModule> Require all denied </Directory> # Disallow web access to directories that don't need it <Directory /usr/share/phpmyadmin/libraries> Require all denied </Directory> <Directory /usr/share/phpmyadmin/setup/lib> Require all denied </Directory> <IfModule headers_module> # Use HTTP Strict Transport Security to force client to use secure connections only Header always set Strict-Transport-Security "max-age=31536000" # mitigate TIME attack Header always append X-Frame-Options "sameorigin" </IfModule> <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> <Directory /usr/lib/cgi-bin> SSLOptions +StdEnvVars </Directory> BrowserMatch "MSIE [2-6]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 # MSIE 7 and newer should be able to use keepalive BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown </VirtualHost> </IfModule>
comment:4 Changed 3 years ago by chris
- Add Hours to Ticket changed from 0 to 2.1
- Total Hours changed from 1.45 to 3.55
Testing SSL/TLS encrypted MySQL access from Crin2 to Crin1, will it work with the CAcert.org cert and the current version of OpenSSL or will openssl-0.9.8 be needed as before?
On Crin2:
sudo -i mkdir /root/bin cd bin wget http://svn.cacert.org/CAcert/Software/CSRGenerator/csr chmod 700 csr ./csr Private Key and Certificate Signing Request Generator This script was designed to suit the request format needed by the CAcert Certificate Authority. www.CAcert.org Short Hostname (ie. imap big_srv www2): crin2 FQDN/CommonName (ie. www.example.com) : crin2.webarch.net Type SubjectAltNames for the certificate, one per line. Enter a blank line to finish SubjectAltName: DNS:crin2.webarch.net SubjectAltName: DNS:*.crin2.webarch.net SubjectAltName: DNS: Running OpenSSL... Generating a 2048 bit RSA private key ............
Save the cert as /root/crin2_cert.pem then move and get the root:
mkdir /etc/ssl/cacert chmod 700 /etc/ssl/cacert/ cd /etc/ssl/cacert/ mv /root/crin2_* . wget https://www.cacert.org/certs/root.crt --no-check-certificate wget https://www.cacert.org/certs/class3.crt --no-check-certificate cat root.crt > cacert.pem cat class3.crt >> cacert.pem chmod 600 *.pem
On Crin2 (the client) create a /root/.my.cnf:
[client] host=crin1 #ssl-cipher=DHE-RSA-AES256-SHA ssl-ca=/etc/ssl/cacert/cacert.pem ssl-cert=/etc/ssl/cacert/crin2_cert.pem ssl-key=/etc/ssl/cacert/crin2_privatekey.pem
On Crin1 (the server) create a test user and database:
mysql mysql> CREATE DATABASE example; mysql> GRANT ALL ON example.* to 'example'@'crin2' identified by 'XXX' REQUIRE SSL; mysql> FLUSH PRIVILEGES;
On Crin2 (the client) add the following to /etc/hosts:
93.95.228.179 crin1 crin1.crin.org crin1.webarch.net
on Crin1 (the server) edit /etc/mysql/my.cnf and add:
ssl=on #ssl-cipher=DHE-RSA-AES256-SHA ssl-ca=/etc/ssl/cacert/cacert.pem ssl-cert=/etc/ssl/cacert/crin1_cert.pem ssl-key=/etc/ssl/cacert/crin1_privatekey.pem
On Crin2 copy the cert from Crin1, install the MySQL client and try to connect:
aptitude install mysql-client-5.5 mysql -uexample -pXXX -hcrin1 --ssl-ca=/etc/ssl/cacert/cacert.pem --ssl-cert=/etc/ssl/cacert/crin1_cert.pem example ERROR 2003 (HY000): Can't connect to MySQL server on 'crin1' (111)
On Crin1 check the firewall:
iptables -L | grep crin2 ACCEPT tcp -- crin2 anywhere tcp dpt:mysql
On Crin2 check the name resolves:
ping crin1 PING crin1 (93.95.228.179) 56(84) bytes of data. 64 bytes from crin1 (93.95.228.179): icmp_seq=1 ttl=64 time=0.690 ms
Edit /etc/mysql/my.cnf on Crin1 and restart:
bind-address = 93.95.228.179
Now we have this error:
ERROR 1045 (28000): Access denied for user 'example'@'crin2' (using password: YES)
Which is progress!
Edit my.cnf to listen on all interfaces:
bind-address = 0.0.0.0
Restart and check the logs, we have this in /var/log/mysql/error.log
SSL error: Unable to get certificate from '/etc/ssl/cacert/crin1_cert.pem'
Could be a permission issue:
chown -R root:mysql /etc/ssl/cacert/ chmod 640 /etc/ssl/cacert/*.pem chmod 750 /etc/ssl/cacert/ service mysql restart
And now we have:
SSL error: Unable to get private key from '/etc/ssl/cacert/crin1_privatekey.pem' 150503 15:14:25 [Warning] Failed to setup SSL 150503 15:14:25 [Warning] SSL error: Unable to get private key
Found this:
So edited the private first and last lines from:
-----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY-----
Into:
-----BEGIN RSA PRIVATE KEY----- ... -----END RSA PRIVATE KEY-----
And restarted, no errors!
Tested from Crin2, and now there is this error:
ERROR 2026 (HY000): SSL connection error: protocol version mismatch
Following the suggestion at the end of this thread, removed RSA on Crin1
cd /etc/ssl/cacert openssl rsa -in crin1_privatekey.pem -out crin1_yassl_privatekey.pem
Tried connecting again from Crin2 and got:
SSL error: Unable to get private key from '/etc/ssl/cacert/crin2_yassl_privatekey.pem' ERROR 2026 (HY000): SSL connection error: Unable to get private key
Copied the Crin1 private key to Crin2 and tried:
mysql -uexample -pXXXX -hcrin1 --ssl-ca=/etc/ssl/cacert/cacert.pem --ssl-cert=/etc/ssl/cacert/crin1_cert.pem --ssl-key=/etc/ssl/cacert/crin1_yassl_privatekey.pem example Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 42 Server version: 5.5.43-0+deb8u1 (Debian) Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | example | +--------------------+ 2 rows in set (0.00 sec)
Edited /root/.my.cnf on Crin2:
[client] host=crin1 ssl-cipher=DHE-RSA-AES256-SHA ssl-ca=/etc/ssl/cacert/cacert.pem ssl-cert=/etc/ssl/cacert/crin1_cert.pem ssl-key=/etc/ssl/cacert/crin1_yassl_privatekey.pem
Test the firewall from another server:
nmap 93.95.228.179 Starting Nmap 6.00 ( http://nmap.org ) at 2015-05-03 15:45 GMT Nmap scan report for crin1.crin.org (93.95.228.179) Host is up (0.00079s latency). Not shown: 997 filtered ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 443/tcp open https Nmap done: 1 IP address (1 host up) scanned in 5.32 seconds
Test it from Crin2:
aptitude install nmap nmap 93.95.228.179 Starting Nmap 6.47 ( http://nmap.org ) at 2015-05-03 15:50 GMT Nmap scan report for crin1 (93.95.228.179) Host is up (0.00096s latency). Not shown: 996 filtered ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 443/tcp open https 3306/tcp open mysql MAC Address: 52:54:5D:5F:E4:B3 (Unknown) Nmap done: 1 IP address (1 host up) scanned in 8.29 seconds
On Crin1 edited the MySQL config file to uncomment these lines and restarted.
general_log_file = /var/log/mysql/mysql.log general_log = 1
And connected again from Crin2 to see what was logged:
150503 15:56:17 38 Connect example@crin2 on example 38 Query show databases 38 Query show tables 38 Query select @@version_comment limit 1
On Crin2, moved the /root/.my.cnf and tried to connect:
mysql -uexample -pXXX -hcrin1 example ERROR 1045 (28000): Access denied for user 'example'@'crin2' (using password: YES)
And there was this in the logs on Crin1:
150503 15:57:41 39 Connect example@crin2 on example 39 Connect Access denied for user 'example'@'crin2' (using password: YES)
This means that I'm sure that only SSL connections are being allowed, logging was switched off again:
general_log = 0
And here is another test, from Crin2:
mysql> \s -------------- mysql Ver 14.14 Distrib 5.5.43, for debian-linux-gnu (x86_64) using readline 6.3 Connection id: 43 Current database: example Current user: example@crin2 SSL: Cipher in use is DHE-RSA-AES256-SHA Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 5.5.43-0+deb8u1 (Debian) Protocol version: 10 Connection: crin1 via TCP/IP Server characterset: latin1 Db characterset: latin1 Client characterset: utf8 Conn. characterset: utf8 TCP port: 3306 Uptime: 8 min 31 sec Threads: 1 Questions: 129 Slow queries: 0 Opens: 181 Flush tables: 1 Open tables: 174 Queries per second avg: 0.252 --------------
Compare that to a connection on Crin1:
mysql> \s -------------- mysql Ver 14.14 Distrib 5.5.43, for debian-linux-gnu (x86_64) using readline 6.3 Connection id: 44 Current database: Current user: root@localhost SSL: Not in use Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 5.5.43-0+deb8u1 (Debian) Protocol version: 10 Connection: Localhost via UNIX socket Server characterset: latin1 Db characterset: latin1 Client characterset: utf8 Conn. characterset: utf8 UNIX socket: /var/run/mysqld/mysqld.sock Uptime: 11 min 43 sec Threads: 2 Questions: 133 Slow queries: 0 Opens: 181 Flush tables: 1 Open tables: 174 Queries per second avg: 0.189 --------------
So we are using SSL for sure and can move onto ticket:6.
comment:5 Changed 3 years ago by chris
- Add Hours to Ticket changed from 0 to 0.25
- Total Hours changed from 3.55 to 3.8
It is important to have SSL/TLS encrypted MySQL traffic between the Crin2 webserver and the Crin1 database server as things like passwords and IP addresses will be stored in the database and with the traffic being encrypted it becomes an awful lot harder to snoop and/or interfere with it.
The Cacert.org keys and certs are only valid for 2 years and I'm not sure if the connections will fail when they expire so we need to be sure to update them before two years is up, and there is a Debian package sepcifically designed to do this -- watch for expiry dates, so, on both servers:
aptitude install ssl-cert-check
On Crin1 this crontab was set up for the chris user:
30 09 * * * sudo ssl-cert-check -qac "/etc/ssl/cacert/crin1_cert.pem" -e "chris@webarchitects.co.uk"
And the corresponding crontab on Crin2:
30 09 * * * sudo ssl-cert-check -qac "/etc/ssl/cacert/crin2_cert.pem" -e "chris@webarchitects.co.uk"
The above means that every day at 9:30am the cert will be checked to see if they expire in less than 30 dayes and if they do then a email will be sent.
It would also be worth setting up checks for the commercial certificates to go to a crin.org email address.
comment:6 Changed 3 years ago by chris
- Add Hours to Ticket changed from 0 to 0.17
- Resolution set to fixed
- Status changed from new to closed
- Total Hours changed from 3.8 to 3.97
I have created a wiki page at wiki:phpMyAdmin and this ticket can now be closed.
comment:7 Changed 3 years ago by chris
- Add Hours to Ticket changed from 0 to 1.25
- Estimated Number of Hours changed from 0 to 5.5
- Total Hours changed from 3.97 to 5.22
phpMyAdmin is available here https://phpmyadmin.crin1.webarch.net/ but we want it at https://phpmyadmin.crin.org/ so a new DNS record was added and a csr generated for CAcert.org, first check what domain names we are using on the server:
grep "ServerAlias\|ServerName" /etc/apache2/sites-enabled/* | awk '{print $3}' | sort -u cloud.crin1.crin.org cloud.crin.org phpmyadmin.crin1.webarch.net phpmyadmin.crin.org stats.crin1.crin.org stats.crin.org trac.crin.org wiki.crin1.crin.org wiki.crin.org www.cloud.crin.org www.stats.crin.org www.wiki.crin.org
Generate a csr:
/root/bin/csr Private Key and Certificate Signing Request Generator This script was designed to suit the request format needed by the CAcert Certificate Authority. www.CAcert.org Short Hostname (ie. imap big_srv www2): crin1 FQDN/CommonName (ie. www.example.com) : crin1.crin.org Type SubjectAltNames for the certificate, one per line. Enter a blank line to finish SubjectAltName: DNS:crin1.crin.org SubjectAltName: DNS:*.crin1.crin.org SubjectAltName: DNS:*.crin.org SubjectAltName: DNS:crin1.webarch.net SubjectAltName: DNS:*.crin1.webarch.net SubjectAltName: DNS: Running OpenSSL... Generating a 2048 bit RSA private key .......
Save it as /root/crin1_privatekey.pem generate a version for MySQL and move certs around:
openssl rsa -in crin1_privatekey.pem -out crin1_yassl_privatekey.pem cd /etc/ssl/cacert mkdir old mv crin1_* old/ mv /root/crin1_* . chmod 640 crin1_* chown root:mysql crin1_*
Do the same on Crin2:
cd /root/bin wget http://svn.cacert.org/CAcert/Software/CSRGenerator/csr chmod 700 csr ./csr Private Key and Certificate Signing Request Generator This script was designed to suit the request format needed by the CAcert Certificate Authority. www.CAcert.org Short Hostname (ie. imap big_srv www2): crin2 FQDN/CommonName (ie. www.example.com) : crin2.crin.org Type SubjectAltNames for the certificate, one per line. Enter a blank line to finish SubjectAltName: DNS:crin2.crin.org SubjectAltName: DNS:*.crin2.crin.org SubjectAltName: DNS:*.crin.org SubjectAltName: DNS:crin2.webarch.net SubjectAltName: DNS:*.crin2.webarch.net SubjectAltName: DNS: Running OpenSSL... Generating a 2048 bit RSA private key .......
Save it as /root/crin2_privatekey.pem generate a version for MySQL and move certs around:
cd openssl rsa -in crin2_privatekey.pem -out crin2_yassl_privatekey.pem cd /etc/ssl/cacert mkdir old mv crin1_* old/ mv /root/crin2_* . chmod 640 crin2_* chown root:www-data crin2_*
Sync files via Crin1 after copying the root public ssh keys between servers, on Crin1 and Crin2 edit /root/.ssh/config and add:
Host crin1 User root Hostname crin1.crin.org Host crin2 User root Hostname crin2.crin.org
Copy the public key from each server to the /root/.ssh/authorized_keys file on each server and limit the IP address from which connections are allowed:
from="93.95.228.180" ssh-rsa AAAA...
Edit the /etc/ssh/sshd_config files on each server, changing:
#PermitRootLogin no PermitRootLogin without-password AllowGroups sudo root
Restart service ssh restart and check the connections and the ssh fingerprints.
Sync the files:
rsync -av /etc/ssl/cacert/crin1* crin2:/etc/ssl/cacert/ rsync -av crin2:/etc/ssl/cacert/crin2* /etc/ssl/cacert/
Chown the files on Crin1:
chown root:mysql crin2*
chown root:www-data crin1_*
Copy Crin2 Nginx config and edit for crin2.crin.org changing the server_name and SSL:
listen 80; listen 443 ssl; server_name crin2.crin.org; ssl_certificate /etc/ssl/cacert/crin2_cert.chained.pem; ssl_certificate_key /etc/ssl/cacert/crin2_privatekey.pem
Generate a chained cert:
cat crin2_cert.pem > crin2_cert.chained.pem cat cacert.pem >> crin2_cert.chained.pem chown root:www-data crin2_cert.chained.pem
Enable the new Nginx config:
cd /etc/nginx/sites-enabled ln -s ../sites-available/crin2.crin.org 10-crin2.crin.org.conf service nginx configtest service niginx restart
And we now have a CAcert.org secure site at https://crin2.crin.org/ and when the dns has updated https://phpmyadmin.crin.org/ should work, the 1984.is servers have updated:
dig @ns0.1984.is phpmyadmin.crin.org +short 93.95.228.179 dig @ns1.1984.is phpmyadmin.crin.org +short 93.95.228.179 dig @ns2.1984.is phpmyadmin.crin.org +short 93.95.228.179 dig @ns2.1984hosting.com phpmyadmin.crin.org +short 93.95.228.179
comment:8 follow-up: ↓ 9 Changed 3 years ago by chris
- Add Hours to Ticket changed from 0 to 0.1
- Total Hours changed from 5.22 to 5.32
I can't see why https://phpmyadmin.crin.org/ isn't working, have changed the documentation to point to https://phpmyadmin.crin1.crin.org/ at wiki:phpMyAdmin and wiki:WikiStart#ServicesandApplications.
comment:9 in reply to: ↑ 8 Changed 3 years ago by chris
- Add Hours to Ticket changed from 0 to 0.1
- Total Hours changed from 5.32 to 5.42
Replying to chris:
I can't see why https://phpmyadmin.crin.org/ isn't working, have changed the documentation to point to https://phpmyadmin.crin1.crin.org/ at wiki:phpMyAdmin and wiki:WikiStart#ServicesandApplications.
It must just heving been taking time for the DNS to update, it's working now at https://phpmyadmin.crin.org/ and the wiki pages wiki:phpMyAdmin and wiki:WikiStart#ServicesandApplications have been updated.
Install:
Delete the symlink in /etc/apache2/conf-enabled as we don't want phpMyAdmin to be available for every site:
Create a new VirtualHost for phpMyAdmin, /etc/apache2/sites-available/phpmyadmin.conf
Generate a username and password, where XXX is the username:
Generate a key pair via https://www.cacert.org/ using https://wiki.cacert.org/CSRGenerator as we don't need a commercial certificate for this site.
And that failed as I had forgotten that we haven't authorised the crin.org domain with CAcert.org (this can be sorted via a email to admin@… when Jonas is available), so set up webarch.net subdomains and generate a new csr:
Save the cert as /root/crin1_cert.pem and then copy to cacert dir:
Edit the Apache config:
Symlink and test and restart:
And test at the following URL and all is working OK: