Apache SSL Nigthmare

I have a nightmare setting up apache of opensuse 11.2 to correctly redirect http to https.
I need to access my mysql databases (via phpmyadmin) from the Internet. Thus:
I opened port 31028 in my firewall.
Modified Apache’s listen.conf file to listen to that:


<IfDefine SSL>
    <IfDefine !NOSSL>
        <IfModule mod_ssl.c>

            Listen 443
            Listen 31028

        </IfModule>
    </IfDefine>
</IfDefine>

Then I created a new virtual host as:


NameVirtualHost *:31028
<VirtualHost *:31028>
        ServerName mysql.home
        ServerAdmin webmaster@server.home
        DocumentRoot /srv/www/vh/phpmyadmin
        DirectoryIndex index.php index.php3 index.php4

        SSLEngine On

        <Directory  /srv/www/vh/phpmyadmin>
                order deny,allow
                allow from 192.168.0.0/24 xx.xx.xx.xx
                deny from all
                AllowOverride None
                Options +ExecCGI -Includes +FollowSymLinks

                RewriteEngine           on
                RewriteCond             %{HTTPS} !=on
                RewriteRule (.*)        https://myhostname.dyndns.com:31028%{REQUEST_URI}
                #SSLRequireSSL

                AuthType Digest
                AuthDigestAlgorithm MD5
                AuthName "Authorized Personel"
                AuthDigestDomain /
                AuthDigestProvider file
                AuthUserFile /srv/www/vh/.htpasswd
                Require valid-user
        </Directory>
        ErrorLog /var/log/apache2/mysql.error
        TransferLog /var/log/apache2/mysql.access
#       SSLLog /var/log/apache2/mysql_ssl.log
        LogLevel debug

        RewriteLog              /var/log/apache2/mysql_rewrite.log
        RewriteLogLevel debug

        SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
        SSLCertificateFile /etc/apache2/ssl.crt/server.crt
        SSLCertificateKeyFile /etc/apache2/ssl.key/server.key
</VirtualHost>

The problem is that the redirection is not working!
When I access the site from the Internet (http://myhostname.dyndns.com:31028) I see the following error:


Bad request!
    Your browser (or proxy) sent a request that
    this server could not understand.
If you think this is a server error, please contact
the webmaster.

Error 400
  mysql.home 
  Mon Apr 12 13:20:36 2010
  Apache/2.2.13 (Linux/SUSE)

The log files have the following:


[Mon Apr 12 13:20:36 2010] [info] [client xxx.xxx.xxx.xxx] Connection to child 0 established (server **mysql.home:443**)
[Mon Apr 12 13:20:36 2010] [info] Seeding PRNG with 136 bytes of entropy
[Mon Apr 12 13:20:36 2010] [debug] ssl_engine_kernel.c(1875): OpenSSL: Handshake: start
[Mon Apr 12 13:20:36 2010] [debug] ssl_engine_kernel.c(1883): OpenSSL: Loop: before/accept initialization
[Mon Apr 12 13:20:36 2010] [debug] ssl_engine_io.c(1858): OpenSSL: read 11/11 bytes from BIO#b7d7d490 [mem: b7d82b08] (BIO dump follows)
[Mon Apr 12 13:20:36 2010] [debug] ssl_engine_io.c(1791): +-------------------------------------------------------------------------+
[Mon Apr 12 13:20:36 2010] [debug] ssl_engine_io.c(1830): | 0000: 47 45 54 20 2f 20 48 54-54 50 2f                 GET / HTTP/      |
[Mon Apr 12 13:20:36 2010] [debug] ssl_engine_io.c(1836): +-------------------------------------------------------------------------+
[Mon Apr 12 13:20:36 2010] [debug] ssl_engine_kernel.c(1912): OpenSSL: Exit: error in SSLv2/v3 read client hello A
[Mon Apr 12 13:20:36 2010] [info] [client xxx.xxx.xxx.xxx] SSL handshake failed: HTTP spoken on HTTPS port; trying to send HTML error page
[Mon Apr 12 13:20:36 2010] [info] SSL Library Error: 336027804 error:1407609C:SSL routines:SSL23_GET_CLIENT_HELLO:http request speaking HTTP to HTTPS port!?

Now the questions:

  • Why on earth it tries to connect at port 443?
  • The 31028 port is an SSL only port, is that a possible problem? Is that the reason for which the redirection fails?
    Thank you
    Peter

Try this recipe:

RewriteEngine on
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

Adjust as needed for your port situation.

HI, thank you for your quick answer. I believe that it is not a solution. Because the HTTP and HTTPS have a common port. So, the solution would be to have the redirection before the SSL introduction. I try to find out if that’s possible.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Your setup is, per my understanding of SSL, invalid. You cannot do what
you want to do if you set your non-SSL port to accept SSL and I’ll try to
explain why. If you are familiar with the ISO OSI (seven-layer) model or
the TCP (five-layer) model that may help with the understanding.

In the OSI model layer four is for TCP things (ports), and layer seven is
for application things (HTTP in your case). Between these layers you have
(as I recall) two other layers… Session and Presentation (layers five
and six, respectively) and it is in here (Presentation) that SSL
technically lives. With this in mind if you tell your web service
(Apache’s httpd) to require SSL on a certain port then once the TCP
connection is established and the browser explicitly has ‘http’ at the
beginning of the URL (which it does by default even if you do not put it
there) then the next step the browser has (as it is assuming non-SSL) is
to send an application-layer (HTTP) ‘GET’ command (see the LAN trace, HTTP
headers, or httpd’s access_log for that). This reaches the web service
which is expecting some kind of handshake for the SSL/TLS side of things.
As what is expected is not what is received the web service throws an
HTTP 400 and closes the connection.

The nature of SSL/TlS is that its operation below the application layer
makes its existence completely transparent to the application layer; it
does not matter if you put one type of traffic or another over SSL/TLS,
making it completely secure, because by the time the data are sent to the
application layer they are in the application’s native format. The SSL
connection is not started with the same command as the application layer
GET command so you are bound to have an error here.

Considering this is something you are not setting up for an audience of
the entire world (or you’d be using default ports) it is probably best
that you treat this HTTP 400 as your notice that you need to remember to
type ‘https’ at the beginning of your URL. Your browser treats that as
its sign to use SSL/TLS before sending the HTTP requests and without that
it will never work properly.

Good luck.

On 04/12/2010 05:36 AM, tpe wrote:
>
> HI, thank you for your quick answer. I believe that it is not a
> solution. Because the HTTP and HTTPS have a common port. So, the
> solution would be to have the redirection before the SSL introduction. I
> try to find out if that’s possible.
>
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.12 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJLwwmWAAoJEF+XTK08PnB56WwQAI/ELkbv+b/69RdMVRdWyG/N
QbjK/hXQ9vtiXCMkQaIPSO9GueKtwcPTnMay/4yKUinszgJK1dxU8ZF84J8gcDwm
iP5e4U0qbca+n4ecPJr+YWsceZAj26JCxBJcELzP/psnoKvXkCHb4YnHEmWOqP4J
cY33vCuErldTlhB2v4sl5Lin9ncJ2afj62EvXucGnM1CfS/+0cAd2SjIb8XJUn24
xWuFZsHOSRN3CQcGA/UzkWZUgrruN5iYCDALxYFr9F/NC4F0svFTPr1APL2olxws
Z/n6rs/HYicSB4oOHdIOK0vagvgjx6qrhiX1UZZF9Lai8JUMhhQyKi9xPK2piUrU
QO/RwuMERr07Ch9h3eG1moOa4sYGRUl9L5mpveDD61T17LqvPRUusY98fe+yfX0s
TyfCI+BaIdOyIv5Ys/Uz7f9UkBt/QSfMRcajtB87BPr2fkvHtx84we2d/b9W46K/
rIWZmUYIgmyFb0LUjMHao54enj+pwNg8XP6vRCyTv7Yg414DHWAaMiEI7DhxgT7e
S/HnFzAFSI8kdcpOcolaPGFDatIwUZvlriEJA5UwvPxeOsf7QIR27oZKPfh0yLmy
2t95bAC/sNqfaB9K/TtWDfyTQyaezBVV4Yz+VBOvWGEIpmkyT8wJ9Y9oBoFxNaiA
TaXO1Hwo2WTD1rKvG29I
=nyUR
-----END PGP SIGNATURE-----

Dear ab, thank you for your answer.
I totally agree with your notes. However, the fact that the issue exists in the application layer, it means that:
Apache should take note of the SSL handshake error, and then, since the SSL IS configured AND the redirection is in place should sent a redirect response to the client which in return will send an HTTPS request.

I will search again on the internet. I saw in some responses that apache is actually capable to use HTTP and HTTPS on the same port. If I found the answer, I will write the How-To.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I hope you find it, but the issue is not within the application layer.
SSL takes place below the Application layer and above the Transport layer
(a weird place which doesn’t exist in the TCP/IP model, but oh well)
though the issue is with the application and the protocol themselves. For
that reason you may find Apache will do this, but I’ve never seen it done.
If you have somebody going through the work of typing :31028 and then
forgetting the ‘s’ in ‘https’ then it’s likely they’ll know what they’re
doing enough to fix it. If they are not technical users but are just
following a link then there shouldn’t be a problem at all since the link
will just work. If you really want to use high ports and have it work
with 31028 on non-SSL ports why not put SSL on 31029 and have the 31028
port forward there?

Anyway, please post back what you end up doing either way.

Good luck.

On 04/12/2010 01:46 PM, tpe wrote:
>
> Dear ab, thank you for your answer.
> I totally agree with your notes. However, the fact that the issue
> exists in the application layer, it means that:
> Apache should take note of the SSL handshake error, and then, since the
> SSL IS configured AND the redirection is in place should sent a redirect
> response to the client which in return will send an HTTPS request.
>
> I will search again on the internet. I saw in some responses that
> apache is actually capable to use HTTP and HTTPS on the same port. If I
> found the answer, I will write the How-To.
>
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.12 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJLw4ooAAoJEF+XTK08PnB59f8P+gImfqsfMU6XsHtAHPFujwrX
8CZPAK3i5gfbsHM4WGiOl27YH9wkN0xjA8HpfqEtMtIFwAeIQnzAvaY/DyACCX0s
UpibpQmr7gribLKdSWGCUwM1PXzt0Ar8WqSK+yEOsUep9vCR+syQdzDBNzF89Voh
pXkXwjiJDQR7qJwoBGk0/zv+jJ1RXxL+lo5GK6FaUQQHVctmQ3L0DCuT6l53HAy/
JQXq3QG6jgOsrt5zPfia8E5C2pj1SsYhU5EIxA0KSAjWw4h22lrhZOhkxV5Rp4OM
8BGiPEr/Pbp3UcDOtbLBArJVA9efkAMNUt6OAxmSMFtAfaw6lnS/e675qBKUAN0j
CE7+X5V4tVIXYIpOJkspQRyU5KkfbeWUHE7B633luLAw2Z2Lf3MZA6pVggtSUqR9
1IMeiL57ivz+DCJByj1aAGwenxs+G0JHghyaKuiyK0kWfDiAScp/aINcMsf8N4Xu
8eOOhfz7+QeQLQ4MPzi/BqLXuG8TRFH5BLvKojQcfyERRA3I0NeJSyFlz8f4khHb
6iYuaQilD/CxmDrn73V3KDRgXra6aLY4F21zPObDQIpE4yJECdL3YoAsld0n2jB0
qWtnuGN8zg8NxikC7NkhPj5Fca5pNRPwI74k8Oc992jUh8nJDecPb/K2k5Sxcgao
kFpIHqZfbPgfOixzyKP/
=7DjF
-----END PGP SIGNATURE-----

You cannot use a common port for the two protocols because the participants do not do STARTTLS like some other protocols. Both sides have to agree that it is a HTTPS connection at the beginning.