diff --git a/docker-compose.yml b/docker-compose.yml index ec70270c..f1f32cdc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,288 +1,295 @@ version: '3' services: coturn: build: context: ./docker/coturn/ container_name: kolab-coturn healthcheck: interval: 10s test: "kill -0 $$(cat /tmp/turnserver.pid)" timeout: 5s retries: 30 environment: - TURN_PUBLIC_IP=${COTURN_PUBLIC_IP} - TURN_LISTEN_PORT=3478 - TURN_STATIC_SECRET=${COTURN_STATIC_SECRET} hostname: sturn.mgmt.com image: kolab-coturn network_mode: host restart: on-failure tty: true kolab: build: context: ./docker/kolab/ container_name: kolab privileged: true depends_on: mariadb: condition: service_healthy pdns: condition: service_healthy extra_hosts: - "kolab.mgmt.com:127.0.0.1" environment: - LDAP_HOST=127.0.0.1 - LDAP_ADMIN_BIND_DN="cn=Directory Manager" - LDAP_ADMIN_BIND_PW=Welcome2KolabSystems - DB_HOST=mariadb - DB_ROOT_PASSWORD=Welcome2KolabSystems - DB_HKCCP_DATABASE=${DB_DATABASE} - DB_HKCCP_USERNAME=${DB_USERNAME} - DB_HKCCP_PASSWORD=${DB_PASSWORD} - DB_KOLAB_DATABASE=kolab - DB_KOLAB_USERNAME=kolab - DB_KOLAB_PASSWORD=Welcome2KolabSystems - DB_RC_USERNAME=roundcube - DB_RC_PASSWORD=Welcome2KolabSystems - SSL_CERTIFICATE=${KOLAB_SSL_CERTIFICATE:?err} - SSL_CERTIFICATE_FULLCHAIN=${KOLAB_SSL_CERTIFICATE_FULLCHAIN:?err} - SSL_CERTIFICATE_KEY=${KOLAB_SSL_CERTIFICATE_KEY:?err} - IMAP_HOST=127.0.0.1 - IMAP_PORT=11993 - MAIL_HOST=127.0.0.1 - MAIL_PORT=10587 healthcheck: interval: 10s test: test -f /tmp/kolab-init.done timeout: 5s retries: 30 # This makes docker's dns, resolve via pdns for this container. # Please note it does not affect /etc/resolv.conf dns: 172.18.0.11 hostname: kolab.mgmt.com image: kolab networks: - kolab tmpfs: - /run - /tmp - /var/run - /var/tmp tty: true volumes: - ./ext/:/src/:ro - /etc/letsencrypt/:/etc/letsencrypt/:ro - ./docker/certs/ca.cert:/etc/pki/tls/certs/ca.cert:ro - ./docker/certs/ca.cert:/etc/pki/ca-trust/source/anchors/ca.cert:ro - ./docker/certs/kolab.hosted.com.cert:${KOLAB_SSL_CERTIFICATE:?err} - ./docker/certs/kolab.hosted.com.chain.pem:${KOLAB_SSL_CERTIFICATE_FULLCHAIN:?err} - ./docker/certs/kolab.hosted.com.key:${KOLAB_SSL_CERTIFICATE_KEY:?err} - ./docker/kolab/utils:/root/utils:ro - /sys/fs/cgroup:/sys/fs/cgroup:ro - imap:/imapdata - ldap:/ldapdata mariadb: container_name: kolab-mariadb environment: - MARIADB_ROOT_PASSWORD=Welcome2KolabSystems - TZ="+02:00" - DB_HKCCP_DATABASE=${DB_DATABASE} - DB_HKCCP_USERNAME=${DB_USERNAME} - DB_HKCCP_PASSWORD=${DB_PASSWORD} healthcheck: interval: 10s test: test -e /var/run/mysqld/mysqld.sock timeout: 5s retries: 30 image: mariadb:latest networks: - kolab volumes: - ./docker/mariadb/mysql-init/:/docker-entrypoint-initdb.d/ - mariadb:/var/lib/mysql haproxy: build: context: ./docker/haproxy/ healthcheck: interval: 10s test: "kill -0 $$(cat /var/run/haproxy.pid)" timeout: 5s retries: 30 container_name: kolab-haproxy hostname: haproxy.hosted.com image: kolab-haproxy networks: - kolab tmpfs: - /run - /tmp - /var/run - /var/tmp tty: true volumes: - ./docker/certs/:/etc/certs/:ro - /etc/letsencrypt/:/etc/letsencrypt/:ro pdns: build: context: ./docker/pdns/ container_name: kolab-pdns hostname: pdns depends_on: mariadb: condition: service_healthy healthcheck: interval: 10s test: "systemctl status pdns || exit 1" timeout: 5s retries: 30 image: kolab-pdns networks: kolab: ipv4_address: 172.18.0.11 tmpfs: - /run - /tmp - /var/run - /var/tmp tty: true volumes: - /sys/fs/cgroup:/sys/fs/cgroup:ro proxy: build: context: ./docker/proxy/ args: APP_WEBSITE_DOMAIN: ${APP_WEBSITE_DOMAIN:?err} SSL_CERTIFICATE: ${PROXY_SSL_CERTIFICATE:?err} SSL_CERTIFICATE_KEY: ${PROXY_SSL_CERTIFICATE_KEY:?err} healthcheck: interval: 10s test: "kill -0 $$(cat /run/nginx.pid)" timeout: 5s retries: 30 container_name: kolab-proxy hostname: ${APP_WEBSITE_DOMAIN:?err} image: kolab-proxy + extra_hosts: + - "meet:${MEET_LISTENING_HOST}" networks: - kolab tmpfs: - /run - /tmp - /var/run - /var/tmp tty: true volumes: - ./docker/certs/:/etc/certs/:ro - /etc/letsencrypt/:/etc/letsencrypt/:ro ports: + # - "80:80" - "443:443" + - "465:465" + - "587:587" + - "143:143" + - "993:993" redis: build: context: ./docker/redis/ healthcheck: interval: 10s test: "redis-cli ping || exit 1" timeout: 5s retries: 30 container_name: kolab-redis hostname: redis image: redis networks: - kolab volumes: - ./docker/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro # ports: # - "6379:6379" swoole: build: context: ./docker/swoole/ container_name: kolab-swoole image: apheleia/swoole:4.8.x webapp: build: context: ./docker/webapp/ container_name: kolab-webapp image: kolab-webapp healthcheck: interval: 10s test: "/src/kolabsrc/artisan octane:status || exit 1" timeout: 5s retries: 30 depends_on: kolab: condition: service_healthy redis: condition: service_healthy networks: - kolab volumes: - ./src:/src/kolabsrc.orig:ro ports: - "8000:8000" tests: build: context: ./docker/tests/ container_name: kolab-tests image: kolab-tests depends_on: kolab: condition: service_healthy networks: - kolab volumes: - ./src:/src/kolabsrc.orig:ro worker: build: context: ./docker/worker/ container_name: kolab-worker depends_on: - kolab hostname: worker image: kolab-worker networks: - kolab tmpfs: - /run - /tmp - /var/run - /var/tmp tty: true volumes: - ./src:/home/worker/src.orig:ro - /sys/fs/cgroup:/sys/fs/cgroup:ro meet: build: context: ./docker/meet/ healthcheck: interval: 10s - test: "curl --insecure -H 'X-AUTH-TOKEN: ${MEET_SERVER_TOKEN}' --fail https://localhost:12443/meetmedia/api/health || exit 1" + test: "curl --insecure -H 'X-AUTH-TOKEN: ${MEET_SERVER_TOKEN}' --fail https://${MEET_LISTENING_HOST}:12443/meetmedia/api/health || exit 1" timeout: 5s retries: 30 environment: - WEBRTC_LISTEN_IP=${MEET_WEBRTC_LISTEN_IP:?err} - PUBLIC_DOMAIN=${MEET_PUBLIC_DOMAIN:?err} - - LISTENING_HOST=0.0.0.0 + - LISTENING_HOST=${MEET_LISTENING_HOST:?err} - LISTENING_PORT=12443 - TURN_SERVER=${MEET_TURN_SERVER} - TURN_STATIC_SECRET=${COTURN_STATIC_SECRET} - AUTH_TOKEN=${MEET_SERVER_TOKEN:?err} - WEBHOOK_TOKEN=${MEET_WEBHOOK_TOKEN:?err} - WEBHOOK_URL=${APP_PUBLIC_URL:?err}/api/webhooks/meet - SSL_CERT=/etc/pki/tls/certs/meet.${APP_WEBSITE_DOMAIN:?err}.cert - SSL_KEY=/etc/pki/tls/private/meet.${APP_WEBSITE_DOMAIN:?err}.key network_mode: host container_name: kolab-meet image: kolab-meet volumes: - ./meet/server:/src/meet/:ro - ./docker/certs/meet.${APP_WEBSITE_DOMAIN}.cert:/etc/pki/tls/certs/meet.${APP_WEBSITE_DOMAIN}.cert - ./docker/certs/meet.${APP_WEBSITE_DOMAIN}.key:/etc/pki/tls/private/meet.${APP_WEBSITE_DOMAIN}.key networks: kolab: driver: bridge ipam: config: - subnet: "172.18.0.0/24" volumes: mariadb: imap: ldap: diff --git a/docker/haproxy/haproxy.cfg b/docker/haproxy/haproxy.cfg index 766dcb38..faf42206 100644 --- a/docker/haproxy/haproxy.cfg +++ b/docker/haproxy/haproxy.cfg @@ -1,76 +1,76 @@ #--------------------------------------------------------------------- # Example configuration for a possible web application. See the # full configuration options online. # # https://www.haproxy.org/download/1.8/doc/configuration.txt # #--------------------------------------------------------------------- #--------------------------------------------------------------------- # Global settings #--------------------------------------------------------------------- global # to have these messages end up in /var/log/haproxy.log you will # need to: # # 1) configure syslog to accept network log events. This is done # by adding the '-r' option to the SYSLOGD_OPTIONS in # /etc/sysconfig/syslog # # 2) configure local2 events to go to the /var/log/haproxy.log # file. A line like the following can be added to # /etc/sysconfig/syslog # # local2.* /var/log/haproxy.log # log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 100 user haproxy group haproxy daemon # turn on stats unix socket stats socket /var/lib/haproxy/stats # utilize system-wide crypto-policies ssl-default-bind-ciphers PROFILE=SYSTEM ssl-default-server-ciphers PROFILE=SYSTEM #--------------------------------------------------------------------- # common defaults that all the 'listen' and 'backend' sections will # use if not designated in their block #--------------------------------------------------------------------- defaults # mode http log global # option httplog # option dontlognull # option http-server-close # option forwardfor except 127.0.0.0/8 # option redispatch # retries 3 # timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m # timeout http-keep-alive 10s timeout check 10s maxconn 3000 frontend ft_imap # Accept the proxy protocol bind :145 accept-proxy mode tcp default_backend bk_imap backend bk_imap mode tcp # imap connections are usually long balance leastconn stick store-request src stick-table type ip size 200k expire 30m # NGINX imap with proxy protocol enabled - server s1 127.0.0.1:144 check send-proxy-v2 + server s1 proxy:144 check send-proxy-v2 diff --git a/docker/kolab/cyrus.conf b/docker/kolab/cyrus.conf index 6075489a..96518409 100644 --- a/docker/kolab/cyrus.conf +++ b/docker/kolab/cyrus.conf @@ -1,46 +1,46 @@ # standard standalone server implementation START { # do not delete this entry! recover cmd="ctl_cyrusdb -r" idled cmd="idled" } # UNIX sockets start with a slash and are put into /var/lib/imap/sockets SERVICES { - nginx cmd="imapd" listen=127.0.0.1:12143 prefork=1 - guam cmd="imapd" listen=127.0.0.1:13143 prefork=1 - imap cmd="imapd" listen=127.0.0.1:11143 prefork=1 - imaps cmd="imapd -s" listen=127.0.0.1:11993 prefork=5 + nginx cmd="imapd" listen=0.0.0.0:12143 prefork=1 + guam cmd="imapd" listen=0.0.0.0:13143 prefork=1 + imap cmd="imapd" listen=0.0.0.0:11143 prefork=1 + imaps cmd="imapd -s" listen=0.0.0.0:11993 prefork=5 sieve cmd="timsieved" listen="sieve" prefork=0 ptloader cmd="ptloader" listen="/var/lib/imap/socket/ptsock" prefork=0 lmtpunix cmd="lmtpd" listen="/var/lib/imap/socket/lmtp" prefork=1 notify cmd="notifyd" listen="/var/lib/imap/socket/notify" proto="udp" prefork=1 } EVENTS { # this is required checkpoint cmd="ctl_cyrusdb -c" period=30 # this is only necessary if using duplicate delivery suppression, # Sieve or NNTP duplicateprune cmd="cyr_expire -E 3" at=0400 # Expire data older then 69 days. Two full months of 31 days # each includes two full backup cycles, plus 1 week margin # because we run our full backups on the first sat/sun night # of each month. deleteprune cmd="cyr_expire -E 4 -D 69" at=0430 expungeprune cmd="cyr_expire -E 4 -X 69" at=0445 # this is only necessary if caching TLS sessions tlsprune cmd="tls_prune" at=0400 # Create search indexes regularly (remove -s for cyrus 3+) #squatter cmd="squatter -s -i" at=0530 } diff --git a/docker/kolab/utils/05-adjust-configs.sh b/docker/kolab/utils/05-adjust-configs.sh index 1417a5aa..bfb8a5cd 100755 --- a/docker/kolab/utils/05-adjust-configs.sh +++ b/docker/kolab/utils/05-adjust-configs.sh @@ -1,179 +1,166 @@ #!/bin/bash -# if [[ ${DB_HOST} == "localhost" || ${DB_HOST} == "127.0.0.1" ]]; then -# mysql -h ${DB_HOST:-127.0.0.1} -u root --password=${DB_ROOT_PASSWORD:-Welcome2KolabSystems} \ -# -e "UPDATE mysql.db SET Host = '127.0.0.1' WHERE Host = 'localhost';" - -# mysql -h ${DB_HOST:-127.0.0.1} -u root --password=${DB_ROOT_PASSWORD:-Welcome2KolabSystems} \ -# -e "FLUSH PRIVILEGES;" -# fi - # Replace localhost -sed -i -e "/hosts/s/localhost/${LDAP_HOST:-127.0.0.1}/" /etc/iRony/dav.inc.php -sed -i -e "/host/s/localhost/${LDAP_HOST:-127.0.0.1}/g" \ - -e "/fbsource/s/localhost/${IMAP_HOST:-127.0.0.1}/g" /etc/kolab-freebusy/config.ini -#sed -i -e "s/server_host.*/server_host = ${LDAP_HOST:-127.0.0.1}/g" /etc/postfix/ldap/* -sed -i -e "/password_ldap_host/s/localhost/${LDAP_HOST:-127.0.0.1}/" /etc/roundcubemail/password.inc.php -sed -i -e "/hosts/s/localhost/${LDAP_HOST:-127.0.0.1}/" /etc/roundcubemail/kolab_auth.inc.php +sed -i -e "/hosts/s/localhost/${LDAP_HOST}/" /etc/iRony/dav.inc.php +sed -i -e "/host/s/localhost/${LDAP_HOST}/g" \ + -e "/fbsource/s/localhost/${IMAP_HOST}/g" /etc/kolab-freebusy/config.ini +#sed -i -e "s/server_host.*/server_host = ${LDAP_HOST}/g" /etc/postfix/ldap/* +sed -i -e "/password_ldap_host/s/localhost/${LDAP_HOST}/" /etc/roundcubemail/password.inc.php +sed -i -e "/hosts/s/localhost/${LDAP_HOST}/" /etc/roundcubemail/kolab_auth.inc.php sed -i -e "s#.*db_dsnw.*# \$config['db_dsnw'] = 'mysql://${DB_RC_USERNAME}:${DB_RC_PASSWORD}@${DB_HOST}/roundcube';#" \ - -e "/default_host/s|= .*$|= 'ssl://${IMAP_HOST:-127.0.0.1}';|" \ - -e "/default_port/s|= .*$|= ${IMAP_PORT:-11993};|" \ - -e "/smtp_server/s|= .*$|= 'tls://${MAIL_HOST:-127.0.0.1}';|" \ - -e "/smtp_port/s/= .*$/= ${MAIL_PORT:-10587};/" \ - -e "/hosts/s/localhost/${LDAP_HOST:-127.0.0.1}/" /etc/roundcubemail/config.inc.php -sed -i -e "/hosts/s/localhost/${LDAP_HOST:-127.0.0.1}/" /etc/roundcubemail/calendar.inc.php + -e "/default_host/s|= .*$|= 'ssl://${IMAP_HOST}';|" \ + -e "/default_port/s|= .*$|= ${IMAP_PORT};|" \ + -e "/smtp_server/s|= .*$|= 'tls://${MAIL_HOST}';|" \ + -e "/smtp_port/s/= .*$/= ${MAIL_PORT};/" \ + -e "/hosts/s/localhost/${LDAP_HOST}/" /etc/roundcubemail/config.inc.php +sed -i -e "/hosts/s/localhost/${LDAP_HOST}/" /etc/roundcubemail/calendar.inc.php . ./settings.sh #Adjust basedn sed -i -r \ -e "s/(\s+)base => '.*',$/\1base => '${hosted_domain_rootdn}',/g" \ -e "/\\\$mydomain = / a\ \$myhostname = '${HOSTNAME:-kolab}.${DOMAIN:-mgmt.com}';" \ -e "s/^base_dn = .*$/base_dn = ${hosted_domain_rootdn}/g" \ -e "s/^search_base = .*$/search_base = ${hosted_domain_rootdn}/g" \ -e "s/(\s+)'base_dn'(\s+)=> '.*',/\1'base_dn'\2=> '${hosted_domain_rootdn}',/g" \ -e "s/(\s+)'search_base_dn'(\s+)=> '.*',/\1'search_base_dn'\2=> '${hosted_domain_rootdn}',/g" \ -e "s/(\s+)'user_specific'(\s+)=> false,/\1'user_specific'\2=> true,/g" \ /etc/amavisd/amavisd.conf \ /etc/kolab-freebusy/config.ini \ /etc/postfix/ldap/*.cf \ /etc/roundcubemail/config.inc.php \ /etc/roundcubemail/calendar.inc.php \ /etc/roundcubemail/kolab_auth.inc.php sed -i -r \ -e "s/^search_base = .*$/search_base = ${domain_base_dn}/g" \ /etc/postfix/ldap/mydestination.cf #Disable amavisd postconf -e content_filter='smtp-wallace:[127.0.0.1]:10026' systemctl stop amavisd systemctl disable amavisd systemctl stop clamd@amavisd systemctl disable clamd@amavisd # Change port numbers cat ${SSL_CERTIFICATE} ${SSL_CERTIFICATE_FULLCHAIN} ${SSL_CERTIFICATE_KEY} > /etc/pki/cyrus-imapd/cyrus-imapd.bundle.pem chown cyrus:mail /etc/pki/cyrus-imapd/cyrus-imapd.bundle.pem cp /etc/pki/cyrus-imapd/cyrus-imapd.bundle.pem /etc/pki/tls/private/postfix.pem chown postfix:mail /etc/pki/tls/private/postfix.pem chmod 655 /etc/pki/tls/private/postfix.pem sed -i "s/smtpd_tls_key_file =.*/smtpd_tls_key_file = \/etc\/pki\/tls\/private\/postfix.pem/" /etc/postfix/main.cf sed -i "s/smtpd_tls_cert_file =.*/smtpd_tls_cert_file = \/etc\/pki\/tls\/private\/postfix.pem/" /etc/postfix/main.cf # Remove the submission block, by matching from submission until the next empty line sed -i -e '/submission inet/,/^$/d' /etc/postfix/master.cf # Insert a new submission block with a modified port cat >> /etc/postfix/master.cf << EOF 127.0.0.1:10587 inet n - n - - smtpd -o cleanup_service_name=cleanup_submission -o syslog_name=postfix/submission #-o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes -o smtpd_sasl_authenticated_header=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_data_restrictions=\$submission_data_restrictions -o smtpd_recipient_restrictions=\$submission_recipient_restrictions -o smtpd_sender_restrictions=\$submission_sender_restrictions 127.0.0.1:10465 inet n - n - - smtpd -o cleanup_service_name=cleanup_submission -o rewrite_service_name=rewrite_submission -o syslog_name=postfix/smtps -o mydestination= -o local_recipient_maps= -o relay_domains= -o relay_recipient_maps= #-o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_sasl_authenticated_header=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_sender_restrictions=\$submission_sender_restrictions -o smtpd_recipient_restrictions=\$submission_recipient_restrictions -o smtpd_data_restrictions=\$submission_data_restrictions EOF sed -i -r \ -e "s/'vlv'(\s+)=> false,/'vlv'\1=> true,/g" \ -e "s/'vlv_search'(\s+)=> false,/'vlv_search'\1=> true,/g" \ -e "s/inetOrgPerson/inetorgperson/g" \ -e "s/kolabInetOrgPerson/inetorgperson/g" \ /etc/roundcubemail/*.inc.php # Adjust postfix # new: (inetdomainstatus:1.2.840.113556.1.4.803:=1) # active: (inetdomainstatus:1.2.840.113556.1.4.803:=2) # suspended: (inetdomainstatus:1.2.840.113556.1.4.803:=4) # deleted: (inetdomainstatus:1.2.840.113556.1.4.803:=8) # confirmed: (inetdomainstatus:1.2.840.113556.1.4.803:=16) # verified: (inetdomainstatus:1.2.840.113556.1.4.803:=32) # ready: (inetdomainstatus:1.2.840.113556.1.4.803:=64) sed -i -r \ -e 's/^query_filter.*$/query_filter = (\&(associatedDomain=%s)(inetdomainstatus:1.2.840.113556.1.4.803:=18)(!(inetdomainstatus:1.2.840.113556.1.4.803:=4)))/g' \ /etc/postfix/ldap/mydestination.cf # new: (inetuserstatus:1.2.840.113556.1.4.803:=1) # active: (inetuserstatus:1.2.840.113556.1.4.803:=2) # suspended: (inetuserstatus:1.2.840.113556.1.4.803:=4) # deleted: (inetuserstatus:1.2.840.113556.1.4.803:=8) # ldapready: (inetuserstatus:1.2.840.113556.1.4.803:=16) # imapready: (inetuserstatus:1.2.840.113556.1.4.803:=32) sed -i -r \ -e 's/^query_filter.*$/query_filter = (\&(|(mail=%s)(alias=%s))(|(objectclass=kolabinetorgperson)(|(objectclass=kolabgroupofuniquenames)(objectclass=kolabgroupofurls))(|(|(objectclass=groupofuniquenames)(objectclass=groupofurls))(objectclass=kolabsharedfolder))(objectclass=kolabsharedfolder))(!(inetuserstatus:1.2.840.113556.1.4.803:=4)))/g' \ /etc/postfix/ldap/local_recipient_maps.cf systemctl restart postfix sed -i -r -e "s|$config\['kolab_files_url'\] = .*$|$config['kolab_files_url'] = 'https://' \. \$_SERVER['HTTP_HOST'] . '/chwala/';|g" /etc/roundcubemail/kolab_files.inc.php sed -i -r -e "s|$config\['kolab_invitation_calendars'\] = .*$|$config['kolab_invitation_calendars'] = true;|g" /etc/roundcubemail/calendar.inc.php sed -i -r -e "/^.*'contextmenu',$/a 'enigma'," /etc/roundcubemail/config.inc.php sed -i -r -e "s|$config\['enigma_passwordless'\] = .*$|$config['enigma_passwordless'] = true;|g" /etc/roundcubemail/enigma.inc.php sed -i -r -e "s|$config\['enigma_multihost'\] = .*$|$config['enigma_multihost'] = true;|g" /etc/roundcubemail/enigma.inc.php echo "\$config['enigma_woat'] = true;" >> /etc/roundcubemail/enigma.inc.php # Run it over haproxy then nginx for 2fa. We need to use startls because otherwise the proxy protocol doesn't work. -sed -i -r -e "s|$config\['default_host'\] = .*$|$config['default_host'] = 'tls://127.0.0.1';|g" /etc/roundcubemail/config.inc.php +sed -i -r -e "s|$config\['default_host'\] = .*$|$config['default_host'] = 'tls://haproxy';|g" /etc/roundcubemail/config.inc.php sed -i -r -e "s|$config\['default_port'\] = .*$|$config['default_port'] = 145;|g" /etc/roundcubemail/config.inc.php # So we can just append sed -i "s/?>//g" /etc/roundcubemail/config.inc.php # Enable the PROXY protocol cat << EOF >> /etc/roundcubemail/config.inc.php \$config['imap_conn_options'] = Array( 'ssl' => Array( 'verify_peer_name' => false, 'verify_peer' => false, 'allow_self_signed' => true ), 'proxy_protocol' => 2 ); \$config['proxy_whitelist'] = array('127.0.0.1'); EOF echo "?>" >> /etc/roundcubemail/config.inc.php - - -# Send dns queries over powerdns -# rm -f /etc/resolv.conf -# echo "nameserver 127.0.0.1:9953" > /etc/resolv.conf diff --git a/docker/kolab/utils/settings.sh b/docker/kolab/utils/settings.sh index 47a14b10..fbf6f045 100755 --- a/docker/kolab/utils/settings.sh +++ b/docker/kolab/utils/settings.sh @@ -1,24 +1,24 @@ #!/bin/bash export rootdn=${LDAP_ADMIN_ROOT_DN:-"dc=mgmt,dc=com"} export domain=${DOMAIN:-"mgmt.com"} export domain_db=${DOMAIN_DB:-"mgmt_com"} -export ldap_host=${LDAP_HOST:-"127.0.0.1"} +export ldap_host=${LDAP_HOST} export ldap_binddn=${LDAP_ADMIN_BIND_DN:-"cn=Directory Manager"} export ldap_bindpw=${LDAP_ADMIN_BIND_PW:-"Welcome2KolabSystems"} export cyrus_admin=${IMAP_ADMIN_LOGIN:-"cyrus-admin"} -export imap_host=${IMAP_HOST:-"127.0.0.1"} +export imap_host=${IMAP_HOST} export cyrus_admin_pw=${IMAP_ADMIN_PASSWORD:-"Welcome2KolabSystems"} export kolab_service_pw=${LDAP_SERVICE_BIND_PW:-"Welcome2KolabSystems"} export hosted_kolab_service_pw=${LDAP_HOSTED_BIND_PW:-"Welcome2KolabSystems"} export hosted_domain=${HOSTED_DOMAIN:-"hosted.com"} export hosted_domain_db=${HOSTED_DOMAIN_DB:-"hosted_com"} export hosted_domain_rootdn=${LDAP_HOSTED_ROOT_DN:-"dc=hosted,dc=com"} export domain_base_dn=${LDAP_DOMAIN_BASE_DN:-"ou=Domains,dc=mgmt,dc=com"} export default_user_password=${DEFAULT_USER_PASSWORD:-"Welcome2KolabSystems"} diff --git a/docker/proxy/Dockerfile b/docker/proxy/Dockerfile index 2a3c8ba9..b18a8bdb 100644 --- a/docker/proxy/Dockerfile +++ b/docker/proxy/Dockerfile @@ -1,29 +1,29 @@ FROM fedora:35 MAINTAINER Jeroen van Meeuwen ENV container docker RUN dnf -y install \ --setopt 'tsflags=nodocs' \ nginx \ nginx-mod-mail && \ dnf clean all COPY rootfs/ / ARG APP_WEBSITE_DOMAIN ARG SSL_CERTIFICATE ARG SSL_CERTIFICATE_KEY RUN sed -i -r -e "s|APP_WEBSITE_DOMAIN|$APP_WEBSITE_DOMAIN|g" /etc/nginx/nginx.conf RUN sed -i -r -e "s|SSL_CERTIFICATE_CERT|$SSL_CERTIFICATE|g" /etc/nginx/nginx.conf RUN sed -i -r -e "s|SSL_CERTIFICATE_KEY|$SSL_CERTIFICATE_KEY|g" /etc/nginx/nginx.conf # Forward request logs to Docker log collector RUN ln -sf /dev/stdout /var/log/nginx/access.log \ && ln -sf /dev/stderr /var/log/nginx/error.log STOPSIGNAL SIGTERM CMD ["nginx", "-g", "daemon off;"] -EXPOSE 80/tcp 443/tcp 110/tcp 143/tcp 993/tcp 995/tcp +EXPOSE 80/tcp 443/tcp 465/tcp 587/tcp 143/tcp 993/tcp diff --git a/docker/proxy/rootfs/etc/nginx/nginx.conf b/docker/proxy/rootfs/etc/nginx/nginx.conf index c961fd59..5616e99f 100644 --- a/docker/proxy/rootfs/etc/nginx/nginx.conf +++ b/docker/proxy/rootfs/etc/nginx/nginx.conf @@ -1,247 +1,247 @@ # For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; map $http_upgrade $connection_upgrade { default upgrade; '' close; } # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; server { listen [::]:443 ssl ipv6only=on; listen 443 ssl; ssl_certificate SSL_CERTIFICATE_CERT; ssl_certificate_key SSL_CERTIFICATE_KEY; server_name APP_WEBSITE_DOMAIN; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { - proxy_pass http://127.0.0.1:8000; + proxy_pass http://webapp:8000; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_no_cache 1; proxy_cache_bypass 1; # Mostly for files, swoole has a 10MB limit client_max_body_size 11m; } location /meetmedia { - proxy_pass https://127.0.0.1:12443; + proxy_pass https://meet:12443; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; } location /meetmedia/api { - proxy_pass https://127.0.0.1:12443; + proxy_pass https://meet:12443; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_no_cache 1; proxy_cache_bypass 1; } location /roundcubemail { - proxy_pass http://127.0.0.1:9080; + proxy_pass http://kolab:9080; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_no_cache 1; proxy_cache_bypass 1; } location /kolab-webadmin { - proxy_pass http://127.0.0.1:9080; + proxy_pass http://kolab:9080; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_no_cache 1; proxy_cache_bypass 1; } location /Microsoft-Server-ActiveSync { auth_request /auth; #auth_request_set $auth_status $upstream_status; - proxy_pass http://127.0.0.1:9080; + proxy_pass http://kolab:9080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_send_timeout 910s; proxy_read_timeout 910s; fastcgi_send_timeout 910s; fastcgi_read_timeout 910s; } location ~* ^/\\.well-known/(caldav|carddav) { - proxy_pass http://127.0.0.1:9080; + proxy_pass http://kolab:9080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /iRony { auth_request /auth; #auth_request_set $auth_status $upstream_status; - proxy_pass http://127.0.0.1:9080; + proxy_pass http://kolab:9080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location = /auth { internal; - proxy_pass http://127.0.0.1:8000/api/webhooks/nginx-httpauth; + proxy_pass http://webapp:8000/api/webhooks/nginx-httpauth; proxy_pass_request_body off; proxy_set_header Host services.APP_WEBSITE_DOMAIN; proxy_set_header Content-Length ""; proxy_set_header X-Original-URI $request_uri; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } } mail { server_name imap.hosted.com; - auth_http 127.0.0.1:8000/api/webhooks/nginx; + auth_http webapp:8000/api/webhooks/nginx; auth_http_header Host services.APP_WEBSITE_DOMAIN; proxy_pass_error_message on; server { listen 143; protocol imap; proxy on; starttls on; ssl_certificate SSL_CERTIFICATE_CERT; ssl_certificate_key SSL_CERTIFICATE_KEY; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; } # Roundcube specific imap endpoint with proxy-protocol enabled server { listen 144 proxy_protocol; protocol imap; - auth_http 127.0.0.1:8000/api/webhooks/nginx-roundcube; + auth_http webapp:8000/api/webhooks/nginx-roundcube; proxy on; starttls on; ssl_certificate SSL_CERTIFICATE_CERT; ssl_certificate_key SSL_CERTIFICATE_KEY; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; } server { listen 465 ssl; protocol smtp; proxy on; ssl_certificate SSL_CERTIFICATE_CERT; ssl_certificate_key SSL_CERTIFICATE_KEY; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; } server { listen 587; protocol smtp; proxy on; starttls on; ssl_certificate SSL_CERTIFICATE_CERT; ssl_certificate_key SSL_CERTIFICATE_KEY; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; } server { listen 993 ssl; protocol imap; proxy on; ssl_certificate SSL_CERTIFICATE_CERT; ssl_certificate_key SSL_CERTIFICATE_KEY; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; } } diff --git a/src/.env.example b/src/.env.example index e10c5be3..d4a563d4 100644 --- a/src/.env.example +++ b/src/.env.example @@ -1,188 +1,183 @@ APP_NAME=Kolab APP_ENV=local APP_KEY= APP_DEBUG=true APP_URL=http://127.0.0.1:8000 #APP_PASSPHRASE= APP_PUBLIC_URL= APP_DOMAIN=kolabnow.com APP_WEBSITE_DOMAIN=kolabnow.com APP_THEME=default APP_TENANT_ID=5 APP_LOCALE=en APP_LOCALES= APP_WITH_ADMIN=1 APP_WITH_RESELLER=1 APP_WITH_SERVICES=1 APP_WITH_FILES=1 APP_HEADER_CSP="connect-src 'self'; child-src 'self'; font-src 'self'; form-action 'self' data:; frame-ancestors 'self'; img-src blob: data: 'self' *; media-src 'self'; object-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-eval' 'unsafe-inline'; default-src 'self';" APP_HEADER_XFO=sameorigin SIGNUP_LIMIT_EMAIL=0 SIGNUP_LIMIT_IP=0 ASSET_URL=http://127.0.0.1:8000 WEBMAIL_URL=/apps SUPPORT_URL=/support SUPPORT_EMAIL= LOG_CHANNEL=stack LOG_SLOW_REQUESTS=5 LOG_DEPRECATIONS_CHANNEL=null LOG_LEVEL=debug DB_CONNECTION=mysql DB_DATABASE=kolabdev DB_HOST=127.0.0.1 DB_PASSWORD=kolab DB_PORT=3306 DB_USERNAME=kolabdev BROADCAST_DRIVER=redis CACHE_DRIVER=redis QUEUE_CONNECTION=redis SESSION_DRIVER=file SESSION_LIFETIME=120 OPENEXCHANGERATES_API_KEY="from openexchangerates.org" MFA_DSN=mysql://roundcube:Welcome2KolabSystems@127.0.0.1/roundcube MFA_TOTP_DIGITS=6 MFA_TOTP_INTERVAL=30 MFA_TOTP_DIGEST=sha1 IMAP_URI=ssl://127.0.0.1:11993 IMAP_ADMIN_LOGIN=cyrus-admin IMAP_ADMIN_PASSWORD=Welcome2KolabSystems IMAP_VERIFY_HOST=false IMAP_VERIFY_PEER=false LDAP_BASE_DN="dc=mgmt,dc=com" LDAP_DOMAIN_BASE_DN="ou=Domains,dc=mgmt,dc=com" LDAP_HOSTS=127.0.0.1 LDAP_PORT=389 LDAP_SERVICE_BIND_DN="uid=kolab-service,ou=Special Users,dc=mgmt,dc=com" LDAP_SERVICE_BIND_PW="Welcome2KolabSystems" LDAP_USE_SSL=false LDAP_USE_TLS=false # Administrative LDAP_ADMIN_BIND_DN="cn=Directory Manager" LDAP_ADMIN_BIND_PW="Welcome2KolabSystems" LDAP_ADMIN_ROOT_DN="dc=mgmt,dc=com" # Hosted (public registration) LDAP_HOSTED_BIND_DN="uid=hosted-kolab-service,ou=Special Users,dc=mgmt,dc=com" LDAP_HOSTED_BIND_PW="Welcome2KolabSystems" LDAP_HOSTED_ROOT_DN="dc=hosted,dc=com" COTURN_PUBLIC_IP=127.0.0.1 COTURN_STATIC_SECRET="Welcome2KolabSystems" MEET_WEBHOOK_TOKEN=Welcome2KolabSystems MEET_SERVER_TOKEN=Welcome2KolabSystems MEET_SERVER_URLS=https://localhost:12443/meetmedia/api/ MEET_SERVER_VERIFY_TLS=true MEET_WEBRTC_LISTEN_IP= MEET_PUBLIC_DOMAIN=127.0.0.1:12443 MEET_TURN_SERVER='turn:127.0.0.1:3478?transport=tcp' -PGP_ENABLED= -PGP_BINARY= -PGP_AGENT= -PGP_GPGCONF= +PGP_ENABLE=true +PGP_BINARY=/usr/bin/gpg +PGP_AGENT=/usr/bin/gpg-agent +PGP_GPGCONF=/usr/bin/gpgconf PGP_LENGTH= # Set these to IP addresses you serve WOAT with. # Have the domain owner point _woat. NS RRs refer to ns0{1,2}. WOAT_NS1=ns01.domain.tld WOAT_NS2=ns02.domain.tld REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 OCTANE_HTTP_HOST=127.0.0.1 SWOOLE_PACKAGE_MAX_LENGTH=10485760 PAYMENT_PROVIDER= MOLLIE_KEY= STRIPE_KEY= STRIPE_PUBLIC_KEY= STRIPE_WEBHOOK_SECRET= MAIL_MAILER=smtp MAIL_HOST=smtp.mailtrap.io MAIL_PORT=2525 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS="noreply@example.com" MAIL_FROM_NAME="Example.com" MAIL_REPLYTO_ADDRESS="replyto@example.com" MAIL_REPLYTO_NAME=null DNS_TTL=3600 DNS_SPF="v=spf1 mx -all" DNS_STATIC="%s. MX 10 ext-mx01.mykolab.com." DNS_COPY_FROM=null AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_DEFAULT_REGION=us-east-1 AWS_BUCKET= AWS_USE_PATH_STYLE_ENDPOINT=false PUSHER_APP_ID= PUSHER_APP_KEY= PUSHER_APP_SECRET= PUSHER_APP_CLUSTER=mt1 MIX_ASSET_PATH='/' MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" # Generate with ./artisan passport:client --password #PASSPORT_PROXY_OAUTH_CLIENT_ID= #PASSPORT_PROXY_OAUTH_CLIENT_SECRET= # Generate with ./artisan passport:client --password #PASSPORT_COMPANIONAPP_OAUTH_CLIENT_ID= #PASSPORT_COMPANIONAPP_OAUTH_CLIENT_SECRET= PASSPORT_PRIVATE_KEY= PASSPORT_PUBLIC_KEY= PASSWORD_POLICY= COMPANY_NAME= COMPANY_ADDRESS= COMPANY_DETAILS= COMPANY_EMAIL= COMPANY_LOGO= COMPANY_FOOTER= VAT_COUNTRIES=CH,LI VAT_RATE=7.7 KB_ACCOUNT_DELETE= KB_ACCOUNT_SUSPENDED= KB_PAYMENT_SYSTEM= KOLAB_SSL_CERTIFICATE=/etc/pki/tls/certs/kolab.hosted.com.cert KOLAB_SSL_CERTIFICATE_FULLCHAIN=/etc/pki/tls/certs/kolab.hosted.com.chain.pem KOLAB_SSL_CERTIFICATE_KEY=/etc/pki/tls/certs/kolab.hosted.com.key PROXY_SSL_CERTIFICATE=/etc/certs/imap.hosted.com.cert PROXY_SSL_CERTIFICATE_KEY=/etc/certs/imap.hosted.com.key - -PGP_ENABLE=true -PGP_BINARY=/usr/bin/gpg -PGP_AGENT=/usr/bin/gpg-agent -PGP_GPGCONF=/usr/bin/gpgconf