Skip to content

Commit

Permalink
Merge pull request #1144 from skalenetwork/beta
Browse files Browse the repository at this point in the history
2.9.0
  • Loading branch information
DmytroNazarenko authored Feb 3, 2025
2 parents e9f2461 + 04b5173 commit d1a99d4
Show file tree
Hide file tree
Showing 20 changed files with 811 additions and 87 deletions.
7 changes: 4 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
FROM python:3.11-bookworm

RUN apt-get update && apt-get install -y wget git libxslt-dev iptables kmod swig
RUN apt-get update && apt-get install -y wget git libxslt-dev iptables kmod swig nftables python3-nftables

RUN mkdir /usr/src/admin
WORKDIR /usr/src/admin

COPY requirements.txt ./
COPY requirements-dev.txt ./

RUN pip3 install --no-cache-dir -r requirements.txt
RUN pip3 install -r requirements.txt

COPY . .

RUN update-alternatives --set iptables /usr/sbin/iptables-legacy && \
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy

ENV PYTHONPATH="/usr/src/admin"
ENV PYTHONPATH="/usr/src/admin":/usr/lib/python3/dist-packages/

ENV COLUMNS=80
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.8.0
2.9.0
16 changes: 14 additions & 2 deletions core/schains/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,11 @@ def volume(self) -> CheckRes:
@property
def firewall_rules(self) -> CheckRes:
"""Checks that firewall rules are set correctly"""
data = {
'inited': False,
'rules': False,
'persistent': False,
}
if self.config:
conf = self.cfm.skaled_config
base_port = get_base_port_from_config(conf)
Expand All @@ -311,8 +316,15 @@ def firewall_rules(self) -> CheckRes:
base_port=base_port, own_ip=own_ip, node_ips=node_ips, sync_ip_ranges=ranges
)
logger.debug(f'Rule controller {self.rc.expected_rules()}')
return CheckRes(self.rc.is_rules_synced())
return CheckRes(False)
data.update({
'inited': self.rc.is_inited(),
'rules': self.rc.is_rules_synced(),
'persistent': self.rc.is_persistent(),
})
logger.debug('Firewall rules check: %s', data)
status = all(data.values())
return CheckRes(status=status, data=data)
return CheckRes(status=False, data=data)

@property
def skaled_container(self) -> CheckRes:
Expand Down
54 changes: 33 additions & 21 deletions core/schains/cleaner.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,33 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

import glob
import logging
import os
import shutil
from multiprocessing import Process
from pathlib import Path
from typing import Optional

from sgx import SgxClient
from skale import Skale

from core.node import get_current_nodes, get_skale_node_version
from core.schains.checks import SChainChecks
from core.schains.config.file_manager import ConfigFileManager
from core.schains.config.directory import schain_config_dir
from core.schains.dkg.utils import get_secret_key_share_filepath
from core.schains.firewall.utils import get_default_rule_controller
from core.schains.config.helper import (
get_base_port_from_config,
get_node_ips_from_config,
get_own_ip_from_config,
)
from core.schains.firewall.utils import cleanup_firewall_for_schain, get_default_rule_controller
from core.schains.process import ProcessReport, terminate_process
from core.schains.runner import get_container_name, is_exited
from core.schains.external_config import ExternalConfig
from core.schains.types import ContainerType
from core.schains.firewall.utils import get_sync_agent_ranges

from tools.configs import SGX_CERTIFICATES_FOLDER, SYNC_NODE
from tools.configs import (
NFT_CHAIN_CONFIG_WILDCARD,
SGX_CERTIFICATES_FOLDER,
SYNC_NODE
)
from tools.configs.schains import SCHAINS_DIR_PATH
from tools.configs.containers import SCHAIN_CONTAINER, IMA_CONTAINER, SCHAIN_STOP_TIMEOUT
from tools.docker_utils import DockerUtils
Expand Down Expand Up @@ -136,18 +136,36 @@ def get_schains_with_containers(dutils=None):
]


def get_schains_firewall_configs() -> list:
return list(map(lambda path: Path(path).stem, glob.glob(NFT_CHAIN_CONFIG_WILDCARD)))


def get_schains_on_node(dutils=None):
dutils = dutils or DockerUtils()
schains_with_dirs = os.listdir(SCHAINS_DIR_PATH)
schains_with_container = get_schains_with_containers(dutils)
schains_active_records = get_schains_names()
schains_firewall_configs = list(
map(
lambda name: name.removeprefix('skale-'),
get_schains_firewall_configs()
)
)
logger.info(
'dirs %s, containers: %s, records: %s',
'dirs %s, containers: %s, records: %s, firewall configs: %s',
schains_with_dirs,
schains_with_container,
schains_active_records
schains_active_records,
schains_firewall_configs
)
return sorted(
merged_unique(
schains_with_dirs,
schains_with_container,
schains_active_records,
schains_firewall_configs
)
)
return sorted(merged_unique(schains_with_dirs, schains_with_container, schains_active_records))


def schain_names_to_ids(skale, schain_names):
Expand Down Expand Up @@ -258,16 +276,10 @@ def cleanup_schain(
remove_schain_container(schain_name, dutils=dutils)
if check_status['volume']:
remove_schain_volume(schain_name, dutils=dutils)
if check_status['firewall_rules']:
conf = ConfigFileManager(schain_name).skaled_config
base_port = get_base_port_from_config(conf)
own_ip = get_own_ip_from_config(conf)
node_ips = get_node_ips_from_config(conf)
ranges = []
if estate is not None:
ranges = estate.ranges
rc.configure(base_port=base_port, own_ip=own_ip, node_ips=node_ips, sync_ip_ranges=ranges)
rc.cleanup()
if any(checks.firewall_rules.data):
logger.info('Cleaning firewall for %s', schain_name)
cleanup_firewall_for_schain(schain_name)

if estate is not None and estate.ima_linked:
if check_status.get('ima_container', False) or is_exited(
schain_name, container_type=ContainerType.ima, dutils=dutils
Expand Down
1 change: 1 addition & 0 deletions core/schains/firewall/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

from .firewall_manager import SChainFirewallManager # noqa
from .iptables import IptablesController # noqa
from .nftables import NFTablesController # noqa
from .rule_controller import SChainRuleController # noqa
from .types import IRuleController # noqa
from .utils import get_default_rule_controller # noqa
34 changes: 31 additions & 3 deletions core/schains/firewall/firewall_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from typing import Iterable, Optional

from core.schains.firewall.iptables import IptablesController
from core.schains.firewall.nftables import NFTablesController
from core.schains.firewall.types import (
IFirewallManager,
IHostFirewallController,
Expand Down Expand Up @@ -70,6 +71,11 @@ def update_rules(self, rules: Iterable[SChainRule]) -> None:
rules_to_remove = actual_rules - expected_rules
self.add_rules(rules_to_add)
self.remove_rules(rules_to_remove)
self.save_rules()

def save_rules(self) -> None:
""" Saves rules into persistent storage """
self.host_controller.save_rules()

def add_rules(self, rules: Iterable[SChainRule]) -> None:
logger.debug('Adding rules %s', rules)
Expand All @@ -81,10 +87,32 @@ def remove_rules(self, rules: Iterable[SChainRule]) -> None:
for rule in rules:
self.host_controller.remove_rule(rule)

def flush(self) -> None:
self.remove_rules(self.rules)


class IptablesSChainFirewallManager(SChainFirewallManager):
def create_host_controller(self) -> IptablesController:
return IptablesController()

def cleanup(self) -> None:
self.remove_rules(self.rules)


class NFTSchainFirewallManager(SChainFirewallManager):
def create_host_controller(self) -> NFTablesController:
nc_controller = NFTablesController(chain=self.name)
nc_controller.create_table()
nc_controller.create_chain(self.first_port, self.last_port)
return nc_controller

def rules_saved(self) -> bool:
saved = self.host_controller.get_saved_rules()
if saved == '':
return False
return saved == self.host_controller.get_plain_chain_rules()

def base_config_applied(self) -> bool:
return self.host_controller.has_chain(self.host_controller.chain) and \
self.host_controller.has_drop_rule(self.first_port, self.last_port)

def cleanup(self) -> None:
self.host_controller.cleanup()
self.host_controller.remove_saved_rules()
6 changes: 6 additions & 0 deletions core/schains/firewall/iptables.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,9 @@ def from_ip_network(cls, ip: str) -> str:
@classmethod
def to_ip_network(cls, ip: str) -> str:
return str(ipaddress.ip_network(ip))

def save_rules(self) -> None:
raise NotImplementedError('save_rules is not implemented for iptables host controller')

def cleanup(self) -> None:
raise NotImplementedError('cleanup is not implemented for iptables host controller')
Loading

0 comments on commit d1a99d4

Please sign in to comment.