diff --git a/deploy.tf b/deploy.tf
index 0ae89d5555844a53e9ea21d6e78bc15cfaae2f42..ada9f0299ae4d8fce173da1886045c52977bbd33 100644
--- a/deploy.tf
+++ b/deploy.tf
@@ -31,6 +31,7 @@ resource "openstack_compute_instance_v2" "server" {
 	flavor_name = "standard.medium"
 	image_name = var.image
 	key_pair = var.ssh
+	security_groups = [openstack_networking_secgroup_v2.secgroup.name]
 	user_data = data.template_cloudinit_config.user_data[count.index].rendered
 	network {
 		name = var.local_network
diff --git a/firewall.tf b/firewall.tf
new file mode 100644
index 0000000000000000000000000000000000000000..fc88506b35949a0c21bfefe97dc2ebcfa99e81f8
--- /dev/null
+++ b/firewall.tf
@@ -0,0 +1,48 @@
+resource "openstack_networking_secgroup_v2" "secgroup" {
+	name = var.domain
+	description = "${title(var.domain)} security group"
+}
+
+resource "openstack_networking_secgroup_rule_v2" "secgroup_rule_self4" {
+	direction = "ingress"
+	ethertype = "IPv4"
+	remote_group_id = openstack_networking_secgroup_v2.secgroup.id
+	security_group_id = openstack_networking_secgroup_v2.secgroup.id
+}
+
+resource "openstack_networking_secgroup_rule_v2" "secgroup_rule_self6" {
+	direction = "ingress"
+	ethertype = "IPv6"
+	remote_group_id = openstack_networking_secgroup_v2.secgroup.id
+	security_group_id = openstack_networking_secgroup_v2.secgroup.id
+}
+
+resource "openstack_networking_secgroup_rule_v2" "secgroup_rule_icmp4" {
+	direction = "ingress"
+	ethertype = "IPv4"
+	protocol = "icmp"
+	security_group_id = openstack_networking_secgroup_v2.secgroup.id
+}
+
+resource "openstack_networking_secgroup_rule_v2" "secgroup_rule_icmp6" {
+	direction = "ingress"
+	ethertype = "IPv6"
+	protocol = "ipv6-icmp"
+	security_group_id = openstack_networking_secgroup_v2.secgroup.id
+}
+
+resource "openstack_networking_secgroup_rule_v2" "secgroup_rule_other4" {
+	for_each = var.security_trusted_cidr4
+	direction = "ingress"
+	ethertype = "IPv4"
+	remote_ip_prefix = each.key
+	security_group_id = openstack_networking_secgroup_v2.secgroup.id
+}
+
+resource "openstack_networking_secgroup_rule_v2" "secgroup_rule_other6" {
+	for_each = var.security_trusted_cidr6
+	direction = "ingress"
+	ethertype = "IPv6"
+	remote_ip_prefix = each.key
+	security_group_id = openstack_networking_secgroup_v2.secgroup.id
+}
diff --git a/variables.tf b/variables.tf
index 5bf6f8e632e6747faa5a70266bfb08b93908499d..8df761986f5c4b5c8ca1a35c9ef6e0efd684c6e7 100644
--- a/variables.tf
+++ b/variables.tf
@@ -44,6 +44,33 @@ variable "public_network" {
 	# default = "public-cesnet-78-128-250-PERSONAL"
 }
 
+variable "security_trusted_cidr4" {
+	description = "Trusted networks"
+	type = set(string)
+	default = [
+		"78.128.128.0/17", # CESNET
+		"116.216.0.0/15",  # UNOB, JČU
+		"146.102.0.0/16",  # VŠE
+		"147.32.0.0/15",   # ČVUT, VSCHT
+		"147.228.0.0/14",  # ZČU, VUT, TUL, AVČR
+		"147.251.0.0/16",  # MUNI
+		"158.194.0.0/16",  # UPOL
+		"158.196.0.0/16",  # VŠB
+		"193.84.32.0/20",  # ČZU
+		"193.84.192.0/19", # SLU
+		"195.113.0.0/16",  # CESNET
+		"195.178.64.0/19", # CESNET
+	]
+}
+
+variable "security_trusted_cidr6" {
+	description = "Trusted networks"
+	type = set(string)
+	default = [
+		"2001:718::/32",   # CESNET
+	]
+}
+
 variable "ssh" {
 	description = "SSH key name"
 	default = "openstack"