Advertisement
  1. Code
  2. Yii

Construyendo To Startup: Básicos de Seguridad

Scroll to top
Read Time: 9 min
This post is part of a series called Building Your Startup With PHP.
Building Your Startup: Issue Tracking and Feature Planning
Building Your Startup: Ajax for Meeting Times and Places

Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)

Final product imageFinal product imageFinal product image
What You'll Be Creating

Este tutorial es parte de la serie Construyendo Tu Startup Con PHP en Envato Tuts+. En esta serie, te estoy guiando a través de lanzar una startup desde el concepto hasta la realidad usando mi aplicación Planificador de Reuniones como un ejemplo de la vida real. Cada paso a lo largo del camino, liberaré código de Planificador de Reuniones como ejemplos de código abierto de los cuáles puedes aprender. También abordaré temas relacionados con negocios y emprendimiento cuando surjan.

El servidor de producción para Planificador de Reuniones actualmente corre sobre Digital Ocean (mira otros tutoriales acerca de ellos en Envato Tuts+.) En el episodio de hoy, nos adentraremos en los básicos de seguridad de servidor web. Cubriré asegurar el VPS Linux ejecutando Planificador de Reuniones y alguna seguridad básica de Yii. En el siguiente episodio, me adentraré más en seguridad programática de aplicación Yii.

Participo en la sección de comentarios de abajo, así que por favor comparte tu retroalimentación. Por favor déjame saber si hay algunos temas de seguridad que sientes que dejé de lado. También estoy abierto a nuevas ideas de características y sugerencias de temas para futuros tutoriales.

Como recordatorio, todo el código para Planificador de Reuniones está escrito en el Framework Yii2 para PHP. Si quisieras aprender más acerca de Yii2, revisa nuestra serie paralela Programando con Yii2.

Si no lo has hecho, prueba nuestro Planificador de Reuniones ahora mismo programando tu primera reunión. Siéntete libre de publicar retroalimentación acerca de tu experiencia en los comentarios de abajo.

Seguridad de Hosting y VPS

Recursos Comunes

Si estás ejecutando un VPS Linux genérico, podrías querer revisar mi tutorial previo de Envato Tuts+, Asegurando Tu Inicio de Sesión de Servidor. Este cubre un número de pasos que revisitaré hoy, incluyendo seguridad SSH y cortafuegos.

Digital Ocean es también un gran recurso para prácticas de seguridad. Una Introducción a Asegurar tu VPS Linux es una de las mejores vistas generales que ofrecen. Además, tienen gráficos interesantes.

Startup Series - 7 Security Measures via Digital Ocean - graphic of Hun-like invadersStartup Series - 7 Security Measures via Digital Ocean - graphic of Hun-like invadersStartup Series - 7 Security Measures via Digital Ocean - graphic of Hun-like invaders
vía 7 Medidas de Seguridad para Proteger Tus Servidores de Digital Ocean

Aquí hay otros tres artículos que ofrecen lo que utilicé para el antecedente de este tutorial:

Manteniendo el Servidor Actualizado

Primeramente, es vital que mantengas tu servidor actualizado con actualizaciones regulares y mejoras. Esto integra parches de seguridad de proveedores de software (y código abierto) que estás usando.

Aquí están los pasos básicos--probablemente estés familiarizado con ellos:

1
$ sudo apt-get update
2
Get:1 http://security.ubuntu.com trusty-security InRelease [65.9 kB]
3
Get:2 http://security.ubuntu.com trusty-security/main Sources [118 kB]        
4
Get:3 http://security.ubuntu.com trusty-security/universe Sources [38.0 kB]    
5
...
6
Ign http://mirrors.digitalocean.com trusty/universe Translation-en_US          
7
Fetched 5,298 kB in 10s (526 kB/s)                                             
8
Reading package lists... Done

Dist-upgrade usa un poco de inteligencia para administrar las interdependencias de paquetes actualizados:

1
$ sudo apt-get dist-upgrade
2
Reading package lists... Done
3
Building dependency tree       
4
Reading state information... Done
5
Calculating upgrade... Done
6
The following packages were automatically installed and are no longer required:
7
  linux-headers-3.13.0-85 linux-headers-3.13.0-85-generic
8
  linux-headers-3.13.0-86 linux-headers-3.13.0-86-generic
9
 ...
10
Setting up cloud-init (0.7.5-0ubuntu1.19) ...
11
Leaving 'diversion of /etc/init/ureadahead.conf to /etc/init/ureadahead.conf.disabled by cloud-init'
12
Processing triggers for libc-bin (2.19-0ubuntu6.9) ...

Para asegurar que toma efecto completo, podrías necesitar reiniciar en ocasión. Siempre detengo mi base de datos y después reinicio:

1
$ sudo service mysql stop
2
mysql stop/waiting
3
$ sudo reboot
4
$

5
Broadcast message from meetingplanner.io
6
    (/dev/pts/0) at 13:51 ...
7
The system is going down for reboot NOW!
8
Connection to meetingplanner.io closed by remote host.
9
Connection to meetingplanner.io closed.

Cuando Planificador de Reuniones tenga más usuarios, podrían necesitarse mecanismos de reinicio más elaborados.

Configurando Inicio de Sesión SSH

Startup Series - SSH Key AuthenticationStartup Series - SSH Key AuthenticationStartup Series - SSH Key Authentication
Imagen vía 7 Medidas de Seguridad para Proteger Tus Servidores de Digital Ocean

Tienes la opción de usar tu llave privada cuando creas un droplet de Digital Ocean. Cuando configuré Planificador de Reuniones, repetí los pasos delineados aquí: Asegurando Tu Inicio de Sesión de Servidor.

También moví el inicio de sesión SSH a un puerto personalizado, no el comúnmente usado (y atacado) puerto 22.

Configurando un Cortafuegos

Startup Series - Firewall Request FilteringStartup Series - Firewall Request FilteringStartup Series - Firewall Request Filtering
Imagen vía 7 Medidas de Seguridad para Proteger Tus Servidores de Digital Ocean

Después, instalé UFW, el cortafuegos sin complicaciones:

1
$ sudo ufw enable

2
Command may disrupt existing ssh connections. Proceed with operation (y|n)?

Sin embargo, no dije sí a esa petición. La advertencia me recordó revisar dos veces todos mis requerimientos SSH.

Por ejemplo, apagué el puerto SSH por defecto y encendí el que estoy usando:

1
$sudo ufw allow 31345
2
$sudo ufw deny 22

Después, establecí una petición sudo para el futuro para deshabilitar UFW en caso de que mis ajustes no fueran correctos.

1
$sudo at now +5 minutes
2
warning: commands will be executed using /bin/sh
3
at> sudo ufw disable
4
at> <EOT>
5
job 9 at Mon Jul 18 16:14:00 2016

Después, habilité UFW y ejecuté mis ajustes restantes:

1
$sudo ufw default deny incoming
2
$sudo ufw default allow outgoing
3
$sudo ufw allow http
4
$sudo ufw allow https
5
$sudo ufw deny mysql
6
$sudo ufw enable

7
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
8
Firewall is active and enabled on system startup

Aquí están los resultados:

1
$ sudo ufw status
2
Status: active
3
4
To                         Action      From
5
--                         ------      ----
6
31345                      ALLOW       Anywhere
7
80                         ALLOW       Anywhere
8
443                        ALLOW       Anywhere
9
22                         DENY        Anywhere
10
3306                       DENY        Anywhere
11
31345 (v6)                 ALLOW       Anywhere (v6)
12
80 (v6)                    ALLOW       Anywhere (v6)
13
443 (v6)                   ALLOW       Anywhere (v6)
14
22 (v6)                    DENY        Anywhere (v6)
15
3306 (v6)                  DENY        Anywhere (v6)

Nota: Debido a que mi base de datos está actualmente corriendo sobre el mismo servidor que los servicios web de Planificador de Reuniones, puedo bloquear el puerto 3306. Sin embargo, mientras que el uso del sitio escala a múltiples servidores, se necesitarán cambios.

También edité la configuración UFW para habilitar el cortafuegos cuando el servidor se reinicia:

1
$sudo nano  /etc/ufw/ufw.conf
2
enabled = on

Debido al retrasado comando de deshabilitar, tube que habilitar UFW de nuevo después de cinco minutos.

En adición a mi Asegurando Tu Inicio de Sesión de Servidor, las guías de Digital Ocean UFW Essentials: Common Firewall Rules and Commands y How to Setup a Firewall with UFW on an Ubuntu and Debian Cloud Server son útiles cuando se configura UFW.

Configurando SSL

Startup Series - Lets Encrypt New Certificate Authority Free Automated and OpenStartup Series - Lets Encrypt New Certificate Authority Free Automated and OpenStartup Series - Lets Encrypt New Certificate Authority Free Automated and Open

Para la seguridad de las personas usando Planificador de Reuniones, también configuré SSL como se describe en Usando Encriptemos SSL Con Tu Proyecto WordPress.

Y, podrías notar, permití acceso https en el puerto 443 cuando configuré el cortafuegos arriba. Las peticiones a http://meetingplanner.io automáticamente redirigen a https://meetingplanner.io.

Comenzando Con Seguridad de Aplicación Yii2

Más allá de los fundamentos de seguridad Linux, también necesitamos ser conscientes sobre asegurar el Framework Yii encima de PHP. Querrás leer Programando Con Yii2: Seguridad, la mayoría de lo cuál revisaremos en el siguiente episodio.

Sin embargo, el día de hoy, vamos a implementar algunas características de control de acceso básico para Planificador de Reuniones.

Control de Acceso

Uno de los beneficios iniciales de usar un framework MVC PHP es que todas las peticiones para páginas están enrutadas a través de un solo archivo index.php. Como describí en Programando Con Yii2: Ruteo y Creación de URL, Yii cuidadosamente administra peticiones entrantes para páginas y las dirige a los controladores apropiados y métodos de acción.

En adición, es nuestro trabajo asegurar peticiones de controlador cuando vienen a la aplicación. Primariamente, ¿quién es esta persona y tienen los permisos para acceder a la página?

Como se discutió en el tutorial de Seguridad Yii2, Yii tiene una variedad de opciones para administrar acceso. Planificador de Reuniones usa primariamente las capacidades de Control de Acceso.

Asegurando Peticiones de Aplicación Front-End

Aquí hay un ejemplo de tráfico viniendo al Controlador de Reuniones el cuál los usuarios acceden comúnmente:

1
class MeetingController extends Controller
2
{
3
  public function behaviors()
4
  {
5
    return [
6
    ...
7
    'access' => [
8
        'class' => \common\filters\MeetingControl::className(), // \yii\filters\AccessControl::className(),

9
        'only' => ['index','view','create','update','delete', 'decline','cancel','command','download','wizard','trash','late'],
10
        'rules' => [
11
          // allow authenticated users

12
           [
13
               'allow' => true,
14
               'actions'=>['create','index','view','update','delete', 'decline','cancel','command','download','wizard','trash','late'],
15
               'roles' => ['@'],
16
           ],
17
          [
18
              'allow' => true,
19
              'actions'=>['command'],
20
              'roles' => ['?'],
21
          ],
22
          // everything else is denied

23
        ],
24
    ],
25
  ];
26
  }

El comportamiento de acceso salvaguarda todos los métodos mencionados en 'only'. Las acciones listadas con roles '@' requieren usuarios autenticados--en otras palabras, solo los usuarios que se han logueado pueden ver estas páginas. Los usuarios que no están logueados son redireccionados a la página de inicio por defecto. Sin embargo, las páginas con roles '?' están abiertas al público.

Así que, por ejemplo, solo un usuario autenticado puede crear una reunión, pero cualquiera puede entrar a la aplicación a través de la URL reunión/comando. Eso es porque usamos el comando URL ampliamente en emails y tiene otra capa de autenticación, descrita en el tutorial de Entregando Invitaciones.

La URL comando permite a los usuarios que no han iniciado sesión (e incluso participantes de reuniones que nunca han estado en el sitio antes) acceder de manera segura a páginas específicas.

Asegurando Peticiones de Aplicación Back-End

Para el sistema back-end de Planificador de Reuniones, solo los administradores pueden acceder a estas páginas. Debido a que los administradores son denotados en nuestra tabla Usuarios en una manera específica personalizada de aplicación, tuve que construir una regla de acceso personalizada para verificarlos. Los roles básicos de Yii solo soportan autenticado @ y desautenticado ?.

Veamos el MessageController del back-end para enviar actualizaciones de email a nuestros usuarios:

1
class MessageController extends Controller
2
{
3
    /**

4
     * @inheritdoc

5
     */
6
    public function behaviors()
7
    {
8
      return [
9
        'access' => [
10
          'class' => AccessControl::className(),         
11
          'rules' => [
12
            [
13
              'allow' => true,
14
              'matchCallback' => function ($rule, $action) {
15
                  return (!\Yii::$app->user->isGuest
16
                    && \common\models\User::findOne(Yii::$app->user->getId())->isAdmin());
17
                }
18
            ],
19
          ],
20
        ],

Esta regla personalizada asegura que el usuario no es un invitado y pasas isAdmin() antes mandandole a la acción apropiada. Otros usuarios son redireccionados a la página de inicio de sesión de back-end.

Hemos logrado mucho hoy, pero aún hay mucho por hacer.

Viendo hacia Adelante

Si corres un servidor, probablemente apreciaste la revisión de hoy de Linux y seguridad de hosting básicos. En el siguiente episodio, exploraremos los pasos de seguridad relacionados más cercanamente al Framework Yii y la aplicación Planificador de Reuniones.

Espera nuestros siguientes tutoriales en la serie Construyendo Tu Startup Con PHP. Hay unas cuántas características grandes en puerta.

Enlaces Relacionados

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.