Apache use ssl virtual host to reverse proxy to http

Documenting partially for myself but also for anyone else who just wants to deal with the http virtual host, but have ssl as well.

You need some basic ssl configs, which I tend to place in a separate file so all virtal hosts can share the same settings.

touch "${tf}" ; chmod 0644 "${tf}" ; chown root.root "${tf}" ;
cat <<EOF 1> "${tf}"
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on

<Files ~ "\.(cgi|shtml|phtml|php3?)$">
        SSLOptions +StdEnvVars
<Directory "/var/www/cgi-bin">
        SSLOptions +StdEnvVars

SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateChainFile /etc/pki/tls/certs/chain-localhost.crt

SetEnvIf User-Agent ".*MSIE 4\.0b2.*"                 nokeepalive ssl-unclean-shutdown                 downgrade-1.0 force-response-1.0

LogLevel warn
ErrorLog logs/ssl_error_log
CustomLog logs/ssl_access_log combinedvhost

<Directory "/var/www/html/notfound/">
        AllowOverride None
        Order allow,deny
        Allow from all

# END OF FILE all-ssl.cnf

And the real config file:

touch "${tf}" ; chmod 0644 "${tf}" ; chown root.root "${tf}" ;
cat <<EOF 1> "${tf}" 
# reference:
# https://bgstack15.wordpress.com/2016/03/24/adding-adfs-integration-to-apache/
# ssl act as proxy: https://httpd.apache.org/docs/2.4/rewrite/proxy.html

#Listen 80 # not needed here in base C7 because this is provided in /etc/httpd/conf/httpd.conf
#Listen 443
<VirtualHost *:80>
ServerName repo1.int.example.com
ServerAlias *.int.example.com *
UseCanonicalName Off

DocumentRoot /var/www/html
Options +Indexes
IndexOptions IgnoreCase FancyIndexing FoldersFirst NameWidth=* DescriptionWidth=*

<VirtualHost *:443>

ServerName repo1.int.example.com:443
ServerAlias *.int.example.com

Include conf.d/all-ssl.cnf
# try the <proxy> stuff from https://bgstack15.wordpress.com/2017/10/12/adding-reverse-proxy-for-plex-to-apache-vhost/

<Proxy *>
Order deny,allow
Allow from all

SSLProxyEngine On
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://repo1.int.example.com/
ProxyPassReverse / http://repo1.int.example.com/


Ansible delegate_to a Windows host

If you use Ansible, and Windows, and you need to perform a few tasks out of a play on a Windows host, you use delegate_to.

However, using a regular delegate_to doesn’t work, because of a certificate validation error.

TASK [certreq : win_shell] *****************************************************************************************
fatal: [linux_host]: UNREACHABLE! => {"changed": false, "msg": "ssl: HTTPSConnectionPool(host='win_host', port=5986): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:579)'),))", "unreachable": true}

What you need to do is set a host fact in the play:

- set_fact:
    ansible_winrm_server_cert_validation: ignore

- win_shell: Write-Host 'Hello World!'
  delegate_to: "{{ winhost_hostname }}"
    ansible_user: "{{ winhost_user }}"
    ansible_port: 5986

I have tried placing the variable in the vars on the win_shell command, but it didn’t work. You have to set it as a host fact of the regular host(s) running the play.
And that’s it! You’ll still get the warning, but the connection will work!

TASK [certreq : win_shell] *****************************************************************************************
/usr/lib/python2.7/site-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
changed: [linux_host -> win_host] => {"changed": true, "cmd": "Write-Host 'Hello World!'", "delta": "0:00:00.265626", "end": "2017-11-14 03:36:10.390993", "rc": 0, "start": "2017-11-14 03:36:10.125366", "stderr": "", "stderr_lines": [], "stdout": "Hello World!\n", "stdout_lines": ["Hello World!"]}



  1. My original research based on info from another github user, jborean93 https://github.com/ansible/ansible/issues/32673#issuecomment-344291429

Manipulating ssl certificates


Last updated 2017-12-14

SSL certificates are used in almost every network application to encrypt traffic to increase the safety of communications.

Manipulating ssl certs

Converting .crt to .pem

A .crt file can be identical to a .pem: They are both a b64-encoded block.

openssl x509 < rapidssl.crt -out rapidssl.pem

A .crt is usually the public key, and a .key is usually the private key.

Converting .crt set to a .pfx for Windows

Run each step separately because you might need to enter an import or export password. Use a simple password for each one for ease.

openssl pkcs12 -export -in wildcard-2016.crt -inkey wildcard-2016.key -out wildcard-2016.p12 -name wildcard -CAfile rapidssl-2016.crt -caname root
openssl pkcs12 -in wildcard-2016.p12 -out wildcard-2016.pem -nodes –clcerts
openssl x509 -in rapidssl-2016.crt -out rapidssl-2016.pem
cat wildcard-2016.pem rapidssl-2016.pem > wildcardchain-2016.pem
openssl pkcs12 -export -in wildcardchain-2016.pem -out wildcardchain-2016.pfx

Source: http://stackoverflow.com/questions/18787491/adding-certificate-chain-to-p12pfx-certificate/18830742#18830742.

Converting pkcs7 to pkcs12

openssl pkcs7 -print_certs -in crx.p7b | openssl pkcs12 -export -inkey crx.key -out crx.pfx -certfile crx.crt

Preparing hash file for ldap

Openldap can use ssl to encrypt its traffic, and the file needs to be rather specific. Around here, the /etc/openldap/ldap.conf file tends to have these directives:

URI ldaps://example.com
BASE dc=example,dc=com
TLS_CACERTDIR /etc/openldap/cacerts

And in /etc/openldap/cacerts you might see these files:

4669ff29.0 -> authconfig.pem
authconfig.pem (the examplemicrosoft certs catted)

Observe that there is a hashed file as a symlink to the real cert file. Openldap will look for the hashed filename, whether it is a real file or just a symlink.
You can generate the hashed file by running c_rehash /etc/openldap/cacerts (or try cacertdir_rehash) from package openssl-perl or you can generate the symlink this way:

cd /etc/openldap/cacerts
ln -sf certs-example-2016.pem "$( openssl x509 -in certs-example-2016.pem -hash -noout ).0"

Reference: Weblink 2

Requesting a certificate signing

A CSR is for when you have a certificate you generated that you want signed by a certificate authority, whether that be the local CA or a public one.
You need a private key to start with, so the genrsa command will generate one.

openssl genrsa -aes256 -out wwwexamplecom-2016.key 2048
openssl req -new -key wwwexamplecom-2016.key -out wwwexamplecom-2016.csr
Enter pass phrase for wwwexamplecom-2016.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:Anystate
Locality Name (eg, city) [Default City]:Anytown
Organization Name (eg, company) [Default Company Ltd]:Example Company
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:www.example.com
Email Address []:linuxadmin@example.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Generally, don’t use a passphrase. If you must, do a simple one like linksys.

Send the csr to someone. This uses the send.sh script from bgscripts package.
send.sh -hs "csr for www.example.com" wwwexamplecom-2016.csr usertwo@example.com

Removing passphrase from private key

Apache in particular struggles with a private key protected with a passphrase. Apparently admins just leave the passphrase blank when generating a cert.
If you already applied one, and want to remove the passphrase, just use openssl.

openssl rsa -in old.key -out new.key

It will ask you for the passphrase, and then export the private key to the new file.
Reference: https://www.mnxsolutions.com/apache/removing-a-passphrase-from-an-ssl-key.html

Adding AD certs to host trusted certificate store

Procure your AD root CA cert or download it from the certificate authority web portal, which could resemble https://ca2.example.com/certsrv/. Save as ca2.example.com.crt.
Reference: Weblink 4 https://support.microsoft.com/en-us/help/555252

cp ca2.example.com.crt /etc/pki/ca-trust/source/anchors/

Reference: Weblink 5 https://stackoverflow.com/questions/29236078/how-to-ldap-bindauthenticate-using-python-ldap/30221592#30221592

Signing a certificate

Internal link 3 https://ca2.example.com/certsrv/ provides the certificate signing operations for Active Directory.

Adding key to java keystore

You might need to add a certificate to a java-like keystore. It is interesting to note that many java keystore files are actually symlinks to /etc/pki/java/cacerts.

/usr/lib/jvm/java/jre/bin/keytool -import -trustcacerts -alias "myaliasname" -storetype jks -keystore /usr/lib/jvm/java/jre/lib/security/cacerts -file ./comodo.cer -storepass changeit

Testing ssl cert from server

To find out if the https or other ssl-enabled service is serving the right certificate, you can use openssl as a client and pull down the ssl cert.

printf '\n' | openssl s_client -connect ipa.example.com:443

And observe the output for the certificate information.
To test SNI, add the parameter -servername myurl.example.com.
Reference: weblink 6 https://major.io/2012/02/07/using-openssls-s_client-command-with-web-servers-using-server-name-indication-sni/

Convert cer to pem format

openssl x509 -inform der -in certificate.cer -out certificate.pem

Reference: weblink 7 https://www.sslshopper.com/article-most-common-openssl-commands.html

Read info from pkcs12 file

openssl pkcs12 -in cert.pfx -passin pass:'' -nodes -clcerts | openssl x509 -noout -subject -issuer -startdate -enddate

Delineate certificates in chain being served by a web connection

certchain="$( mktemp )" ; echo '' | openssl s_client -showcerts -connect pypi.python.org:443 > ${certchain} ; certcount=$( grep -cE '^-----BEGIN CERT' ${certchain} 2>/dev/null ); cat ${certchain} | { x=0 ; while test $x -lt ${certcount} ; do openssl x509 -noout -subject -issuer -dates ; x=$(( x + 1 )) ; done ; }



  1. Pkcs12 chained certificates demo: http://stackoverflow.com/questions/18787491/adding-certificate-chain-to-p12pfx-certificate/18830742#18830742
  2. How to get the cert file hash without the c_rehash tool http://www.linuxquestions.org/questions/linux-server-73/openldap-certificate-4175480164-print/
  3. Removing passphrase from ssl key https://www.mnxsolutions.com/apache/removing-a-passphrase-from-an-ssl-key.html
  4. AD get root CA certificate https://support.microsoft.com/en-us/help/555252
  5. https://stackoverflow.com/questions/29236078/how-to-ldap-bindauthenticate-using-python-ldap/30221592#30221592
  6. https://major.io/2012/02/07/using-openssls-s_client-command-with-web-servers-using-server-name-indication-sni/
  7. https://www.sslshopper.com/article-most-common-openssl-commands.html
  8. The Most Common Java Keytool Keystore Commands