Commit b1dcbf77 authored by Alain Takoudjou's avatar Alain Takoudjou

kvm: Add restrict mode for nat interface

If restrict mode is set to true, nat interface (eth0) will be isolated, no network access, only host and guest forward rules will work throught that interface.
This option is true by default for kvm-cluster, and false for single and resilient kvm.
parent 392f3ead
...@@ -98,7 +98,7 @@ mode = 0644 ...@@ -98,7 +98,7 @@ mode = 0644
recipe = hexagonit.recipe.download recipe = hexagonit.recipe.download
url = ${:_profile_base_location_}/instance-kvm.cfg.jinja2 url = ${:_profile_base_location_}/instance-kvm.cfg.jinja2
mode = 644 mode = 644
md5sum = ade64ba25dd4e98514479ac3363ea6ce md5sum = 4aeffb282779b43a55eb9067450cbefc
download-only = true download-only = true
on-update = true on-update = true
...@@ -106,7 +106,7 @@ on-update = true ...@@ -106,7 +106,7 @@ on-update = true
recipe = hexagonit.recipe.download recipe = hexagonit.recipe.download
url = ${:_profile_base_location_}/instance-kvm-cluster.cfg.jinja2.in url = ${:_profile_base_location_}/instance-kvm-cluster.cfg.jinja2.in
mode = 644 mode = 644
md5sum = 1f5a7b9307059a46318fab4fe63f3ecd md5sum = 33f5f81dc2a19f74acda8316e5fde25e
download-only = true download-only = true
on-update = true on-update = true
...@@ -184,7 +184,7 @@ recipe = hexagonit.recipe.download ...@@ -184,7 +184,7 @@ recipe = hexagonit.recipe.download
url = ${:_profile_base_location_}/template/template-kvm-run.in url = ${:_profile_base_location_}/template/template-kvm-run.in
mode = 644 mode = 644
filename = template-kvm-run.in filename = template-kvm-run.in
md5sum = 42e5c653780fdb86b50aa89d73814934 md5sum = 24b09d68f7cd0e81630c685cc679676b
download-only = true download-only = true
on-update = true on-update = true
......
...@@ -221,7 +221,8 @@ ...@@ -221,7 +221,8 @@
"title": "Use keyboard layout language", "title": "Use keyboard layout language",
"description": "Use keyboard layout language (for example fr for French). Can be usefull with VNC display", "description": "Use keyboard layout language (for example fr for French). Can be usefull with VNC display",
"type": "string", "type": "string",
"enum": ["ar", "da", "de", "de-ch", "en-gb", "en-us", "es", "et", "fi", "fo", "fr", "fr-be", "fr-ca", "fr-ch", "hr", "hu", "is", "it", "ja", "lt", "lv", "mk", "nl", "nl-be", "no", "pl", "pt", "pt-br", "ru", "sl", "sv", "th", "tr"] "enum": ["ar", "da", "de", "de-ch", "en-gb", "en-us", "es", "et", "fi", "fo", "fr", "fr-be", "fr-ca", "fr-ch", "hr", "hu", "is", "it", "ja", "lt", "lv", "mk", "nl", "nl-be", "no", "pl", "pt", "pt-br", "ru", "sl", "sv", "th", "tr"],
"default": "fr"
}, },
"nbd-host": { "nbd-host": {
"title": "NBD hostname or IP", "title": "NBD hostname or IP",
...@@ -294,7 +295,7 @@ ...@@ -294,7 +295,7 @@
"default": true "default": true
}, },
"use-nat": { "use-nat": {
"title": "Use QEMU USER Mode networking", "title": "Use QEMU USER Mode interface (NAT)",
"description": "Use QEMU user-mode network stack (NAT).", "description": "Use QEMU user-mode network stack (NAT).",
"type": "boolean", "type": "boolean",
"default": true "default": true
...@@ -303,11 +304,13 @@ ...@@ -303,11 +304,13 @@
"title": "List of rules for NAT of QEMU user mode network stack.", "title": "List of rules for NAT of QEMU user mode network stack.",
"description": "List of rules for NAT of QEMU user mode network stack, as comma-separated list of ports. For each port specified, it will redirect port x of the VM (example: 80) to the port x + 10000 of the public IPv6 (example: 10080). Defaults to \"22 80 443\".", "description": "List of rules for NAT of QEMU user mode network stack, as comma-separated list of ports. For each port specified, it will redirect port x of the VM (example: 80) to the port x + 10000 of the public IPv6 (example: 10080). Defaults to \"22 80 443\".",
"type": "array", "type": "array",
"default": [ "default": []
22, },
80, "nat-restrict-mode": {
443 "title": "Isolate the NAT Interface (No Internet access)",
] "description": "If this option is enabled, the NAT interface will be isolated, i.e. it will not be able to contact the host and no guest IP packets will be routed over the host to the outside. This option does not affect any explicitly set nat rules.",
"type": "boolean",
"default": true
}, },
"enable-vhost": { "enable-vhost": {
"title": "Use vhost-net to improve network performance of tap interface", "title": "Use vhost-net to improve network performance of tap interface",
......
...@@ -56,6 +56,7 @@ config-nat-rules = {{ nat_rules_list | join(' ') }} ...@@ -56,6 +56,7 @@ config-nat-rules = {{ nat_rules_list | join(' ') }}
config-publish-nat-url = True config-publish-nat-url = True
config-use-nat = {{ use_nat }} config-use-nat = {{ use_nat }}
config-use-tap = {{ dumps(kvm_parameter_dict.get('use-tap', True)) }} config-use-tap = {{ dumps(kvm_parameter_dict.get('use-tap', True)) }}
config-nat-restrict-mode = {{ dumps(kvm_parameter_dict.get('nat-restrict-mode', True)) }}
config-enable-vhost = {{ dumps(kvm_parameter_dict.get('enable-vhost', False)) }} config-enable-vhost = {{ dumps(kvm_parameter_dict.get('enable-vhost', False)) }}
config-virtual-hard-drive-url = {{ dumps(kvm_parameter_dict.get('virtual-hard-drive-url', '')) }} config-virtual-hard-drive-url = {{ dumps(kvm_parameter_dict.get('virtual-hard-drive-url', '')) }}
config-virtual-hard-drive-md5sum = {{ dumps(kvm_parameter_dict.get('virtual-hard-drive-md5sum', '')) }} config-virtual-hard-drive-md5sum = {{ dumps(kvm_parameter_dict.get('virtual-hard-drive-md5sum', '')) }}
......
...@@ -135,7 +135,7 @@ ...@@ -135,7 +135,7 @@
"default": false "default": false
}, },
"use-nat": { "use-nat": {
"title": "Use QEMU USER Mode networking", "title": "Use QEMU USER Mode interface (NAT)",
"description": "Use QEMU user-mode network stack (NAT).", "description": "Use QEMU user-mode network stack (NAT).",
"type": "boolean", "type": "boolean",
"default": true "default": true
...@@ -145,6 +145,12 @@ ...@@ -145,6 +145,12 @@
"description": "List of rules for NAT of QEMU user mode network stack, as comma-separated list of ports. For each port specified, it will redirect port x of the VM (example: 80) to the port x + 10000 of the public IPv6 (example: 10080). Defaults to \"22 80 443\". Ignored if \"use-tap\" parameter is enabled.", "description": "List of rules for NAT of QEMU user mode network stack, as comma-separated list of ports. For each port specified, it will redirect port x of the VM (example: 80) to the port x + 10000 of the public IPv6 (example: 10080). Defaults to \"22 80 443\". Ignored if \"use-tap\" parameter is enabled.",
"type": "string" "type": "string"
}, },
"nat-restrict-mode": {
"title": "Isolate the NAT Interface (No Internet access)",
"description": "If this option is enabled, the NAT interface will be isolated, i.e. it will not be able to contact the host and no guest IP packets will be routed over the host to the outside. This option does not affect any explicitly set nat rules.",
"type": "boolean",
"default": true
},
"enable-vhost": { "enable-vhost": {
"title": "Use vhost-net to improve network performance of tap interface", "title": "Use vhost-net to improve network performance of tap interface",
"description": "The vhost-net provides much improved network performance for your VM. Only work if the vhost-net kernel module is loaded and available on host machine, please keep this option off if you're not shure.", "description": "The vhost-net provides much improved network performance for your VM. Only work if the vhost-net kernel module is loaded and available on host machine, please keep this option off if you're not shure.",
......
{% set enable_http = slapparameter_dict.get('enable-http-server', 'False').lower() -%} {% set enable_http = slapparameter_dict.get('enable-http-server', 'False').lower() -%}
{% set use_tap = slapparameter_dict.get('use-tap', 'False').lower() -%} {% set use_tap = slapparameter_dict.get('use-tap', 'False').lower() -%}
{% set use_nat = slapparameter_dict.get('use-nat', 'True').lower() -%} {% set use_nat = slapparameter_dict.get('use-nat', 'True').lower() -%}
{% set nat_restrict = slapparameter_dict.get('nat-restrict-mode', 'False').lower() -%}
{% set name = slapparameter_dict.get('name', 'localhost') -%} {% set name = slapparameter_dict.get('name', 'localhost') -%}
{% set disable_ansible_promise = slapparameter_dict.get('disable-ansible-promise', 'False').lower() -%} {% set disable_ansible_promise = slapparameter_dict.get('disable-ansible-promise', 'False').lower() -%}
{% set instance_type = slapparameter_dict.get('type', 'standalone') -%} {% set instance_type = slapparameter_dict.get('type', 'standalone') -%}
...@@ -95,6 +96,7 @@ tap-mac-address = ${create-tap-mac:mac-address} ...@@ -95,6 +96,7 @@ tap-mac-address = ${create-tap-mac:mac-address}
use-tap = ${slap-parameter:use-tap} use-tap = ${slap-parameter:use-tap}
use-nat = ${slap-parameter:use-nat} use-nat = ${slap-parameter:use-nat}
nat-rules = {{ nat_rule_list }} nat-rules = {{ nat_rule_list }}
nat-restrict= {{ nat_restrict }}
enable-vhost = ${slap-parameter:enable-vhost} enable-vhost = ${slap-parameter:enable-vhost}
virtual-hard-drive-url = ${slap-parameter:virtual-hard-drive-url} virtual-hard-drive-url = ${slap-parameter:virtual-hard-drive-url}
...@@ -407,6 +409,8 @@ route-iface = route add ${slap-network-information:tap-gateway} dev {{ iface }} ...@@ -407,6 +409,8 @@ route-iface = route add ${slap-network-information:tap-gateway} dev {{ iface }}
route-network = route add -net ${slap-network-information:tap-network} netmask ${slap-network-information:tap-netmask} gw ${slap-network-information:tap-gateway} route-network = route add -net ${slap-network-information:tap-network} netmask ${slap-network-information:tap-netmask} gw ${slap-network-information:tap-gateway}
{% if iface == 'eth0' -%} {% if iface == 'eth0' -%}
route-default = route add default gw ${slap-network-information:tap-gateway} route-default = route add default gw ${slap-network-information:tap-gateway}
{% elif nat_restrict == 'true' -%}
route-default = route add default gw ${slap-network-information:tap-gateway} dev {{ iface }}
{% elif global_ipv4_prefix -%} {% elif global_ipv4_prefix -%}
route-default = ip route add {{ global_ipv4_prefix }} via ${slap-network-information:tap-gateway} dev {{ iface }} src ${slap-network-information:tap-ipv4} route-default = ip route add {{ global_ipv4_prefix }} via ${slap-network-information:tap-gateway} dev {{ iface }} src ${slap-network-information:tap-ipv4}
{% else -%} {% else -%}
...@@ -438,6 +442,12 @@ mode = {{ mode }} ...@@ -438,6 +442,12 @@ mode = {{ mode }}
# write public key for vms to public/authorized_keys # write public key for vms to public/authorized_keys
{{ writefile('get-authorized-key', '${directory:public}/authorized_keys', slapparameter_dict.get('authorized-key', ''), '700') }} {{ writefile('get-authorized-key', '${directory:public}/authorized_keys', slapparameter_dict.get('authorized-key', ''), '700') }}
{% if use_tap == 'true' and nat_restrict == 'true' -%}
# Ask to set default to tap interface in the vm
{{ writefile('set-default-interface', '${directory:public}/delDefaultIface', iface, '600') }}
{% do part_list.append('set-default-interface') -%}
{% endif -%}
[publish-host-config] [publish-host-config]
recipe = plone.recipe.command recipe = plone.recipe.command
name = {{ slapparameter_dict.get('name', 'localhost') }} name = {{ slapparameter_dict.get('name', 'localhost') }}
...@@ -502,6 +512,13 @@ context = ...@@ -502,6 +512,13 @@ context =
raw logs ${directory:public}/ansible raw logs ${directory:public}/ansible
raw name {{ name }} raw name {{ name }}
[cron-entry-logrotate]
<= cron
recipe = slapos.cookbook:cron.d
name = logrotate
# One time per week
frequency = 0 0 * * * 0
command = ${logrotate:wrapper}
[logrotate-vm-bootstrap] [logrotate-vm-bootstrap]
< = logrotate-entry-base < = logrotate-entry-base
...@@ -537,6 +554,7 @@ numa = ...@@ -537,6 +554,7 @@ numa =
nat-rules = 22 80 443 nat-rules = 22 80 443
use-nat = True use-nat = True
use-tap = False use-tap = False
nat-restrict-mode = False
enable-vhost = False enable-vhost = False
virtual-hard-drive-url = virtual-hard-drive-url =
...@@ -598,6 +616,7 @@ parts = ...@@ -598,6 +616,7 @@ parts =
novnc-promise novnc-promise
# kvm-monitor # kvm-monitor
cron cron
cron-entry-logrotate
# cron-entry-monitor # cron-entry-monitor
frontend-promise frontend-promise
{% if monitor -%} {% if monitor -%}
......
...@@ -33,6 +33,7 @@ virtual_hard_drive_gzipped = '{{ parameter_dict.get("virtual-hard-drive-gzipped" ...@@ -33,6 +33,7 @@ virtual_hard_drive_gzipped = '{{ parameter_dict.get("virtual-hard-drive-gzipped"
nat_rules = '{{ parameter_dict.get("nat-rules") }}'.strip() nat_rules = '{{ parameter_dict.get("nat-rules") }}'.strip()
use_tap = '{{ parameter_dict.get("use-tap") }}'.lower() use_tap = '{{ parameter_dict.get("use-tap") }}'.lower()
use_nat = '{{ parameter_dict.get("use-nat") }}'.lower() use_nat = '{{ parameter_dict.get("use-nat") }}'.lower()
set_nat_restrict = '{{ parameter_dict.get("nat-restrict") }}'.lower()
enable_vhost = '{{ parameter_dict.get("enable-vhost") }}'.lower() enable_vhost = '{{ parameter_dict.get("enable-vhost") }}'.lower()
tap_interface = '{{ parameter_dict.get("tap-interface") }}' tap_interface = '{{ parameter_dict.get("tap-interface") }}'
listen_ip = '{{ parameter_dict.get("ipv4") }}' listen_ip = '{{ parameter_dict.get("ipv4") }}'
...@@ -228,6 +229,8 @@ if use_nat == 'true': ...@@ -228,6 +229,8 @@ if use_nat == 'true':
if cluster_doc_host and cluster_doc_port > 0: if cluster_doc_host and cluster_doc_port > 0:
rules += ',guestfwd=tcp:10.0.2.101:443-cmd:%s %s %s' % (netcat_bin, rules += ',guestfwd=tcp:10.0.2.101:443-cmd:%s %s %s' % (netcat_bin,
cluster_doc_host, cluster_doc_port) cluster_doc_host, cluster_doc_port)
if set_nat_restrict == 'true':
rules += ',restrict=on'
nat_network_parameter = ['-netdev', rules, nat_network_parameter = ['-netdev', rules,
'-device', 'virtio-net-pci,netdev=lan%s,mac=%s' % (number, mac_address)] '-device', 'virtio-net-pci,netdev=lan%s,mac=%s' % (number, mac_address)]
if use_tap == 'true': if use_tap == 'true':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment