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



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.



Aquí hay otros tres artículos que ofrecen lo que utilicé para el antecedente de este tutorial:
- 7 Medidas de Seguridad para Proteger Tus Servidores
- Esenciales UFW: Reglas y Comandos Comunes de Cortafuegos
- Cómo Proteger un Servidor Apache con Fail2Ban en Ubuntu 14.04
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



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



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



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.