Category Archives: Web Servers

Apache setting and reading Environmental Variables

A common .htaccess issue: you need one for production and another for development.

Here’s a simple trick to set and read apache env vars.

1
2
3
4
5
6
7
8
9
10
11
12
13
<IfModule mod_rewrite.c>
  RewriteEngine On

  # do not force https on local environment
  RewriteCond %{SERVER_NAME} local.yoursite.net
  RewriteRule .? - [E=siteenv:local]

  RewriteCond %{HTTP:X-Forwarded-Proto} !https # not on https
  RewriteCond %{ENV:siteenv} !local # not on local environment
  RewriteRule !/status https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

  ...
</IfModule>

On this example we do not force HTTP when accessing via “local.yoursite.net” (a development environment)

Apache SSL Configuration for HTTPS and HTTP

HTTP

1
2
3
4
5
6
7
8
9
10
11
12
<VirtualHost *:80>
        ServerName yourdomain.com
        ServerAlias www.yourdomain.com
        DocumentRoot /var/www/yourdomain.com/httpdocs/web

        ErrorLog /var/www/yourdomain.com/logs/error_log
        CustomLog  /var/www/yourdomain.com/logs/access_log common

        <Directory /var/www/yourdomain.com/httpdocs/web>
                AllowOverride All
        </Directory>
</VirtualHost>

HTTPS (with certificate key chain)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<VirtualHost *:443>
        # http://support.godaddy.com/help/article/5349/installing-ssl-certificate-apache-2x
        SSLEngine on
        SSLCertificateFile /etc/httpd/conf/ssl.crt/yourdomain.com.crt
        SSLCertificateKeyFile /etc/httpd/conf/ssl.key/yourdomain.com.key
        SSLCertificateChainFile /etc/httpd/conf/ssh.chain/sf_bundle.crt
        # http://www.networking4all.com/en/support/tools/site+check/cipher+suite/
        SSLProtocol -ALL +SSLv3 +TLSv1
        SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP

        ServerName yourdomain.com
        ServerAlias www.yourdomain.com
        DocumentRoot /var/www/yourdomain.com/httpdocs/web

        ErrorLog /var/www/yourdomain.com/logs/error_log
        CustomLog  /var/www/yourdomain.com/logs/access_log common

        <Directory /var/www/yourdomain.com/httpdocs/web>
                AllowOverride All
        </Directory>
</VirtualHost>

Amazon Load Balancer setting SSL with Certificate Chain

First of all, let’s assume you have the following files with you:

  • yourdomain.key Your domain’s private Key
  • yourdomain.crt Your domain’s public Key
  • sf_bundle.crt The Certificate Chain

Step 1 – Preparing the files

Create a PEM-encoded version of your private key

1
openssl rsa -in yourdomain.key -outform PEM -out yourdomain.pem

Step 2 – Setting the certificate on Amazon

On your Amazon account go to Load Balancers > Your Load Balencer > Listeners

Load Balencer Protocol: HTTPS
Load Balencer Port: 443
Instance Protocol: HTTP
Instance Port: 80
Cipher: ELBSample-OpenSSLDefaultCipherPolicy
Certificate Name: Yourdomain.com
Private Key: <past yourdomain.pem file here>
Public Key Certificate: <past yourdomain.crt file here>
Certificate Chain: <past sf_bundle.crt file here>

Note: This means every request to the Load Balancer will be made on HTTPS. The traffic from the Load Balancer to the destiny instance will be regular HTTP. This way you don’t have to setup any certificate on your instance’s Apache/Nginx web server.

Step 3 – Test

If everything went as expected you should be able to open https://yourdomain.com.

Now, use a SSL check tool to see if everything is OK: http://www.sslshopper.com/ssl-checker.html#hostname=https://yourdomain.com

You should see something like this:

2833574

 

nginx serve subdirectory as domain root

Say you have the following file structure:

1
2
3
4
5
site.com/
  main_site/
  site_a/
  site_b/
  site_c/

If you want:

  • http://site.com to show /main_site/’s files
  • all remaining sites to be served as usual (example: http://site.com/site_b/)

All you have to do is to edit site.com.conf’s file as follows:

1
2
3
4
5
6
7
8
9
10
11
  location / {
    try_files $uri $uri/ @missing; # try to get site.com/requested_file, if does not exist jump to @missing
  }

  location /main_site {
    # do nothing
  }

  location @missing { # if file is not present on the root, serve the /main_site
    rewrite ^ /main_site$request_uri?;
  }

Source

Nginx SSL configuration for HTTPS and HTTP

The following config will make the domain available both on HTTP and HTTPS protocols:

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
  listen 80;
  listen 443 default ssl;
  #ssl on;  ##### SEE: http://stackoverflow.com/a/8811733/269622
  ssl_certificate /var/www/domain.com/ssl/domain.com.crt;
  ssl_certificate_key /var/www/domain.com/ssl/domain.com.key;

  server_name domain.com;

  root /var/www/domain.com/httpdocs/;

  # ...
}

Some tips on using .htaccess

Imagine you have a website running on http://myserver.com/site1/ and you need to redirect all the traffic to other website that is located on http://someguyserver.com/modules/app/good_app/

The site running on someguyserver.com has the same structure as your site:

  • http://myserver.com/site1/pagina3.html -> http://http://someguyserver.com/modules/app/good_ap/pagina3.html
  • http://myserver.com/site1/hello_world/index.html<7a> -> http://http://someguyserver.com/modules/app/good_ap/hello_world/index.html

    This can be done defining the following rules on the .htaccess file in the root folder of http://myserver.com/site1:

    1
    2
    3
    4
    RewriteEngine on

    ## Redirect the requests to http://myserver.com/site1 into someguyserver.com
    RewriteRule ^(.*)$ http://someguyserver.com/modules/app/good_app/$1 [P]

    The [P] flag is for Proxy which means request will be proxied to the new destination but the user will keep seeing the same URL.

    Now, imagine that all the images, css and javascript on the HTML files inside http://myserver.com/site1/ are being referenced from the root folder like:

    1
    2
    <link rel="stylesheet" type="text/css" media="screen" href="/css/conventional.css" />
    <script type="text/javascript" src="/js/jquery.js"></script>

    This means that our redirect using .htaccess inside the /site1/ directory would not work. To solve this, we need to place a .htaccess file in the root directory of the domain (the directory that serves http://myserver.com) but what if myserver.com is a website itself or has other /site*/ websites that you don’t want to redirect the requests into http://someguyserver.com)?

    This can be done by using a RewriteCond to trigger the RewriteRule. And our RewriteCond can be based on the HTTP_REFERER of the request that will let us know if the request is coming from http://myserver.com or not):

    1
    2
    3
    4
    5
    6
    RewriteEngine on

    ## Requests for css, images or js (/css or /images or /js) that are coming from
    ## http://myserver.com/site1 will be redirected to someguyserver.com
    RewriteCond %{HTTP_REFERER} http://www.myserver.com/site1 [NC]
    RewriteRule ^(css|images|js)/(.*)$ http://www.someguyserver.com/$1/$2 [P]

    If you keep struggling with .htacess files and are not understanding why rules are not being matched and why it is not working, you can enable logging by placing the following in the virtual host configuration for the web site.

    1
    2
    RewriteLog "/var/www/myserver.com/logs/rewrite.log"
    RewriteLogLevel 5

    Note: This requires having MOD_REWRITE installed and enabled on Apache.