Inventario#
FakeNOS utiliza un inventario para definir un conjunto de hosts SSH y su configuración. Es una parte clave del proyecto. El inventario es un diccionario que contiene dos secciones: default
y hosts
. La sección default
contiene parámetros y configuración que FakeNOS utiliza por defecto para cada host. La sección hosts
es un diccionario indexado por los nombres de los hosts que contienen la definición del host. Cualquier parámetro definido por host anula los parámetros definidos en la sección default
.
Hay dos formas de proporcionar datos de inventario a FakeNOS:
- Usando un archivo YAML
- Usando un diccionario de Python
Estructura básica#
En todos los casos, los datos del inventario deben tener la siguiente estructura, independientemente del método utilizado para proporcionarlos:
- default: Un diccionario que contiene parámetros y configuración por defecto que FakeNOS utiliza por defecto para cada host.
- hosts: Un diccionario indexado por los nombres de los hosts que contienen la definición del host. Cualquier parámetro definido por host anula los parámetros definidos en la sección
default
.
Es obligatorio proporcionar siempre la sección hosts
. La sección default
es opcional. Si no se proporciona, FakeNOS utiliza una configuración por defecto. Esta estructura funciona de forma jerárquica, por lo que la sección hosts
anulará la sección default
.
Warning
Aunque puedes cambiar libremente los parámetros por defecto, se recomienda mantenerlos como están y anularlos a través de la sección hosts
. En caso de que cambies la sección default
, debes proporcionar todos los parámetros que están en la configuración por defecto.
Inventario por defecto#
Si no se proporcionan datos de inventario en la instanciación del objeto FakeNOS, FakeNOS utiliza la configuración de inventario por defecto. Estos son los valores por defecto actuales1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
YAML#
Esta es la forma más sencilla de proporcionar datos de inventario. En un simple archivo YAML, puedes definir los datos del inventario. El archivo YAML debe tener la siguiente estructura:
default:
username: user
password: user
port: 6000
platform: cisco_ios
En este caso, creará un host llamado router0
con el nombre de usuario user
, la contraseña user
y el puerto 6000
. La plataforma será cisco_ios
. Si deseas crear más hosts, puedes añadirlos a la sección hosts
:
hosts:
router1:
port: 6001
platform: huawei_smartax
router2:
port: 6002
platform: cisco_ios
En este caso, estás creando 2 hosts: router1
y router2
. router1
tendrá el puerto 6001
y la plataforma huawei_smartax
. router2
tendrá el puerto 6002
y la plataforma cisco_ios
. Como las credenciales no se proporcionan en la sección hosts
, FakeNOS utilizará las credenciales por defecto.
Para utilizar el archivo YAML, puedes utilizar la herramienta CLI de FakeNOS:
fakenos -i path/to/inventory.yaml
Diccionario de Python#
Aunque YAML es la forma más sencilla de proporcionar datos de inventario a FakeNOS, utilizar un diccionario de Python es más flexible y permite estructuras de datos de inventario más complejas. De hecho, los diccionarios de Python se utilizan internamente en FakeNOS para manejar los datos del inventario.
En caso de que quieras utilizar tu propio diccionario de Python, puedes proporcionarlo directamente a FakeNOS. En el siguiente código estamos haciendo exactamente lo mismo que en el primer código en YAML:
from fakenos import FakeNOS
inventory_data = {
"hosts": {
"username": "user",
"password": "user",
"port": 6000,
"platform": "cisco_ios",
}
}
network = FakeNOS(inventory=inventory_data)
Como antes, en caso de que quieras crear más hosts, puedes añadirlos a la sección hosts
:
inventory_data = {
"hosts": {
"router1": {"port": 6001, "platform": "huawei_smartax"},
"router2": {"port": 6002, "platform": "cisco_ios"}
}
}
Otros ejemplos#
Aquí tienes un ejemplo de datos de inventario y código para iniciar los servidores:
from fakenos import FakeNOS
fake_network = {
"default": { # (4)
"username": "user",
"password": "user",
"port": [5000, 6000],
"server": {
"plugin": "ParamikoSshServer",
"configuration": {
"ssh_key_file": "./ssh-keys/ssh_host_rsa_key",
"timeout": 1,
"address": "127.0.0.1",
},
},
"shell": {"plugin": "CMDShell", "configuration": {}},
"nos": {"plugin": "cisco_ios", "configuration": {}},
},
"hosts": {
"R1": {
"port": 5001,
"username": "fakenos", # (2)
"password": "fakenos",
"server": {
"plugin": "ParamikoSshServer",
"configuration": {"address": "0.0.0.0"}, # (1)
},
"shell": {
"plugin": "CMDShell",
"configuration": {"intro": "Custom SSH Shell"},
},
},
"R2": {},
"core-router": {"replicas": 2, "port": [5000, 6000]}, # (3)
},
}
network = FakeNOS(inventory=fake_network)
network.starts()
print(network.list_hosts())
0.0.0.0
- Dirección IP para escuchar todas las interfaces de red- Anula
username
ypassword
definidos en la seccióndefault
- Inicia dos hosts
core-router1
ycore-router2
utilizando el siguiente puerto disponible del rango proporcionado - Configuración utilizada por todos los hosts por defecto
Una alternativa a ejecutar el código anterior es proporcionar un inventario personalizado a la herramienta CLI de FakeNOS:
fakenos -i path/to/my_inventory.yaml
Donde my_inventory.yaml
podría contener un inventario YAML equivalente al código Python anterior:
default:
password: user
username: user
port: [5000, 6000]
server:
plugin: ParamikoSshServer
configuration:
address: 127.0.0.1
ssh_key_file: ./ssh-keys/ssh_host_rsa_key
timeout: 1
shell:
configuration: {}
plugin: CMDShell
nos:
configuration: {}
plugin: cisco_ios
hosts:
R1:
password: fakenos
port: 5001
username: fakenos
server:
plugin: ParamikoSshServer
configuration:
address: 0.0.0.0
shell:
plugin: CMDShell
configuration:
intro: Custom SSH Shell
R2: {}
core-router:
replicas: 2
port: [5000, 6000]
O podría contener este inventario simplificado:
default:
password: user
username: user
port: [5000, 6000]
server:
plugin: ParamikoSshServer
configuration:
address: 0.0.0.0
hosts:
router:
replicas: 10
platform: cisco_ios
Réplicas de Hosts#
Antes se podía ver que algunos hosts tenían el indicador de réplicas establecido. La definición de host puede contener el parámetro replicas
para definir hosts en bloque, por ejemplo, este inventario:
inventory_data = {
"hosts": {
"router": {"replicas": 10, "port": [5001, 6000]}
}
}
Esta configuración hará que FakeNOS ejecute 10 instancias de servidores de hosts llamados router1
a router10
utilizando los puertos 5001 a 5010 respectivamente. Esto hace que sea muy fácil definir conjuntos de hosts que utilizan la misma configuración para escalar la configuración.
Warning
Si los datos del inventario del host contienen el parámetro replicas
, el parámetro port
debe ser una lista de dos enteros que representan el rango para asignar puertos. Si el host no contiene el parámetro replicas
, port
debe ser un entero positivo del rango de 1 a 65535.
Generación de la clave privada SSH#
Por defecto FakeNOS utiliza la clave privada SSH incrustada con el paquete, lo que hace que esa clave sea pública, lo cual es inseguro. En su lugar, FakeNOS puede utilizar una clave SSH generada localmente.
Linux y MacOS#
Utiliza el comando ssh-keygen -A
en la terminal para generar todas tus claves SSH. Una vez ejecutado el comando, puedes encontrar la clave RSA en la siguiente ubicación: ~/.ssh/id_rsa
alias /home/<username>.ssh/id_rsa
. Proporciona la ruta anterior como argumento ssh_key_file
a la configuración del servidor FakeNOS.
Alternativamente, puedes utilizar el comando ckeygen -t rsa -f ssh-keys/ssh_host_rsa_key
para generar la clave privada.
Windows 10#
Presiona la tecla de Windows, escribe Manage Optional Features
. Si OpenSSH Client & Server está en la lista, estás listo.
Si no está, haz clic en "Add a feature" y busca OpenSSH
, haz clic en ellos para instalarlos.
A continuación, abre cmd como administrador. Introduce el comando ssh-keygen
y sigue las instrucciones en pantalla.
La ubicación de la clave se mostrará. Proporciona la ruta mostrada como argumento ssh_key_file
a la configuración del servidor FakeNOS. Si pones una contraseña, inclúyela como el parámetro ssh_key_file_password
.
Esquema JSON del Inventario#
FakeNOS utiliza internamente modelos Pydantic para validar los datos del inventario y lanzar ValidationError
si el inventario no cumple con el esquema definido.
Mientras el inventario está modelado utilizando modelos de Pydantic, el esquema equivalente en JSON sería así:
{
"title": "ModelFakenosInventory",
"description": "FakeNOS inventory data schema",
"type": "object",
"properties": {
"default": {
"$ref": "#/definitions/InventoryDefaultSection"
},
"hosts": {
"title": "Hosts",
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/HostConfig"
}
}
},
"required": [
"hosts"
],
"additionalProperties": false,
"definitions": {
"ParamikoSshServerConfig": {
"title": "ParamikoSshServerConfig",
"type": "object",
"properties": {
"ssh_key_file": {
"title": "Ssh Key File",
"type": "string"
},
"ssh_key_file_password": {
"title": "Ssh Key File Password",
"type": "string"
},
"ssh_banner": {
"title": "Ssh Banner",
"default": "FakeNOS Paramiko SSH Server",
"type": "string"
},
"timeout": {
"title": "Timeout",
"default": 1,
"type": "integer"
},
"address": {
"title": "Address",
"anyOf": [
{
"enum": [
"localhost"
],
"type": "string"
},
{
"type": "string",
"format": "ipvanyaddress"
}
]
},
"watchdog_interval": {
"title": "Watchdog Interval",
"default": 1,
"type": "integer"
}
}
},
"ParamikoSshServerPlugin": {
"title": "ParamikoSshServerPlugin",
"type": "object",
"properties": {
"plugin": {
"title": "Plugin",
"enum": [
"ParamikoSshServer"
],
"type": "string"
},
"configuration": {
"$ref": "#/definitions/ParamikoSshServerConfig"
}
},
"required": [
"plugin"
]
},
"CMDShellConfig": {
"title": "CMDShellConfig",
"type": "object",
"properties": {
"intro": {
"title": "Intro",
"default": "Custom SSH Shell",
"type": "string"
},
"ruler": {
"title": "Ruler",
"default": "",
"type": "string"
},
"completekey": {
"title": "Completekey",
"default": "tab",
"type": "string"
},
"newline": {
"title": "Newline",
"default": "\r\n",
"type": "string"
}
}
},
"CMDShellPlugin": {
"title": "CMDShellPlugin",
"type": "object",
"properties": {
"plugin": {
"title": "Plugin",
"enum": [
"CMDShell"
],
"type": "string"
},
"configuration": {
"$ref": "#/definitions/CMDShellConfig"
}
},
"required": [
"plugin"
]
},
"NosPlugin": {
"title": "NosPlugin",
"type": "object",
"properties": {
"plugin": {
"title": "Plugin",
"type": "string"
},
"configuration": {
"title": "Configuration",
"type": "object"
}
},
"required": [
"plugin"
]
},
"InventoryDefaultSection": {
"title": "InventoryDefaultSection",
"type": "object",
"properties": {
"username": {
"title": "Username",
"type": "string"
},
"password": {
"title": "Password",
"type": "string"
},
"port": {
"title": "Port",
"anyOf": [
{
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 65535
},
{
"type": "array",
"items": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 65535
},
"minItems": 2,
"maxItems": 2,
"uniqueItems": true
}
]
},
"server": {
"$ref": "#/definitions/ParamikoSshServerPlugin"
},
"shell": {
"$ref": "#/definitions/CMDShellPlugin"
},
"nos": {
"$ref": "#/definitions/NosPlugin"
}
}
},
"HostConfig": {
"title": "HostConfig",
"type": "object",
"properties": {
"username": {
"title": "Username",
"type": "string"
},
"password": {
"title": "Password",
"type": "string"
},
"port": {
"title": "Port",
"anyOf": [
{
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 65535
},
{
"type": "array",
"items": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 65535
},
"minItems": 2,
"maxItems": 2,
"uniqueItems": true
}
]
},
"server": {
"$ref": "#/definitions/ParamikoSshServerPlugin"
},
"shell": {
"$ref": "#/definitions/CMDShellPlugin"
},
"nos": {
"$ref": "#/definitions/NosPlugin"
},
"count": {
"title": "Count",
"exclusiveMinimum": 0,
"type": "integer"
}
}
}
}
}
Opciones de Inventario#
Las siguientes opciones pueden ser utilizadas en la sección default
o en la sección hosts
para anular los valores por defecto.
Opciones de nivel superior#
Opción | Emoji | Descripción | E.g. |
---|---|---|---|
username |
nombre de usuario del dispositivo | username: admin |
|
password |
contraseña del dispositivo | password: admin |
|
platform |
sistema operativo de red utilizado | platform: cisco_ios |
|
port |
puerto al que conectarse | port: 6000 |
|
replicas |
número de hosts a crear | replicas: 10 |
|
server |
configuración del servidor | Ver la sección Opciones de servidor | |
shell |
configuración de la shell | Ver la sección Opciones de shell | |
nos |
configuración de NOS | Ver la sección Opciones de NOS |
Opciones de servidor#
Opción | Emoji | Descripción | E.g. |
---|---|---|---|
plugin |
plugin del servidor a utilizar | plugin: ParamikoSshServer |
|
configuration |
configuración del servidor | Ver la sección Opciones de configuración del servidor |
Opciones de configuración del servidor#
Opción | Emoji | Descripción | E.g. |
---|---|---|---|
ssh_key_file |
ruta al archivo de clave privada SSH | ssh_key_file: /path/to/ssh_key |
|
ssh_key_file_password |
contraseña para la clave privada SSH | ssh_key_file_password: password |
|
ssh_banner |
banner SSH a mostrar | ssh_banner: "Bienvenido al servidor SSH de FakeNOS" |
|
timeout |
tiempo de espera para el servidor | timeout: 1 |
|
address |
dirección a la que enlazar el servidor | address: 127.0.0.1 |
|
watchdog_interval |
interval for watchdog | watchdog_interval: 1 |
Opciones de shell#
Opción | Emoji | Descripción | E.g. |
---|---|---|---|
plugin |
shell plugin que se utilizará | plugin: CMDShell |
|
configuration |
configuración del shell | La configuración depende completamente del plugin |
Opciones de NOS#
Opción | Emoji | Descripción | E.g. |
---|---|---|---|
plugin |
NOS plugin usado | plugin: cisco_ios |
|
configuration |
NOS configuración | La configuración depende completamente del plugin |
-
Para ver los valores por defecto actuales, consulta el código fuente de FakeNOS. ↩