Use tls #28

Merged
nserrano merged 5 commits from tls into main 2025-05-06 10:32:15 +02:00
7 changed files with 64 additions and 10 deletions

View File

@ -6,6 +6,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [5.0.0] - 2025-04-25
### Added
- Use TLS
## [4.0.0] - 2025-04-24
### Added

View File

@ -1,3 +1,9 @@
ogagent (5.0.0-1) stable; urgency=medium
* Use TLS
-- OpenGnsys developers <info@opengnsys.es> Fri, 25 Apr 2025 13:09:49 +0200
ogagent (4.0.0-1) stable; urgency=medium
* Handle authn/authz in the oglive agent

View File

@ -1 +1 @@
4.0.0
5.0.0

View File

@ -17,6 +17,12 @@ level=full
# Log Level, if omitted, will be set to INFO
log=DEBUG
# TLS
ca=C:\Program Files (x86)\OGagent\ca.crt
crt=C:\Program Files (x86)\OGagent\ogagent.crt
key=C:\Program Files (x86)\OGagent\ogagent.key
# Module specific
# The sections must match the module name
# This section will be passes on activation to module
@ -28,3 +34,8 @@ log=DEBUG
pathinterface=/opt/opengnsys/interfaceAdm
urlMenu={}://{}/menu-browser
urlMsg=http://localhost/cgi-bin/httpd-log.sh
# TLS
ca=/opt/opengnsys/etc/ca.crt
crt=/opt/opengnsys/etc/ogagent.crt
key=/opt/opengnsys/etc/ogagent.key

View File

@ -34,6 +34,7 @@
import os
import requests
import logging
import json
@ -43,7 +44,6 @@ from .log import logger
from .utils import exceptionToMessage
VERIFY_CERT = False # Do not check server certificate
TIMEOUT = 5 # Connection timout, in seconds
@ -88,7 +88,7 @@ class REST(object):
the deserialized JSON result or raises an exception in case of error
"""
def __init__(self, url):
def __init__(self, url, ca_file=None, crt_file=None, key_file=None):
"""
Initializes the REST helper
url is the full url of the REST API Base, as for example "https://example.com/rest/v1".
@ -105,6 +105,26 @@ class REST(object):
except Exception:
self.newerRequestLib = False # I no version, guess this must be an old requests
if not self.newerRequestLib:
logger.debug ('TLS not available: python requests library is old')
self.use_tls = url.startswith ('https')
if self.use_tls:
if not ca_file or not crt_file or not key_file:
raise Exception ('missing TLS parameters in REST constructor')
errs = 0
for f in [ca_file, crt_file, key_file]:
if not os.path.exists (f):
logger.error (f'{f}: No such file or directory')
errs += 1
if errs:
raise Exception ('TLS files not found')
self.ca_file = ca_file
self.crt_file = crt_file
self.key_file = key_file
# Disable logging requests messages except for errors, ...
logging.getLogger("requests").setLevel(logging.CRITICAL)
# Tries to disable all warnings
@ -135,14 +155,19 @@ class REST(object):
logger.debug('Requesting using GET (no data provided) {}'.format(url))
# Old requests version does not support verify, but it do not checks ssl certificate by default
if self.newerRequestLib:
r = requests.get(url, verify=VERIFY_CERT, timeout=TIMEOUT)
if self.use_tls:
r = requests.get(url, cert=(self.crt_file, self.key_file), verify=self.ca_file, timeout=TIMEOUT)
else:
r = requests.get(url, timeout=TIMEOUT)
else:
r = requests.get(url)
else: # POST
logger.debug('Requesting using POST {}, data: {}'.format(url, data))
if self.newerRequestLib:
r = requests.post(url, data=data, headers={'content-type': 'application/json'},
verify=VERIFY_CERT, timeout=TIMEOUT)
if self.use_tls:
r = requests.post(url, data=data, headers={'content-type': 'application/json'}, cert=(self.crt_file, self.key_file), verify=self.ca_file, timeout=TIMEOUT)
else:
r = requests.post(url, data=data, headers={'content-type': 'application/json'}, timeout=TIMEOUT)
else:
r = requests.post(url, data=data, headers={'content-type': 'application/json'})

View File

@ -131,10 +131,13 @@ class OpenGnSysWorker(ServerWorker):
# Ensure cfg has required configuration variables or an exception will be thrown
try:
url = self.service.config.get(self.name, 'remote')
ca_file = self.service.config.get(self.name, 'ca')
crt_file = self.service.config.get(self.name, 'crt')
key_file = self.service.config.get(self.name, 'key')
except NoOptionError as e:
logger.error("Configuration error: {}".format(e))
raise e
self.REST = REST(url)
self.REST = REST (url, ca_file=ca_file, crt_file=crt_file, key_file=key_file)
# Execution level ('full' by default)
try:
self.exec_level = self.service.config.get(self.name, 'level')
@ -174,7 +177,7 @@ class OpenGnSysWorker(ServerWorker):
logger.warn (str (e))
# Trying to initialize on alternative server, if defined
# (used in "exam mode" from the University of Seville)
self.REST = REST(self.service.config.get(self.name, 'altremote'))
self.REST = REST(self.service.config.get(self.name, 'altremote'), ca_file=ca_file, crt_file=crt_file, key_file=key_file)
self.REST.sendMessage('ogagent/started', {'mac': self.interface.mac, 'ip': self.interface.ip,
'secret': self.random, 'ostype': operations.os_type,
'osversion': operations.os_version, 'alt_url': True,

View File

@ -449,13 +449,16 @@ class ogLiveWorker(ServerWorker):
self.urlMenu = self.service.config.get (self.name, 'urlMenu')
self.urlMsg = self.service.config.get (self.name, 'urlMsg')
ca_file = self.service.config.get (self.name, 'ca')
crt_file = self.service.config.get (self.name, 'crt')
key_file = self.service.config.get (self.name, 'key')
url = url.format (ogcore_scheme, ogcore_ip_port)
self.urlMenu = self.urlMenu.format (urlmenu_scheme, urlmenu_ip_port)
except NoOptionError as e:
logger.error ("Configuration error: {}".format (e))
raise e
logger.setLevel (loglevel)
self.REST = REST (url)
self.REST = REST (url, ca_file=ca_file, crt_file=crt_file, key_file=key_file)
if not self.tomaIPlocal():
raise Exception ('Se han generado errores. No se puede continuar la ejecución de este módulo')