Redirect HTTP to HTTPS Using .htaccess

In today’s world, security is of paramount importance when it comes to web applications. One of the simplest ways to enhance your website’s security is by enforcing HTTPS, which stands for Hypertext Transfer Protocol Secure. HTTPS ensures that all communication between your browser and the website are encrypted.

When a user visits your website using an unsecured HTTP connection, we would ideally want to redirect them to the secure HTTPS version. This is where the Apache’s .htaccess file comes into play.

In Apache web servers, the .htaccess (hypertext access) file is a directory-level configuration file that allows for decentralized management of web server configuration. You can use .htaccess to rewrite URLs, password-protect directories, enable/disable additional functionalities, and much more. In this blog post, we’ll focus on how to use .htaccess to redirect all HTTP traffic to HTTPS.

The .htaccess File

The .htaccess file should be located in the root directory of your website. If the file doesn’t already exist, you can create it using a plain text editor. Note that the file has no name and the extension is .htaccess.

Now, let’s dive into the code to achieve this HTTP to HTTPS redirect.

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Here’s what each line does:

  1. RewriteEngine On: This line enables the runtime rewriting engine. Essentially, it tells the server to start interpreting the rewrite rules that follow.
  2. RewriteCond %{HTTPS} off: This is a condition that checks if the HTTPS is off for the current request. If it is, the following RewriteRule will be executed.
  3. RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]: This is the rule that will be executed if the preceding condition is met. In essence, it tells the server to redirect all traffic ((.*)) to the same host (%{HTTP_HOST}) and the same requested resource (%{REQUEST_URI}), but over HTTPS. The [R=301,L] flag indicates that it is a permanent redirect (301) and this should be the last rule processed (L).

By incorporating these lines of code into your .htaccess file, you can ensure that all incoming HTTP traffic is seamlessly redirected to HTTPS, hence making your website more secure.

With a little knowledge of how .htaccess works and some simple code, you can significantly improve your website’s security and user trust in a short amount of time.

Apache reverse proxy configuration for socket.io

sudo a2enmod proxy_http
sudo a2enmod proxy_fcgi
sudo a2enmod proxy_wstunnel
# VirtualHost ms.example.net
<VirtualHost *:80>
  ServerName ms.example.net
  ProxyRequests Off
  ProxyPreserveHost On
  RemoteIPHeader X-Forwarded-For
  <Proxy *>
    Order deny,allow
    Allow from all
  </Proxy>
  RewriteEngine On
  RewriteCond %{REQUEST_URI} ^/socket.io          [NC]
  RewriteCond %{QUERY_STRING} transport=websocket [NC]
  RewriteRule /(.*) ws://localhost:14102/$1        [P,L]

  ProxyPass /socket.io http://localhost:14102/socket.io
  ProxyPassReverse /socket.io http://localhost:14102/socket.io
</VirtualHost>

<VirtualHost *:443>
  ServerName ms.example.net
  ProxyRequests Off
  ProxyPreserveHost On
  RemoteIPHeader X-Forwarded-For
  RewriteEngine on
  <Proxy *>
    Order deny,allow
    Allow from all
  </Proxy>
  SSLEngine On
  SSLCertificateFile /etc/letsencrypt/live/example.net/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/example.net/privkey.pem
  
  RewriteEngine On
  RewriteCond %{REQUEST_URI} ^/socket.io          [NC]
  RewriteCond %{QUERY_STRING} transport=websocket [NC]
  RewriteRule /(.*) ws://localhost:14102/$1        [P,L]
  ProxyPass /socket.io http://localhost:14102/socket.io
  ProxyPassReverse /socket.io http://localhost:14102/socket.io
  
</VirtualHost>

Use a secure URL for your initial connection, i.e. instead of “http://” use “https://”. If the WebSocket transport is chosen, then Socket.IO should automatically use “wss://” (SSL) for the WebSocket connection too.

var socket = io.connect('https://localhost', {secure: true});

References
http://xpo6.com/socket-io-via-apache-reverse-proxy/
https://stackoverflow.com/questions/36472920/apache-proxy-configuration-for-socket-io-project-not-in-root
https://gist.github.com/iacchus/954e0787d6893c5ab8e1
https://stackoverflow.com/questions/6599470/node-js-socket-io-with-ssl

Secure Apache with Let’s Encrypt on Ubuntu 18.04

Installing Certbot

sudo add-apt-repository ppa:certbot/certbot
sudo apt install python-certbot-apache

Set Up the SSL Certificate

Certbot needs to be able to find the correct virtual host in your Apache configuration for it to automatically configure SSL. Specifically, it does this by looking for a ServerName directive that matches the domain you request a certificate for.

Obtaining an SSL Certificate

sudo certbot --apache -d example.com -d www.example.com

This runs certbot with the --apache plugin, using -d to specify the names you’d like the certificate to be valid for.

Verifying Certbot Auto-Renewal

sudo certbot renew --dry-run

References
https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-18-04

How to Install and Secure the Mosquitto MQTT Messaging Broker on Ubuntu 16.04

Installing Mosquitto

sudo add-apt-repository ppa:mosquitto-dev/mosquitto-ppa
sudo apt-get update
sudo apt-get install mosquitto mosquitto-clients

Installing Certbot for Let’s Encrypt Certificates

sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot

Running Certbot

sudo ufw allow 80
sudo ufw allow 443
sudo certbot certonly --standalone

Enter your domain : mqtt.example.com

Setting up Certbot Automatic Renewals

sudo crontab -e
. . .
15 3 * * * certbot renew --noninteractive --post-hook "systemctl restart mosquitto"

Configuring MQTT Passwords

sudo mosquitto_passwd -c /etc/mosquitto/passwd sammy
sudo nano /etc/mosquitto/conf.d/default.conf
allow_anonymous false
password_file /etc/mosquitto/passwd
sudo systemctl restart mosquitto

Configuring MQTT SSL

sudo nano /etc/mosquitto/conf.d/default.conf
. . .
listener 1883 localhost

listener 8883
certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem
sudo systemctl restart mosquitto
sudo ufw allow 8883

References
https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-the-mosquitto-mqtt-messaging-broker-on-ubuntu-16-04

Redirect Request to SSL on Apache

NameVirtualHost *:80
<VirtualHost *:80>
   ServerName mysite.example.com
   DocumentRoot /usr/local/apache2/htdocs
   Redirect /secure https://mysite.example.com/secure
</VirtualHost>

<VirtualHost _default_:443>
   ServerName mysite.example.com
   DocumentRoot /usr/local/apache2/htdocs
   SSLEngine On
# etc...
</VirtualHost>

When redirecting everything you don’t even need a DocumentRoot:

NameVirtualHost *:80
<VirtualHost *:80>
   ServerName www.example.com
   Redirect / https://secure.example.com/
</VirtualHost>

<VirtualHost _default_:443>
   ServerName secure.example.com
   DocumentRoot /usr/local/apache2/htdocs
   SSLEngine On
# etc...
</VirtualHost>

Note: Once the configuration is working as intended, a permanent redirection can be considered. This avoids caching issues by most browsers while testing. The directive would then become:

Redirect permanent / https://secure.example.com/

—————

<Directory /topsecret>
  SSLRequireSSL
</Directory>

References
https://wiki.apache.org/httpd/RedirectSSL
https://serverfault.com/questions/429634/restrict-apache-to-only-allow-access-using-ssl-for-some-directories
https://www.tecmint.com/redirect-http-to-https-on-apache/

Configure Let’s Encrypt for Apache on Ubuntu

sudo apt-get install python-letsencrypt-apache 
letsencrypt --apache
nano /etc/apache2/apache2.conf
<VirtualHost *:443>
	SSLEngine on
	SSLCertificateKeyFile /etc/letsencrypt/live/dl.mhdr.ir/privkey.pem
	SSLCertificateFile /etc/letsencrypt/live/dl.mhdr.ir/cert.pem
	SSLCertificateChainFile /etc/letsencrypt/live/dl.mhdr.ir/chain.pem
    DocumentRoot "/var/www/html/dl"
    ServerName dl.mhdr.ir
</VirtualHost>
service apache2 restart

PPA

$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install python-certbot-apache

note : only the last VitualHost will be detected by letsencrypt
References
https://certbot.eff.org/#ubuntuxenial-apache
https://www.digitalocean.com/community/tutorials/how-to-use-apache-http-server-as-reverse-proxy-using-mod_proxy-extension
https://letsencrypt.org/