diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9642e92f6..953e2940f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -13,10 +13,3 @@ ## How to test ... - -## Validation - -- [ ] Principle agreement 0/2 : -- [ ] Quick review 0/1 : -- [ ] Simple test 0/1 : -- [ ] Deep review 0/1 : diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ac3584630..eb34de38e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,124 +1,22 @@ stages: - - postinstall + - build + - install - tests - lint + - doc -######################################## -# POSTINSTALL -######################################## +default: + tags: + - yunohost-ci + # All jobs are interruptible by default + interruptible: true -postinstall: - image: before-postinstall - stage: postinstall - script: - - yunohost tools postinstall -d domain.tld -p the_password --ignore-dyndns +variables: + YNH_BUILD_DIR: "ynh-build" -######################################## -# TESTS -######################################## - -.test-stage: - image: after-postinstall - stage: tests - before_script: - - apt-get install python-pip -y - - mkdir -p .pip - - pip install -U pip - - hash -d pip - - pip --cache-dir=.pip install pytest pytest-sugar pytest-mock requests-mock mock - - export PYTEST_ADDOPTS="--color=yes" - cache: - paths: - - .pip - - src/yunohost/tests/apps - key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG" - -root-tests: - extends: .test-stage - script: - - py.test tests - -test-apps: - extends: .test-stage - script: - - cd src/yunohost - - py.test tests/test_apps.py - -test-appscatalog: - extends: .test-stage - script: - - cd src/yunohost - - py.test tests/test_appscatalog.py - -test-appurl: - extends: .test-stage - script: - - cd src/yunohost - - py.test tests/test_appurl.py - -test-backuprestore: - extends: .test-stage - script: - - cd src/yunohost - - py.test tests/test_backuprestore.py - -test-changeurl: - extends: .test-stage - script: - - cd src/yunohost - - py.test tests/test_changeurl.py - -test-permission: - extends: .test-stage - script: - - cd src/yunohost - - py.test tests/test_permission.py - -test-settings: - extends: .test-stage - script: - - cd src/yunohost - - py.test tests/test_settings.py - -test-user-group: - extends: .test-stage - script: - - cd src/yunohost - - py.test tests/test_user-group.py - -test-regenconf: - extends: .test-stage - script: - - cd src/yunohost - - py.test tests/test_regenconf.py - -######################################## -# LINTER -######################################## - -.lint-stage: - image: before-postinstall - stage: lint - before_script: - - apt-get install python-pip -y - - mkdir -p .pip - - pip install -U pip - - hash -d pip - - pip --cache-dir=.pip install tox - cache: - paths: - - .pip - - .tox - key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG" - -lint: - extends: .lint-stage - allow_failure: true - script: - - tox -e lint - -# Disabled, waiting for buster -#format-check: -# extends: .lint-stage -# script: -# - black --check --diff +include: + - local: .gitlab/ci/build.gitlab-ci.yml + - local: .gitlab/ci/install.gitlab-ci.yml + - local: .gitlab/ci/test.gitlab-ci.yml + - local: .gitlab/ci/lint.gitlab-ci.yml + - local: .gitlab/ci/doc.gitlab-ci.yml diff --git a/.gitlab/ci/build.gitlab-ci.yml b/.gitlab/ci/build.gitlab-ci.yml new file mode 100644 index 000000000..67232ba1f --- /dev/null +++ b/.gitlab/ci/build.gitlab-ci.yml @@ -0,0 +1,52 @@ +.build-stage: + stage: build + image: "before-install" + variables: + YNH_SOURCE: "https://github.com/yunohost" + before_script: + - mkdir -p $YNH_BUILD_DIR + artifacts: + paths: + - $YNH_BUILD_DIR/*.deb + +.build_script: &build_script + - cd $YNH_BUILD_DIR/$PACKAGE + - VERSION=$(dpkg-parsechangelog -S Version 2>/dev/null) + - VERSION_NIGHTLY="${VERSION}+$(date +%Y%m%d%H%M)" + - dch --package "${PACKAGE}" --force-bad-version -v "${VERSION_NIGHTLY}" -D "unstable" --force-distribution "Daily build." + - debuild --no-lintian -us -uc + +######################################## +# BUILD DEB +######################################## + +build-yunohost: + extends: .build-stage + variables: + PACKAGE: "yunohost" + script: + - git ls-files | xargs tar -czf archive.tar.gz + - mkdir -p $YNH_BUILD_DIR/$PACKAGE + - cat archive.tar.gz | tar -xz -C $YNH_BUILD_DIR/$PACKAGE + - rm archive.tar.gz + - DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $(pwd)/$YNH_BUILD_DIR/$PACKAGE + - *build_script + + +build-ssowat: + extends: .build-stage + variables: + PACKAGE: "ssowat" + script: + - git clone $YNH_SOURCE/$PACKAGE -b $CI_COMMIT_REF_NAME $YNH_BUILD_DIR/$PACKAGE || git clone $YNH_SOURCE/$PACKAGE $YNH_BUILD_DIR/$PACKAGE + - DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $(pwd)/$YNH_BUILD_DIR/$PACKAGE + - *build_script + +build-moulinette: + extends: .build-stage + variables: + PACKAGE: "moulinette" + script: + - git clone $YNH_SOURCE/$PACKAGE -b $CI_COMMIT_REF_NAME $YNH_BUILD_DIR/$PACKAGE || git clone $YNH_SOURCE/$PACKAGE $YNH_BUILD_DIR/$PACKAGE + - DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $(pwd)/$YNH_BUILD_DIR/$PACKAGE + - *build_script diff --git a/.gitlab/ci/doc.gitlab-ci.yml b/.gitlab/ci/doc.gitlab-ci.yml new file mode 100644 index 000000000..b246cc238 --- /dev/null +++ b/.gitlab/ci/doc.gitlab-ci.yml @@ -0,0 +1,14 @@ +######################################## +# DOC +######################################## + +generate-helpers-doc: + stage: doc + image: "before-install" + needs: [] + script: + - cd doc + - python generate_helper_doc.py + artifacts: + paths: + - doc/helpers.html diff --git a/.gitlab/ci/install.gitlab-ci.yml b/.gitlab/ci/install.gitlab-ci.yml new file mode 100644 index 000000000..eb5187e11 --- /dev/null +++ b/.gitlab/ci/install.gitlab-ci.yml @@ -0,0 +1,37 @@ +.install-stage: + stage: install + needs: + - job: build-yunohost + artifacts: true + - job: build-ssowat + artifacts: true + - job: build-moulinette + artifacts: true + +######################################## +# INSTALL DEB +######################################## + +upgrade: + extends: .install-stage + image: "after-install" + script: + - apt-get update -o Acquire::Retries=3 + - DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ./$YNH_BUILD_DIR/*.deb + + +install-postinstall: + extends: .install-stage + image: "before-install" + script: + - apt-get update -o Acquire::Retries=3 + - DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ./$YNH_BUILD_DIR/*.deb + - systemctl -q stop apt-daily.timer + - systemctl -q stop apt-daily-upgrade.timer + - systemctl -q stop apt-daily.service + - systemctl -q stop apt-daily-upgrade.service + - systemctl -q disable apt-daily.timer + - systemctl -q disable apt-daily-upgrade.timer + - systemctl -q disable apt-daily.service + - systemctl -q disable apt-daily-upgrade.service + - yunohost tools postinstall -d domain.tld -p the_password --ignore-dyndns diff --git a/.gitlab/ci/lint.gitlab-ci.yml b/.gitlab/ci/lint.gitlab-ci.yml new file mode 100644 index 000000000..c6967d5a5 --- /dev/null +++ b/.gitlab/ci/lint.gitlab-ci.yml @@ -0,0 +1,24 @@ +######################################## +# LINTER +######################################## + +lint: + stage: lint + image: "before-install" + needs: [] + allow_failure: true + script: + - tox -e lint + +invalidcode: + stage: lint + image: "before-install" + needs: [] + script: + - tox -e invalidcode + +# Disabled, waiting for buster +#format-check: +# extends: .lint-stage +# script: +# - black --check --diff diff --git a/.gitlab/ci/test.gitlab-ci.yml b/.gitlab/ci/test.gitlab-ci.yml new file mode 100644 index 000000000..12379342a --- /dev/null +++ b/.gitlab/ci/test.gitlab-ci.yml @@ -0,0 +1,128 @@ +.install_debs: &install_debs + - systemctl -q stop apt-daily.timer + - systemctl -q stop apt-daily-upgrade.timer + - systemctl -q stop apt-daily.service + - systemctl -q stop apt-daily-upgrade.service + - systemctl -q disable apt-daily.timer + - systemctl -q disable apt-daily-upgrade.timer + - systemctl -q disable apt-daily.service + - systemctl -q disable apt-daily-upgrade.service + - apt-get update -o Acquire::Retries=3 + - DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ./$YNH_BUILD_DIR/*.deb + +.test-stage: + stage: tests + image: "after-install" + variables: + PYTEST_ADDOPTS: "--color=yes" + before_script: + - *install_debs + cache: + paths: + - src/yunohost/tests/apps + key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG" + needs: + - job: build-yunohost + artifacts: true + - job: build-ssowat + artifacts: true + - job: build-moulinette + artifacts: true + - job: upgrade + + +######################################## +# TESTS +######################################## + +full-tests: + stage: tests + image: "before-install" + variables: + PYTEST_ADDOPTS: "--color=yes" + before_script: + - *install_debs + - yunohost tools postinstall -d domain.tld -p the_password --ignore-dyndns + script: + - pytest --cov=yunohost tests/ src/yunohost/tests/ --junitxml=report.xml + needs: + - job: build-yunohost + artifacts: true + - job: build-ssowat + artifacts: true + - job: build-moulinette + artifacts: true + artifacts: + reports: + junit: report.xml + +root-tests: + extends: .test-stage + script: + - py.test tests + +test-apps: + extends: .test-stage + script: + - cd src/yunohost + - py.test tests/test_apps.py + +test-appscatalog: + extends: .test-stage + script: + - cd src/yunohost + - py.test tests/test_appscatalog.py + +test-appurl: + extends: .test-stage + script: + - cd src/yunohost + - py.test tests/test_appurl.py + +test-apps-arguments-parsing: + extends: .test-stage + script: + - cd src/yunohost + - py.test tests/test_apps_arguments_parsing.py + +test-backuprestore: + extends: .test-stage + script: + - cd src/yunohost + - py.test tests/test_backuprestore.py + +test-changeurl: + extends: .test-stage + script: + - cd src/yunohost + - py.test tests/test_changeurl.py + +test-permission: + extends: .test-stage + script: + - cd src/yunohost + - py.test tests/test_permission.py + +test-settings: + extends: .test-stage + script: + - cd src/yunohost + - py.test tests/test_settings.py + +test-user-group: + extends: .test-stage + script: + - cd src/yunohost + - py.test tests/test_user-group.py + +test-regenconf: + extends: .test-stage + script: + - cd src/yunohost + - py.test tests/test_regenconf.py + +test-service: + extends: .test-stage + script: + - cd src/yunohost + - py.test tests/test_service.py diff --git a/bin/yunohost b/bin/yunohost index b640c8c52..546d2d913 100755 --- a/bin/yunohost +++ b/bin/yunohost @@ -5,70 +5,28 @@ import os import sys import argparse -# Either we are in a development environment or not -IN_DEVEL = False +sys.path.insert(0, "/usr/lib/moulinette/") +import yunohost -# Level for which loggers will log -LOGGERS_LEVEL = 'DEBUG' -TTY_LOG_LEVEL = 'INFO' - -# Handlers that will be used by loggers -# - file: log to the file LOG_DIR/LOG_FILE -# - tty: log to current tty -LOGGERS_HANDLERS = ['file', 'tty'] - -# Directory and file to be used by logging -LOG_DIR = '/var/log/yunohost' -LOG_FILE = 'yunohost-cli.log' - -# Check and load - as needed - development environment -if not __file__.startswith('/usr/'): - IN_DEVEL = True -if IN_DEVEL: - basedir = os.path.abspath('%s/../' % os.path.dirname(__file__)) - if os.path.isdir(os.path.join(basedir, 'moulinette')): - sys.path.insert(0, basedir) - LOG_DIR = os.path.join(basedir, 'log') - - -import moulinette -from moulinette.actionsmap import ActionsMap -from moulinette.interfaces.cli import colorize, get_locale - - -# Initialization & helpers functions ----------------------------------- - -def _die(message, title='Error:'): - """Print error message and exit""" - print('%s %s' % (colorize(title, 'red'), message)) - sys.exit(1) def _parse_cli_args(): """Parse additional arguments for the cli""" parser = argparse.ArgumentParser(add_help=False) - parser.add_argument('--no-cache', - action='store_false', default=True, dest='use_cache', - help="Don't use actions map cache", - ) parser.add_argument('--output-as', choices=['json', 'plain', 'none'], default=None, - help="Output result in another format", + help="Output result in another format" ) parser.add_argument('--debug', action='store_true', default=False, - help="Log and print debug messages", + help="Log and print debug messages" ) parser.add_argument('--quiet', action='store_true', default=False, - help="Don't produce any output", + help="Don't produce any output" ) parser.add_argument('--timeout', type=int, default=None, - help="Number of seconds before this command will timeout because it can't acquire the lock (meaning that another command is currently running), by default there is no timeout and the command will wait until it can get the lock", - ) - parser.add_argument('--admin-password', - default=None, dest='password', metavar='PASSWORD', - help="The admin password to use to authenticate", + help="Number of seconds before this command will timeout because it can't acquire the lock (meaning that another command is currently running), by default there is no timeout and the command will wait until it can get the lock" ) # deprecated arguments parser.add_argument('--plain', @@ -88,96 +46,6 @@ def _parse_cli_args(): return (parser, opts, args) -def _init_moulinette(debug=False, quiet=False): - """Configure logging and initialize the moulinette""" - # Define loggers handlers - handlers = set(LOGGERS_HANDLERS) - if quiet and 'tty' in handlers: - handlers.remove('tty') - elif 'tty' not in handlers: - handlers.append('tty') - - root_handlers = set(handlers) - if not debug and 'tty' in root_handlers: - root_handlers.remove('tty') - - # Define loggers level - level = LOGGERS_LEVEL - tty_level = TTY_LOG_LEVEL - if debug: - tty_level = 'DEBUG' - - # Custom logging configuration - logging = { - 'version': 1, - 'disable_existing_loggers': True, - 'formatters': { - 'tty-debug': { - 'format': '%(relativeCreated)-4d %(fmessage)s' - }, - 'precise': { - 'format': '%(asctime)-15s %(levelname)-8s %(name)s %(funcName)s - %(fmessage)s' - }, - }, - 'filters': { - 'action': { - '()': 'moulinette.utils.log.ActionFilter', - }, - }, - 'handlers': { - 'tty': { - 'level': tty_level, - 'class': 'moulinette.interfaces.cli.TTYHandler', - 'formatter': 'tty-debug' if debug else '', - }, - 'file': { - 'class': 'logging.FileHandler', - 'formatter': 'precise', - 'filename': '%s/%s' % (LOG_DIR, LOG_FILE), - 'filters': ['action'], - }, - }, - 'loggers': { - 'yunohost': { - 'level': level, - 'handlers': handlers, - 'propagate': False, - }, - 'moulinette': { - 'level': level, - 'handlers': [], - 'propagate': True, - }, - 'moulinette.interface': { - 'level': level, - 'handlers': handlers, - 'propagate': False, - }, - }, - 'root': { - 'level': level, - 'handlers': root_handlers, - }, - } - - # Create log directory - if not os.path.isdir(LOG_DIR): - try: - os.makedirs(LOG_DIR, 0750) - except os.error as e: - _die(str(e)) - - # Initialize moulinette - moulinette.init(logging_config=logging, _from_source=IN_DEVEL) - -def _retrieve_namespaces(): - """Return the list of namespaces to load""" - ret = ['yunohost'] - for n in ActionsMap.get_namespaces(): - # Append YunoHost modules - if n.startswith('ynh_'): - ret.append(n) - return ret # Stupid PATH management because sometimes (e.g. some cron job) PATH is only /usr/bin:/bin ... default_path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" @@ -188,33 +56,18 @@ if os.environ["PATH"] != default_path: if __name__ == '__main__': if os.geteuid() != 0: - # since moulinette isn't initialized, we can't use m18n here - sys.stderr.write("\033[1;31mError:\033[0m yunohost command must be " \ + sys.stderr.write("\033[1;31mError:\033[0m yunohost command must be " "run as root or with sudo.\n") sys.exit(1) parser, opts, args = _parse_cli_args() - _init_moulinette(opts.debug, opts.quiet) - - # Check that YunoHost is installed - if not os.path.isfile('/etc/yunohost/installed') and \ - (len(args) < 2 or (args[0] +' '+ args[1] != 'tools postinstall' and \ - args[0] +' '+ args[1] != 'backup restore' and \ - args[0] +' '+ args[1] != 'log display')): - - from moulinette import m18n - # Init i18n - m18n.load_namespace('yunohost') - m18n.set_locale(get_locale()) - - # Print error and exit - _die(m18n.n('yunohost_not_installed'), m18n.g('error')) # Execute the action - ret = moulinette.cli( - _retrieve_namespaces(), args, - use_cache=opts.use_cache, output_as=opts.output_as, - password=opts.password, parser_kwargs={'top_parser': parser}, + yunohost.cli( + debug=opts.debug, + quiet=opts.quiet, + output_as=opts.output_as, timeout=opts.timeout, + args=args, + parser=parser ) - sys.exit(ret) diff --git a/bin/yunohost-api b/bin/yunohost-api index e518c34b0..cc849590a 100755 --- a/bin/yunohost-api +++ b/bin/yunohost-api @@ -1,52 +1,16 @@ #! /usr/bin/python # -*- coding: utf-8 -*- -import os import sys import argparse -# Either we are in a development environment or not -IN_DEVEL = False +sys.path.insert(0, "/usr/lib/moulinette/") +import yunohost # Default server configuration DEFAULT_HOST = 'localhost' DEFAULT_PORT = 6787 -# Level for which loggers will log -LOGGERS_LEVEL = 'DEBUG' -API_LOGGER_LEVEL = 'INFO' - -# Handlers that will be used by loggers -# - file: log to the file LOG_DIR/LOG_FILE -# - api: serve logs through the api -# - console: log to stderr -LOGGERS_HANDLERS = ['file', 'api'] - -# Directory and file to be used by logging -LOG_DIR = '/var/log/yunohost' -LOG_FILE = 'yunohost-api.log' - -# Check and load - as needed - development environment -if not __file__.startswith('/usr/'): - IN_DEVEL = True -if IN_DEVEL: - basedir = os.path.abspath('%s/../' % os.path.dirname(__file__)) - if os.path.isdir(os.path.join(basedir, 'moulinette')): - sys.path.insert(0, basedir) - LOG_DIR = os.path.join(basedir, 'log') - - -import moulinette -from moulinette.actionsmap import ActionsMap -from moulinette.interfaces.cli import colorize - - -# Initialization & helpers functions ----------------------------------- - -def _die(message, title='Error:'): - """Print error message and exit""" - print('%s %s' % (colorize(title, 'red'), message)) - sys.exit(1) def _parse_api_args(): """Parse main arguments for the api""" @@ -62,149 +26,19 @@ def _parse_api_args(): action='store', default=DEFAULT_PORT, type=int, help="Port to listen on (default: %d)" % DEFAULT_PORT, ) - srv_group.add_argument('--no-websocket', - action='store_true', default=True, dest='use_websocket', - help="Serve without WebSocket support, used to handle " - "asynchronous responses such as the messages", - ) glob_group = parser.add_argument_group('global arguments') - glob_group.add_argument('--no-cache', - action='store_false', default=True, dest='use_cache', - help="Don't use actions map cache", - ) glob_group.add_argument('--debug', action='store_true', default=False, help="Set log level to DEBUG", ) - glob_group.add_argument('--verbose', - action='store_true', default=False, - help="Be verbose in the output", - ) glob_group.add_argument('--help', action='help', help="Show this help message and exit", ) return parser.parse_args() -def _init_moulinette(use_websocket=True, debug=False, verbose=False): - """Configure logging and initialize the moulinette""" - # Define loggers handlers - handlers = set(LOGGERS_HANDLERS) - if not use_websocket and 'api' in handlers: - handlers.remove('api') - if verbose and 'console' not in handlers: - handlers.add('console') - root_handlers = handlers - set(['api']) - - # Define loggers level - level = LOGGERS_LEVEL - api_level = API_LOGGER_LEVEL - if debug: - level = 'DEBUG' - api_level = 'DEBUG' - - # Custom logging configuration - logging = { - 'version': 1, - 'disable_existing_loggers': True, - 'formatters': { - 'console': { - 'format': '%(relativeCreated)-5d %(levelname)-8s %(name)s %(funcName)s - %(fmessage)s' - }, - 'precise': { - 'format': '%(asctime)-15s %(levelname)-8s %(name)s %(funcName)s - %(fmessage)s' - }, - }, - 'filters': { - 'action': { - '()': 'moulinette.utils.log.ActionFilter', - }, - }, - 'handlers': { - 'api': { - 'level': api_level, - 'class': 'moulinette.interfaces.api.APIQueueHandler', - }, - 'file': { - 'class': 'logging.handlers.WatchedFileHandler', - 'formatter': 'precise', - 'filename': '%s/%s' % (LOG_DIR, LOG_FILE), - 'filters': ['action'], - }, - 'console': { - 'class': 'logging.StreamHandler', - 'formatter': 'console', - 'stream': 'ext://sys.stdout', - 'filters': ['action'], - }, - }, - 'loggers': { - 'yunohost': { - 'level': level, - 'handlers': handlers, - 'propagate': False, - }, - 'moulinette': { - 'level': level, - 'handlers': [], - 'propagate': True, - }, - 'gnupg': { - 'level': 'INFO', - 'handlers': [], - 'propagate': False, - }, - }, - 'root': { - 'level': level, - 'handlers': root_handlers, - }, - } - - # Create log directory - if not os.path.isdir(LOG_DIR): - try: - os.makedirs(LOG_DIR, 0750) - except os.error as e: - _die(str(e)) - - # Initialize moulinette - moulinette.init(logging_config=logging, _from_source=IN_DEVEL) - -def _retrieve_namespaces(): - """Return the list of namespaces to load""" - ret = ['yunohost'] - for n in ActionsMap.get_namespaces(): - # Append YunoHost modules - if n.startswith('ynh_'): - ret.append(n) - return ret - - -# Callbacks for additional routes -------------------------------------- - -def is_installed(): - """ - Check whether YunoHost is installed or not - - """ - installed = False - if os.path.isfile('/etc/yunohost/installed'): - installed = True - return { 'installed': installed } - - -# Main action ---------------------------------------------------------- if __name__ == '__main__': opts = _parse_api_args() - _init_moulinette(opts.use_websocket, opts.debug, opts.verbose) - # Run the server - ret = moulinette.api( - _retrieve_namespaces(), - host=opts.host, port=opts.port, routes={ - ('GET', '/installed'): is_installed, - }, use_cache=opts.use_cache, use_websocket=opts.use_websocket - ) - sys.exit(ret) + yunohost.api(debug=opts.debug, host=opts.host, port=opts.port) diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index a748e4533..d61538c5c 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -996,7 +996,6 @@ service: choices: - file - systemd - default: file --test_status: help: Specify a custom bash command to check the status of the service. Note that it only makes sense to specify this if the corresponding systemd service does not return the proper information already. --test_conf: @@ -1692,6 +1691,9 @@ diagnosis: --share: help: Share the logs using yunopaste action: store_true + --human-readable: + help: Show a human-readable output + action: store_true run: action_help: Run diagnosis @@ -1706,6 +1708,9 @@ diagnosis: --except-if-never-ran-yet: help: Don't run anything if diagnosis never ran yet ... (this is meant to be used by the webadmin) action: store_true + --email: + help: Send an email to root with issues found (this is meant to be used by cron job) + action: store_true ignore: action_help: Configure some diagnosis results to be ignored and therefore not considered as actual issues diff --git a/data/helpers.d/apt b/data/helpers.d/apt index 3b4b199d0..377464786 100644 --- a/data/helpers.d/apt +++ b/data/helpers.d/apt @@ -10,6 +10,7 @@ # Requires YunoHost version 3.3.1 or higher. ynh_wait_dpkg_free() { local try + set +o xtrace # set +x # With seq 1 17, timeout will be almost 30 minutes for try in `seq 1 17` do @@ -32,13 +33,16 @@ ynh_wait_dpkg_free() { then # If so, that a remaining of dpkg. ynh_print_err "E: dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem." + set -o xtrace # set -x return 1 fi done 9<<< "$(ls -1 $dpkg_dir)" + set -o xtrace # set -x return 0 fi done echo "apt still used, but timeout reached !" + set -o xtrace # set -x } # Check either a package is installed or not @@ -96,7 +100,7 @@ ynh_package_version() { # Requires YunoHost version 2.4.0.3 or higher. ynh_apt() { ynh_wait_dpkg_free - LC_ALL=C DEBIAN_FRONTEND=noninteractive apt-get --assume-yes $@ + LC_ALL=C DEBIAN_FRONTEND=noninteractive apt-get --assume-yes --quiet -o=Acquire::Retries=3 -o=Dpkg::Use-Pty=0 $@ } # Update package index files @@ -256,15 +260,17 @@ ynh_install_app_dependencies () { # And we have packages from sury installed (7.0.33-10+weirdshiftafter instead of 7.0.33-0 on debian) if dpkg --list | grep "php7.0" | grep --quiet --invert-match "7.0.33-0+deb9" then - # And sury ain't already installed - if ! grep --line-number --recursive --quiet "sury" /etc/apt/sources.list* + # And sury ain't already in sources.lists + if ! grep --recursive --quiet "^ *deb.*sury" /etc/apt/sources.list* then # Re-add sury - ynh_install_extra_repo --repo="https://packages.sury.org/php/ $(ynh_get_debian_release) main" --key="https://packages.sury.org/php/apt.gpg" --name=extra_php_version + ynh_install_extra_repo --repo="https://packages.sury.org/php/ $(ynh_get_debian_release) main" --key="https://packages.sury.org/php/apt.gpg" --name=extra_php_version --priority=600 # Pin this sury repository to prevent sury of doing shit - ynh_pin_repo --package="*" --pin="origin \"packages.sury.org\"" --priority=200 --name=extra_php_version - ynh_pin_repo --package="php${YNH_DEFAULT_PHP_VERSION}*" --pin="origin \"packages.sury.org\"" --priority=600 --name=extra_php_version --append + for package_to_not_upgrade in "php" "php-fpm" "php-mysql" "php-xml" "php-zip" "php-mbstring" "php-ldap" "php-gd" "php-curl" "php-bz2" "php-json" "php-sqlite3" "php-intl" "openssl" "libssl1.1" "libssl-dev" + do + ynh_pin_repo --package="$package_to_not_upgrade" --pin="origin \"packages.sury.org\"" --priority="-1" --name=extra_php_version --append + done fi fi fi @@ -329,8 +335,6 @@ ynh_remove_app_dependencies () { ynh_package_autopurge ${dep_app}-ynh-deps # Remove the fake package and its dependencies if they not still used. } -#================================================= - # Install packages from an extra repository properly. # # usage: ynh_install_extra_app_dependencies --repo="repo" --package="dep1 dep2" [--key=key_url] [--name=name] @@ -463,8 +467,8 @@ ynh_remove_extra_repo () { ynh_secure_remove "/etc/apt/sources.list.d/$name.list" ynh_secure_remove "/etc/apt/preferences.d/$name" - ynh_secure_remove "/etc/apt/trusted.gpg.d/$name.gpg" - ynh_secure_remove "/etc/apt/trusted.gpg.d/$name.asc" + ynh_secure_remove "/etc/apt/trusted.gpg.d/$name.gpg" > /dev/null + ynh_secure_remove "/etc/apt/trusted.gpg.d/$name.asc" > /dev/null # Update the list of package to exclude the old repo ynh_package_update diff --git a/data/helpers.d/fail2ban b/data/helpers.d/fail2ban index d8777a16d..f9bdd89b2 100644 --- a/data/helpers.d/fail2ban +++ b/data/helpers.d/fail2ban @@ -134,7 +134,7 @@ EOF ynh_systemd_action --service_name=fail2ban --action=reload --line_match="(Started|Reloaded) Fail2Ban Service" --log_path=systemd - local fail2ban_error="$(journalctl --unit=fail2ban | tail --lines=50 | grep "WARNING.*$app.*")" + local fail2ban_error="$(journalctl --no-hostname --unit=fail2ban | tail --lines=50 | grep "WARNING.*$app.*")" if [[ -n "$fail2ban_error" ]] then ynh_print_err --message="Fail2ban failed to load the jail for $app" diff --git a/data/helpers.d/getopts b/data/helpers.d/getopts index 10c06930c..a4bbe20e6 100644 --- a/data/helpers.d/getopts +++ b/data/helpers.d/getopts @@ -80,10 +80,10 @@ ynh_handle_getopts_args () { arguments[arg]="${arguments[arg]//--${args_array[$option_flag]}-/--${args_array[$option_flag]}\\TOBEREMOVED\\-}" # And replace long option (value of the option_flag) by the short option, the option_flag itself # (e.g. for [u]=user, --user will be -u) - # Replace long option with = - arguments[arg]="${arguments[arg]//--${args_array[$option_flag]}/-${option_flag} }" - # And long option without = - arguments[arg]="${arguments[arg]//--${args_array[$option_flag]%=}/-${option_flag}}" + # Replace long option with = (match the beginning of the argument) + arguments[arg]="$(echo "${arguments[arg]}" | sed "s/^--${args_array[$option_flag]}/-${option_flag} /")" + # And long option without = (match the whole line) + arguments[arg]="$(echo "${arguments[arg]}" | sed "s/^--${args_array[$option_flag]%=}$/-${option_flag} /")" done done diff --git a/data/helpers.d/logging b/data/helpers.d/logging index d5f4f5eec..45b5b7e67 100644 --- a/data/helpers.d/logging +++ b/data/helpers.d/logging @@ -80,7 +80,7 @@ ynh_print_warn () { # Manage arguments with getopts ynh_handle_getopts_args "$@" - ynh_print_log "\e[93m\e[1m[WARN]\e[0m ${message}" >&2 + ynh_print_log "${message}" >&2 } # Print an error on stderr @@ -97,7 +97,7 @@ ynh_print_err () { # Manage arguments with getopts ynh_handle_getopts_args "$@" - ynh_print_log "\e[91m\e[1m[ERR]\e[0m ${message}" >&2 + ynh_print_log "[Error] ${message}" >&2 } # Execute a command and print the result as an error @@ -332,7 +332,7 @@ ynh_debug () { if [ -n "$message" ] then - ynh_print_log "\e[34m\e[1m[DEBUG]\e[0m ${message}" >&2 + ynh_print_log "[Debug] ${message}" >&2 fi if [ "$trace" == "1" ] diff --git a/data/helpers.d/mysql b/data/helpers.d/mysql index 84acc1029..05f75e0a2 100644 --- a/data/helpers.d/mysql +++ b/data/helpers.d/mysql @@ -44,8 +44,13 @@ ynh_mysql_execute_as_root() { ynh_handle_getopts_args "$@" database="${database:-}" + if [ -n "$database" ] + then + database="--database=$database" + fi + ynh_mysql_connect_as --user="root" --password="$(cat $MYSQL_ROOT_PWD_FILE)" \ - --database="$database" <<< "$sql" + $database <<< "$sql" } # Execute a command from a file as root user @@ -65,8 +70,14 @@ ynh_mysql_execute_file_as_root() { ynh_handle_getopts_args "$@" database="${database:-}" + if [ -n "$database" ] + then + database="--database=$database" + fi + + ynh_mysql_connect_as --user="root" --password="$(cat $MYSQL_ROOT_PWD_FILE)" \ - --database="$database" < "$file" + $database < "$file" } # Create a database and grant optionnaly privilegies to a user diff --git a/data/helpers.d/nodejs b/data/helpers.d/nodejs index 3ad0c400f..75472c278 100644 --- a/data/helpers.d/nodejs +++ b/data/helpers.d/nodejs @@ -1,5 +1,6 @@ #!/bin/bash +n_version=6.5.1 n_install_dir="/opt/node_n" node_version_path="$n_install_dir/n/versions/node" # N_PREFIX is the directory of n, it needs to be loaded as a environment variable. @@ -16,8 +17,8 @@ ynh_install_n () { ynh_print_info --message="Installation of N - Node.js version management" # Build an app.src for n mkdir --parents "../conf" - echo "SOURCE_URL=https://github.com/tj/n/archive/v4.1.0.tar.gz -SOURCE_SUM=3983fa3f00d4bf85ba8e21f1a590f6e28938093abe0bb950aeea52b1717471fc" > "../conf/n.src" + echo "SOURCE_URL=https://github.com/tj/n/archive/v${n_version}.tar.gz +SOURCE_SUM=5833f15893b9951a9ed59487e87b6c181d96b83a525846255872c4f92f0d25dd" > "../conf/n.src" # Download and extract n ynh_setup_source --dest_dir="$n_install_dir/git" --source_id=n # Install n @@ -125,7 +126,10 @@ ynh_install_nodejs () { test -x /usr/bin/npm && mv /usr/bin/npm /usr/bin/npm_n # If n is not previously setup, install it - if ! test $(n --version > /dev/null 2>&1) + if ! $n_install_dir/bin/n --version > /dev/null 2>&1 + then + ynh_install_n + elif dpkg --compare-versions "$($n_install_dir/bin/n --version)" lt $n_version then ynh_install_n fi diff --git a/data/helpers.d/php b/data/helpers.d/php index e8de6d9ff..7ff671317 100644 --- a/data/helpers.d/php +++ b/data/helpers.d/php @@ -1,6 +1,6 @@ #!/bin/bash -readonly YNH_DEFAULT_PHP_VERSION=7.0 +readonly YNH_DEFAULT_PHP_VERSION=7.3 # Declare the actual php version to use. # A packager willing to use another version of php can override the variable into its _common.sh. YNH_PHP_VERSION=${YNH_PHP_VERSION:-$YNH_DEFAULT_PHP_VERSION} @@ -148,8 +148,14 @@ ynh_add_fpm_config () { if [ $use_template -eq 1 ] then - # Usage 1, use the template in ../conf/php-fpm.conf - cp ../conf/php-fpm.conf "$finalphpconf" + # Usage 1, use the template in conf/php-fpm.conf + local phpfpm_path="../conf/php-fpm.conf" + if [ ! -e "$phpfpm_path" ]; then + phpfpm_path="../settings/conf/php-fpm.conf" # Into the restore script, the php-fpm template is not at the same place + fi + # Make sure now that the template indeed exists + [ -e "$phpfpm_path" ] || ynh_die --message="Unable to find template to configure php-fpm." + cp "$phpfpm_path" "$finalphpconf" ynh_replace_string --match_string="__NAMETOCHANGE__" --replace_string="$app" --target_file="$finalphpconf" ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$finalphpconf" ynh_replace_string --match_string="__USER__" --replace_string="$app" --target_file="$finalphpconf" @@ -297,7 +303,10 @@ ynh_remove_fpm_config () { fi ynh_secure_remove --file="$fpm_config_dir/pool.d/$app.conf" - ynh_exec_warn_less ynh_secure_remove --file="$fpm_config_dir/conf.d/20-$app.ini" + if [ -e $fpm_config_dir/conf.d/20-$app.ini ] + then + ynh_secure_remove --file="$fpm_config_dir/conf.d/20-$app.ini" + fi # If the php version used is not the default version for YunoHost if [ "$phpversion" != "$YNH_DEFAULT_PHP_VERSION" ] @@ -345,7 +354,7 @@ ynh_install_php () { fi # Add an extra repository for those packages - ynh_install_extra_repo --repo="https://packages.sury.org/php/ $(ynh_get_debian_release) main" --key="https://packages.sury.org/php/apt.gpg" --priority=995 --name=extra_php_version + ynh_install_extra_repo --repo="https://packages.sury.org/php/ $(ynh_get_debian_release) main" --key="https://packages.sury.org/php/apt.gpg" --priority=995 --name=extra_php_version --priority=600 # Install requested dependencies from this extra repository. # Install php-fpm first, otherwise php will install apache as a dependency. @@ -356,8 +365,10 @@ ynh_install_php () { update-alternatives --set php /usr/bin/php$YNH_DEFAULT_PHP_VERSION # Pin this extra repository after packages are installed to prevent sury of doing shit - ynh_pin_repo --package="*" --pin="origin \"packages.sury.org\"" --priority=200 --name=extra_php_version - ynh_pin_repo --package="php${YNH_DEFAULT_PHP_VERSION}*" --pin="origin \"packages.sury.org\"" --priority=600 --name=extra_php_version --append + for package_to_not_upgrade in "php" "php-fpm" "php-mysql" "php-xml" "php-zip" "php-mbstring" "php-ldap" "php-gd" "php-curl" "php-bz2" "php-json" "php-sqlite3" "php-intl" "openssl" "libssl1.1" "libssl-dev" + do + ynh_pin_repo --package="$package_to_not_upgrade" --pin="origin \"packages.sury.org\"" --priority="-1" --name=extra_php_version --append + done # Advertise service in admin panel yunohost service add php${phpversion}-fpm --log "/var/log/php${phpversion}-fpm.log" diff --git a/data/helpers.d/postgresql b/data/helpers.d/postgresql index e2bef8746..11b9c0fed 100644 --- a/data/helpers.d/postgresql +++ b/data/helpers.d/postgresql @@ -1,6 +1,7 @@ #!/bin/bash PSQL_ROOT_PWD_FILE=/etc/yunohost/psql +PSQL_VERSION=11 # Open a connection as a user # @@ -45,8 +46,13 @@ ynh_psql_execute_as_root() { ynh_handle_getopts_args "$@" database="${database:-}" + if [ -n "$database" ] + then + database="--database=$database" + fi + ynh_psql_connect_as --user="postgres" --password="$(cat $PSQL_ROOT_PWD_FILE)" \ - --database="$database" <<<"$sql" + $database <<<"$sql" } # Execute a command from a file as root user @@ -66,8 +72,13 @@ ynh_psql_execute_file_as_root() { ynh_handle_getopts_args "$@" database="${database:-}" + if [ -n "$database" ] + then + database="--database=$database" + fi + ynh_psql_connect_as --user="postgres" --password="$(cat $PSQL_ROOT_PWD_FILE)" \ - --database="$database" <"$file" + $database <"$file" } # Create a database and grant optionnaly privilegies to a user @@ -212,7 +223,7 @@ ynh_psql_drop_user() { # usage: ynh_psql_setup_db --db_user=user --db_name=name [--db_pwd=pwd] # | arg: -u, --db_user= - Owner of the database # | arg: -n, --db_name= - Name of the database -# | arg: -p, --db_pwd= - Password of the database. If not given, a password will be generated +# | arg: -p, --db_pwd= - Password of the database. If not provided, a password will be generated # # After executing this helper, the password of the created database will be available in $db_pwd # It will also be stored as "psqlpwd" into the app settings. @@ -228,12 +239,14 @@ ynh_psql_setup_db() { # Manage arguments with getopts ynh_handle_getopts_args "$@" - local new_db_pwd=$(ynh_string_random) # Generate a random password - # If $db_pwd is not given, use new_db_pwd instead for db_pwd - db_pwd="${db_pwd:-$new_db_pwd}" - if ! ynh_psql_user_exists --user=$db_user; then + local new_db_pwd=$(ynh_string_random) # Generate a random password + # If $db_pwd is not provided, use new_db_pwd instead for db_pwd + db_pwd="${db_pwd:-$new_db_pwd}" + ynh_psql_create_user "$db_user" "$db_pwd" + elif [ -z $db_pwd ]; then + ynh_die --message="The user $db_user exists, please provide his password" fi ynh_psql_create_db "$db_name" "$db_user" # Create the database @@ -273,6 +286,7 @@ ynh_psql_remove_db() { } # Create a master password and set up global settings +# It also make sure that postgresql is installed and running # Please always call this script in install and restore scripts # # usage: ynh_psql_test_if_first_run @@ -280,45 +294,38 @@ ynh_psql_remove_db() { # Requires YunoHost version 2.7.13 or higher. ynh_psql_test_if_first_run() { - if [ -f "$PSQL_ROOT_PWD_FILE" ] + # Make sure postgresql is indeed installed + dpkg --list | grep -q "ii postgresql-$PSQL_VERSION" || ynh_die "postgresql-$PSQL_VERSION is not installed !?" + + # Check for some weird issue where postgresql could be installed but etc folder would not exist ... + [ -e "/etc/postgresql/$PSQL_VERSION" ] || ynh_die "It looks like postgresql was not properly configured ? /etc/postgresql/$PSQL_VERSION is missing ... Could be due to a locale issue, c.f.https://serverfault.com/questions/426989/postgresql-etc-postgresql-doesnt-exist" + + # Make sure postgresql is started and enabled + # (N.B. : to check the active state, we check the cluster state because + # postgresql could be flagged as active even though the cluster is in + # failed state because of how the service is configured..) + systemctl is-active postgresql@$PSQL_VERSION-main -q || ynh_systemd_action --service_name=postgresql --action=restart + systemctl is-enabled postgresql -q || systemctl enable postgresql --quiet + + # If this is the very first time, we define the root password + # and configure a few things + if [ ! -f "$PSQL_ROOT_PWD_FILE" ] then - ynh_print_info --message="PostgreSQL is already installed, no need to create master password" - return + local pg_hba=/etc/postgresql/$PSQL_VERSION/main/pg_hba.conf + + local psql_root_password="$(ynh_string_random)" + echo "$psql_root_password" >$PSQL_ROOT_PWD_FILE + sudo --login --user=postgres psql -c"ALTER user postgres WITH PASSWORD '$psql_root_password'" postgres + + # force all user to connect to local databases using hashed passwords + # https://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html#EXAMPLE-PG-HBA.CONF + # Note: we can't use peer since YunoHost create users with nologin + # See: https://github.com/YunoHost/yunohost/blob/unstable/data/helpers.d/user + ynh_replace_string --match_string="local\(\s*\)all\(\s*\)all\(\s*\)peer" --replace_string="local\1all\2all\3md5" --target_file="$pg_hba" + + # Integrate postgresql service in yunohost + yunohost service add postgresql --log "/var/log/postgresql/" + + ynh_systemd_action --service_name=postgresql --action=reload fi - - local psql_root_password="$(ynh_string_random)" - echo "$psql_root_password" >$PSQL_ROOT_PWD_FILE - - if [ -e /etc/postgresql/9.4/ ] - then - local pg_hba=/etc/postgresql/9.4/main/pg_hba.conf - local logfile=/var/log/postgresql/postgresql-9.4-main.log - elif [ -e /etc/postgresql/9.6/ ] - then - local pg_hba=/etc/postgresql/9.6/main/pg_hba.conf - local logfile=/var/log/postgresql/postgresql-9.6-main.log - else - if dpkg --list | grep -q "ii postgresql-9." - then - ynh_die "It looks like postgresql was not properly configured ? /etc/postgresql/9.* is missing ... Could be due to a locale issue, c.f.https://serverfault.com/questions/426989/postgresql-etc-postgresql-doesnt-exist" - else - ynh_die "postgresql shoud be 9.4 or 9.6" - fi - fi - - ynh_systemd_action --service_name=postgresql --action=start - - sudo --login --user=postgres psql -c"ALTER user postgres WITH PASSWORD '$psql_root_password'" postgres - - # force all user to connect to local databases using hashed passwords - # https://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html#EXAMPLE-PG-HBA.CONF - # Note: we can't use peer since YunoHost create users with nologin - # See: https://github.com/YunoHost/yunohost/blob/unstable/data/helpers.d/user - ynh_replace_string --match_string="local\(\s*\)all\(\s*\)all\(\s*\)peer" --replace_string="local\1all\2all\3md5" --target_file="$pg_hba" - - # Advertise service in admin panel - yunohost service add postgresql --log "$logfile" - - systemctl enable postgresql - ynh_systemd_action --service_name=postgresql --action=reload } diff --git a/data/helpers.d/systemd b/data/helpers.d/systemd index 613f023fa..5c5fda852 100644 --- a/data/helpers.d/systemd +++ b/data/helpers.d/systemd @@ -58,7 +58,7 @@ ynh_add_systemd_config () { ynh_store_file_checksum --file="$finalsystemdconf" chown root: "$finalsystemdconf" - systemctl enable $service + systemctl enable $service --quiet systemctl daemon-reload } @@ -81,7 +81,7 @@ ynh_remove_systemd_config () { if [ -e "$finalsystemdconf" ] then ynh_systemd_action --service_name=$service --action=stop - systemctl disable $service + systemctl disable $service --quiet ynh_secure_remove --file="$finalsystemdconf" systemctl daemon-reload fi @@ -145,7 +145,7 @@ ynh_systemd_action() { if ! systemctl $action $service_name then # Show syslog for this service - ynh_exec_err journalctl --no-pager --lines=$length --unit=$service_name + ynh_exec_err journalctl --quiet --no-hostname --no-pager --lines=$length --unit=$service_name # If a log is specified for this service, show also the content of this log if [ -e "$log_path" ] then @@ -183,7 +183,7 @@ ynh_systemd_action() { then ynh_print_warn --message="The service $service_name didn't fully executed the action ${action} before the timeout." ynh_print_warn --message="Please find here an extract of the end of the log of the service $service_name:" - ynh_exec_warn journalctl --no-pager --lines=$length --unit=$service_name + ynh_exec_warn journalctl --quiet --no-hostname --no-pager --lines=$length --unit=$service_name if [ -e "$log_path" ] then ynh_print_warn --message="\-\-\-" diff --git a/data/helpers.d/utils b/data/helpers.d/utils index 9c2f40618..8647002e0 100644 --- a/data/helpers.d/utils +++ b/data/helpers.d/utils @@ -144,8 +144,13 @@ ynh_setup_source () { then # Use the local source file if it is present cp $local_src $src_filename else # If not, download the source + # NB. we have to declare the var as local first, + # otherwise 'local foo=$(false) || echo 'pwet'" does'nt work + # because local always return 0 ... + local out # Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget) - local out=`wget --timeout 900 --no-verbose --output-document=$src_filename $src_url 2>&1` || ynh_print_err --message="$out" + out=$(wget --tries 3 --no-dns-cache --timeout 900 --no-verbose --output-document=$src_filename $src_url 2>&1) \ + || ynh_die --message="$out" fi # Check the control sum diff --git a/data/hooks/backup/05-conf_ldap b/data/hooks/backup/05-conf_ldap index 75b4c2075..e3e8e455d 100755 --- a/data/hooks/backup/05-conf_ldap +++ b/data/hooks/backup/05-conf_ldap @@ -10,7 +10,8 @@ source /usr/share/yunohost/helpers backup_dir="${1}/conf/ldap" # Backup the configuration -ynh_backup "/etc/ldap/slapd.conf" "${backup_dir}/slapd.conf" +ynh_backup "/etc/ldap/ldap.conf" "${backup_dir}/ldap.conf" +ynh_backup "/etc/ldap/slapd.ldif" "${backup_dir}/slapd.ldif" slapcat -b cn=config -l "${backup_dir}/cn=config.master.ldif" # Backup the database diff --git a/data/hooks/backup/11-conf_ynh_mysql b/data/hooks/backup/11-conf_ynh_mysql deleted file mode 100755 index 031707337..000000000 --- a/data/hooks/backup/11-conf_ynh_mysql +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -# Exit hook on subcommand error or unset variable -set -eu - -# Source YNH helpers -source /usr/share/yunohost/helpers - -# Backup destination -backup_dir="${1}/conf/ynh/mysql" - -# Save MySQL root password -ynh_backup "/etc/yunohost/mysql" "${backup_dir}/root_pwd" diff --git a/data/hooks/conf_regen/01-yunohost b/data/hooks/conf_regen/01-yunohost index 236619079..c4120d487 100755 --- a/data/hooks/conf_regen/01-yunohost +++ b/data/hooks/conf_regen/01-yunohost @@ -55,14 +55,63 @@ do_pre_regen() { fi # add cron job for diagnosis to be ran at 7h and 19h + a random delay between - # 0 and 10min, meant to avoid every instances running their diagnosis at + # 0 and 20min, meant to avoid every instances running their diagnosis at # exactly the same time, which may overload the diagnosis server. mkdir -p $pending_dir/etc/cron.d/ cat > $pending_dir/etc/cron.d/yunohost-diagnosis << EOF SHELL=/bin/bash -0 7,19 * * * root : YunoHost Diagnosis; sleep \$((RANDOM\\%600)); yunohost diagnosis run > /dev/null +0 7,19 * * * root : YunoHost Automatic Diagnosis; sleep \$((RANDOM\\%1200)); yunohost diagnosis run --email > /dev/null 2>/dev/null || echo "Running the automatic diagnosis failed miserably" EOF + # legacy stuff to avoid yunohost reporting etckeeper as manually modified + # (this make sure that the hash is null / file is flagged as to-delete) + mkdir -p $pending_dir/etc/etckeeper + touch $pending_dir/etc/etckeeper/etckeeper.conf + + # Skip ntp if inside a container (inspired from the conf of systemd-timesyncd) + mkdir -p ${pending_dir}/etc/systemd/system/ntp.service.d/ + echo " +[Unit] +ConditionCapability=CAP_SYS_TIME +ConditionVirtualization=!container +" > ${pending_dir}/etc/systemd/system/ntp.service.d/ynh-override.conf + + # Make nftable conflict with yunohost-firewall + mkdir -p ${pending_dir}/etc/systemd/system/nftables.service.d/ + cat > ${pending_dir}/etc/systemd/system/nftables.service.d/ynh-override.conf << EOF +[Unit] +# yunohost-firewall and nftables conflict with each other +Conflicts=yunohost-firewall.service +ConditionFileIsExecutable=!/etc/init.d/yunohost-firewall +ConditionPathExists=!/etc/systemd/system/multi-user.target.wants/yunohost-firewall.service +EOF +} + +do_post_regen() { + regen_conf_files=$1 + + ###################### + # Enfore permissions # + ###################### + + # Certs + # We do this with find because there could be a lot of them... + chown -R root:ssl-cert /etc/yunohost/certs + chmod 750 /etc/yunohost/certs + find /etc/yunohost/certs/ -type f -exec chmod 640 {} \; + find /etc/yunohost/certs/ -type d -exec chmod 750 {} \; + + # Misc configuration / state files + chown root:root $(ls /etc/yunohost/{*.yml,*.yaml,*.json,mysql,psql} 2>/dev/null) + chmod 600 $(ls /etc/yunohost/{*.yml,*.yaml,*.json,mysql,psql} 2>/dev/null) + + # Apps folder, custom hooks folder + [[ ! -e /etc/yunohost/hooks.d ]] || (chown root /etc/yunohost/hooks.d && chmod 700 /etc/yunohost/hooks.d) + [[ ! -e /etc/yunohost/apps ]] || (chown root /etc/yunohost/apps && chmod 700 /etc/yunohost/apps) + + # Propagates changes in systemd service config overrides + [[ ! "$regen_conf_files" =~ "ntp.service.d/ynh-override.conf" ]] || { systemctl daemon-reload; systemctl restart ntp; } + [[ ! "$regen_conf_files" =~ "nftables.service.d/ynh-override.conf" ]] || systemctl daemon-reload } _update_services() { @@ -74,7 +123,7 @@ with open('services.yml') as f: new_services = yaml.load(f) with open('/etc/yunohost/services.yml') as f: - services = yaml.load(f) + services = yaml.load(f) or {} updated = False @@ -132,6 +181,7 @@ case "$1" in do_pre_regen $4 ;; post) + do_post_regen $4 ;; init) do_init_regen diff --git a/data/hooks/conf_regen/02-ssl b/data/hooks/conf_regen/02-ssl index a893b21e1..310a5d526 100755 --- a/data/hooks/conf_regen/02-ssl +++ b/data/hooks/conf_regen/02-ssl @@ -69,12 +69,11 @@ do_init_regen() { -out "${ssl_dir}/certs/yunohost_crt.pem" \ -batch >>$LOGFILE 2>&1 - last_cert=$(ls $ssl_dir/newcerts/*.pem | sort -V | tail -n 1) chmod 640 "${ssl_dir}/certs/yunohost_key.pem" - chmod 640 "$last_cert" + chmod 640 "${ssl_dir}/certs/yunohost_crt.pem" cp "${ssl_dir}/certs/yunohost_key.pem" "$ynh_key" - cp "$last_cert" "$ynh_crt" + cp "${ssl_dir}/certs/yunohost_crt.pem" "$ynh_crt" ln -sf "$ynh_crt" /etc/ssl/certs/yunohost_crt.pem ln -sf "$ynh_key" /etc/ssl/private/yunohost_key.pem fi diff --git a/data/hooks/conf_regen/06-slapd b/data/hooks/conf_regen/06-slapd index 9b2c20138..9f808b58e 100755 --- a/data/hooks/conf_regen/06-slapd +++ b/data/hooks/conf_regen/06-slapd @@ -12,27 +12,52 @@ do_init_regen() { do_pre_regen "" - # fix some permissions - chown root:openldap /etc/ldap/slapd.conf + systemctl daemon-reload + + _regenerate_slapd_conf + + # Enforce permissions + chown root:openldap /etc/ldap/slapd.ldif chown -R openldap:openldap /etc/ldap/schema/ usermod -aG ssl-cert openldap - # check the slapd config file at first - slaptest -Q -u -f /etc/ldap/slapd.conf - - # regenerate LDAP config directory from slapd.conf - rm -Rf /etc/ldap/slapd.d - mkdir /etc/ldap/slapd.d - slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d/ 2>&1 - chown -R openldap:openldap /etc/ldap/slapd.d/ - service slapd restart } +_regenerate_slapd_conf() { + + # Validate the new slapd config + # To do so, we have to use the .ldif to generate the config directory + # so we use a temporary directory slapd_new.d + rm -Rf /etc/ldap/slapd_new.d + mkdir /etc/ldap/slapd_new.d + slapadd -n0 -l /etc/ldap/slapd.ldif -F /etc/ldap/slapd_new.d/ 2>&1 + # Actual validation (-Q is for quiet, -u is for dry-run) + slaptest -Q -u -F /etc/ldap/slapd_new.d + + # "Commit" / apply the new config (meaning we delete the old one and replace + # it with the new one) + rm -Rf /etc/ldap/slapd.d + mv /etc/ldap/slapd_new.d /etc/ldap/slapd.d + + chown -R openldap:openldap /etc/ldap/slapd.d/ +} + do_pre_regen() { pending_dir=$1 - cd /usr/share/yunohost/templates/slapd + # remove temporary backup file + rm -f "$tmp_backup_dir_file" + + # Define if we need to migrate from hdb to mdb + curr_backend=$(grep '^database' /etc/ldap/slapd.conf 2>/dev/null | awk '{print $2}') + if [ -e /etc/ldap/slapd.conf ] && [ -n "$curr_backend" ] && \ + [ $curr_backend != 'mdb' ]; then + backup_dir="/var/backups/dc=yunohost,dc=org-${curr_backend}-$(date +%s)" + mkdir -p "$backup_dir" + slapcat -b dc=yunohost,dc=org -l "${backup_dir}/dc=yunohost-dc=org.ldif" + echo "$backup_dir" > "$tmp_backup_dir_file" + fi # create needed directories ldap_dir="${pending_dir}/etc/ldap" @@ -40,28 +65,15 @@ do_pre_regen() { mkdir -p "$ldap_dir" "$schema_dir" # remove legacy configuration file - [ ! -f /etc/ldap/slapd-yuno.conf ] \ - || touch "${pending_dir}/etc/ldap/slapd-yuno.conf" + [ ! -f /etc/ldap/slapd-yuno.conf ] || touch "${ldap_dir}/slapd-yuno.conf" + [ ! -f /etc/ldap/slapd.conf ] || touch "${ldap_dir}/slapd.conf" + [ ! -f /etc/ldap/schema/yunohost.schema ] || touch "${schema_dir}/yunohost.schema" - # remove temporary backup file - rm -f "$tmp_backup_dir_file" - - # retrieve current and new backends - curr_backend=$(grep '^database' /etc/ldap/slapd.conf 2>/dev/null | awk '{print $2}') - new_backend=$(grep '^database' slapd.conf | awk '{print $2}') - - # save current database before any conf changes - if [[ -n "$curr_backend" && "$curr_backend" != "$new_backend" ]]; then - backup_dir="/var/backups/dc=yunohost,dc=org-${curr_backend}-$(date +%s)" - mkdir -p "$backup_dir" - slapcat -b dc=yunohost,dc=org \ - -l "${backup_dir}/dc=yunohost-dc=org.ldif" - echo "$backup_dir" > "$tmp_backup_dir_file" - fi + cd /usr/share/yunohost/templates/slapd # copy configuration files - cp -a ldap.conf slapd.conf "$ldap_dir" - cp -a sudo.schema mailserver.schema yunohost.schema "$schema_dir" + cp -a ldap.conf slapd.ldif "$ldap_dir" + cp -a sudo.ldif mailserver.ldif permission.ldif "$schema_dir" mkdir -p ${pending_dir}/etc/systemd/system/slapd.service.d/ cp systemd-override.conf ${pending_dir}/etc/systemd/system/slapd.service.d/ynh-override.conf @@ -72,19 +84,13 @@ do_pre_regen() { do_post_regen() { regen_conf_files=$1 - # ensure that slapd.d exists - mkdir -p /etc/ldap/slapd.d - # fix some permissions - echo "Making sure we have the right permissions needed ..." + echo "Enforce permissions on ldap/slapd directories and certs ..." # penldap user should be in the ssl-cert group to let it access the certificate for TLS usermod -aG ssl-cert openldap - chown root:openldap /etc/ldap/slapd.conf + chown root:openldap /etc/ldap/slapd.ldif chown -R openldap:openldap /etc/ldap/schema/ chown -R openldap:openldap /etc/ldap/slapd.d/ - chown -R root:ssl-cert /etc/yunohost/certs/yunohost.org/ - chmod o-rwx /etc/yunohost/certs/yunohost.org/ - chmod -R g+rx /etc/yunohost/certs/yunohost.org/ # If we changed the systemd ynh-override conf if echo "$regen_conf_files" | sed 's/,/\n/g' | grep -q "^/etc/systemd/system/slapd.service.d/ynh-override.conf$" @@ -95,29 +101,17 @@ do_post_regen() { [ -z "$regen_conf_files" ] && exit 0 - # check the slapd config file at first - slaptest -Q -u -f /etc/ldap/slapd.conf + # regenerate LDAP config directory from slapd.conf + echo "Regenerate LDAP config directory from slapd.ldif" + _regenerate_slapd_conf - # check if a backup should be restored + # If there's a backup, re-import its data backup_dir=$(cat "$tmp_backup_dir_file" 2>/dev/null || true) if [[ -n "$backup_dir" && -f "${backup_dir}/dc=yunohost-dc=org.ldif" ]]; then # regenerate LDAP config directory and import database as root - # since the admin user may be unavailable - echo "Regenerate LDAP config directory and import the database using slapadd" - sh -c "rm -Rf /etc/ldap/slapd.d; - mkdir /etc/ldap/slapd.d; - slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d; - chown -R openldap:openldap /etc/ldap/slapd.d; - slapadd -F /etc/ldap/slapd.d -b dc=yunohost,dc=org \ - -l '${backup_dir}/dc=yunohost-dc=org.ldif'; - chown -R openldap:openldap /var/lib/ldap" 2>&1 - else - # regenerate LDAP config directory from slapd.conf - echo "Regenerate LDAP config directory from slapd.conf" - rm -Rf /etc/ldap/slapd.d - mkdir /etc/ldap/slapd.d - slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d/ 2>&1 - chown -R openldap:openldap /etc/ldap/slapd.d/ + echo "Import the database using slapadd" + slapadd -F /etc/ldap/slapd.d -b dc=yunohost,dc=org -l "${backup_dir}/dc=yunohost-dc=org.ldif" + chown -R openldap:openldap /var/lib/ldap 2>&1 fi echo "Running slapdindex" @@ -157,6 +151,9 @@ case "$1" in init) do_init_regen ;; + apply_config) + do_post_regen /etc/ldap/slapd.ldif + ;; *) echo "hook called with unknown argument \`$1'" >&2 exit 1 diff --git a/data/hooks/conf_regen/12-metronome b/data/hooks/conf_regen/12-metronome index 7e8c7eb0c..31d11555a 100755 --- a/data/hooks/conf_regen/12-metronome +++ b/data/hooks/conf_regen/12-metronome @@ -57,6 +57,9 @@ do_post_regen() { done # fix some permissions + + # metronome should be in ssl-cert group to let it access SSL certificates + usermod -aG ssl-cert metronome chown -R metronome: /var/lib/metronome/ chown -R metronome: /etc/metronome/conf.d/ diff --git a/data/hooks/conf_regen/15-nginx b/data/hooks/conf_regen/15-nginx index 4924b6f91..a7574b070 100755 --- a/data/hooks/conf_regen/15-nginx +++ b/data/hooks/conf_regen/15-nginx @@ -26,6 +26,9 @@ do_init_regen() { ynh_render_template "security.conf.inc" "${nginx_conf_dir}/security.conf.inc" ynh_render_template "yunohost_admin.conf" "${nginx_conf_dir}/yunohost_admin.conf" + mkdir -p $nginx_conf_dir/default.d/ + cp "redirect_to_admin.conf" $nginx_conf_dir/default.d/ + # Restart nginx if conf looks good, otherwise display error and exit unhappy nginx -t 2>/dev/null || { nginx -t; exit 1; } systemctl restart nginx || { journalctl --no-pager --lines=10 -u nginx >&2; exit 1; } @@ -77,6 +80,8 @@ do_pre_regen() { done ynh_render_template "yunohost_admin.conf" "${nginx_conf_dir}/yunohost_admin.conf" + mkdir -p $nginx_conf_dir/default.d/ + cp "redirect_to_admin.conf" $nginx_conf_dir/default.d/ # remove old domain conf files conf_files=$(ls -1 /etc/nginx/conf.d \ diff --git a/data/hooks/conf_regen/31-rspamd b/data/hooks/conf_regen/31-rspamd index 861549e27..6da4af643 100755 --- a/data/hooks/conf_regen/31-rspamd +++ b/data/hooks/conf_regen/31-rspamd @@ -42,6 +42,8 @@ do_post_regen() { chown _rspamd /etc/dkim/*.mail.key chmod 400 /etc/dkim/*.mail.key + [ ! -e /var/log/rspamd ] || chown _rspamd:_rspamd /var/log/rspamd + regen_conf_files=$1 [ -z "$regen_conf_files" ] && exit 0 diff --git a/data/hooks/conf_regen/34-mysql b/data/hooks/conf_regen/34-mysql index 43f9fdde1..ac2395f34 100755 --- a/data/hooks/conf_regen/34-mysql +++ b/data/hooks/conf_regen/34-mysql @@ -15,6 +15,18 @@ do_pre_regen() { do_post_regen() { regen_conf_files=$1 + # mysql is supposed to be an alias to mariadb... but in some weird case is not + # c.f. https://forum.yunohost.org/t/mysql-ne-fonctionne-pas/11661 + # Playing with enable/disable allows to recreate the proper symlinks. + if [ ! -e /etc/systemd/system/mysql.service ] + then + systemctl stop mysql -q + systemctl disable mysql -q + systemctl disable mariadb -q + systemctl enable mariadb -q + systemctl is-active mariadb -q || systemctl start mariadb + fi + if [ ! -f /etc/yunohost/mysql ]; then # ensure that mysql is running diff --git a/data/hooks/conf_regen/40-glances b/data/hooks/conf_regen/40-glances deleted file mode 100755 index 70b8f4b5a..000000000 --- a/data/hooks/conf_regen/40-glances +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -set -e - -do_pre_regen() { - pending_dir=$1 - - cd /usr/share/yunohost/templates/glances - - install -D -m 644 glances.default "${pending_dir}/etc/default/glances" -} - -do_post_regen() { - regen_conf_files=$1 - - [[ -z "$regen_conf_files" ]] \ - || service glances restart -} - -FORCE=${2:-0} -DRY_RUN=${3:-0} - -case "$1" in - pre) - do_pre_regen $4 - ;; - post) - do_post_regen $4 - ;; - *) - echo "hook called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -exit 0 diff --git a/data/hooks/conf_regen/43-dnsmasq b/data/hooks/conf_regen/43-dnsmasq index 8a2985f34..75d74b09c 100755 --- a/data/hooks/conf_regen/43-dnsmasq +++ b/data/hooks/conf_regen/43-dnsmasq @@ -64,8 +64,21 @@ do_post_regen() { systemctl restart resolvconf fi - [[ -z "$regen_conf_files" ]] \ - || service dnsmasq restart + # Some stupid things like rabbitmq-server used by onlyoffice won't work if + # the *short* hostname doesn't exists in /etc/hosts -_- + short_hostname=$(hostname -s) + grep -q "127.0.0.1.*$short_hostname" /etc/hosts || echo -e "\n127.0.0.1\t$short_hostname" >>/etc/hosts + + [[ -n "$regen_conf_files" ]] || return + + # Remove / disable services likely to conflict with dnsmasq + for SERVICE in systemd-resolved bind9 + do + systemctl is-enabled $SERVICE &>/dev/null && systemctl disable $SERVICE 2>/dev/null + systemctl is-active $SERVICE &>/dev/null && systemctl stop $SERVICE + done + + systemctl restart dnsmasq } FORCE=${2:-0} diff --git a/data/hooks/diagnosis/00-basesystem.py b/data/hooks/diagnosis/00-basesystem.py index 51926924a..ec802c870 100644 --- a/data/hooks/diagnosis/00-basesystem.py +++ b/data/hooks/diagnosis/00-basesystem.py @@ -1,9 +1,11 @@ #!/usr/bin/env python import os +import json +import subprocess from moulinette.utils.process import check_output -from moulinette.utils.filesystem import read_file +from moulinette.utils.filesystem import read_file, read_json, write_to_json from yunohost.diagnosis import Diagnoser from yunohost.utils.packages import ynh_packages_version @@ -32,7 +34,7 @@ class BaseSystemDiagnoser(Diagnoser): # Also possibly the board name if os.path.exists("/proc/device-tree/model"): - model = read_file('/proc/device-tree/model').strip() + model = read_file('/proc/device-tree/model').strip().replace('\x00', '') hardware["data"]["model"] = model hardware["details"] = ["diagnosis_basesystem_hardware_board"] @@ -74,5 +76,75 @@ class BaseSystemDiagnoser(Diagnoser): details=ynh_version_details) + if self.is_vulnerable_to_meltdown(): + yield dict(meta={"test": "meltdown"}, + status="ERROR", + summary="diagnosis_security_vulnerable_to_meltdown", + details=["diagnosis_security_vulnerable_to_meltdown_details"] + ) + + def is_vulnerable_to_meltdown(self): + # meltdown CVE: https://security-tracker.debian.org/tracker/CVE-2017-5754 + + # We use a cache file to avoid re-running the script so many times, + # which can be expensive (up to around 5 seconds on ARM) + # and make the admin appear to be slow (c.f. the calls to diagnosis + # from the webadmin) + # + # The cache is in /tmp and shall disappear upon reboot + # *or* we compare it to dpkg.log modification time + # such that it's re-ran if there was package upgrades + # (e.g. from yunohost) + cache_file = "/tmp/yunohost-meltdown-diagnosis" + dpkg_log = "/var/log/dpkg.log" + if os.path.exists(cache_file): + if not os.path.exists(dpkg_log) or os.path.getmtime(cache_file) > os.path.getmtime(dpkg_log): + self.logger_debug("Using cached results for meltdown checker, from %s" % cache_file) + return read_json(cache_file)[0]["VULNERABLE"] + + # script taken from https://github.com/speed47/spectre-meltdown-checker + # script commit id is store directly in the script + SCRIPT_PATH = "/usr/lib/moulinette/yunohost/vendor/spectre-meltdown-checker/spectre-meltdown-checker.sh" + + # '--variant 3' corresponds to Meltdown + # example output from the script: + # [{"NAME":"MELTDOWN","CVE":"CVE-2017-5754","VULNERABLE":false,"INFOS":"PTI mitigates the vulnerability"}] + try: + self.logger_debug("Running meltdown vulnerability checker") + call = subprocess.Popen("bash %s --batch json --variant 3" % + SCRIPT_PATH, shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + + # TODO / FIXME : here we are ignoring error messages ... + # in particular on RPi2 and other hardware, the script complains about + # "missing some kernel info (see -v), accuracy might be reduced" + # Dunno what to do about that but we probably don't want to harass + # users with this warning ... + output, err = call.communicate() + assert call.returncode in (0, 2, 3), "Return code: %s" % call.returncode + + # If there are multiple lines, sounds like there was some messages + # in stdout that are not json >.> ... Try to get the actual json + # stuff which should be the last line + output = output.strip() + if "\n" in output: + self.logger_debug("Original meltdown checker output : %s" % output) + output = output.split("\n")[-1] + + CVEs = json.loads(output) + assert len(CVEs) == 1 + assert CVEs[0]["NAME"] == "MELTDOWN" + except Exception as e: + import traceback + traceback.print_exc() + self.logger_warning("Something wrong happened when trying to diagnose Meltdown vunerability, exception: %s" % e) + raise Exception("Command output for failed meltdown check: '%s'" % output) + + self.logger_debug("Writing results from meltdown checker to cache file, %s" % cache_file) + write_to_json(cache_file, CVEs) + return CVEs[0]["VULNERABLE"] + + def main(args, env, loggers): return BaseSystemDiagnoser(args, env, loggers).diagnose() diff --git a/data/hooks/diagnosis/10-ip.py b/data/hooks/diagnosis/10-ip.py index fe4993935..b18b4f435 100644 --- a/data/hooks/diagnosis/10-ip.py +++ b/data/hooks/diagnosis/10-ip.py @@ -108,7 +108,7 @@ class IPDiagnoser(Diagnoser): return False # If we are indeed connected in ipv4 or ipv6, we should find a default route - routes = check_output("ip -%s route" % protocol).split("\n") + routes = check_output("ip -%s route show table all" % protocol).split("\n") def is_default_route(r): # Typically the default route starts with "default" diff --git a/data/hooks/diagnosis/12-dnsrecords.py b/data/hooks/diagnosis/12-dnsrecords.py index 560127bb0..91dec7006 100644 --- a/data/hooks/diagnosis/12-dnsrecords.py +++ b/data/hooks/diagnosis/12-dnsrecords.py @@ -12,9 +12,7 @@ from yunohost.utils.network import dig from yunohost.diagnosis import Diagnoser from yunohost.domain import domain_list, _build_dns_conf, _get_maindomain -# We put here domains we know has dyndns provider, but that are not yet -# registered in the public suffix list -PENDING_SUFFIX_LIST = ['ynh.fr', 'netlib.re'] +YNH_DYNDNS_DOMAINS = ['nohost.me', 'noho.st', 'ynh.fr'] class DNSRecordsDiagnoser(Diagnoser): @@ -38,7 +36,7 @@ class DNSRecordsDiagnoser(Diagnoser): psl = PublicSuffixList() domains_from_registrar = [psl.get_public_suffix(domain) for domain in all_domains] domains_from_registrar = [domain for domain in domains_from_registrar if "." in domain] - domains_from_registrar = set(domains_from_registrar) - set(PENDING_SUFFIX_LIST) + domains_from_registrar = set(domains_from_registrar) - set(YNH_DYNDNS_DOMAINS + ["netlib.re"]) for report in self.check_expiration_date(domains_from_registrar): yield report @@ -100,7 +98,13 @@ class DNSRecordsDiagnoser(Diagnoser): summary=summary) if discrepancies: - output["details"] = ["diagnosis_dns_point_to_doc"] + discrepancies + # For ynh-managed domains (nohost.me etc...), tell people to try to "yunohost dyndns update --force" + if any(domain.endswith(ynh_dyndns_domain) for ynh_dyndns_domain in YNH_DYNDNS_DOMAINS): + output["details"] = ["diagnosis_dns_try_dyndns_update_force"] + # Otherwise point to the documentation + else: + output["details"] = ["diagnosis_dns_point_to_doc"] + output["details"] += discrepancies yield output diff --git a/data/hooks/diagnosis/14-ports.py b/data/hooks/diagnosis/14-ports.py index bd68c60d6..38f6e0089 100644 --- a/data/hooks/diagnosis/14-ports.py +++ b/data/hooks/diagnosis/14-ports.py @@ -87,7 +87,7 @@ class PortsDiagnoser(Diagnoser): # If any AAAA record is set, IPv6 is important... def ipv6_is_important(): dnsrecords = Diagnoser.get_cached_report("dnsrecords") or {} - return any(record["data"]["AAAA:@"] in ["OK", "WRONG"] for record in dnsrecords.get("items", [])) + return any(record["data"].get("AAAA:@") in ["OK", "WRONG"] for record in dnsrecords.get("items", [])) if failed == 4 or ipv6_is_important(): yield dict(meta={"port": port}, diff --git a/data/hooks/diagnosis/24-mail.py b/data/hooks/diagnosis/24-mail.py index bc159c3b7..a483e676d 100644 --- a/data/hooks/diagnosis/24-mail.py +++ b/data/hooks/diagnosis/24-mail.py @@ -126,7 +126,7 @@ class MailDiagnoser(Diagnoser): query += '.ip6.arpa' # Do the DNS Query - status, value = dig(query, 'PTR') + status, value = dig(query, 'PTR', resolvers="force_external") if status == "nok": yield dict(meta={"test": "mail_fcrdns", "ipversion": ipversion}, data={"ip": ip, "ehlo_domain": self.ehlo_domain}, diff --git a/data/hooks/diagnosis/30-services.py b/data/hooks/diagnosis/30-services.py index 6217d89d3..d0fe50ae9 100644 --- a/data/hooks/diagnosis/30-services.py +++ b/data/hooks/diagnosis/30-services.py @@ -21,7 +21,7 @@ class ServicesDiagnoser(Diagnoser): data={"status": result["status"], "configuration": result["configuration"]}) if result["status"] != "running": - item["status"] = "ERROR" + item["status"] = "ERROR" if result["status"] != "unknown" else "WARNING" item["summary"] = "diagnosis_services_bad_status" item["details"] = ["diagnosis_services_bad_status_tip"] diff --git a/data/hooks/diagnosis/50-systemresources.py b/data/hooks/diagnosis/50-systemresources.py index 66d27866a..682fb897f 100644 --- a/data/hooks/diagnosis/50-systemresources.py +++ b/data/hooks/diagnosis/50-systemresources.py @@ -45,14 +45,15 @@ class SystemResourcesDiagnoser(Diagnoser): item = dict(meta={"test": "swap"}, data={"total": human_size(swap.total), "recommended": "512 MiB"}) if swap.total <= 1 * MB: - item["status"] = "ERROR" + item["status"] = "INFO" item["summary"] = "diagnosis_swap_none" - elif swap.total < 500 * MB: - item["status"] = "WARNING" + elif swap.total < 450 * MB: + item["status"] = "INFO" item["summary"] = "diagnosis_swap_notsomuch" else: item["status"] = "SUCCESS" item["summary"] = "diagnosis_swap_ok" + item["details"] = ["diagnosis_swap_tip"] yield item # FIXME : add a check that swapiness is low if swap is on a sdcard... diff --git a/data/hooks/diagnosis/90-security.py b/data/hooks/diagnosis/90-security.py deleted file mode 100644 index d281042b0..000000000 --- a/data/hooks/diagnosis/90-security.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python - -import os -import json -import subprocess - -from yunohost.diagnosis import Diagnoser -from moulinette.utils.filesystem import read_json, write_to_json - - -class SecurityDiagnoser(Diagnoser): - - id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1] - cache_duration = 3600 - dependencies = [] - - def run(self): - - "CVE-2017-5754" - - if self.is_vulnerable_to_meltdown(): - yield dict(meta={"test": "meltdown"}, - status="ERROR", - summary="diagnosis_security_vulnerable_to_meltdown", - details=["diagnosis_security_vulnerable_to_meltdown_details"] - ) - else: - yield dict(meta={}, - status="SUCCESS", - summary="diagnosis_security_all_good" - ) - - - def is_vulnerable_to_meltdown(self): - # meltdown CVE: https://security-tracker.debian.org/tracker/CVE-2017-5754 - - # We use a cache file to avoid re-running the script so many times, - # which can be expensive (up to around 5 seconds on ARM) - # and make the admin appear to be slow (c.f. the calls to diagnosis - # from the webadmin) - # - # The cache is in /tmp and shall disappear upon reboot - # *or* we compare it to dpkg.log modification time - # such that it's re-ran if there was package upgrades - # (e.g. from yunohost) - cache_file = "/tmp/yunohost-meltdown-diagnosis" - dpkg_log = "/var/log/dpkg.log" - if os.path.exists(cache_file): - if not os.path.exists(dpkg_log) or os.path.getmtime(cache_file) > os.path.getmtime(dpkg_log): - self.logger_debug("Using cached results for meltdown checker, from %s" % cache_file) - return read_json(cache_file)[0]["VULNERABLE"] - - # script taken from https://github.com/speed47/spectre-meltdown-checker - # script commit id is store directly in the script - SCRIPT_PATH = "/usr/lib/moulinette/yunohost/vendor/spectre-meltdown-checker/spectre-meltdown-checker.sh" - - # '--variant 3' corresponds to Meltdown - # example output from the script: - # [{"NAME":"MELTDOWN","CVE":"CVE-2017-5754","VULNERABLE":false,"INFOS":"PTI mitigates the vulnerability"}] - try: - self.logger_debug("Running meltdown vulnerability checker") - call = subprocess.Popen("bash %s --batch json --variant 3" % - SCRIPT_PATH, shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - - # TODO / FIXME : here we are ignoring error messages ... - # in particular on RPi2 and other hardware, the script complains about - # "missing some kernel info (see -v), accuracy might be reduced" - # Dunno what to do about that but we probably don't want to harass - # users with this warning ... - output, err = call.communicate() - assert call.returncode in (0, 2, 3), "Return code: %s" % call.returncode - - # If there are multiple lines, sounds like there was some messages - # in stdout that are not json >.> ... Try to get the actual json - # stuff which should be the last line - output = output.strip() - if "\n" in output: - self.logger_debug("Original meltdown checker output : %s" % output) - output = output.split("\n")[-1] - - CVEs = json.loads(output) - assert len(CVEs) == 1 - assert CVEs[0]["NAME"] == "MELTDOWN" - except Exception as e: - import traceback - traceback.print_exc() - self.logger_warning("Something wrong happened when trying to diagnose Meltdown vunerability, exception: %s" % e) - raise Exception("Command output for failed meltdown check: '%s'" % output) - - self.logger_debug("Writing results from meltdown checker to cache file, %s" % cache_file) - write_to_json(cache_file, CVEs) - return CVEs[0]["VULNERABLE"] - - -def main(args, env, loggers): - return SecurityDiagnoser(args, env, loggers).diagnose() diff --git a/data/hooks/restore/05-conf_ldap b/data/hooks/restore/05-conf_ldap index 74093136d..bdc1ebcdf 100644 --- a/data/hooks/restore/05-conf_ldap +++ b/data/hooks/restore/05-conf_ldap @@ -39,6 +39,9 @@ else # Restore the configuration mv /etc/ldap/slapd.d "$TMPDIR" mkdir -p /etc/ldap/slapd.d + cp -a "${backup_dir}/ldap.conf" /etc/ldap/ldap.conf + cp -a "${backup_dir}/slapd.ldif" /etc/ldap/slapd.ldif + # Legacy thing but we need it to force the regen-conf in case of it exist cp -a "${backup_dir}/slapd.conf" /etc/ldap/slapd.conf slapadd -F /etc/ldap/slapd.d -b cn=config \ -l "${backup_dir}/cn=config.master.ldif" \ diff --git a/data/hooks/restore/11-conf_ynh_mysql b/data/hooks/restore/11-conf_ynh_mysql index f54641d6f..11353425a 100644 --- a/data/hooks/restore/11-conf_ynh_mysql +++ b/data/hooks/restore/11-conf_ynh_mysql @@ -1,42 +1,5 @@ -backup_dir="$1/conf/ynh/mysql" -MYSQL_PKG="$(dpkg --list | sed -ne 's/^ii \(mariadb-server-[[:digit:].]\+\) .*$/\1/p')" +# We don't backup/restore mysql password anymore +# c.f. https://github.com/YunoHost/yunohost/pull/912 -. /usr/share/yunohost/helpers - -# ensure that mysql is running -service mysql status >/dev/null 2>&1 \ - || service mysql start - -# retrieve current and new password -[ -f /etc/yunohost/mysql ] \ - && curr_pwd=$(cat /etc/yunohost/mysql) -new_pwd=$(cat "${backup_dir}/root_pwd" || cat "${backup_dir}/mysql") -[ -z "$curr_pwd" ] && curr_pwd="yunohost" -[ -z "$new_pwd" ] && { - new_pwd=$(ynh_string_random 10) -} - -# attempt to change it -mysqladmin -s -u root -p"$curr_pwd" password "$new_pwd" || { - - echo "It seems that you have already configured MySQL." \ - "YunoHost needs to have a root access to MySQL to runs its" \ - "applications, and is going to reset the MySQL root password." \ - "You can find this new password in /etc/yunohost/mysql." >&2 - - # set new password with debconf - debconf-set-selections << EOF -$MYSQL_PKG mysql-server/root_password password $new_pwd -$MYSQL_PKG mysql-server/root_password_again password $new_pwd -EOF - - # reconfigure Debian package - dpkg-reconfigure -freadline -u "$MYSQL_PKG" 2>&1 -} - -# store new root password -echo "$new_pwd" | tee /etc/yunohost/mysql -chmod 400 /etc/yunohost/mysql - -# reload the grant tables -mysqladmin -s -u root -p"$new_pwd" reload +# This is a dummy empty file as a workaround for +# https://github.com/YunoHost/issues/issues/1553 until it is fixed diff --git a/data/other/ffdhe2048.pem b/data/other/ffdhe2048.pem new file mode 100644 index 000000000..9b182b720 --- /dev/null +++ b/data/other/ffdhe2048.pem @@ -0,0 +1,8 @@ +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz ++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a +87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 +YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi +7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD +ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== +-----END DH PARAMETERS----- diff --git a/data/templates/dovecot/dovecot.conf b/data/templates/dovecot/dovecot.conf index 8fc0e75ae..d64b15356 100644 --- a/data/templates/dovecot/dovecot.conf +++ b/data/templates/dovecot/dovecot.conf @@ -14,18 +14,16 @@ mail_plugins = $mail_plugins quota ############################################################################### -# generated 2020-04-03, Mozilla Guideline v5.4, Dovecot 2.2.27, OpenSSL 1.1.0l, intermediate configuration -# https://ssl-config.mozilla.org/#server=dovecot&version=2.2.27&config=intermediate&openssl=1.1.0l&guideline=5.4 +# generated 2020-05-02, Mozilla Guideline v5.4, Dovecot 2.3.4.1, OpenSSL 1.1.1d, intermediate configuration +# https://ssl-config.mozilla.org/#server=dovecot&version=2.3.4.1&config=intermediate&openssl=1.1.1d&guideline=5.4 ssl = required ssl_cert = openssl dhparam -out /etc/ssl/private/dh2048.pem -outform PEM -2 2048 -#ssl_dhparam /etc/ssl/private/dh2048.pem; +# Pre-defined FFDHE group (RFC 7919) +# From https://ssl-config.mozilla.org/ffdhe2048.txt +# https://security.stackexchange.com/a/149818 +ssl_dhparam /usr/share/yunohost/other/ffdhe2048.pem; +{% endif %} + # Follows the Web Security Directives from the Mozilla Dev Lab and the Mozilla Obervatory + Partners # https://wiki.mozilla.org/Security/Guidelines/Web_Security # https://observatory.mozilla.org/ more_set_headers "Content-Security-Policy : upgrade-insecure-requests"; -more_set_headers "Content-Security-Policy-Report-Only : default-src https: data: 'unsafe-inline' 'unsafe-eval'"; +more_set_headers "Content-Security-Policy-Report-Only : default-src https: data: 'unsafe-inline' 'unsafe-eval' "; more_set_headers "X-Content-Type-Options : nosniff"; more_set_headers "X-XSS-Protection : 1; mode=block"; more_set_headers "X-Download-Options : noopen"; diff --git a/data/templates/nginx/yunohost_admin.conf b/data/templates/nginx/yunohost_admin.conf index 3df838c4a..8a7a40231 100644 --- a/data/templates/nginx/yunohost_admin.conf +++ b/data/templates/nginx/yunohost_admin.conf @@ -2,13 +2,7 @@ server { listen 80 default_server; listen [::]:80 default_server; - location / { - return 302 https://$http_host/yunohost/admin; - } - - location /yunohost/admin { - return 301 https://$http_host$request_uri; - } + include /etc/nginx/conf.d/default.d/*.conf; } server { @@ -22,23 +16,13 @@ server { more_set_headers "Strict-Transport-Security : max-age=63072000; includeSubDomains; preload"; more_set_headers "Referrer-Policy : 'same-origin'"; - more_set_headers "Content-Security-Policy : upgrade-insecure-requests; object-src 'none'; script-src https: 'unsafe-eval'"; - - location / { - return 302 https://$http_host/yunohost/admin; - } location /yunohost { - # Block crawlers bot - if ($http_user_agent ~ (crawl|Googlebot|Slurp|spider|bingbot|tracker|click|parser|spider|facebookexternalhit) ) { - return 403; - } - # X-Robots-Tag to precise the rules applied. - add_header X-Robots-Tag "nofollow, noindex, noarchive, nosnippet"; # Redirect most of 404 to maindomain.tld/yunohost/sso access_by_lua_file /usr/share/ssowat/access.lua; } include /etc/nginx/conf.d/yunohost_admin.conf.inc; include /etc/nginx/conf.d/yunohost_api.conf.inc; + include /etc/nginx/conf.d/default.d/*.conf; } diff --git a/data/templates/nslcd/nslcd.conf b/data/templates/nslcd/nslcd.conf index 091ecb7cc..7cfe73e07 100644 --- a/data/templates/nslcd/nslcd.conf +++ b/data/templates/nslcd/nslcd.conf @@ -15,6 +15,18 @@ base dc=yunohost,dc=org # The LDAP protocol version to use. #ldap_version 3 +# The DN to bind with for normal lookups. +#binddn cn=annonymous,dc=example,dc=net +#bindpw secret + +# The DN used for password modifications by root. +#rootpwmoddn cn=admin,dc=example,dc=com + +# SSL options +#ssl off +#tls_reqcert never +tls_cacertfile /etc/ssl/certs/ca-certificates.crt + # The search scope. #scope sub diff --git a/data/templates/nsswitch/nsswitch.conf b/data/templates/nsswitch/nsswitch.conf index b55e01b02..8f46e4f5d 100644 --- a/data/templates/nsswitch/nsswitch.conf +++ b/data/templates/nsswitch/nsswitch.conf @@ -1,12 +1,8 @@ # /etc/nsswitch.conf -# -# Example configuration of GNU Name Service Switch functionality. -# If you have the `glibc-doc-reference' and `info' packages installed, try: -# `info libc "Name Service Switch"' for information about this file. -passwd: compat ldap -group: compat ldap -shadow: compat ldap +passwd: files systemd ldap +group: files systemd ldap +shadow: files ldap gshadow: files hosts: files myhostname mdns4_minimal [NOTFOUND=return] dns diff --git a/data/templates/postfix/main.cf b/data/templates/postfix/main.cf index 61cbfa2e6..18e457a76 100644 --- a/data/templates/postfix/main.cf +++ b/data/templates/postfix/main.cf @@ -170,7 +170,7 @@ smtpd_milters = inet:localhost:11332 milter_default_action = accept # Avoid to send simultaneously too many emails -smtp_destination_concurrency_limit = 1 +smtp_destination_concurrency_limit = 2 default_destination_rate_delay = 5s # Avoid email adress scanning diff --git a/data/templates/slapd/mailserver.schema b/data/templates/slapd/mailserver.ldif similarity index 79% rename from data/templates/slapd/mailserver.schema rename to data/templates/slapd/mailserver.ldif index 23d0d24bd..849d1d9e1 100644 --- a/data/templates/slapd/mailserver.schema +++ b/data/templates/slapd/mailserver.ldif @@ -2,58 +2,62 @@ ## Version 0.1 ## Adrien Beudin +dn: cn=mailserver,cn=schema,cn=config +objectClass: olcSchemaConfig +cn: mailserver +# # Attributes -attributetype ( 1.3.6.1.4.1.40328.1.20.2.1 +olcAttributeTypes: ( 1.3.6.1.4.1.40328.1.20.2.1 NAME 'maildrop' DESC 'Mail addresses where mails are forwarded -- ie forwards' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{512}) - -attributetype ( 1.3.6.1.4.1.40328.1.20.2.2 +# +olcAttributeTypes: ( 1.3.6.1.4.1.40328.1.20.2.2 NAME 'mailalias' DESC 'Mail addresses accepted by this account -- ie aliases' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{512}) - -attributetype ( 1.3.6.1.4.1.40328.1.20.2.3 +# +olcAttributeTypes: ( 1.3.6.1.4.1.40328.1.20.2.3 NAME 'mailenable' DESC 'Mail Account validity' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{8}) - -attributetype ( 1.3.6.1.4.1.40328.1.20.2.4 +# +olcAttributeTypes: ( 1.3.6.1.4.1.40328.1.20.2.4 NAME 'mailbox' DESC 'Mailbox path where mails are delivered' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{512}) - -attributetype ( 1.3.6.1.4.1.40328.1.20.2.5 +# +olcAttributeTypes: ( 1.3.6.1.4.1.40328.1.20.2.5 NAME 'virtualdomain' DESC 'A mail domain name' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{512}) - -attributetype ( 1.3.6.1.4.1.40328.1.20.2.6 +# +olcAttributeTypes: ( 1.3.6.1.4.1.40328.1.20.2.6 NAME 'virtualdomaindescription' DESC 'Virtual domain description' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{512}) - -attributetype ( 1.3.6.1.4.1.40328.1.20.2.7 +# +olcAttributeTypes: ( 1.3.6.1.4.1.40328.1.20.2.7 NAME 'mailuserquota' DESC 'Mailbox quota for a user' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{16} SINGLE-VALUE ) - +# # Mail Account Objectclass -objectclass ( 1.3.6.1.4.1.40328.1.1.2.1 +olcObjectClasses: ( 1.3.6.1.4.1.40328.1.1.2.1 NAME 'mailAccount' DESC 'Mail Account' SUP top @@ -65,9 +69,9 @@ objectclass ( 1.3.6.1.4.1.40328.1.1.2.1 mailalias $ maildrop $ mailenable $ mailbox $ mailuserquota ) ) - +# # Mail Domain Objectclass -objectclass ( 1.3.6.1.4.1.40328.1.1.2.2 +olcObjectClasses: ( 1.3.6.1.4.1.40328.1.1.2.2 NAME 'mailDomain' DESC 'Domain mail entry' SUP top @@ -79,9 +83,9 @@ objectclass ( 1.3.6.1.4.1.40328.1.1.2.2 virtualdomaindescription $ mailuserquota ) ) - +# # Mail Group Objectclass -objectclass ( 1.3.6.1.4.1.40328.1.1.2.3 +olcObjectClasses: ( 1.3.6.1.4.1.40328.1.1.2.3 NAME 'mailGroup' SUP top AUXILIARY DESC 'Mail Group' MUST ( mail ) diff --git a/data/templates/slapd/yunohost.schema b/data/templates/slapd/permission.ldif similarity index 55% rename from data/templates/slapd/yunohost.schema rename to data/templates/slapd/permission.ldif index 7da60a20c..a97249d07 100644 --- a/data/templates/slapd/yunohost.schema +++ b/data/templates/slapd/permission.ldif @@ -1,33 +1,35 @@ -#dn: cn=yunohost,cn=schema,cn=config -#objectClass: olcSchemaConfig -#cn: yunohost +# Yunohost schema for group and permission support + +dn: cn=yunohost,cn=schema,cn=config +objectClass: olcSchemaConfig +cn: yunohost # ATTRIBUTES # For Permission -attributetype ( 1.3.6.1.4.1.17953.9.1.1 NAME 'permission' +olcAttributeTypes: ( 1.3.6.1.4.1.17953.9.1.1 NAME 'permission' DESC 'Yunohost permission on user and group side' SUP distinguishedName ) -attributetype ( 1.3.6.1.4.1.17953.9.1.2 NAME 'groupPermission' +olcAttributeTypes: ( 1.3.6.1.4.1.17953.9.1.2 NAME 'groupPermission' DESC 'Yunohost permission for a group on permission side' SUP distinguishedName ) -attributetype ( 1.3.6.1.4.1.17953.9.1.3 NAME 'inheritPermission' +olcAttributeTypes: ( 1.3.6.1.4.1.17953.9.1.3 NAME 'inheritPermission' DESC 'Yunohost permission for user on permission side' SUP distinguishedName ) -attributetype ( 1.3.6.1.4.1.17953.9.1.4 NAME 'URL' +olcAttributeTypes: ( 1.3.6.1.4.1.17953.9.1.4 NAME 'URL' DESC 'Yunohost application URL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) # OBJECTCLASS # For Applications -objectclass ( 1.3.6.1.4.1.17953.9.2.1 NAME 'groupOfNamesYnh' +olcObjectClasses: ( 1.3.6.1.4.1.17953.9.2.1 NAME 'groupOfNamesYnh' DESC 'Yunohost user group' SUP top AUXILIARY MAY ( member $ businessCategory $ seeAlso $ owner $ ou $ o $ permission ) ) -objectclass ( 1.3.6.1.4.1.17953.9.2.2 NAME 'permissionYnh' +olcObjectClasses: ( 1.3.6.1.4.1.17953.9.2.2 NAME 'permissionYnh' DESC 'a Yunohost application' SUP top AUXILIARY MUST cn MAY ( groupPermission $ inheritPermission $ URL ) ) # For User -objectclass ( 1.3.6.1.4.1.17953.9.2.3 NAME 'userPermissionYnh' +olcObjectClasses: ( 1.3.6.1.4.1.17953.9.2.3 NAME 'userPermissionYnh' DESC 'a Yunohost application' SUP top AUXILIARY MAY ( permission ) ) diff --git a/data/templates/slapd/slapd.conf b/data/templates/slapd/slapd.conf deleted file mode 100644 index 0750b43aa..000000000 --- a/data/templates/slapd/slapd.conf +++ /dev/null @@ -1,154 +0,0 @@ -# This is the main slapd configuration file. See slapd.conf(5) for more -# info on the configuration options. - -####################################################################### -# Global Directives: - -# Features to permit -#allow bind_v2 - -# Schema and objectClass definitions -include /etc/ldap/schema/core.schema -include /etc/ldap/schema/cosine.schema -include /etc/ldap/schema/nis.schema -include /etc/ldap/schema/inetorgperson.schema -include /etc/ldap/schema/mailserver.schema -include /etc/ldap/schema/sudo.schema -include /etc/ldap/schema/yunohost.schema - -# Where the pid file is put. The init.d script -# will not stop the server if you change this. -pidfile /var/run/slapd/slapd.pid - -# List of arguments that were passed to the server -argsfile /var/run/slapd/slapd.args - -# Read slapd.conf(5) for possible values -loglevel none - -# Hashes to be used in generation of user passwords -password-hash {SSHA} - -# Where the dynamically loaded modules are stored -modulepath /usr/lib/ldap -moduleload back_mdb -moduleload memberof - -# The maximum number of entries that is returned for a search operation -sizelimit 500 - -# The tool-threads parameter sets the actual amount of cpu's that is used -# for indexing. -tool-threads 1 - -# TLS Support -TLSCertificateFile /etc/yunohost/certs/yunohost.org/crt.pem -TLSCertificateKeyFile /etc/yunohost/certs/yunohost.org/key.pem - -####################################################################### -# Specific Backend Directives for mdb: -# Backend specific directives apply to this backend until another -# 'backend' directive occurs -backend mdb - -####################################################################### -# Specific Directives for database #1, of type mdb: -# Database specific directives apply to this databasse until another -# 'database' directive occurs -database mdb - -# The base of your directory in database #1 -suffix "dc=yunohost,dc=org" - -# rootdn directive for specifying a superuser on the database. This is needed -# for syncrepl. -# rootdn "cn=admin,dc=yunohost,dc=org" - -# Where the database file are physically stored for database #1 -directory "/var/lib/ldap" - -# Indexing options for database #1 -index objectClass eq -index uid,sudoUser eq,sub -index entryCSN,entryUUID eq -index cn,mail eq -index gidNumber,uidNumber eq -index member,memberUid,uniqueMember eq -index virtualdomain eq -index permission eq - -# Save the time that the entry gets modified, for database #1 -lastmod on - -# Checkpoint the BerkeleyDB database periodically in case of system -# failure and to speed slapd shutdown. -checkpoint 512 30 - -# The userPassword by default can be changed -# by the entry owning it if they are authenticated. -# Others should not be able to see it, except the -# admin entry below -# These access lines apply to database #1 only -access to attrs=userPassword,shadowLastChange - by dn="cn=admin,dc=yunohost,dc=org" write - by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write - by anonymous auth - by self write - by * none - -# Personnal information can be changed by the entry -# owning it if they are authenticated. -# Others should be able to see it. -access to attrs=cn,gecos,givenName,mail,maildrop,displayName,sn - by dn="cn=admin,dc=yunohost,dc=org" write - by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write - by self write - by * read - -# Ensure read access to the base for things like -# supportedSASLMechanisms. Without this you may -# have problems with SASL not knowing what -# mechanisms are available and the like. -# Note that this is covered by the 'access to *' -# ACL below too but if you change that as people -# are wont to do you'll still need this if you -# want SASL (and possible other things) to work -# happily. -access to dn.base="" by * read - -# The admin dn has full write access, everyone else -# can read everything. -access to * - by dn="cn=admin,dc=yunohost,dc=org" write - by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write - by group/groupOfNames/Member="cn=admin,ou=groups,dc=yunohost,dc=org" write - by * read - -# Configure Memberof Overlay (used for Yunohost permission) - -# Link user <-> group -#dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config -overlay memberof -memberof-group-oc groupOfNamesYnh -memberof-member-ad member -memberof-memberof-ad memberOf -memberof-dangling error -memberof-refint TRUE - -# Link permission <-> groupes -#dn: olcOverlay={1}memberof,olcDatabase={1}mdb,cn=config -overlay memberof -memberof-group-oc permissionYnh -memberof-member-ad groupPermission -memberof-memberof-ad permission -memberof-dangling error -memberof-refint TRUE - -# Link permission <-> user -#dn: olcOverlay={2}memberof,olcDatabase={1}mdb,cn=config -overlay memberof -memberof-group-oc permissionYnh -memberof-member-ad inheritPermission -memberof-memberof-ad permission -memberof-dangling error -memberof-refint TRUE diff --git a/data/templates/slapd/slapd.ldif b/data/templates/slapd/slapd.ldif new file mode 100644 index 000000000..d3ed2e053 --- /dev/null +++ b/data/templates/slapd/slapd.ldif @@ -0,0 +1,235 @@ +# OpenLDAP server configuration for Yunohost +# ------------------------------------------ +# +# Because of the Yunohost's regen-conf mechanism, it is NOT POSSIBLE to +# edit the config database using an LDAP request. +# +# If you wish to edit the config database, you should edit THIS file +# and update the config database based on this file. +# +# Config database customization: +# 1. Edit this file as you want. +# 2. Apply your modifications. For this just run this following command in a shell: +# $ /usr/share/yunohost/hooks/conf_regen/06-slapd apply_config +# +# Note that if you customize this file, YunoHost's regen-conf will NOT +# overwrite this file. But that also means that you should be careful about +# upgrades, because they may ship important/necessary changes to this +# configuration that you will have to propagate yourself. + +# +# Main configuration +# +dn: cn=config +objectClass: olcGlobal +cn: config +olcConfigFile: /etc/ldap/slapd.conf +olcConfigDir: /etc/ldap/slapd.d/ +# List of arguments that were passed to the server +olcArgsFile: /var/run/slapd/slapd.args +# +olcAttributeOptions: lang- +olcAuthzPolicy: none +olcConcurrency: 0 +olcConnMaxPending: 100 +olcConnMaxPendingAuth: 1000 +olcIdleTimeout: 0 +olcIndexSubstrIfMaxLen: 4 +olcIndexSubstrIfMinLen: 2 +olcIndexSubstrAnyLen: 4 +olcIndexSubstrAnyStep: 2 +olcIndexIntLen: 4 +olcListenerThreads: 1 +olcLocalSSF: 71 +# Read slapd.conf(5) for possible values +olcLogLevel: None +# Where the pid file is put. The init.d script +# will not stop the server if you change this. +olcPidFile: /var/run/slapd/slapd.pid +olcReverseLookup: FALSE +olcThreads: 16 +# TLS Support +olcTLSCertificateFile: /etc/yunohost/certs/yunohost.org/crt.pem +olcTLSCertificateKeyFile: /etc/yunohost/certs/yunohost.org/key.pem +olcTLSVerifyClient: never +olcTLSProtocolMin: 0.0 +# The tool-threads parameter sets the actual amount of cpu's that is used +# for indexing. +olcToolThreads: 1 +structuralObjectClass: olcGlobal + +# +# Schema and objectClass definitions +# +dn: cn=schema,cn=config +objectClass: olcSchemaConfig +cn: schema + +include: file:///etc/ldap/schema/core.ldif +include: file:///etc/ldap/schema/cosine.ldif +include: file:///etc/ldap/schema/nis.ldif +include: file:///etc/ldap/schema/inetorgperson.ldif +include: file:///etc/ldap/schema/mailserver.ldif +include: file:///etc/ldap/schema/sudo.ldif +include: file:///etc/ldap/schema/permission.ldif + +# +# Module management +# +dn: cn=module{0},cn=config +objectClass: olcModuleList +cn: module{0} +# Where the dynamically loaded modules are stored +olcModulePath: /usr/lib/ldap +olcModuleLoad: {0}back_mdb +olcModuleLoad: {1}memberof +structuralObjectClass: olcModuleList + +# +# Frontend database +# +dn: olcDatabase={-1}frontend,cn=config +objectClass: olcDatabaseConfig +objectClass: olcFrontendConfig +olcDatabase: {-1}frontend +olcAddContentAcl: FALSE +olcLastMod: TRUE +olcSchemaDN: cn=Subschema +# Hashes to be used in generation of user passwords +olcPasswordHash: {SSHA} +structuralObjectClass: olcDatabaseConfig + +# +# Config database Configuration (#0) +# +dn: olcDatabase={0}config,cn=config +objectClass: olcDatabaseConfig +olcDatabase: {0}config +# Give access to root user. +# This give the possiblity to the admin to customize the LDAP configuration +olcAccess: {0}to * by * none +olcAddContentAcl: TRUE +olcLastMod: TRUE +olcRootDN: cn=config +structuralObjectClass: olcDatabaseConfig + +# +# Main database Configuration (#1) +# +dn: olcDatabase={1}mdb,cn=config +objectClass: olcDatabaseConfig +objectClass: olcMdbConfig +olcDatabase: {1}mdb +# The base of your directory in database #1 +olcSuffix: dc=yunohost,dc=org +# +# The userPassword by default can be changed +# by the entry owning it if they are authenticated. +# Others should not be able to see it, except the +# admin entry below +# These access lines apply to database #1 only +olcAccess: {0}to attrs=userPassword,shadowLastChange + by dn.base="cn=admin,dc=yunohost,dc=org" write + by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write + by anonymous auth + by self write + by * none +# +# Personnal information can be changed by the entry +# owning it if they are authenticated. +# Others should be able to see it. +olcAccess: {1}to attrs=cn,gecos,givenName,mail,maildrop,displayName,sn + by dn.base="cn=admin,dc=yunohost,dc=org" write + by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write + by self write + by * read +# +# Ensure read access to the base for things like +# supportedSASLMechanisms. Without this you may +# have problems with SASL not knowing what +# mechanisms are available and the like. +# Note that this is covered by the 'access to *' +# ACL below too but if you change that as people +# are wont to do you'll still need this if you +# want SASL (and possible other things) to work +# happily. +olcAccess: {2}to dn.base="" + by * read +# +# The admin dn has full write access, everyone else +# can read everything. +olcAccess: {3}to * + by dn.base="cn=admin,dc=yunohost,dc=org" write + by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write + by group/groupOfNames/member.exact="cn=admin,ou=groups,dc=yunohost,dc=org" write + by * read +# +olcAddContentAcl: FALSE +# Save the time that the entry gets modified, for database #1 +olcLastMod: TRUE +# Where the database file are physically stored for database #1 +olcDbDirectory: /var/lib/ldap +# Checkpoint the BerkeleyDB database periodically in case of system +# failure and to speed slapd shutdown. +olcDbCheckpoint: 512 30 +olcDbNoSync: FALSE +# Indexing options for database #1 +olcDbIndex: objectClass eq +olcDbIndex: entryUUID eq +olcDbIndex: entryCSN eq +olcDbIndex: cn eq +olcDbIndex: uid eq,sub +olcDbIndex: uidNumber eq +olcDbIndex: gidNumber eq +olcDbIndex: sudoUser eq,sub +olcDbIndex: member eq +olcDbIndex: mail eq +olcDbIndex: memberUid eq +olcDbIndex: uniqueMember eq +olcDbIndex: virtualdomain eq +olcDbIndex: permission eq +olcDbMaxSize: 10485760 +structuralObjectClass: olcMdbConfig + +# +# Configure Memberof Overlay (used for Yunohost permission) +# + +# Link user <-> group +dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config +objectClass: olcOverlayConfig +objectClass: olcMemberOf +olcOverlay: {0}memberof +olcMemberOfDangling: error +olcMemberOfDanglingError: constraintViolation +olcMemberOfRefInt: TRUE +olcMemberOfGroupOC: groupOfNamesYnh +olcMemberOfMemberAD: member +olcMemberOfMemberOfAD: memberOf +structuralObjectClass: olcMemberOf + +# Link permission <-> groupes +dn: olcOverlay={1}memberof,olcDatabase={1}mdb,cn=config +objectClass: olcOverlayConfig +objectClass: olcMemberOf +olcOverlay: {1}memberof +olcMemberOfDangling: error +olcMemberOfDanglingError: constraintViolation +olcMemberOfRefInt: TRUE +olcMemberOfGroupOC: permissionYnh +olcMemberOfMemberAD: groupPermission +olcMemberOfMemberOfAD: permission +structuralObjectClass: olcMemberOf + +# Link permission <-> user +dn: olcOverlay={2}memberof,olcDatabase={1}mdb,cn=config +objectClass: olcOverlayConfig +objectClass: olcMemberOf +olcOverlay: {2}memberof +olcMemberOfDangling: error +olcMemberOfDanglingError: constraintViolation +olcMemberOfRefInt: TRUE +olcMemberOfGroupOC: permissionYnh +olcMemberOfMemberAD: inheritPermission +olcMemberOfMemberOfAD: permission +structuralObjectClass: olcMemberOf diff --git a/data/templates/slapd/sudo.schema b/data/templates/slapd/sudo.ldif similarity index 72% rename from data/templates/slapd/sudo.schema rename to data/templates/slapd/sudo.ldif index d3e95e00c..a7088c855 100644 --- a/data/templates/slapd/sudo.schema +++ b/data/templates/slapd/sudo.ldif @@ -1,76 +1,78 @@ # # OpenLDAP schema file for Sudo -# Save as /etc/openldap/schema/sudo.schema +# Save as /etc/openldap/schema/sudo.ldif # -attributetype ( 1.3.6.1.4.1.15953.9.1.1 +dn: cn=sudo,cn=schema,cn=config +objectClass: olcSchemaConfig +cn: sudo +olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) - -attributetype ( 1.3.6.1.4.1.15953.9.1.2 +# +olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.2 NAME 'sudoHost' DESC 'Host(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) - -attributetype ( 1.3.6.1.4.1.15953.9.1.3 +# +olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.3 NAME 'sudoCommand' DESC 'Command(s) to be executed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) - -attributetype ( 1.3.6.1.4.1.15953.9.1.4 +# +olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.4 NAME 'sudoRunAs' DESC 'User(s) impersonated by sudo (deprecated)' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) - -attributetype ( 1.3.6.1.4.1.15953.9.1.5 +# +olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.5 NAME 'sudoOption' DESC 'Options(s) followed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) - -attributetype ( 1.3.6.1.4.1.15953.9.1.6 +# +olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'User(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) - -attributetype ( 1.3.6.1.4.1.15953.9.1.7 +# +olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC 'Group(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) - -attributetype ( 1.3.6.1.4.1.15953.9.1.8 +# +olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.8 NAME 'sudoNotBefore' DESC 'Start of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 ) - -attributetype ( 1.3.6.1.4.1.15953.9.1.9 +# +olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.9 NAME 'sudoNotAfter' DESC 'End of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 ) - -attributeTypes ( 1.3.6.1.4.1.15953.9.1.10 +# +olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.10 NAME 'sudoOrder' DESC 'an integer to order the sudoRole entries' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ) - -objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL +# +olcObjectClasses: ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL DESC 'Sudoer Entries' MUST ( cn ) - MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoOrder $ sudoNotBefore $ sudoNotAfter $ - description ) + MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoOrder $ sudoNotBefore $ sudoNotAfter $ description ) ) diff --git a/data/templates/ssh/sshd_config b/data/templates/ssh/sshd_config index 8dc0e8dfc..bd3efdef3 100644 --- a/data/templates/ssh/sshd_config +++ b/data/templates/ssh/sshd_config @@ -27,9 +27,6 @@ HostKey {{ key }}{% endfor %} MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com {% endif %} -# Use kernel sandbox mechanisms where possible in unprivileged processes -UsePrivilegeSeparation sandbox - # LogLevel VERBOSE logs user's key fingerprint on login. # Needed to have a clear audit track of which key was using to log in. SyslogFacility AUTH diff --git a/data/templates/unattended/02periodic b/data/templates/unattended/02periodic deleted file mode 100644 index f16105466..000000000 --- a/data/templates/unattended/02periodic +++ /dev/null @@ -1,5 +0,0 @@ -# https://wiki.debian.org/UnattendedUpgrades#automatic_call_via_.2Fetc.2Fapt.2Fapt.conf.d.2F02periodic -APT::Periodic::Enable "1"; -APT::Periodic::Update-Package-Lists "1"; -APT::Periodic::Unattended-Upgrade "1"; -APT::Periodic::Verbose "1"; diff --git a/data/templates/unattended/50unattended-upgrades b/data/templates/unattended/50unattended-upgrades deleted file mode 100644 index 49b600a3b..000000000 --- a/data/templates/unattended/50unattended-upgrades +++ /dev/null @@ -1,36 +0,0 @@ -// Automatically upgrade packages from these (origin, archive) pairs -Unattended-Upgrade::Allowed-Origins { - "${distro_id} stable"; - "${distro_id} testing"; - "Depot-Debian testing"; - "${distro_id} ${distro_codename}-security"; - "${distro_id} ${distro_codename}-updates"; -// "${distro_id} ${distro_codename}-proposed-updates"; -}; - -// List of packages to not update -Unattended-Upgrade::Package-Blacklist { -// "vim"; -// "libc6"; -// "libc6-dev"; -// "libc6-i686"; -}; - -// Send email to this address for problems or packages upgrades -// If empty or unset then no email is sent, make sure that you -// have a working mail setup on your system. The package 'mailx' -// must be installed or anything that provides /usr/bin/mail. -//Unattended-Upgrade::Mail "root@localhost"; - -// Do automatic removal of new unused dependencies after the upgrade -// (equivalent to apt-get autoremove) -Unattended-Upgrade::Remove-Unused-Dependencies "true"; - -// Automatically reboot *WITHOUT CONFIRMATION* if a -// the file /var/run/reboot-required is found after the upgrade -Unattended-Upgrade::Automatic-Reboot "false"; - - -// Use apt bandwidth limit feature, this example limits the download -// speed to 70kb/sec -//Acquire::http::Dl-Limit "70"; diff --git a/data/templates/yunohost/services.yml b/data/templates/yunohost/services.yml index e1dd57e55..73ae9403e 100644 --- a/data/templates/yunohost/services.yml +++ b/data/templates/yunohost/services.yml @@ -20,10 +20,9 @@ nginx: test_conf: nginx -t needs_exposed_ports: [80, 443] category: web -nslcd: {} -php7.0-fpm: - log: /var/log/php7.0-fpm.log - test_conf: php-fpm7.0 --test +php7.3-fpm: + log: /var/log/php7.3-fpm.log + test_conf: php-fpm7.3 --test category: web postfix: log: [/var/log/mail.log,/var/log/mail.err] @@ -64,3 +63,5 @@ postgrey: null spamassassin: null rmilter: null php5-fpm: null +php7.0-fpm: null +nslcd: null diff --git a/debian/changelog b/debian/changelog index c119d57e7..0fc8ef27b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,260 @@ +yunohost (4.0.4) stable; urgency=low + + - Debugging and robustness improvements for postgresql 9.6 -> 11 and xtables->nftables migrations (accc2da4, 59bd7d66, 4cb6f7fd, 4b14402c) + + -- Alexandre Aubin Wed, 12 Aug 2020 18:14:00 +0200 + +yunohost (4.0.3) stable; urgency=low + + - Bump version number for stable release + + -- Alexandre Aubin Wed, 29 Jul 2020 17:00:00 +0200 + +yunohost (4.0.2~beta) testing; urgency=low + + - [mod] Rebase on stretch-unstable to include recent changes + - [fix] Create admin's home during postinstall (#1021) + + Thanks to all contributors <3 ! (Kay0u) + + -- Alexandre Aubin Fri, 19 Jun 2020 15:16:26 +0200 + +yunohost (4.0.1~alpha) testing; urgency=low + + - [fix] It just make no sense to backup/restore the mysql password... (#911) + - [fix] Fix getopts and helpers (#885, #886) + - [fix] Explicitly create home using mkhomedir_helper instead of obscure pam rule that doesn't work anymore (b67ff314) + - [fix] Ldap interface seems to expect lists everywhere now? (fb8c2b7b) + - [deb] Clean control file, remove some legacy Conflicts and Replaces (ca0d4933) + - [deb] Add conflicts with versions from backports for critical dependencies (#967) + - [cleanup] Stale / legacy code (217aaa36, d77da6a0, af047468, 82d468a3) + - [conf] Automatically disable/stop systemd-resolved that conflicts with dnsmasq on fresh setups ... (e7214b37) + - [conf] Remove deprecated option in sshd conf, c.f. https://patchwork.openembedded.org/patch/139981/ (2723d245) + - [conf] Small tweak in dovecot conf (deprecated settings) (dc0481e2) + - [conf] Update nslcd and nsswitch stuff using new Buster's default configs + get rid of nslcd service, only keep the regen-conf part (6ef3520f) + - [php] Migrate from php7.0 to php7.3 (3374e653, 9be10506, dd9564d3, 9679c291, 212a15e4, 25fcaa19, c4ad66f5) + - [psql] Migrate from psql 11 to 9.6 (e88aed72, 4920d4f9, c70b0ae4) + - [firewall] Migrate from xtable to nftable (05fb58f2, 2c4a8b73, 625d5372) + - [slapd] Rework slapd regenconf to use new backend (#984) + + Thanks to all contributors <3 ! (Étienne M., Josué, Kay0u) + + -- Alexandre Aubin Fri, 05 Jun 2020 03:10:09 +0200 + +yunohost (3.8.5.5) stable; urgency=low + + - [enh] Allow to extend the nginx default_server configuration (f1bfc521) + - [mod] Move redirect to /yunohost/admin to a separate nginx conf file to allow customizing it more easily (ac9182d6) + - [enh] Make sure to validate/upgrade that we don't have any active weak certificate used by nginx at the beginning of the buster migration, otherwise nginx will later miserably fail to start (d4358897) + - [fix] get_files_diff crashing if {orig,new}_file is None (7bfe564a) + - [enh] Remove some useless message about file that "wasn't deleted because it doesn't exist." (#1024) + - [mod] Remove useless robot protection code (#1026) + - [fix] Let's not redefine the value for the 'service' var ... (1a2f26dc) + - [fix] More general stretch->buster patching for sources.list (#1028) + - [mod] Tweak custom disclaimer about the migration still being a bit touchy in preparation for stable release (852dea07) + - [mod] Typo/wording in en.json (#1030) + - [i18n] Translations updated for Catalan, French, Italian, Occitan + + Thanks to all contributors <3 ! (É. Gaspar, Kay0u, L. Noferini, ppr, Quentí, xaloc33) + + -- Alexandre Aubin Mon, 27 Jul 2020 19:03:33 +0200 + +yunohost (3.8.5.4) testing; urgency=low + + - [fix] Fix unscd version parsing *again* + - [fix] Enforce permissions on rspamd log directory + - [enh] Ignore stupid warnings about sudo-ldap that is already provided + + -- Alexandre Aubin Sun, 21 Jun 2020 23:37:09 +0200 + +yunohost (3.8.5.3) testing; urgency=low + + - [fix] Fix the fix about unscd downgrade :/ + + -- Alexandre Aubin Fri, 19 Jun 2020 18:50:58 +0200 + +yunohost (3.8.5.2) testing; urgency=low + + - [fix] Small issue with unscd upgrade/downgrade ... new version ain't always 0.53.1, so find it using dirty scrapping + + -- Alexandre Aubin Thu, 18 Jun 2020 16:19:35 +0200 + +yunohost (3.8.5.1) testing; urgency=low + + - [fix] Update Stretch->Buster migration disclaimer to make it clear that this is alpha-stage + + -- Alexandre Aubin Sat, 06 Jun 2020 03:30:00 +0200 + +yunohost (3.8.5) testing; urgency=low + + - [enh] Add migration procedure for Stretch->Buster (a2b83c0f, a26411db, 9f1211e9, e544bf3e, a0511cca) + - [fix] Disable/skip ntp when inside a container (9d0c0924) + + -- Alexandre Aubin Sat, 06 Jun 2020 02:11:51 +0200 + +yunohost (3.8.4.9) stable; urgency=low + + - [fix] Force lowercase on domain names (804f4b3e) + - [fix] Add dirmngr to Depends:, needed for apt-key / gpg (cd115ed8) + - [fix] Improve debugging when diagnosis ain't happy when renewing certs (0f0194be) + - [enh] Add yunohost version to logs metadata (d615546b) + - [enh] Alway filter irrelevant log lines when sharing it (38704cba, 51d53be5) + - [fix] Regen-conf outputing many 'forget-about-it' because of files flagged as to be removed (f4525488) + - [fix] postfix per-domain destination concurrency (#988) + - [fix] Call regenconf for ssh before the general regenconf during the postinstall to avoid an irrelevant warning (7805837b) + - [i18n] Translations updated for Catalan, French, German + + Thanks to all contributors <3 ! (taziden, ljf, ppr, xaloc33, Yasss Gurl) + + -- Alexandre Aubin Thu, 18 Jun 2020 15:13:01 +0200 + +yunohost (3.8.4.8) stable; urgency=low + + - [fix] Don't add unprotected_urls if it's already in skipped_urls (#1005) + - [enh] Add pre-defined DHE group and set up Nginx to use it (#1007) + - [fix] Make sure to propagate change in slapd systemd conf during initial install (2d42480f) + - [fix] More accurate grep to avoid mistakenly grepping commented lines... (2408a620) + - [enh] Update n to 6.5.1 (#1012) + - [fix] Set sury default pinning to 600 (653c5fde) + - [enh] Clean stale file/hashes in regen-conf (#1009) + - [fix] Weirdness in regen-conf mechanism for SSH conf (#1014) + + Thanks to all contributors <3 ! (É. Gaspar, Josué, SohKa) + + -- Alexandre Aubin Sat, 06 Jun 2020 01:59:08 +0200 + +yunohost (3.8.4.7) stable; urgency=low + + - [fix] Remove some remains of glances (17eec25e) + - [fix] Force external resolution for reverse DNS dig (852cd14c) + - [fix] Make sure mysql is an alias to mariadb (e24191ce, ca89607d) + - [fix] Path for ynh_add_fpm_config template in restore (#1001) + - [fix] Add -o Acquire::Retries=3 to fix some stupid network issues happening sometimes with apt (03432349) + - [fix] ynh_setup_source: Retry wget on non-critical failures to try to avoid tmp dns issues (3d66eaec) + - [fix] ynh_setup_source: Calling ynh_print_err in case of error didn't work, and we probably want a ynh_die here (55036fad) + - [i18n] Translations updated for Catalan, French, Italian, Occitan + + Thanks to all contributors <3 ! (JimboJoe, Leandro N., ppr, Quentí, xaloc33, yalh76) + + -- Alexandre Aubin Thu, 04 Jun 2020 02:28:33 +0200 + +yunohost (3.8.4.6) stable; urgency=low + + - [fix] Bump server_names_hash_bucket_size to 128 to avoid nginx exploding for stupid reasons (b3db4d92) + - [fix] More sensible strategy for sury pinning (#1006) + - [fix] Stop trying to fetch log categories that are not implemented yet T.T (77bd9ae3) + - [enh] Add logging and persistent as default config for new muc room (#1008) + - [tests] Moar tests for app args parsing (#1004) + + Thanks to all contributors <3 ! (Gabriel, Kay0u, Bram) + + -- Alexandre Aubin Thu, 28 May 2020 00:22:10 +0200 + +yunohost (3.8.4.5) stable; urgency=low + + - [enh] Tell systemctl to stfu about creating symlinks when enabling/disabling services (6637c8a8) + - [enh] Add maindomain in diagnosis email subject (e30e25fa) + - [fix] Webpath should also be normalized for args_list, so that we can get rid of the 'malformed path' check of the CI... (58ce6e5e) + - [fix] Increase time window for auto diagnosis cron to avoid remote diagnosis server overload (dc221495) + - [fix] encoding bullshit (4c600125, 64596bc1) + - [fix] Typo in diagnosis message + fix FR translation report format of bad DNS conf (#1002, b8f8ea14) + - [fix] Flag old etckeeper.conf as 'should not exist' in regenconf (5a3b382f) + - [enh] Detect dyndns-domains managed by yunohost and advice to use yunohost dyndns update --force (8b169f13) + - [enh] Complain if apps savagely edit system configurations during install and upgrade (a23f02db) + - [i18n] Translations updated for Arabic, Catalan, French, German, Italian + - [tests] CI V2 : Rework CI workflow (#991) + + Thanks to all contributors <3 ! (ButterflyOfFire, Kay0u, L. Noferini, rynas, V. Rubiolo, xaloc33, Yasss Gurl) + + -- Alexandre Aubin Tue, 26 May 2020 03:20:39 +0200 + +yunohost (3.8.4.4) stable; urgency=low + + - [fix] Crash when the services file is empty (85f1802) + - [fix] IPv6 detection when using wg-quick (#997) + - [fix] Use a .get() to avoid crash if key doesn't exist (1f1b2338) + - [enh] Don't display the hostname when calling journalctl, this takes horizontal space for nothing (2bcfb5a1) + - [fix] Add --quiet, otherwise getopts is confused by "-- Logs" at the beginning (bdbf1822) + - [mod] We don't need those color codes... and warnings are already warnings... (2a631fa2) + - [fix] psql_setup_db: Do not create a new password if the user already exists (#998) + - [enh] Add an exception if packaging format is not recognized (f0cc6798) + + Thanks to all contributors <3 ! (Aleks, Julien Rabier, Kayou) + + -- Kay0u Fri, 22 May 2020 19:26:05 +0000 + +yunohost (3.8.4.3) stable; urgency=low + + - [fix] Workaround for the sury pinning issues when installing dependencies + - [i18n] Translations updated for Catalan, French, Occitan + + Thanks to all contributors <3 ! (Aleks, clecle226, Kay0u, ppr, Quenti) + + -- Kay0u Wed, 20 May 2020 18:41:49 +0000 + +yunohost (3.8.4.2) testing; urgency=low + + - [enh] During failed upgrades: Only mention packages that couldn't be upgraded (26fcfed7) + - [enh] Also run dpkg --audit to check if dpkg is in a broken state (09d8500f, 97199d19) + - [enh] Improve logs readability (c6f18496, 9cbd368d, 5850bf61, 413778d2, 5c8c07b8, f73c34bf, 94ea8265) + - [enh] Crash early about apps already installed when attempting to restore (f9e4c96c) + - [fix] Add the damn short hostname to /etc/hosts automagically (c.f. rabbitmq-server) (e67dc791) + - [fix] Don't miserably crash if doveadm fails to run (c9b22138) + - [fix] Diagnosis: Try to not have weird warnings if no diagnosis ran yet... (65c87d55) + - [fix] Diagnosis: Change logic of --email to avoid sending empty mail if some issues are found but ignored (4cd4938e) + - [enh] Diagnosis/services: Report the service status as warning/unknown if service type is oneshot and status exited (dd09758f, 1cd7ffea) + - [fix] Rework ynh_psql_test_if_first_run (#993) + - [tests] Tests for args parsing (#989, 108a3ca4) + + Thanks to all contributors <3 ! (Bram, Kayou) + + -- Alexandre Aubin Tue, 19 May 2020 20:08:47 +0200 + +yunohost (3.8.4.1) testing; urgency=low + + - [mod] Tweak diagnosis threshold for swap warning (429df8c4) + - [fix] Make sure we have a list for log_list + make sure item is in list before using .remove()... (afbeb145, 43facfd5) + - [fix] Sometimes tree-model has a weird \x00 which breaks yunopaste (c346f5f1) + + -- Alexandre Aubin Mon, 11 May 2020 00:50:34 +0200 + +yunohost (3.8.4) testing; urgency=low + + - [fix] Restoration of custom hooks / missing restore hooks (#927) + - [enh] Real CSP headers for the webadmin (#961) + - [enh] Simplify / optimize reading version of yunohost packages... (#968) + - [fix] handle new auto restart of ldap in moulinette (#975) + - [enh] service.py cleanup + add tests for services (#979, #986) + - [fix] Enforce permissions for stuff in /etc/yunohost/ (#963) + - [mod] Remove security diagnosis category for now, Move meltdown check to base system (a799740a) + - [mod] Change warning/errors about swap as info instead ... add a tip about the fact that having swap on SD or SSD is dangerous (23147161) + - [enh] Improve auto diagnosis cron UX, add a --human-readable option to diagnosis_show() (aecbb14a) + - [enh] Rely on new diagnosis for letsencrypt elligibility (#985) + - [i18n] Translations updated for Catalan, Esperanto, French, Spanish + + Thanks to all contributors <3 ! (amirale qt, autra, Bram, clecle226, I. Hernández, Kay0u, xaloc33) + + -- Alexandre Aubin Sat, 09 May 2020 21:20:00 +0200 + +yunohost (3.8.3) testing; urgency=low + + - [fix] Remove dot in reverse DNS check + - [fix] Upgrade of multi-instance apps was broken (#976) + - [fix] Check was broken if an apps with no domain setting was installed (#978) + - [enh] Add a timeout to wget (#972) + - [fix] ynh_get_ram: Enforce choosing --free or --total (#972) + - [fix] Simplify / improve robustness of backup list + - [enh] Make nodejs helpers easier to use (#939) + - [fix] Misc tweak for disk usage diagnosis, some values were inconsistent / bad UX / ... + - [enh] Assert slapd is running to avoid miserably crashing with weird ldap errors + - [enh] Try to show smarter / more useful logs by filtering irrelevant lines like set +x etc + - Technical tweaks for metronome 3.14.0 support + - Misc improvements for tests and linters + + Thanks to all contributors <3 ! (Bram, Kay0u, Maniack C., ljf, Maranda) + + -- Alexandre Aubin Thu, 07 Apr 2020 04:00:00 +0000 + yunohost (3.8.2.2) testing; urgency=low Aleks broke everything /again/ *.* @@ -1626,7 +1883,7 @@ yunohost (2.5.2) testing; urgency=low Other fixes and improvements: * [enh] remove timeout from cli interface - * [fix] [#662](https://dev.yunohost.org/issues/662): missing 'python-openssl' dependency for Let's Encrypt integration. + * [fix] #662: missing 'python-openssl' dependency for Let's Encrypt integration. * [fix] --no-remove-on-failure for app install should behave as a flag. * [fix] don't remove trailing char if it's not a slash diff --git a/debian/conf/pam/mkhomedir b/debian/conf/pam/mkhomedir deleted file mode 100644 index eedc8b745..000000000 --- a/debian/conf/pam/mkhomedir +++ /dev/null @@ -1,6 +0,0 @@ -Name: Create home directory during login -Default: yes -Priority: 900 -Session-Type: Additional -Session: - required pam_mkhomedir.so umask=0022 skel=/etc/skel diff --git a/debian/control b/debian/control index 5061ad4f2..1f2c24678 100644 --- a/debian/control +++ b/debian/control @@ -11,12 +11,11 @@ Package: yunohost Essential: yes Architecture: all Depends: ${python:Depends}, ${misc:Depends} - , moulinette (>= 3.7), ssowat (>= 3.7) + , moulinette (>= 4.0.0~alpha), ssowat (>= 4.0.0~alpha) , python-psutil, python-requests, python-dnspython, python-openssl - , python-apt, python-miniupnpc, python-dbus, python-jinja2 - , python-toml - , apt, apt-transport-https - , nginx, nginx-extras (>=1.6.2) + , python-miniupnpc, python-dbus, python-jinja2 + , python-toml, python-packaging, python-publicsuffix + , apt, apt-transport-https, dirmngr , php-fpm, php-ldap, php-intl , mariadb-server, php-mysql | php-mysqlnd , openssh-server, iptables, fail2ban, dnsutils, bind9utils @@ -25,31 +24,29 @@ Depends: ${python:Depends}, ${misc:Depends} , dnsmasq, avahi-daemon, libnss-mdns, resolvconf, libnss-myhostname , postfix, postfix-ldap, postfix-policyd-spf-perl, postfix-pcre , dovecot-core, dovecot-ldap, dovecot-lmtpd, dovecot-managesieved, dovecot-antispam - , rspamd (>= 1.6.0), opendkim-tools, postsrsd, procmail, mailutils + , rspamd, opendkim-tools, postsrsd, procmail, mailutils , redis-server - , metronome - , git, curl, wget, cron, unzip, jq + , metronome (>=3.14.0) + , git, curl, wget, cron, unzip, jq, bc , lsb-release, haveged, fake-hwclock, equivs, lsof, whois, python-publicsuffix Recommends: yunohost-admin , ntp, inetutils-ping | iputils-ping , bash-completion, rsyslog - , php-gd, php-curl, php-gettext, php-mcrypt + , php-gd, php-curl, php-gettext , python-pip , unattended-upgrades , libdbd-ldap-perl, libnet-dns-perl Suggests: htop, vim, rsync, acpi-support-base, udisks2 Conflicts: iptables-persistent - , moulinette-yunohost, yunohost-config - , yunohost-config-others, yunohost-config-postfix - , yunohost-config-dovecot, yunohost-config-slapd - , yunohost-config-nginx, yunohost-config-amavis - , yunohost-config-mysql, yunohost-predepends - , apache2, bind9 -Replaces: moulinette-yunohost, yunohost-config - , yunohost-config-others, yunohost-config-postfix - , yunohost-config-dovecot, yunohost-config-slapd - , yunohost-config-nginx, yunohost-config-amavis - , yunohost-config-mysql, yunohost-predepends + , apache2 + , bind9 + , nginx-extras (>= 1.16) + , openssl (>= 1.1.1g) + , slapd (>= 2.4.49) + , dovecot-core (>= 1:2.3.7) + , redis-server (>= 5:5.0.7) + , fail2ban (>= 0.11) + , iptables (>= 1.8.3) Description: manageable and configured self-hosting server YunoHost aims to make self-hosting accessible to everyone. It configures an email, Web and IM server alongside a LDAP base. It also provides diff --git a/debian/install b/debian/install index a814d1617..1691a4849 100644 --- a/debian/install +++ b/debian/install @@ -8,11 +8,11 @@ data/other/yunoprompt.service /etc/systemd/system/ data/other/password/* /usr/share/yunohost/other/password/ data/other/dpkg-origins/yunohost /etc/dpkg/origins data/other/dnsbl_list.yml /usr/share/yunohost/other/ +data/other/ffdhe2048.pem /usr/share/yunohost/other/ data/other/* /usr/share/yunohost/yunohost-config/moulinette/ data/templates/* /usr/share/yunohost/templates/ data/helpers /usr/share/yunohost/ data/helpers.d/* /usr/share/yunohost/helpers.d/ -debian/conf/pam/* /usr/share/pam-configs/ lib/metronome/modules/* /usr/lib/metronome/modules/ locales/* /usr/lib/moulinette/yunohost/locales/ src/yunohost /usr/lib/moulinette diff --git a/debian/postinst b/debian/postinst index 9c78c8432..4b43b2506 100644 --- a/debian/postinst +++ b/debian/postinst @@ -29,11 +29,6 @@ do_configure() { # Yunoprompt systemctl enable yunoprompt.service - - # remove old PAM config and update it - [[ ! -f /usr/share/pam-configs/my_mkhomedir ]] \ - || rm /usr/share/pam-configs/my_mkhomedir - pam-auth-update --package } # summary of how this script can be called: diff --git a/doc/helper_doc_template.html b/doc/helper_doc_template.html index 92611c737..f96a0190e 100644 --- a/doc/helper_doc_template.html +++ b/doc/helper_doc_template.html @@ -2,6 +2,8 @@

App helpers

+

Doc auto-generated by this script on {{data.date}} (Yunohost version {{data.version}})

+ {% for category, helpers in data.helpers %}

{{ category }}

@@ -70,7 +72,7 @@

{% endif %}

- Dude, show me the code ! + Dude, show me the code !

@@ -81,9 +83,6 @@ {% endfor %} {% endfor %} -

Generated by this script on {{data.date}} (Yunohost version {{data.version}})

- -