Quitar ciphers inseguros de SSH UNIX RHEL8 (CBC, 3DES, WEAK MESSAGE, WEAK KEX)

La nota del día de hoy surge a partir de querer quitar un par (no menos como 5) de vulnerabilidades que salían tras un escaneo de un RHEL8 en la parte del SSH.

Vulnerabilidades que me encontré en el RHEL en cuestión.

Para quitarlas, revisé primero las políticas actuales del operativo, ya que no era una imagen REHL oficial, si no una hecha a la medida de cierta empresa.

Con el siguiente comando, revisamos las políticas por defecto del sistema.

[brianmiranda@server ~]# update-crypto-policies --show
LEGACY

Y me impresionó que tenía activada la política LEGACY por defecto. Los valores posibles son:

  • DEFAULT: secure settings for current threat models
  • LEGACY: ensures maximum compatibility but is less secure
  • FUTURE: conservative security level that is believed to withstand any near-term future attacks
  • FIPS: conforms with the FIPS 140-2 requirements

Si quieres más info oficial acerca de las diferencias click aquí.

Lo primero, es cambiar la política a la FUTURE, donde tendremos acceso SSH de una forma mucho más segura. Realmente te recomiendo visitar el link de arriba para entender la magnitud del cambio.

[brianmiranda@server ~]# update-crypto-policies --set FUTURE
Setting system policy to FUTURE
Note: System-wide crypto policies are applied on application start-up.
It is recommended to restart the system for the change of policies
to fully take place.

Con esto, las políticas van a aplicarse por completo tras un reinicio, aunque ya están listos muchos de los criterios. Reiniciaré y tras ello, las vulnerabilidades se reducen a 2:

ssh-cbc-ciphers – La resolveremos ahora.

generic-icmp-timestamp – La resolví en un post anterior y/o puedes ir a ver este post. (https://www.putorius.net/mitigate-icmp-timestamp-vulnerabilities.html)

Comprobación ciphers CBC

Si compruebas con otros métodos, puede ser confuso el que NO aparezcan los ciphers CBC como disponibles para conexión. Intenté algunas veces quitarlos mediante el archivo /etc/ssh/sshd_config pero no tuve éxito.

Una forma rápida de comprobar que están disponibles es:

ssh -vvv localhost | grep -i cbc

debug2: ciphers ctos: aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc

debug2: ciphers stoc: aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc

Crear complemento de política de seguridad

Para poder denegar el uso de los ciphers CBC, lo que mejor me ha servido es que generar una política relacionada que impida su uso. Para eso generamos un archivo de texto y lo escribimos en la carpeta donde se leen estas instrucciones.

sudo vi /etc/crypto-policies/policies/modules/DISABLE-CBC.pmod

Y dentro de este archivo pmod, escribimos lo siguiente:

tls_cipher = -AES-256-CBC -AES-128-CBC
cipher = -AES-128-CBC -AES-256-CBC -CAMELLIA-256-CBC -CAMELLIA-128-CBC
ssh_cipher = -AES-128-CBC -AES-256-CBC

Guardamos el archivo, salimos y aplicamos la nueva política con nuestras especificaciones.

sudo update-crypto-policies --set FUTURE:DISABLE-CBC

Nótese que se llama igual que el archivo generado dentro de /etc/crypto-policies/policies/modules/.

Yo estoy conectado por SSH, así que doy un reinicio del sistema y proceso a realizar el escaneo.

systemctl restart sshd

Tras el reinicio, podemos verificar con ssh -vvv localhost y comprueba que los ciphers CBC ya no aparecen.

Pues, listo. Vámonos.

¿No quedó?

Fuentes de refuerzo:

https://ins3cure.com/disabling-weak-ciphers-rhel8/

https://www.redhat.com/en/blog/configuring-rhel-8-compliance-crypto-policy-related-cipher-block-chaining

Limitar acceso SSH a una dirección IP específica con UFW en RHEL8

Últimamente me ha dado por utilizar UFW como firewall generalista, sin tanto problema para limitar las conexiones de mis instancias EC2.

En este ejemplo utilizo RHEL8.

Instalación de UFW

Para la instalación de UFW en RHEL8, iniciamos con la instalación de un paquete para tener disponible ufw:

sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

Sin este paquete en RHEL, obtenemos un error de epel-release no reconocido -obvio-.

Procedemos con la instalación de UFW:

sudo yum install ufw

Tras bajar algunos archivos y ser instalado, procedemos a habilitarlo y preguntar por el estatus del firewall.

sudo ufw enable

sudo ufw status

Ahora, para el objetivo que nos convoca el día de hoy aquí, listamos las reglas que se encuentran activas y bajo el control de ufw.

sudo ufw status numbered

Si no le has movido a tu operativo, aparecerán 2 reglas referentes al SSH. En mi caso siempre han sido la 1 y la 3. Algo importante es que si las elimino, no pierdo la conexión sí no hasta reiniciar el SSH. Proceso a eliminar:

sudo ufw delete 3 

sudo ufw delete 1

Y antes de perder mi conexión, agrego la IP por la cual quiero tener acceso al puerto 22. Agregaré en este ejemplo una IP publica que podría ser mi VPN y una IP local para el acceso desde una VPC.

sudo ufw allow from 18.119.41.10 to any port 22 proto tcp

sudo ufw allow from 10.48.125.15 to any port 22 proto tcp

Y ahora si, podemos reiniciar la conexión SSH.

Importante. Si reinicias la instancia, el firewall no entra en acción, así que espera a los atacantes (inserte musica dramática).

Para corregir esto, puedes ejecutar lo siguiente para activar el firewall automáticamente tras un reinicio:

sudo systemctl enable ufw

Listo. Aquí se rompió la taza 🍺

¿Quitar respuestas ICMP en un UNIX?

Cada que nos encontramos en el proceso de certificación de un sistema productivo nos debemos asegurar de tener ninguna vulnerabilidad en nuestro sistema, de por sí con ataques del día 0 tenemos suficiente.

Un básico para este objetivo es quitar las solicitudes y respuestas ICMP que permiten a un atacante determinar cosas como la hora del sistema objetivo o comprobar comunicación con ping.

En el caso de la hora, no tiene mucho peligro, pero si tenemos este dato para ataques combinados con generadores de random podría ser un gran dolor de cabeza y desembocar en pérdidas importantes.

Es por eso que a modo de nota para ustedes y para mi, vacío mis notas para este objetivo en esta entrada.

Comprobar respuestas ICMP con hping3

Antes de iniciar y a modo de verificación, instalamos hping3 en nuestro sistema local o en una maquina externa. Yo uso RHEL8 y lo tengo de forma local.

Una vez instalado, ejecutamos una solicitud (request) ICMP a nuestro localhost:

hping3 --icmp --icmptype 13 localhost 

Similar a la respuesta de un ping, se escribirá en la terminal la respuesta si es que no tenemos estas solicitudes bloqueadas. Por ahora no tengo un sistema con esto instalado y/o la intención de vulnerar alguno para un screenshot ¡Sorry!.

Podemos ejecutar lo mismo y simular una respuesta (response) ICMP:

hping3 --icmp --icmptype 14 localhost

Cómo pueden observar, sólo cambia el 13 por el 14.

Bloquear respuestas ICMP

Para el bloqueo de estas respuestas, podemos utilizar iptables. En este caso, lo utilizaremos para bloquear el timestamp-request y timestamp-reply.

Entonces, bloqueamos las respuestas timestamp ICMP:

iptables -A INPUT -p icmp --icmp-type timestamp-request -j DROP

Y luego bloqueamos las respuestas ICMP del mismo tipo:

iptables -A OUTPUT -p icmp --icmp-type timestamp-reply -j DROP

Podemos verificar con hping3 y ver el resultado 😎

Borrar reglas de bloqueo ICMP

Para eliminar estas reglas, nos dirigimos a iptables y buscamos el numero de regla que corresponde a nuestro bloqueo.

iptables -L INPUT --line-numbers | grep timestamp

Una vez con el numero de la regla de entrada (en este ejemplo la número 6) eliminamos con:

iptables --delete INPUT 6

Va lo mismo para la regla de salida de ICMP. Va todo de un jalón:

iptables -L OUTPUT --line-numbers | grep timestamp
iptables --delete OUTPUT 2

Y pues.. listo. A seguir verificando vulnerabilidades con Metasploit, Rapid7 o manual manualito.

Y si no te gusta iptables, puedes verificar estos otros métodos para el mismo objetivo: https://www.putorius.net/mitigate-icmp-timestamp-vulnerabilities.html

Déjame tus comentarios

Manejo de inflación con Python (USD)

Manejar cantidades a través del tiempo es un reto cuando se trata de hacer conversiones por inflación. En esta entrada muestro una de las librerías que utilizo para el tratado de datos con Python y dejar tus datos listos para ser utilizados sin tanto esfuerzo.

Teoría básica del manejo de la inflación

Partiré del hecho que sabemos un concepto más amplio del que daré a continuación, pero para definir la inflación en una frase:

Es el aumento general del nivel de precios de una economía durante un periodo de tiempo.

– Brian Miranda ja!

Significa que cuando el nivel general de precios sube, con cada unidad de moneda (sean dólares, euros, etc.) podemos comprar menos unidades de ciertos bienes o servicios. Y esa es la reducción del poder adquisitivo del dinero que se mencionaba antes.

Esta inflación la medimos con la tasa de inflación, que es la variación porcentual anualizada de un índice general de precios, normalmente el índice de precios al consumo (IPC).

Ejemplo en python

Primero, importamos las librerías necesarias:

import pandas as pd
from datetime import date
import cpi
import matplotlib.pyplot as plt

Librerías conocidas sin duda alguna, pero la que nos estará ayudando a realizar la magia es CPI. Esta librería trabaja solo con dólares aunque podemos hacer ajustes para manejar otras monedas. También podemos actualizar los datos frecuentemente de una forma muy sencilla para estar al día en nuestros desarrollos.

Error de uso con CPI

Una consideración importante es que al instalar puede salirnos el siguiente error

StaleDataWarning: CPI data is out of date. To accurately inflate to today’s dollars, you must run `cpi.update()`.

Eso es porque los datos no están actualizados aún.

Para resolverlo, es muy sencillo:

cpi.update()

Y listo. Pasemos a la función más importante con la que cuenta esta librería.

Función Inflate de CPI

Es la función bandera de la librería y se le pasan un par de parámetros.

El primero es el valor de los dólares que quieres convertir

El segundo es el año al que quieres la conversión.

El resultado, es el monto actual en dólares equivalentes al año en curso

Por tanto:

cpi.inflate(100, 2001)

# 148.6631 

Interpretación:

Por algo de 100 dólares en el año 2001, estaríamos pagando 148.6631 en 2021.

¿Y si no lo quieres para 2021?

cpi.inflate(100, 2000, to=2010)

#126.6295

O bien, puedes obtener el índice CPI para hacer las conversiones como tú quieras

cpi.get(2020)

# 258.811

¿Te parece útil?

Déjame tus comentarios

Activar S3 AWS en CentOS 7

Resulta que tengo la necesidad de escribir con python para leer con hadoop en un bucket de S3 de Amazon Web Services.

Encontré varios tutoriales en inglés pero casi ninguno en español. Then: Aquí actualizado a Junio de 2020 y en nuestro idioma.

Proceso que seguiremos el día de hoy:

  • Instalar dependencias
  • Descargar s3fs
  • Instalar s3fs
  • Montando s3fs
  • Verificamos que se haya montado correctamente

Requisitos:

Tener instalado paquetes de configuracion e instalación. Yo no los tenía porque estaba trabajando en una instalación mínima de CentOS 7. Para instalarlos, tengo otra entrada en este blog.

https://brianmirandamexico.wordpress.com/2020/06/07/intalacion-de-configure-centos-7/

Instalar dependencias:

Paso 1 – Dependencias para conectar a EC2 vía ssh.

sudo yum install automake fuse fuse-devel gcc-c++ git libcurl-devel libxml2-devel make openssl-devel

Paso 2 – Descargar s3fs

# cd /usr/src
# git clone https://github.com/s3fs-fuse/s3fs-fuse.git

Paso 3 – Compilar el sistema de archivos de S3 S3fs

# cd s3fs-fuse
# ./autogen.sh
# ./configure
# make

Paso 3 – Instalar s3fs

# sudo make install

Paso 4 – Configurando s3fs

Para eso debemos tener nuestra llave de acceso y clave de acceso. Las podemos encontrar aquí

echo AWS_ACCESS_KEY_ID:AWS_SECRET_ACCESS_KEY > ~/.passwd-s3fs

chmod 600 ~/.passwd-s3fs

Nota: Cambia los valores en mayusculas del código anterior con tus claves

Las mías quedan algo así (obviamente no son estas):

echo AKLB6C3AB2X4UKI7LZZX:ZaE5khuAqRaAieqqQvE90ZMCOFu9ZfxHI0nOqcsQ > ~/.passwd-s3fs
chmod 600 ~/.passwd-s3fs

Paso 5 – Montando s3fs

Creamos una carpeta donde enrutaremos el bucket que tengamos en s3. Si no tenemos uno, crearlo en la consola de amazon. Yo le puse «pairdev» pero sustituye al gusto.

mkdir /mnt/pairdev

Luego solicitamos permisos de administrador

sudo su

Montamos nuestro bucket en la carpeta. Sustituye «pair-dev» por el nombre de tu bucket y «pairdev» por la carpeta que creaste arriba.

echo s3fs#pair-dev /mnt/pairdev fuse _netdev,rw,nosuid,nodev,allow_other,nonempty 0 0 >> /etc/fstab

Paso 6 -Verificamos que se haya montado correctamente

mount -a

Podemos verificar los arcchivos existentes en el bucket (si tenemos) con un típico ls (Suelen tardar un poco los comandos).

¡Y listo!

Instalación de ./configure CentOS 7

¿Harto de? :

./autogen.sh: línea «X»: aclocal: no se encontró la orden

-bash: ./configure: No existe el fichero o el directorio

Sucede cuando no tienes los paquetes para instalación y compilación de aplicaciones. Nos damos cuenta cuando necesitamos compilar a partir de un tar gz o en instalaciones mínimas.

Proceso que seguiremos el día de hoy:

  • Verificar inexistencia de paquetes
  • Instalación de paquetes

Comandos:

Verificar inexistencia de paquetes:

Escribe en terminal:

./configure

¿Algún error? Frecuentemente aparece (o en inglés):

-bash: ./configure: No existe el fichero o el directorio

Instalación de paquetes

yum install automake

Puedes ejecutar el archivo autogen.sh que esta en tu carpeta descomprimida (y si lo tienes) para verificar la solución de tu error.

Listo, puedes seguir en tu proceso de instalación de aplicación.

Recuerda que el proceso de instalación en unix de paquetes descargados y descomprimidos comúnmente es:

./configure

make

make install

Listo!

Ejemplo NetRemoting usando Visual Basic

La semana pasada publiqué como hacer NetRemoting con C#.  ( https://brianmirandamexico.wordpress.com/2015/04/30/ejemplo-de-una-calculadora-usando-net-remoting-en-c/ ) Esta vez les enseñare como crear un cliente y servidor con esta tecnología pero con Visual Basic. Al final adjunto el proyecto completo para ser ejecutado y modificado.

También leía la documentación de Microsoft y nos recomienda ya no usar este método para compartir información por red (principalmente para aplicaciones distribuidas) y que nos inclinemos por usar Windows Communication Foundation (WCF).

Sin mas preámbulo, comencemos!

Requerimientos:

Visual Studio 2013.

Implementación:

Paso 1. Crearemos 3 proyectos dentro de una solución en Visual Studio y los referenciamos.

Uno contendrá todo el código para el cliente, otro para el servidor y otro la interface que ambos comparten para conocer el objeto que se usara en la red. Este último proyecto se va a referenciar en ambos proyectos para que conozcan los métodos y funciones que contiene el objeto en red, pero en el proyecto del servidor se va a tener que implementar la funcionalidad de todo lo que indique la interface, ya que será el responsable de dar la respuesta a los clientes.

Yo hice 3 proyectos de la siguiente forma:

ClienteRemoting Proyecto de tipo – Windows Application

ServidorRemoting Proyecto de tipo – Windows Application

NetRemotingObjs Proyecto de tipo – Biblioteca de clases

Creados los proyectos, referencio en ambos del tipo Aplicación el de tipo bliblioteca de clases.

Paso 2. Creamos el código de la interface.

En el proyecto NetRemotingObs agregue una nueva interface llamada RemotingInterface y escribí el código para una función salutes que regresa una cadena de texto.

Public Interface RemotingInterface

    Function salutes() As String

End Interface

Paso 3. Escribimos el cliente.

En el proyecto del cliente, hice un nuevo formulario con nombre cliente, y lo puse como formulario de inicio. Después puse un botón y escribí el código del siguiente modo.

Escribi 2 variables globales,

Dim obj As RemotingInterface

Dim channel As New TcpChannel

En el evento load del formulario puse la conexión al objeto en red con el nombre brianmiranda.

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

ChannelServices.RegisterChannel(channel)

obj = CType(Activator.GetObject(GetType(RemotingInterface), «tcp://localhost:8888/brianmiranda»), RemotingInterface)

End Sub

En el evento click del botón puse la llamada a la función «salutes» del objeto recién instanciado.

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Try 

            MsgBox(obj.salutes())

        Catch ex As Exception

            MsgBox(ex.Message)

        End Try

    End Sub

Mis imports se ven así:

Imports System.Runtime.Remoting.Channels.Tcp

Imports System.Runtime.Remoting.Channels

Imports NetRemotingObjs

cliente_netremoting

Paso 4. Escribimos el código del servidor.

Agregamos una nueva clase para escribir el código que ejecuta la función que definimos en la interface y le indicamos que hereda de MarshalByRefObject y que implementaremos la clase RemotingInterface.

El código queda así:

Imports NetRemotingObjs

Public Class RemoteClassServer

    Inherits MarshalByRefObject

    Implements RemotingInterface

    Function salutes() As String Implements RemotingInterface.salutes

        Return «Hola!»

    End Function

End Class

Con esto concluido, procedemos a crear un botón en un formulario del cliente para iniciar el servidor de NetRemoting y le asignamos al evento click del botón el siguiente código.

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Try

            Dim channel As New TcpChannel(8888)

            ChannelServices.RegisterChannel(channel)

RemotingConfiguration.RegisterWellKnownServiceType(GetType(RemoteClassServer), «brianmiranda», WellKnownObjectMode.SingleCall)

            MsgBox(«Servidor iniciado….»)

        Catch ex As Exception

            MsgBox(ex.Message)

        End Try

    End Sub

servidor_netremoting

Paso 5. Ajustamos para abrir los 2 proyectos de la solución al mismo tiempo.

Vamos a especificar que cuando le demos el botón de debug a visual studio abra 2 proyectos al mismo tiempo. Esto se hace con click derecho a la solución en el Solution Explorer de VS2013, -> Propiedades -> Common Properties -> Startup Project -> Múltiple Startup Project -> ClientRemoting START, ServerRemoting START.

multiple_startup

Corremos el programa y listo!

Se verá algo así.

netRemoting_vb

Pueden descargar el código completo del proyecto desde aquí.

http://goo.gl/kDHcWD

Ejemplo de una calculadora usando .Net Remoting en C#.

Hoy les traigo el método mas sencillo para hacer NetRemoting con Visual Studio en C#.

A los que ya han manejado RMI de Java notarán que es bastante similar (de hecho casi idéntico pero mas fácil) a las clases/interfaces que se generan en el cliente y servidor.

Les mostrare como crear un objeto que usare para una calculadora y al final adjuntaré el proyecto completo, compilado y listo para ser abierto con Visual Studio 2013. Lo importante lo pongo en negritas.

Paso 1. Creamos solución y un proyecto para el código del servidor.

servidor_vb

Creamos una solución en VS2013, y borramos el proyecto que nos crea por default (si así desean) y creamos uno nuevo, yo lo llame «Calculadora_Remoting_DDSOK». Aquí contendré todo el código del servidor.

Paso 2. Creamos interface 

Servidor:

Creamos interface de un objeto (donde solo ponemos la definición de los métodos de un objeto para cuando se implemente en una clase, obligar a escribir el funcionamiento de todos los descritos en esa interface.). Para esto damos click derecho en el proyecto, Add -> New ítem -> Interface -> Visual C# ítems -> Interface ->  La llamaremos «RemoteInterface» y le damos -> Add.

Así queda el código.


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace Calculadora_Remoting_DDSOK

{

    public interface RemoteInterface

    {

        float suma(float a, float b);

        float resta(float a, float b);

        float multiplicacion(float a, float b);

        float division(float a, float b);

        float porcentaje(float a, float b);

        String correrADerecha(String a);

        String correrAIzquierda(String a);

        float modulo(float a,float b);

        String invertir(String a);

    }

}


Paso 3. Escribimos el código de cada método e indicamos que implementamos la interface y que el objeto será usado para NetRemoting.

Creamos clase «RemoteClass» dando click derecho en el proyecto, -> Add -> New ítem -> Class -> Visual C# ítems -> Class -> La llamaremos «RemoteClass» y le damos Add.

Al proyecto tenemos que agregar la referencia de Remoting en Click derecho al proyecto, ->Add -> Reference -> Assemblies -> Framework -> System.Runtime.Remoting

Implementamos la interface RemoteInterface a la clase y heredamos de la clase MarshalByRefObject para indicar que usaremos NetRemoting.

Así queda el código:


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace Calculadora_Remoting_DDSOK

{

    public class RemoteClass: MarshalByRefObject, RemoteInterface

    {

        public float suma(float a, float b)

        {

            float res = 0;

            res = a + b;

            return res;

        }

        public float resta(float a, float b)

        {   

            float res = 0;

            res = a – b;

            return res;

        }

        public float multiplicacion(float a, float b)

        {

            float res = 0;

            res = a * b;

            return res;

        }

        public float division(float a, float b)

        {

            float res = 0;

            res = a / b;

            return res;

        }

        public float porcentaje(float a, float b)

        {

            float res = 0;

            res = a * (b / 100);

            return res;

        }

        public String correrADerecha(String a)

        {

            String res = «»;

            if(a.Length>2)

            res = a.Substring(0, a.Length – 1);

            return res;

        }

        public String correrAIzquierda(String a)

        {

            String res = «»;

            res = a + «0»;

            return res;

        }

        public float modulo(float a, float b)

        {

            float res = 0;

            res = a % b;

            return res;

        }

        public String invertir(String a)

        {

            string invertido = «»;

            for (int i = a.Length – 1; i >= 0; i–)

                invertido = invertido + a.Substring(i, 1);

            return invertido;

        }

    }

}


Paso 4. Creamos el código para activar el servidor.

Yo puse un botón para que se inicie el servidor al presionarlo. El código es el siguiente:


            TcpChannel channel = new TcpChannel(8888); // USAREMOS EL PUERTO 8888 P/COMUNICARNOS

            ChannelServices.RegisterChannel(channel);

            RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteClass), «cincom», WellKnownObjectMode.SingleCall); // EL NOMBRE DEL OBJETO QUE BUSCAREMOS EN LA RED SE LLAMA cincom

            MessageBox.Show(«El servidor esta listo…»);

            System.Console.ReadLine();


El servidor esta listo para ejecutar. Si desean pueden ejecutar el proyecto y buscar en donde hace falta algunas referencias para completarlas. Cuando el programa de servidor se ejecute correctamente, podrán ver que aparece una alerta de que el programa quiere comunicarse con la red y salta la protección de Firewall de Windows.

Paso 5. Creamos un proyecto para el cliente. (Yo lo puse en la misma solución).

calculadora_vb

 

Si lo quieren agregar en la misma solución como yo, Click derecho en la solución -> Add -> New Project -> Yo lo nombre «Calculadora_Remoting_DDSOK_Cliente» y le damos OK.

Paso 6. Creamos una interface en el cliente.

Esto lo haremos para que nuestro cliente se entere de que funciones tiene nuestro objeto de la red. No las implementaremos como en el servidor, el cliente no sabe como funcionan, solo se comunica con ellas, les da parámetros y recibe resultados.

Para esto damos click derecho en el proyecto, Add -> New ítem -> Interface -> Visual C# ítems -> Interface ->  La llamaremos «RemoteInterface» y le damos -> Add.

El código es exactamente igual que la interfaz del servidor.

Paso 7. Nos conectamos al objeto de la red.

Mi ejemplo es de una calculadora, así que puse en el constructor del form donde puse mis botones el código para abrir la comunicación con el servidor.


            try

            {

                TcpChannel chan = new TcpChannel();

                ChannelServices.RegisterChannel(chan);

                // CREAMOS UNA INSTANCIA DEL OBJETO.

                obj = (RemoteInterface)Activator.GetObject(typeof(RemoteInterface), «tcp://localhost:8888/cincom»);

// AQUI PODEMOS USAR YA EL OBJETO

            }

            catch

            {

                // localhost  OR your server name

                if (obj.Equals(null))

                {

                    System.Console.WriteLine(«Error: unable to locate server»);

                }

            }


Y ya pueden usar el objeto para consumir todas las operaciones. Les regresara los tipos de datos que definimos en la interface y en la clase. Nota: El objeto se crea en el servidor, por tanto cuando llaman a alguna función se ejecuta en el servidor y este regresa al cliente la respuesta.

Pueden descargar el proyecto completo de aquí.

http://goo.gl/a5egvu

Ejemplo RMI de Java

Introducción.

El mecanismo RMI de Java permite poner en la red un objeto disponible para poder ejecutar los métodos que este contiene y estos métodos pueden ser invocados desde otra computadora por medio de una interfaz que indique los métodos que contiene nuestro objeto.

En el siguiente tutorial  implementaré la forma equivalente en Visual Basic con Visual Studio 2013 usando .Net Remoting. Mientras pueden dar un vistazo de su funcionamiento con el proyecto que nos deja Microsoft en su sitio.

https://code.msdn.microsoft.com/windowsdesktop/VBRemoting-87884881


Actualización. – NetRemoting disponible.

https://brianmirandamexico.wordpress.com/2015/04/30/ejemplo-de-una-calculadora-usando-net-remoting-en-c/


Comencemos!

Requerimientos.

Java:

Sublime Text para escribir las clases Java

Consola para compilar las clases Java. (Estoy usando Java 1.7 para Mac OSX Yosemite)

Implementación

Servidor Java.

Crearemos 3 archivos, el:

RMI_Server.java: Ejecutable del servidor Java

RemoteInterface.java: Interface que servirá para indicar los métodos que contiene nuestro objeto (sin implementar)

RemoteClass.java: Implementación de los métodos de nuestro objeto y objeto que estará disponible enla red.


RMI_Servier.java:

import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

/**
*
* @author brianmiranda
*/
public class RMI_Server {

/**
* @param args the command line arguments
*/
public static void main(String args[])
{
try
{
RemoteClass robj = new RemoteClass();

//Esta linea obtiene el objeto para poner disponible y el puerto en que escuchara conexiones. 0 es para puerto por dafault, 1099.

RemoteInterface stub = (RemoteInterface)UnicastRemoteObject.exportObject(robj,0);

Registry registry = LocateRegistry.getRegistry ();

/*

Esta linea pone en linea al objeto y para que se ejecute correctamente se debe iniciar el «miregistry» de java con el comando: brianmiranda$ rmiregistry &

*/
registry.bind(«brianmirandamexico», stub);
System.out.println(«Servidor listo en espera de peticiones…»);
}
catch (AlreadyBoundException | RemoteException e)
{
System.err.println(«Server exception thrown: » +
e.toString());
}
}

}


RemoteInterface.java:

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface RemoteInterface extends Remote
{
public void WriteName(String str) throws RemoteException;
public String ReadWelcome() throws RemoteException;
}


RemoteClass.java
public class RemoteClass implements RemoteInterface {
private static String strWelcomeClient;
RemoteClass ()
{
System.out.println(«Object created»);
}
@Override
public String ReadWelcome()
{
return strWelcomeClient;
}
@Override
public void WriteName(String strNameFromClient)
{
strWelcomeClient = «HI » + strNameFromClient +
«. Welcome to RMI World!!»;
}
}


Cliente Java.

Solo crearemos una clase cliente para ver como se consume el método  del objeto en red.


Cliente.java
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

/**
*
* @author brianmiranda
*/
public class Client
{
private static RemoteInterface stub = null;
private Client() {}
public static void main(String[] args)
{
try
{
Registry reg = LocateRegistry.getRegistry(«localhost»);
// localhost OR your server name
stub = (RemoteInterface) reg.lookup(«brianmirandamexico»);
}
catch (Exception e)
{
System.err.println(«Client exception thrown: » +
e.toString());
}
String strArgs;
if (args.length == 0)
{
strArgs = «Client»;
}
else
{
strArgs = args[0];
}
try
{
stub.WriteName(strArgs);
System.out.println(stub.ReadWelcome());
}
catch(Exception e)
{
System.out.println(«Remote method exception thrown: » +
e.getMessage());
}
}
}


Compilamos cada clase (4 archivos .class).

La ejecución será:

Servidor:

brianmiranda$ rmiregistry &

brianmiranda$ java RMI_Server

Cliente:

brianmiranda$ java Cliente

compilacion1compilacion2

Con esto, veremos como el cliente ejecuta el método ReadWelcome y aparece en pantalla un mensaje de bienvenida definida en nuestra clase RemoteClass.

 

Puedes descargar el proyecto completo desde aquí!

http://goo.gl/pzb4ji