From 099bbe0e66cf135bea45165f2e0e1f4867362808 Mon Sep 17 00:00:00 2001 From: Stefan Bethke Date: Sat, 5 Aug 2023 18:59:58 +0200 Subject: [PATCH] Nextcloud-Config weiter entwickeln --- inventories/chaosknoten/host_vars/cloud.yaml | 2 + inventories/chaosknoten/hosts.yaml | 3 + playbooks/deploy.yaml | 5 + .../cloud/nginx/cloud.hamburg.ccc.de.conf | 94 +++++++++++++++++- playbooks/roles/nextcloud/tasks/main.yaml | 9 ++ .../chaosknoten/configs/cloud/compose.yaml.j2 | 25 +++-- .../chaosknoten/configs/cloud/config.php.j2 | 98 +++++++++++++++++++ 7 files changed, 225 insertions(+), 11 deletions(-) create mode 100644 playbooks/roles/nextcloud/tasks/main.yaml create mode 100644 playbooks/templates/chaosknoten/configs/cloud/config.php.j2 diff --git a/inventories/chaosknoten/host_vars/cloud.yaml b/inventories/chaosknoten/host_vars/cloud.yaml index f85ce69..887ef25 100644 --- a/inventories/chaosknoten/host_vars/cloud.yaml +++ b/inventories/chaosknoten/host_vars/cloud.yaml @@ -6,6 +6,8 @@ certbot__acme_account_email_address: le-admin@hamburg.ccc.de certbot__certificate_domains: - "cloud.hamburg.ccc.de" +nextcloud__config_php: "{{ lookup('ansible.builtin.template', 'chaosknoten/configs/cloud/config.php.j2') }}" + nginx__version_spec: "" nginx__configurations: - name: cloud.hamburg.ccc.de diff --git a/inventories/chaosknoten/hosts.yaml b/inventories/chaosknoten/hosts.yaml index 83e415d..7956eae 100644 --- a/inventories/chaosknoten/hosts.yaml +++ b/inventories/chaosknoten/hosts.yaml @@ -24,6 +24,9 @@ all: hosts: cloud: pad: + nextcloud_hosts: + hosts: + cloud: nginx_hosts: hosts: cloud: diff --git a/playbooks/deploy.yaml b/playbooks/deploy.yaml index e48a20d..3196d79 100644 --- a/playbooks/deploy.yaml +++ b/playbooks/deploy.yaml @@ -7,6 +7,11 @@ roles: - deploy_ssh_server_config +- name: Ensure Nextcloud config + hosts: nextcloud_hosts + roles: + - nextcloud + - name: Ensure Send-Only-Mailserver deployment on send_only_mail_server_hosts hosts: send_only_mail_server_hosts roles: diff --git a/playbooks/files/chaosknoten/configs/cloud/nginx/cloud.hamburg.ccc.de.conf b/playbooks/files/chaosknoten/configs/cloud/nginx/cloud.hamburg.ccc.de.conf index 5ee469c..1c94733 100644 --- a/playbooks/files/chaosknoten/configs/cloud/nginx/cloud.hamburg.ccc.de.conf +++ b/playbooks/files/chaosknoten/configs/cloud/nginx/cloud.hamburg.ccc.de.conf @@ -1,5 +1,9 @@ # partly generated 2022-01-08, Mozilla Guideline v5.6, nginx 1.17.7, OpenSSL 1.1.1k, intermediate configuration # https://ssl-config.mozilla.org/#server=nginx&version=1.17.7&config=intermediate&openssl=1.1.1k&guideline=5.6 +upstream nextcloud { + server 127.0.0.1:9000; +} + server { # Listen on a custom port for the proxy protocol. listen 8443 ssl http2 proxy_protocol; @@ -36,7 +40,95 @@ server { # Also provide "_hidden" for by, since it's not relevant. proxy_set_header Forwarded "for=$remote_addr;proto=https;host=$host;by=_hidden"; + # HTTP response headers borrowed from Nextcloud `.htaccess` + add_header Referrer-Policy "no-referrer" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-Download-Options "noopen" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Permitted-Cross-Domain-Policies "none" always; + add_header X-Robots-Tag "none" always; + add_header X-XSS-Protection "1; mode=block" always; + + # Remove X-Powered-By, which is an information leak + fastcgi_hide_header X-Powered-By; + + # Path to the root of your installation + root /data/docker/volumes/nextcloud; + + # Specify how to handle directories -- specifying `/index.php$request_uri` + # here as the fallback means that Nginx always exhibits the desired behaviour + # when a client requests a path that corresponds to a directory that exists + # on the server. In particular, if that directory contains an index.php file, + # that file is correctly served; if it doesn't, then the request is passed to + # the front-end controller. This consistent behaviour means that we don't need + # to specify custom rules for certain paths (e.g. images and other assets, + # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus + # `try_files $uri $uri/ /index.php$request_uri` + # always provides the desired behaviour. + index index.php index.html /index.php$request_uri; + + # Rule borrowed from `.htaccess` to handle Microsoft DAV clients + location = / { + if ( $http_user_agent ~ ^DavClnt ) { + return 302 /remote.php/webdav/$is_args$args; + } + } + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + # Rules borrowed from `.htaccess` to hide certain paths from clients + location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; } + location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; } + + # Ensure this block, which passes PHP files to the PHP process, is above the blocks + # which handle static assets (as seen below). If this block is not declared first, + # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php` + # to the URI, resulting in a HTTP 500 error response. + location ~ \.php(?:$|/) { + # Required for legacy support + rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri; + + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + set $path_info $fastcgi_path_info; + + try_files $fastcgi_script_name =404; + + include fastcgi_params; + #fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param SCRIPT_FILENAME /var/www/html/index.php; + fastcgi_param PATH_INFO $path_info; + #fastcgi_param HTTPS on; + + fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice + fastcgi_param front_controller_active true; # Enable pretty urls + fastcgi_pass nextcloud; + + fastcgi_intercept_errors on; + fastcgi_request_buffering off; + } + + location ~ \.(?:css|js|svg|gif)$ { + try_files $uri /index.php$request_uri; + expires 6M; # Cache-Control policy borrowed from `.htaccess` + access_log off; # Optional: Don't log access to assets + } + + location ~ \.woff2?$ { + try_files $uri /index.php$request_uri; + expires 7d; # Cache-Control policy borrowed from `.htaccess` + access_log off; # Optional: Don't log access to assets + } + + # Rule borrowed from `.htaccess` + location /remote { + return 301 /remote.php$request_uri; + } + location / { - proxy_pass http://127.0.0.1:8080/; + try_files $uri $uri/ /index.php$request_uri; } } diff --git a/playbooks/roles/nextcloud/tasks/main.yaml b/playbooks/roles/nextcloud/tasks/main.yaml new file mode 100644 index 0000000..9710763 --- /dev/null +++ b/playbooks/roles/nextcloud/tasks/main.yaml @@ -0,0 +1,9 @@ +--- +- name: Nextcloud config + become: true + ansible.builtin.copy: + content: "{{ nextcloud__config_php }}" + dest: "/data/docker/volumes/nextcloud/config/config.php" + mode: "0644" + owner: www-data + group: www-data diff --git a/playbooks/templates/chaosknoten/configs/cloud/compose.yaml.j2 b/playbooks/templates/chaosknoten/configs/cloud/compose.yaml.j2 index 4f57689..b6c883d 100644 --- a/playbooks/templates/chaosknoten/configs/cloud/compose.yaml.j2 +++ b/playbooks/templates/chaosknoten/configs/cloud/compose.yaml.j2 @@ -7,32 +7,37 @@ services: restart: always command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW volumes: - - database:/var/lib/mysql + - /data/docker/volumes/database:/var/lib/mysql environment: - - "MYSQL_ROOT_PASSWORD={{ lookup("community.general.passwordstore", "noc/vm-secrets/chaosknoten/pad/DB_PASSWORD", create=false, missing="error") }}" - - "MYSQL_PASSWORD={{ lookup("community.general.passwordstore", "noc/vm-secrets/chaosknoten/pad/DB_PASSWORD", create=false, missing="error") }}" + - "MYSQL_ROOT_PASSWORD={{ lookup("community.general.passwordstore", "noc/vm-secrets/chaosknoten/cloud/DB_PASSWORD", create=false, missing="error") }}" + - "MYSQL_PASSWORD={{ lookup("community.general.passwordstore", "noc/vm-secrets/chaosknoten/cloud/DB_PASSWORD", create=false, missing="error") }}" - "MYSQL_DATABASE=nextcloud" - "MYSQL_USER=nextcloud" + networks: + backend: {} app: image: docker.io/library/nextcloud:25-fpm restart: always ports: - - 8080:8080 + - 9000:9000 links: - - db + - database volumes: - - nextcloud:/var/www/html + - /data/docker/volumes/nextcloud:/var/www/html environment: - "MYSQL_PASSWORD={{ lookup("community.general.passwordstore", "noc/vm-secrets/chaosknoten/cloud/DB_PASSWORD", create=false, missing="error") }}" - "MYSQL_DATABASE=nextcloud" - "MYSQL_USER=nextcloud" - - "MYSQL_HOST=db" + - "MYSQL_HOST=database" + networks: + backend: {} + frontend: {} -volumes: +volumes: {} # FIXME: tell Docker to put volumes in /data instead of /var/lib/docker/ - database: {} - nextcloud: {} + #database: {} + #nextcloud: {} networks: backend: diff --git a/playbooks/templates/chaosknoten/configs/cloud/config.php.j2 b/playbooks/templates/chaosknoten/configs/cloud/config.php.j2 new file mode 100644 index 0000000..718bcb8 --- /dev/null +++ b/playbooks/templates/chaosknoten/configs/cloud/config.php.j2 @@ -0,0 +1,98 @@ + '\\OC\\Memcache\\APCu', + 'apps_paths' => + array ( + 0 => + array ( + 'path' => '/var/www/html/apps', + 'url' => '/apps', + 'writable' => false, + ), + 1 => + array ( + 'path' => '/var/www/html/custom_apps', + 'url' => '/custom_apps', + 'writable' => true, + ), + ), + 'instanceid' => 'oc9uqhr7buka', + 'passwordsalt' => 'SK2vmQeTEHrkkwx9K+hC1WX33lPJDs', + 'secret' => '3dBt5THD2ehg0yWdVDAvMmsY8yLtrfk/gE560lkMqYqgh6lu', + 'trusted_domains' => + array ( + 0 => 'cloud.hamburg.ccc.de', + ), + 'datadirectory' => '/var/www/html/data', + 'dbtype' => 'mysql', + 'version' => '25.0.9.2', + 'overwrite.cli.url' => 'https://cloud.hamburg.ccc.de', + 'dbname' => 'nextcloud', + 'dbhost' => 'database', + 'dbport' => '', + 'dbtableprefix' => 'oc_', + 'mysql.utf8mb4' => true, + 'dbuser' => 'nextcloud', + 'dbpassword' => 'TdBLMQQeKbz1zab3sySUsGxo3', + 'installed' => true, + // Some Nextcloud options that might make sense here + 'allow_user_to_change_display_name' => false, + 'lost_password_link' => 'disabled', + // URL of provider. All other URLs are auto-discovered from .well-known + 'oidc_login_provider_url' => 'https://id.ccchh.net/realms/ccchh', + // Client ID and secret registered with the provider + 'oidc_login_client_id' => 'cloud', + 'oidc_login_client_secret' => '{{ lookup("community.general.passwordstore", "noc/vm-secrets/chaosknoten/cloud/kc-client-secret", create=false, missing="error") }}', + // Automatically redirect the login page to the provider + 'oidc_login_auto_redirect' => true, + // Redirect to this page after logging out the user + //'oidc_login_logout_url' => 'https://openid.example.com/thankyou', + // If set to true the user will be redirected to the + // logout endpoint of the OIDC provider after logout + // in Nextcloud. After successfull logout the OIDC + // provider will redirect back to 'oidc_login_logout_url' (MUST be set). + 'oidc_login_end_session_redirect' => true, + // Quota to assign if no quota is specified in the OIDC response (bytes) + // + // NOTE: If you want to allow NextCloud to manage quotas, omit this option. Do not set it to + // zero or -1 or ''. + 'oidc_login_default_quota' => '1000000000', + // Login button text + 'oidc_login_button_text' => 'Log in via id.ccchh.net', + // Hide the NextCloud password change form. + 'oidc_login_hide_password_form' => false, + // Use ID Token instead of UserInfo + 'oidc_login_use_id_token' => false, + 'oidc_login_attributes' => array ( + 'id' => 'preferred_username', + 'name' => 'name', + 'mail' => 'email', + 'quota' => 'ownCloudQuota', + 'home' => 'homeDirectory', + 'ldap_uid' => 'uid', + 'groups' => 'ownCloudGroups', + 'login_filter' => 'realm_access_roles', + 'photoURL' => 'picture', + 'is_admin' => 'ownCloudAdmin', + ), + // Default group to add users to (optional, defaults to nothing) + //'oidc_login_default_group' => 'oidc', + 'oidc_login_filter_allowed_values' => null, + // Set OpenID Connect scope + 'oidc_login_scope' => 'openid profile', + // The `id` attribute in `oidc_login_attributes` must return the + // "Internal Username" (see expert settings in LDAP integration) + 'oidc_login_proxy_ldap' => false, + // Fallback to direct login if login from OIDC fails + // Note that no error message will be displayed if enabled + 'oidc_login_disable_registration' => false, + //'oidc_login_redir_fallback' => false, + // If you get your groups from the oidc_login_attributes, you might want + // to create them if they are not already existing, Default is `false`. + 'oidc_create_groups' => true, + // Enable use of WebDAV via OIDC bearer token. + 'oidc_login_webdav_enabled' => true, + // Enable authentication with user/password for DAV clients that do not + // support token authentication (e.g. DAVx⁵) + 'oidc_login_password_authentication' => false, +); \ No newline at end of file