Prerequisities

1. Install glype into /var/www/htdocs on your server

2. Create a DNS entry for server (I used the NOIP service)

3. Update /etc/hosts adding your DNS, e.g.

 127.0.0.1       localhost MicroServer myproxy.hopto.org justsomestuff-dev.co.uk puppet

NOTE 1: For Ubuntu 14.04 based disties there's a bug in aufs. Part of this procedure involves installing apache into the docker container. If you use aufs as the underlying filesystem you'll get

 Installing  :        httpd-2.4.18-1.fc23.x86_64  15/18 
 Error unpacking rpm package httpd-2.4.18-1.fc23.x86_64
 Error unpacking rpm package httpd-2.4.18-1.fc23.x86_64
 error: unpacking of archive failed on file /usr/sbin/suexec;573c37c5: cpio: cap_set_file

The bug is with the underlying server not the container. To get around this I switched to devicemapper. Update /etc/default/docker adding following to docker file and restart docker (devicemapper part):

 DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4 -s devicemapper"

Note 2: Centos/RedHat is already based on devicemapper for containers but you need to create an lv for docker if this is your server platform. You therefore need to reserve some space in root VG and carry out the following:

 # vgs
 VG     #PV #LV #SN Attr   VSize  VFree
 centos   2   3   0 wz--n- 30.51g 10.83g
 
 # docker-storage-setup
 INFO: Metadata volume docker-poolmeta already exists. Not creating a new one.
 Logical volume "docker-pool" created.
 WARNING: Converting logical volume centos/docker-pool and centos/docker-poolmeta to pool's data and metadata volumes.
 THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)
 Converted centos/docker-pool to thin pool.
 Logical volume "docker-pool" changed.
 # lvs
 LV          VG     Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
 docker-pool centos twi-a-t---  4.33g             0.00   0.15
 root        centos -wi-ao---- 17.66g
 swap        centos -wi-ao----  2.00g

You'll also need to do the following:

 # groupadd -g 48 apache
 
 disable selinux 
 
 # systemctl start docker

Of course if you actually use selinux (and I'm told some people do) you'll have to do something much more clever than just disabling it!

Setting up the docker container

For this test I decided to use a container based on Fedora. First pull down the latest Fedora image from docker hub

 :~$ docker pull fedora:23
 23: Pulling from library/fedora
 
 a3ed95caeb02: Already exists
 236608c7b546: Pull complete
 Digest: sha256:008c29c39619425de93eee20100661bef85a3f4fe0eaaf5b33532f615ccc2cd7
 Status: Downloaded newer image for fedora:23
 :~$ docker images
 REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
 fedora              23                  ddd5c9c1d0f2        5 minutes ago       204.7 MB
 centos-with-git     latest              37533ba9a45a        5 weeks ago         318.8 MB
 centos-with-git     test                37533ba9a45a        5 weeks ago         318.8 MB
 centos              latest              0f0be3675ebb        7 weeks ago         196.6 MB
 phpwithmysql        v2                  b5a8a29f293e        6 months ago        483.7 MB
 phpwithmysql        latest              d206203dd8ea        6 months ago        483.7 MB
 wordpress           latest              ba297914d5df        6 months ago        512.3 MB
 php                 5.6-apache          e0cd35a1d2d5        7 months ago        480.7 MB
 mysql               5.7                 93220007617a        7 months ago        321.2 MB
 hello-world         latest              0ebda6c3e276        12 months ago       910 B
 :~$

Now we need to customise our docker image. To do that start it with a bash shell.

 :~$ docker run --name web-test -v /var/www/htdocs:/var/www/htdocs -it fedora:23 /bin/bash
 
 (From another window)
 :~$ docker ps
 CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
 5f4313be03a3        fedora:23           "/bin/bash"         About a minute ago   Up About a minute                       web-test

The “-v /var/www/htdocs:/var/www/htdocs” part of the command means that server directory /var/www/htdocs will be mounted in the docker container as /var/www/htdocs. I did this to make customisations to glype easier (they can be made from the server rather than having to update the docker image)

You should now get the container bash prompt in which you can run commands

 [root@5f4313be03a3 /]# ls /var/www/htdocs
 glype

Now install the additional packages:

 dnf -y install httpd php php-common php-xml openssl mod_ssl && dnf -y clean all
 
 sed -i.orig 's/#ServerName/ServerName/' /etc/httpd/conf/httpd.conf

Set up the virtual host (we're going to use https):

 cd /etc/httpd/conf.d
 
 vi test-proxy.conf
 <IfModule mod_ssl.c>
      <VirtualHost _default_:443>
              ServerAdmin someplace@yahoo.com
              ServerName  myproxy.hopto.org
              ServerAlias tony-proxy
 
 
              DocumentRoot /var/www/htdocs
              <Directory /var/www/htdocs/>
                 Options Indexes FollowSymLinks MultiViews
                 AllowOverride all
                 Require all granted
              </Directory>
 
 
              # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
              # error, crit, alert, emerg.
              # It is also possible to configure the loglevel for particular
              # modules, e.g.
              #LogLevel info ssl:warn

              ErrorLog /var/log/httpd/error.log
              CustomLog /var/log/httpd/access.log combined

              # For most configuration files from conf-available/, which are
              # enabled or disabled at a global level, it is possible to
              # include a line for only one particular virtual host. For example the
              # following line enables the CGI configuration for this host only
              # after it has been globally disabled with "a2disconf".
              #Include conf-available/serve-cgi-bin.conf

              #   SSL Engine Switch:
              #   Enable/Disable SSL for this virtual host.
              SSLEngine on

              #   A self-signed (snakeoil) certificate can be created by installing
              #   the ssl-cert package. See
              #   /usr/share/doc/apache2/README.Debian.gz for more info.
              #   If both key and certificate are stored in the same file, only the
              #   SSLCertificateFile directive is needed.
              SSLCertificateFile      /etc/httpd/ssl/apache.crt
              SSLCertificateKeyFile /etc/httpd/ssl/apache.key

              #   Server Certificate Chain:
              #   Point SSLCertificateChainFile at a file containing the
              #   concatenation of PEM encoded CA certificates which form the
              #   certificate chain for the server certificate. Alternatively
              #   the referenced file can be the same as SSLCertificateFile
              #   when the CA certificates are directly appended to the server
              #   certificate for convinience.
              #SSLCertificateChainFile /etc/httpd/ssl.crt/server-ca.crt

              #   Certificate Authority (CA):
              #   Set the CA certificate verification path where to find CA
              #   certificates for client authentication or alternatively one
              #   huge file containing all of them (file must be PEM encoded)
              #   Note: Inside SSLCACertificatePath you need hash symlinks
              #                to point to the certificate files. Use the provided
              #                Makefile to update the hash symlinks after changes.
              #SSLCACertificatePath /etc/ssl/certs/
              #SSLCACertificateFile /etc/httpd/ssl.crt/ca-bundle.crt

              #   Certificate Revocation Lists (CRL):
              #   Set the CA revocation path where to find CA CRLs for client
              #   authentication or alternatively one huge file containing all
              #   of them (file must be PEM encoded)
              #   Note: Inside SSLCARevocationPath you need hash symlinks
              #                to point to the certificate files. Use the provided
              #                Makefile to update the hash symlinks after changes.
              #SSLCARevocationPath /etc/httpd/ssl.crl/
              #SSLCARevocationFile /etc/httpd/ssl.crl/ca-bundle.crl

              #   Client Authentication (Type):
              #   Client certificate verification type and depth.  Types are
              #   none, optional, require and optional_no_ca.  Depth is a
              #   number which specifies how deeply to verify the certificate
              #   issuer chain before deciding the certificate is not valid.
              #SSLVerifyClient require
              #SSLVerifyDepth  10
 
              #   SSL Engine Options:
              #   Set various options for the SSL engine.
              #   o FakeBasicAuth:
              #        Translate the client X.509 into a Basic Authorisation.  This means that
              #        the standard Auth/DBMAuth methods can be used for access control.  The
              #        user name is the `one line' version of the client's X.509 certificate.
              #        Note that no password is obtained from the user. Every entry in the user
              #        file needs this password: `xxj31ZMTZzkVA'.
              #   o ExportCertData:
              #        This exports two additional environment variables: SSL_CLIENT_CERT and
              #        SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
              #        server (always existing) and the client (only existing when client
              #        authentication is used). This can be used to import the certificates
              #        into CGI scripts.
              #   o StdEnvVars:
              #        This exports the standard SSL/TLS related `SSL_*' environment variables.
              #        Per default this exportation is switched off for performance reasons,
              #        because the extraction step is an expensive operation and is usually
              #        useless for serving static content. So one usually enables the
              #        exportation for CGI and SSI requests only.
              #   o OptRenegotiate:
              #        This enables optimized SSL connection renegotiation handling when SSL
              #        directives are used in per-directory context.
              #SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
              <FilesMatch "\.(cgi|shtml|phtml|php)$">
                              SSLOptions +StdEnvVars
              </FilesMatch>
              <Directory /usr/lib/cgi-bin>
                              SSLOptions +StdEnvVars
              </Directory>

              #   SSL Protocol Adjustments:
              #   The safe and default but still SSL/TLS standard compliant shutdown
              #   approach is that mod_ssl sends the close notify alert but doesn't wait for
              #   the close notify alert from client. When you need a different shutdown
              #   approach you can use one of the following variables:
              #   o ssl-unclean-shutdown:
              #        This forces an unclean shutdown when the connection is closed, i.e. no
              #        SSL close notify alert is send or allowed to received.  This violates
              #        the SSL/TLS standard but is needed for some brain-dead browsers. Use
              #        this when you receive I/O errors because of the standard approach where
              #        mod_ssl sends the close notify alert.
              #   o ssl-accurate-shutdown:
              #        This forces an accurate shutdown when the connection is closed, i.e. a
              #        SSL close notify alert is send and mod_ssl waits for the close notify
              #        alert of the client. This is 100% SSL/TLS standard compliant, but in
              #        practice often causes hanging connections with brain-dead browsers. Use
              #        this only for browsers where you know that their SSL implementation
              #        works correctly.
              #   Notice: Most problems of broken clients are also related to the HTTP
              #   keep-alive facility, so you usually additionally want to disable
              #   keep-alive for those clients, too. Use variable "nokeepalive" for this.
              #   Similarly, one has to force some clients to use HTTP/1.0 to workaround
              #   their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
              #   "force-response-1.0" for this.
              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>

Create a script to run when the docker container is launched:

 vi /etc/httpd/run_apache_foreground
 
 #!/bin/bash
 
 #set variables
 APACHE_LOG_DIR="/var/log/httpd"
 APACHE_LOCK_DIR="/var/lock/httpd"
 APACHE_RUN_USER="apache"
 APACHE_RUN_GROUP="apache"
 APACHE_PID_FILE="/var/run/httpd/httpd.pid"
 APACHE_RUN_DIR="/var/run/httpd"
 
 #create directories if necessary
 if ! [ -d /var/run/httpd ]; then mkdir /var/run/httpd;fi
 if ! [ -d /var/log/httpd ]; then mkdir /var/log/httpd;fi
 if ! [ -d /var/lock/httpd ]; then mkdir /var/lock/httpd;fi
 
 #run Apache
 httpd -D FOREGROUND

Set the permissions of the script

 
 chmod 755 /etc/httpd/run_apache_foreground

Set up SSL certificate

 [root@4d72e44a810d httpd]# mkdir /etc/httpd/ssl
 [root@4d72e44a810d httpd]# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/httpd/ssl/apache.key -out /etc/httpd/ssl/apache.crt
 Generating a 2048 bit RSA private key
 ..............+++
 .......................+++
 writing new private key to '/etc/httpd/ssl/apache.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]:GB
 State or Province Name (full name) []:Cornwall
 Locality Name (eg, city) [Default City]:St Tudy
 Organization Name (eg, company) [Default Company Ltd]:JSS
 Organizational Unit Name (eg, section) []:
 Common Name (eg, your name or your server's hostname) []:glype-proxy
 Email Address []:someplace@yahoo.com

I had to correct invalid symbolic link (not sure if that always happens?)

 [root@9607ef40c1b9 var]# cd /var; rm lock
 rm: remove symbolic link 'lock'? y
 [root@9607ef40c1b9 var]# ln -s ../run lock

Now add user so can access externaly mounted directory (/var/www/htdocs)

 groupadd -g 1000 tony
 useradd -u 1000 -g 1000 -d /home/tony -m -s /bin/bash tony 
 add apache to tape group

(last step was due to a clash with group IDs between the container and server due to different Linux distributions)

Now we can save the container state. To leave the container environment, you must press Ctrl+p followed by Ctrl+q, if you just call exit in the shell, you will also stop the container and lost what you have done so far.

 :~$ docker commit web-test glype-proxy
 sha256:4cba2b74369a1670826ffa98f4d31f0764ecf8f4bb4592a9a1e8e7c14a87d4e4
 :~$ docker images
 REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
 glype-proxy         latest              26bc3d21a2f8        7 seconds ago       257 MB
 fedora              23                  ddd5c9c1d0f2        5 weeks ago         204.7 MB

Start container using our customised image with listening on external port 8443 which maps to internal 443 (-p 8443:443) and runs the script to run apache in foreground.

 :~$ docker run -v /var/www/htdocs:/var/www/htdocs -p 8443:443 -d -t glype-proxy /etc/httpd/run_apache_foreground
 7eb47608b5a00722a107ad12ee6d947ea14db99c429ced6e89fbc1329e517b0b
 :~$
 
 :~$ docker ps
 CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
 7eb47608b5a0        glype-proxy         "/etc/httpd/run_apach"   30 seconds ago      Up 21 seconds       0.0.0.0:8443->443/tcp   happy_turing
 afa9adf95f2d        fedora:23           "/bin/bash"              47 minutes ago      Up 47 minutes                      web-test

Problem, when I test connecting to port 8443 I get an error saying ioncube not installed. So I need to install that.

 docker stop 7eb47608b5a0

As before start container with a bash shell

 docker run --name web-test3 -v /development/glype:/development/glype -it glype-proxy  /bin/bash

Copy the ioncube package:

 docker cp ioncube_loaders_lin_x86-64_5.1.2.tar.gz 3f4e9fbc1b36:/var/tmp
 
 [root@3f4e9fbc1b36 /]# cd /var/tmp
 [root@3f4e9fbc1b36 tmp]# ls
 ioncube_loaders_lin_x86-64_5.1.2.tar.gz
 [root@3f4e9fbc1b36 tmp]# tar xvzf ioncube_loaders_lin_x86-64_5.1.2.tar.gz
 bash: tar: command not found

doh, need to install tar

 dnf -y install tar && dnf -y clean all
 
 [root@3f4e9fbc1b36 local]# cd /usr/local 
 [root@3f4e9fbc1b36 local]# tar xzf /var/tmp/ioncube_loaders_lin_x86-64_5.1.2.tar.gz 
 [root@3f4e9fbc1b36 local]# cd ioncube
 [root@3f4e9fbc1b36 ioncube]# cp loader-wizard.php /var/www/htdocs/glype
 [root@3f4e9fbc1b36 ioncube]# cd /usr/lib64/php/modules
 [root@3f4e9fbc1b36 modules]# cp /usr/local/ioncube/ioncube_loader_lin_5.6* . 
 [root@3f4e9fbc1b36 modules]# chmod 755 ioncube*
 [root@3f4e9fbc1b36 modules]# cd /etc/php.d
 [root@3f4e9fbc1b36 php.d]# vi 00-ioncube.ini
 add line: zend_extension = /usr/lib64/php/modules/ioncube_loader_lin_5.6.so
 
 ctrl+p ctrl+q
 docker commit web-test3 glype-proxy

Now try again

 docker run -v /var/www/htdocs:/var/www/htdocs -p 8443:443 -d -t glype-proxy /etc/httpd/run_apache_foreground

Broswe to https://myproxy.hopto.org:8443/loader-wizard.php - should confirm it's installed OK

Browse to https://myproxy.hopto.org:8443 - Glype proxy page should now open

Running the container

Socket Based Activation

Intially my aim was to start this container on demand. systemd has socket based activation (like inetd performs) so that if you connect on a socket a process will start. However, docker containers are not socket aware. I then found the following atlassian article which describes how you can use systemd-socket-proxyd to start non socket aware processes using socket activation. Could I get this to work, could I fk! I could get a socket running fine and if I manually started the proxy service, the docker container started but the link between the socket starting the proxy just didn't want to know. Unfortunately systemd-socket-proxyd isn't extensively documented (as far as I could see) so after some frustrating hours, I switched to plan B. ===Plan B=== Plan B just involves using a SSH client on my smart phone ( I use JuicsSSH) to start the docker container (using SSH keys and a script to start the docker container on the server makes it pretty slick). I then have the glype proxy available for use.

===Recent Changes===

Contribute to this wiki

Why not help others by sharing your knowledge? Contribute something to this wiki and join out hall of fame!
Contact us for a user name and password