Rails 4 : exécuter une application dans un sous-répertoire avec Nginx

Cet article détaille la configuration Nginx et Rails pour faire tourner une application Rails dans un sous-répertoire.

Contexte

On ne va pas discuter ici si nous utilisons la meilleure architecture pour ce cas de figure mais  comment configurer un environnement existant pour faire fonctionner notre application dans un sous-répertoire.

L’application utilise Rails 4 et est servie par thin.

  • L’ancienne url de l’application : http://www.mydomain.com
  • La nouvelle url de l’application : http://www.mydomain.com/fr
  • Nginx écoute sur le port 80 et sert de reverse proxy vers un cluster thin qui sert l’application Rails

Configuration de Rails

config.ru

  • config.ru avant
# This file is used by Rack-based servers to start the application.

require ::File.expand_path('../config/environment', __FILE__)
run Rails.application
  • config.ru après
map MyApp::Application.config.relative_url_root || "/" do
    run Rails.application
end

config/application.rb

Pour servir votre application dans un sous-répertoire, il faut utiliser l’option relative_url_root.

Cette option se change dans le fichier config/application.rb

config.relative_url_root = "/fr"

Configuration de Nginx

La configuration a été modifiée pour changer le « location / » en « location /fr ».

Nous avons rajouté un règle de réécriture pour gérer les assets rails qui sont servis directement par Nginx.

  • La configuration de notre vhost nginx
upstream thin_cluster {
    server unix:/var/www/myapp/shared/tmp/sockets/thin.0.sock;
    server unix:/var/www/myapp/shared/tmp/sockets/thin.1.sock;
}

server {
    listen 80;
    server_name  www.mydomain.com

    root /var/www/myapp/current/public;
    index.html;

    location ~ ^/fr/assets/  {
            rewrite ^/fr(.*)$ $1 last;
    }

    location /fr {
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host:$server_port;
        proxy_redirect off;

        if (-f $request_filename/index.html) {
            rewrite (.*) $1/index.html break;
        }

        if (-f $request_filename.html) {
            rewrite (.*) $1.html break;
        }

        if (!-f $request_filename) {
            proxy_pass http://thin_cluster;
            break;
        }
    }
}

 

 

Changer le mot de passe root MySQL sur Ubuntu 16.04

Cet article vous décrit la procédure pour changer le mot de passe root MySQL sur Ubuntu 16.04.

Lorsque vous installez MySQL sur Ubuntu (16.04), l’installation vous demande de fixer un mot de passe pour le compte root MySQL. Il peut arriver que si vous générez un mot de passe aléatoire que certains caractères ne passent pas bien dans la boite de dialogue prévue à cet effet. Vous vous retrouvez alors dans l’impossibilité de vous connecter en root sur votre nouvelle installation.

Désactiver l’authentification MySQL

Pour changer le mot de passe root MySQL, il faut d’abord désactiver l’authentification MySQL afin de pouvoir se connecter.

Cette opération est possible grâce à l’option skip-grant-tables

Editez le fichier /etc/mysql/mysql.conf.d/mysqld.cnf et ajoutez cette option dans la section [mysqld]

[mysqld]
#
# * Basic Settings
#
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
skip-grant-tables

Redémarrer mysql :

$ /etc/init.d/mysql restart

Changer le mot de passe root MySQL

Vous pouvez maintenant vous connecter sans mot de passe. Exécutez la console mysql en ligne de commande pour changer le mot de passe comme suit :

$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.16-0ubuntu0.16.04.1 (Ubuntu)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use mysql;

mysql> UPDATE user SET authentication_string = PASSWORD('password'), password_expired = 'N' WHERE User = 'root' AND Host = 'localhost';
Query OK, 1 row affected, 1 warning (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 1

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Réactivez l’authentification MySQL

Editez le fichier /etc/mysql/mysql.conf.d/mysqld.cnf et enlevez l’option skip-grant-tables.

Redémarrez mysql, l’authentification et votre mot de passe root MySQL sont à jour

$ /etc/init.d/mysql restart

 

Restriction d’accès par IP ou password avec Nginx

Cet article vous montre comment configurer la restriction d’accès à votre serveur web Nginx à une ou plusieurs adresses IP de votre choix.

Configuration de la restriction d’accès

La configuration du site par défaut se trouve dans /etc/nginx/sites-available/default

La section qui nous intéresse est le location

location / {
    # First attempt to serve request as file, then
    # as directory, then fall back to displaying a 404.
    try_files $uri $uri/ =404;
 }

Il faut ajouter les règles d’accès. Ici on autorise une adresse IP et on exclut tout le reste.

location / {
    # bureau
    allow 2a01:xxxx:51e:xxxx:14d:xxxx:9146:xxxx;
    # Deny the rest of the world
    deny all;

    # First attempt to serve request as file, then
    # as directory, then fall back to displaying a 404.
    try_files $uri $uri/ =404;
 }

Test de la configuration Nginx

Avant d’activer une nouvelle configuration, il est toujours utile de bien s’assurer que la configuration est correcte et qu’il n’y a pas d’erreur de syntaxe dans le fichier.

Pour effectuer ce test, il faut utiliser le paramètre configtest avec le script de démarrage :

$ /etc/init.d/nginx configtest
* Testing nginx configuration
...done.

Si vous avez une erreur dans votre fichier de configuration, comme par exemple un ‘;’ oublié, le test va vous l’indiquer de la façon suivante :

$ /etc/init.d/nginx configtest
 * Testing nginx configuration
   ...fail!

Vérifiez les logs pour obtenir un message plus explicite :

$ tail /var/log/nginx/error.log
 [...]
 2016/11/22 10:39:05 [emerg] 14733#14733: invalid number of arguments in "allow" directive in /etc/nginx/sites-enabled/default:47

 

Recharger la configuration Nginx :

$ /etc/init.d/nginx reload

Vous pouvez aussi recharger la configuration avec le binaire Nginx :

$ nginx -s reload

Vous pouvez vérifier dans les logs Nginx que la configuration a bien été rechargée :

$ tail /var/log/nginx/error.log
[...]
2016/11/22 10:32:32 [notice] 14665#14665: signal process started

Test de la restriction d’accès

On peut tester la configuration depuis une IP externe :

$ curl -I http://vm.domain.com/
HTTP/1.1 403 Forbidden
Server: nginx/1.10.0 (Ubuntu)
Date: Tue, 22 Nov 2016 09:12:41 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive

Restriction d’accès par mot de passe

Pour créer un fichier de mot passe au format utilisé par Apache, vous pouvez utiliser la commande openssl :

$ printf "USER:$(openssl passwd -crypt)\n" >> .htpasswd

La fonction -crypt limite les mots de passe à 8 caractères

Pour des mots de passe plus long, utilisez la fonction -apr1

$ printf "USER:$(openssl passwd -apr1)\n" >> .htpasswd

Les 2 commandes précédentes vont vous demander le mot de passe de manière interactive dans le terminal.
Pour scripter cette commande, vous pouvez indiquer directement le mot de passe :

$ printf "USER:$(openssl passwd -apr1 PASSWORD)\n" >> .htpasswd

Attention, en utilisant cette dernière commande, vous pouvez faire apparaitre votre mot de passe dans l’historique du shell.

Configuration de Nginx pour l’accès par mot de passe

Il faut modifier votre section « location » pour indiquer à Nginx d’utiliser un fichier d’authentification:

location / {
    satisfy any;
    deny all;

    auth_basic "private";
    auth_basic_user_file /var/www/.htpasswd;

    try_files $uri $uri/ =404;
}

Configurer Nginx pour restreindre l’accès par IP ou par mot de passe

Dans cette configuration vous pouvez whitelister une ou plusieurs adresses IP et quand même laisser la possibilité de se connecter via un mot de passe si vous n’avez pas d’IP fixe.

location / {
    satisfy any;
    allow 111.222.333.444;
    deny all;

    auth_basic "private";
    auth_basic_user_file /var/www/.htpasswd;

    try_files $uri $uri/ =404;
}