├── .gitignore ├── LICENSE ├── README.md ├── local.yml ├── tasks ├── general-last.yml ├── general.yml ├── myaac.yml ├── mysql.yml ├── nginx.yml ├── php-fpm.yml ├── phpmyadmin-sso.yml ├── phpmyadmin.yml ├── systemd.yml ├── tfs-old.yml ├── tfs.yml ├── wine.yml └── znoteaac.yml └── templates ├── .my.cnf ├── .otsmanager ├── 60-charset.cnf ├── 61-otshosting-motd ├── nginx-vhost.conf ├── php-fpm-pool.conf ├── systemd ├── journald.conf └── php-session-dir.conf ├── tfs-gdb.service └── tfs.service /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Daniel Speichert 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [DOCUMENTATION on wiki](https://github.com/DevelopersPL/otshosting-provisioning/wiki) 2 | 3 | otshosting-provisioning 4 | ======================= 5 | This is an Ansible playbook used to fully provision a Ubuntu machine for OTS Hosting. 6 | 7 | __Supported OS: Ubuntu 20.04, 22.04, 24.04__ 8 | 9 | Make sure to have universe, multiverse and restricted repositories enabled. 10 | 11 | A script to run on a standalone machine to provision it. If user "otsmanager" does not exist, it will be created with password: "otsmanager". 12 | ```bash 13 | #!/bin/bash -ex 14 | apt-get update 15 | apt install -y -q python3-simplejson git-core ansible 16 | ansible-pull -i localhost, -U https://github.com/DevelopersPL/otshosting-provisioning.git -d /srv/otshosting-provisioning --purge -t default 17 | ``` 18 | 19 | Available tags: 20 | 21 | * systemd - enables persistent journald logging (default) 22 | * general - software & integration (default) 23 | * mysql - MariaDB SQL server (default) 24 | * php-fpm - PHP support for website (default) 25 | * nginx - web server (default) 26 | * pma - phpMyAdmin for easy administration (default) 27 | * tfs - TFS 1.X automatically compiled and installed (default) 28 | * tfs-old - packages ONLY to compile older versions 29 | * znote - ZnoteAAC automatically installed & configured (default) 30 | * myaac - only installation, without configuration 31 | * wine - wine packages to run exe (engines compiled for Windows) 32 | 33 | 34 | ## cloud-init based provisioning 35 | 36 | A cloud-init script to provision a cloud instance using this playbook: 37 | ``` 38 | #cloud-config 39 | users: 40 | - name: otsmanager 41 | gecos: OTS Manager 42 | lock-passwd: false 43 | 44 | disable_root: true 45 | ssh_pwauth: True 46 | timezone: Europe/Warsaw 47 | 48 | package_upgrade: true 49 | package_update: true 50 | 51 | packages: 52 | - python3-simplejson 53 | - git 54 | - ansible 55 | - aptitude 56 | 57 | runcmd: 58 | - 'ansible-pull -i localhost, -U https://github.com/DevelopersPL/otshosting-provisioning.git -d /srv/otshosting-provisioning --purge' 59 | ``` 60 | -------------------------------------------------------------------------------- /local.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | handlers: 4 | - name: reload systemd 5 | command: /bin/systemctl daemon-reload 6 | 7 | - name: restart systemd-journald 8 | service: 9 | name: systemd-journald 10 | state: restarted 11 | 12 | - name: restart nginx 13 | service: 14 | name: nginx 15 | state: restarted 16 | 17 | - name: restart php7.4-fpm 18 | service: 19 | name: php7.4-fpm 20 | state: restarted 21 | 22 | - name: restart php8.1-fpm 23 | service: 24 | name: php8.1-fpm 25 | state: restarted 26 | 27 | - name: restart php8.3-fpm 28 | service: 29 | name: php8.3-fpm 30 | state: restarted 31 | 32 | - name: restart mysql 33 | service: 34 | name: mysql 35 | state: restarted 36 | 37 | tasks: 38 | - name: Fail if not running on Ubuntu 39 | fail: 40 | msg: This playbook only works on Ubuntu systems! 41 | when: ansible_distribution != 'Ubuntu' 42 | tags: always 43 | 44 | - name: Fail if Ubuntu older than 20.04 45 | fail: 46 | msg: This playbook requires Ubuntu >= 20.04 47 | when: ansible_distribution_major_version|int < 20 48 | tags: always 49 | 50 | - name: Check available PHP package name/version 51 | shell: apt-cache show php-fpm | grep Depends | head | awk '{print $2}' 52 | register: php_version_query 53 | changed_when: False 54 | tags: always 55 | 56 | - name: Register available PHP package name/version 57 | set_fact: 58 | # e.g.: php7.3-fpm 59 | php_fpm_package_name: "{{ php_version_query.stdout }}" 60 | # e.g.: php7.3 61 | php_version: "{{ php_version_query.stdout.split('-')[0] }}" 62 | # e.g.: 7.3 63 | php_version_number: "{{ php_version_query.stdout.split('-')[0][3:] }}" 64 | tags: always 65 | 66 | - import_tasks: tasks/systemd.yml 67 | tags: 68 | - default 69 | - systemd 70 | 71 | - import_tasks: tasks/general.yml 72 | tags: 73 | - default 74 | - general 75 | 76 | - import_tasks: tasks/mysql.yml 77 | tags: 78 | - default 79 | - mysql 80 | 81 | - import_tasks: tasks/php-fpm.yml 82 | tags: 83 | - default 84 | - php-fpm 85 | 86 | - import_tasks: tasks/nginx.yml 87 | tags: 88 | - default 89 | - nginx 90 | 91 | - import_tasks: tasks/phpmyadmin.yml 92 | tags: 93 | - default 94 | - pma 95 | 96 | - import_tasks: tasks/phpmyadmin-sso.yml 97 | when: ansible_distribution_major_version|int >= 22 98 | tags: 99 | - sso 100 | 101 | - import_tasks: tasks/tfs.yml 102 | tags: 103 | - default 104 | - tfs 105 | 106 | - import_tasks: tasks/tfs-old.yml 107 | tags: 108 | - tfs-old 109 | 110 | - import_tasks: tasks/znoteaac.yml 111 | tags: 112 | - default 113 | - znote 114 | 115 | - import_tasks: tasks/myaac.yml 116 | tags: 117 | - myaac 118 | 119 | - import_tasks: tasks/general-last.yml 120 | tags: 121 | - default 122 | - general 123 | 124 | - import_tasks: tasks/wine.yml 125 | tags: wine 126 | -------------------------------------------------------------------------------- /tasks/general-last.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create public_html directory 3 | file: 4 | path: /home/otsmanager/www/public_html 5 | owner: otsmanager 6 | group: otsmanager 7 | mode: 0755 8 | state: directory 9 | 10 | - name: Make public_html accessible to nginx 11 | file: 12 | path: /home/otsmanager 13 | mode: o+x 14 | state: directory 15 | -------------------------------------------------------------------------------- /tasks/general.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Remove LXC, snapd in case it's installed (Ubuntu Cloud has it) 3 | apt: 4 | state: absent 5 | pkg: 6 | - lxc 7 | - lxd 8 | - snapd 9 | 10 | - name: Upgrade whole system 11 | apt: 12 | upgrade: full 13 | 14 | - name: Install admin essentials 15 | apt: 16 | state: latest 17 | pkg: 18 | - mc 19 | - htop 20 | - unrar 21 | - rar 22 | - zip 23 | - p7zip 24 | - curl 25 | - python3-certbot-nginx 26 | - systemd-coredump 27 | - gdb 28 | - ncdu 29 | 30 | - name: Create otsmanager system user 31 | user: 32 | name: otsmanager 33 | password: $6$e8gmLzXM.YGXKz$L5YwwV8FitP1WGZQoVTH.1mUcOyFGe7HbYxhl2jJS7a05D1BIsjxUgfxRcjTwGd9riy6w1bqfRCjIq53WN3Kh. 34 | update_password: on_create 35 | shell: /bin/bash 36 | groups: systemd-journal 37 | append: yes 38 | 39 | - name: Select editor for otsmanager 40 | copy: 41 | dest: /home/otsmanager/.selected_editor 42 | content: "SELECTED_EDITOR=\"/usr/bin/mcedit\"" 43 | owner: otsmanager 44 | group: otsmanager 45 | 46 | - name: Install .otsmanager shell configuration 47 | template: 48 | src: templates/.otsmanager 49 | dest: /home/otsmanager/.otsmanager 50 | owner: otsmanager 51 | group: otsmanager 52 | mode: 0644 53 | 54 | - name: Activate .otsmanager shell configuration file 55 | lineinfile: 56 | dest: /home/otsmanager/.bashrc 57 | line: . ~/.otsmanager 58 | regexp: ^\. ~/\.otsmanager 59 | 60 | - name: Delete Ubuntu Cloud ad 61 | file: 62 | path: /etc/update-motd.d/51-cloudguest 63 | state: absent 64 | 65 | - name: Install welcome message 66 | template: 67 | src: templates/61-otshosting-motd 68 | dest: /etc/update-motd.d/61-otshosting-motd 69 | owner: root 70 | group: root 71 | mode: 0755 72 | -------------------------------------------------------------------------------- /tasks/myaac.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Clone MyAAC from Github 3 | git: 4 | repo: https://github.com/slawkens/myaac.git 5 | dest: /home/otsmanager/www/public_html 6 | become: true 7 | become_user: otsmanager 8 | 9 | - name: Configure config.lua path 10 | lineinfile: 11 | dest: /home/otsmanager/www/public_html/config.php 12 | regexp: "'server_path' =>" 13 | line: " 'server_path' => '/home/otsmanager/forgottenserver/'," 14 | 15 | - name: Configure friendly_urls 16 | lineinfile: 17 | dest: /home/otsmanager/www/public_html/config.php 18 | regexp: "'friendly_urls' =>" 19 | line: " 'friendly_urls' => true," 20 | 21 | #- name: Import MyAAC database schema 22 | # mysql_db: 23 | # name: forgottenserver 24 | # state: import 25 | # target: /home/otsmanager/www/public_html/install/includes/schema.sql 26 | -------------------------------------------------------------------------------- /tasks/mysql.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install MySQL Server and backup packages 3 | apt: 4 | state: latest 5 | pkg: 6 | - mariadb-server 7 | - python3-mysqldb 8 | - automysqlbackup 9 | 10 | - name: Change MySQL charset to prevent MySQL error 1709 11 | template: 12 | src: templates/60-charset.cnf 13 | dest: /etc/mysql/mariadb.conf.d/60-charset.cnf 14 | when: ansible_distribution_major_version|int > 15 15 | notify: restart mysql 16 | 17 | - name: Start Mysql Service 18 | service: 19 | name: mysql 20 | state: restarted 21 | enabled: true 22 | 23 | - name: Parse existing .my.cnf 24 | shell: grep -s pass /home/otsmanager/.my.cnf | sed 's/password=//' 25 | register: existingpass 26 | 27 | - name: Generate random MySQL otsmanager password 28 | command: openssl rand -base64 18 29 | register: randompass 30 | when: not existingpass.stdout 31 | 32 | - set_fact: 33 | mysql_otsmanager_pass: "{{ randompass.stdout if randompass is not skipped else existingpass.stdout }}" 34 | 35 | - name: Set MySQL otsmanager password (localhost) 36 | mysql_user: 37 | name: otsmanager 38 | password: "{{ mysql_otsmanager_pass }}" 39 | host: localhost 40 | priv: "*.*:ALL,GRANT" 41 | check_implicit_admin: yes 42 | 43 | - name: Save MySQL otsmanager password 44 | template: 45 | src: .my.cnf 46 | dest: /home/otsmanager/.my.cnf 47 | owner: otsmanager 48 | group: otsmanager 49 | mode: 0600 50 | 51 | - name: Set MySQL otsmanager password (%) 52 | mysql_user: 53 | name: otsmanager 54 | password: "{{ mysql_otsmanager_pass }}" 55 | host: "%" 56 | priv: "*.*:ALL,GRANT" 57 | check_implicit_admin: yes 58 | 59 | - name: Check hostname 60 | command: hostname -f 61 | register: realhostname 62 | 63 | - name: Delete MySQL root accounts we don't want 64 | mysql_user: 65 | name: root 66 | host: "{{item}}" 67 | state: absent 68 | check_implicit_admin: yes 69 | with_items: 70 | - 127.0.0.1 71 | - ::1 72 | - realhostname.stdout 73 | - "%" 74 | 75 | - name: Ensure anonymous MySQL users are not in the database 76 | mysql_user: 77 | name: "" 78 | host_all: yes 79 | state: absent 80 | check_implicit_admin: yes 81 | 82 | - name: Delete MySQL test database 83 | mysql_db: 84 | name: test 85 | state: absent 86 | 87 | - name: Allow otsmanager to access automysqlbackup directory 88 | file: 89 | path: /var/lib/automysqlbackup 90 | state: directory 91 | group: otsmanager 92 | -------------------------------------------------------------------------------- /tasks/nginx.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install nginx 3 | apt: 4 | pkg: nginx 5 | state: latest 6 | 7 | - name: Create /etc/nginx/default.d 8 | file: 9 | dest: /etc/nginx/default.d 10 | state: directory 11 | 12 | - name: Copy nginx configuration for default vhost 13 | template: 14 | src: templates/nginx-vhost.conf 15 | dest: /etc/nginx/sites-available/default 16 | notify: restart nginx 17 | 18 | - name: Start nginx Service 19 | service: 20 | name: nginx 21 | state: started 22 | enabled: yes 23 | -------------------------------------------------------------------------------- /tasks/php-fpm.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install php-fpm 3 | apt: 4 | state: latest 5 | pkg: 6 | - php-fpm 7 | - php-apcu 8 | - php-mysqlnd 9 | - php-curl 10 | - php-xml 11 | - php-mbstring 12 | - composer 13 | 14 | - name: Set php.ini display_errors 15 | lineinfile: 16 | dest: /etc/php/{{ php_version_number }}/fpm/php.ini 17 | line: "display_errors = On" 18 | regexp: "^display_errors =" 19 | notify: restart php{{ php_version_number }}-fpm 20 | 21 | - name: Set php.ini default_timezone 22 | lineinfile: 23 | dest: /etc/php/{{ php_version_number }}/fpm/php.ini 24 | line: "date.timezone = Europe/Warsaw" 25 | regexp: "^date.timezone =" 26 | notify: restart php{{ php_version_number }}-fpm 27 | 28 | - name: Set php.ini upload_max_filesize 29 | lineinfile: 30 | dest: /etc/php/{{ php_version_number }}/fpm/php.ini 31 | line: "upload_max_filesize = 64M" 32 | regexp: "^upload_max_filesize =" 33 | notify: restart php{{ php_version_number }}-fpm 34 | 35 | - name: Set php.ini post_max_size 36 | lineinfile: 37 | dest: /etc/php/{{ php_version_number }}/fpm/php.ini 38 | line: "post_max_size = 64M" 39 | regexp: "^post_max_size =" 40 | notify: restart php{{ php_version_number }}-fpm 41 | 42 | - name: Copy php{{ php_version_number }}-fpm pool configuration 43 | template: 44 | src: templates/php-fpm-pool.conf 45 | dest: /etc/php/{{ php_version_number }}/fpm/pool.d/otsmanager.conf 46 | notify: restart php{{ php_version_number }}-fpm 47 | 48 | - name: Create /etc/systemd/system/php{{ php_version_number }}-fpm.service.d 49 | file: 50 | dest: /etc/systemd/system/php{{ php_version_number }}-fpm.service.d 51 | state: directory 52 | 53 | - name: Copy session-dir.conf unit override for PHP{{ php_version_number }}-FPM 54 | template: 55 | src: templates/systemd/php-session-dir.conf 56 | dest: /etc/systemd/system/php{{ php_version_number }}-fpm.service.d/session-dir.conf 57 | notify: 58 | - reload systemd 59 | - restart php{{ php_version_number }}-fpm 60 | 61 | - name: Start php{{ php_version_number }}-fpm Service 62 | service: 63 | name: php{{ php_version_number }}-fpm 64 | state: started 65 | enabled: true 66 | -------------------------------------------------------------------------------- /tasks/phpmyadmin-sso.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Give www-data access to MySQL 3 | mysql_user: 4 | name: www-data 5 | host: localhost 6 | priv: "*.*:ALL,GRANT" 7 | plugin: unix_socket 8 | plugin_hash_string: www-data 9 | check_implicit_admin: yes 10 | 11 | - name: Download latest PMA SSO 12 | git: 13 | repo: https://gist.github.com/857dfc08aacb208bbade901ba7b9f9ba.git 14 | dest: /usr/local/share/pmasso 15 | 16 | - name: Install dependencies 17 | community.general.composer: 18 | command: install 19 | working_dir: /usr/local/share/pmasso 20 | environment: 21 | COMPOSER_HOME: /root/.config/composer 22 | COMPOSER_ALLOW_SUPERUSER: 1 23 | 24 | - name: Activate PMA SSO 25 | file: 26 | src: /usr/local/share/pmasso/sso.php 27 | dest: /etc/phpmyadmin/conf.d/sso.php 28 | owner: root 29 | group: root 30 | state: link 31 | -------------------------------------------------------------------------------- /tasks/phpmyadmin.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install debconf to set preseed info 3 | apt: 4 | pkg: debconf-utils 5 | 6 | - name: Set preseed info phpmyadmin/dbconfig-install 7 | debconf: 8 | name: phpmyadmin 9 | question: phpmyadmin/dbconfig-install 10 | value: true 11 | vtype: boolean 12 | 13 | - name: Set preseed info phpmyadmin/app-password-confirm 14 | debconf: 15 | name: phpmyadmin 16 | question: phpmyadmin/app-password-confirm 17 | value: '' 18 | vtype: password 19 | 20 | - name: Set preseed info phpmyadmin/mysql/admin-pass 21 | debconf: 22 | name: phpmyadmin 23 | question: phpmyadmin/mysql/admin-pass 24 | value: '' 25 | vtype: password 26 | 27 | - name: Set preseed info phpmyadmin/mysql/app-pass 28 | debconf: 29 | name: phpmyadmin 30 | question: phpmyadmin/mysql/app-pass 31 | value: '' 32 | vtype: password 33 | 34 | - name: Set preseed info phpmyadmin/reconfigure-webserver 35 | debconf: 36 | name: phpmyadmin 37 | question: phpmyadmin/reconfigure-webserver 38 | value: '' 39 | vtype: multiselect 40 | 41 | - name: Install phpmyadmin 42 | apt: 43 | pkg: phpmyadmin 44 | state: latest 45 | -------------------------------------------------------------------------------- /tasks/systemd.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # journal config 3 | - name: Create /var/log/journal 4 | file: 5 | path: /var/log/journal 6 | state: directory 7 | owner: root 8 | group: systemd-journal 9 | mode: 02755 10 | 11 | - name: Create /etc/systemd/journald.conf.d 12 | file: 13 | path: /etc/systemd/journald.conf.d 14 | state: directory 15 | 16 | - name: Install /etc/systemd/journald.conf.d/journald.conf 17 | template: 18 | src: systemd/journald.conf 19 | dest: /etc/systemd/journald.conf.d/journald.conf 20 | owner: root 21 | group: root 22 | mode: 0644 23 | notify: restart systemd-journald 24 | -------------------------------------------------------------------------------- /tasks/tfs-old.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: 'Compatibility: Install packages needed to compile old TFS (0.3/0.4)' 3 | apt: 4 | state: latest 5 | pkg: 6 | - autoconf 7 | - libxml2-dev 8 | - libboost-thread-dev 9 | - libboost-regex-dev 10 | - libboost-filesystem-dev 11 | - liblua5.1-dev 12 | - libcrypto++-dev 13 | - libssl-dev 14 | - libgmp-dev 15 | -------------------------------------------------------------------------------- /tasks/tfs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install packages needed to compile TFS 3 | apt: 4 | state: latest 5 | pkg: 6 | - git 7 | - cmake 8 | - build-essential 9 | - libmysqlclient-dev 10 | - libboost-system-dev 11 | - libboost-date-time-dev 12 | - libboost-filesystem-dev 13 | - libboost-iostreams-dev 14 | - libboost-locale-dev 15 | - libboost-json-dev 16 | - libcrypto++-dev 17 | - liblua5.2-dev 18 | - libluajit-5.1-dev 19 | - libpugixml-dev 20 | - libfmt-dev 21 | 22 | - name: Install systemd service for TFS 23 | template: 24 | src: templates/{{item}} 25 | dest: /etc/systemd/system/{{item}} 26 | with_items: 27 | - tfs.service 28 | - tfs-gdb.service 29 | 30 | - name: Download latest TFS from git 31 | git: 32 | repo: https://github.com/otland/forgottenserver.git 33 | dest: /home/otsmanager/forgottenserver 34 | version: master 35 | become: true 36 | become_user: otsmanager 37 | 38 | - name: Parse existing config.lua 39 | shell: grep -s mysqlPass /home/otsmanager/forgottenserver/config.lua | sed -E 's/mysqlPass = "(.*)"/\1/g' 40 | register: existingpass 41 | 42 | - name: Generate random MySQL forgottenserver password 43 | command: openssl rand -base64 18 44 | register: randompass 45 | when: not existingpass.stdout 46 | 47 | - set_fact: 48 | mysql_forgottenserver_pass: "{{ randompass.stdout if randompass is not skipped else existingpass.stdout }}" 49 | 50 | - name: Create database user for TFS 51 | mysql_user: 52 | name: forgottenserver 53 | password: "{{mysql_forgottenserver_pass}}" 54 | priv: forgottenserver.*:ALL 55 | check_implicit_admin: yes 56 | 57 | - name: Create database for TFS 58 | mysql_db: 59 | name: forgottenserver 60 | 61 | - name: Import database for TFS 62 | mysql_db: 63 | name: forgottenserver 64 | state: import 65 | target: /home/otsmanager/forgottenserver/schema.sql 66 | login_unix_socket: /var/run/mysqld/mysqld.sock 67 | 68 | - name: Copy config.lua.dist to config.lua if necessary 69 | copy: 70 | dest: /home/otsmanager/forgottenserver/config.lua 71 | src: /home/otsmanager/forgottenserver/config.lua.dist 72 | remote_src: yes 73 | owner: otsmanager 74 | group: otsmanager 75 | 76 | - name: Put mysqlHost for database in config.lua 77 | lineinfile: 78 | dest: /home/otsmanager/forgottenserver/config.lua 79 | regexp: ^mysqlHost 80 | line: 'mysqlHost = "localhost"' 81 | 82 | - name: Put mysqlSock for database in config.lua 83 | lineinfile: 84 | dest: /home/otsmanager/forgottenserver/config.lua 85 | regexp: ^mysqlSock 86 | line: 'mysqlSock = "/var/run/mysqld/mysqld.sock"' 87 | 88 | - name: Put password for database in config.lua 89 | lineinfile: 90 | dest: /home/otsmanager/forgottenserver/config.lua 91 | regexp: ^mysqlPass 92 | line: 'mysqlPass = "{{mysql_forgottenserver_pass}}"' 93 | 94 | - name: Put server's IP address in config.lua 95 | lineinfile: 96 | dest: /home/otsmanager/forgottenserver/config.lua 97 | regexp: "^ip =" 98 | line: 'ip = "{{ansible_default_ipv4.address}}"' 99 | 100 | - name: Create build directory 101 | file: 102 | path: /home/otsmanager/forgottenserver/build 103 | owner: otsmanager 104 | group: otsmanager 105 | mode: 0755 106 | state: directory 107 | become: true 108 | become_user: otsmanager 109 | 110 | - name: Cmake forgottenserver source 111 | command: cmake .. 112 | args: 113 | chdir: /home/otsmanager/forgottenserver/build 114 | tags: compile 115 | become: true 116 | become_user: otsmanager 117 | 118 | - name: Compile forgottenserver source 119 | command: make -j2 120 | args: 121 | chdir: /home/otsmanager/forgottenserver/build 122 | tags: compile 123 | become: true 124 | become_user: otsmanager 125 | -------------------------------------------------------------------------------- /tasks/wine.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install wine-development 3 | apt: 4 | pkg: wine-development 5 | state: latest 6 | update_cache: yes 7 | -------------------------------------------------------------------------------- /tasks/znoteaac.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Clone ZnoteAAC from Github 3 | git: 4 | repo: https://github.com/Znote/ZnoteAAC.git 5 | dest: /home/otsmanager/www/public_html 6 | become: true 7 | become_user: otsmanager 8 | 9 | - name: Configure SQL username 10 | lineinfile: 11 | dest: /home/otsmanager/www/public_html/config.php 12 | regexp: \$config\['sqlUser'\] 13 | line: " $config['sqlUser'] = 'forgottenserver';" 14 | 15 | - name: Configure SQL password 16 | lineinfile: 17 | dest: /home/otsmanager/www/public_html/config.php 18 | regexp: \$config\['sqlPassword'\] 19 | line: " $config['sqlPassword'] = '{{mysql_forgottenserver_pass}}';" 20 | 21 | - name: Configure SQL database 22 | lineinfile: 23 | dest: /home/otsmanager/www/public_html/config.php 24 | regexp: \$config\['sqlDatabase'\] 25 | line: " $config['sqlDatabase'] = 'forgottenserver';" 26 | 27 | - name: Configure SQL host 28 | lineinfile: 29 | dest: /home/otsmanager/www/public_html/config.php 30 | regexp: \$config\['sqlHost'\] 31 | line: " $config['sqlHost'] = 'localhost';" 32 | 33 | - name: Configure server path 34 | lineinfile: 35 | dest: /home/otsmanager/www/public_html/config.php 36 | regexp: \$config\['server_path'\] 37 | line: " $config['server_path'] = '/home/otsmanager/forgottenserver';" 38 | 39 | - name: Import ZnoteAAC database schema 40 | mysql_db: 41 | name: forgottenserver 42 | state: import 43 | target: /home/otsmanager/www/public_html/engine/database/znote_schema.sql 44 | login_unix_socket: /var/run/mysqld/mysqld.sock 45 | -------------------------------------------------------------------------------- /templates/.my.cnf: -------------------------------------------------------------------------------- 1 | [client] 2 | user=otsmanager 3 | password={{ mysql_otsmanager_pass }} 4 | -------------------------------------------------------------------------------- /templates/.otsmanager: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | alias start='sudo systemctl start' 3 | alias stop='sudo systemctl stop' 4 | alias status='sudo systemctl --no-pager status' 5 | alias restart='sudo systemctl restart' 6 | alias enable='sudo systemctl enable' 7 | alias disable='sudo systemctl disable' 8 | alias log='journalctl -u' 9 | alias follow='journalctl -f -u' 10 | alias updatetfs='cd /home/otsmanager/forgottenserver && git pull && rm -rf build && mkdir -p build && cd build && cmake .. && make && cd' 11 | alias duedate=`echo date -d $(curl -m 1 -s https://otshosting.pl/api/otshosting/expires)` 12 | function GetLocalIP() 13 | { 14 | ip -4 -o addr show eth0 | egrep -o '([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}' | head -n 1 15 | } 16 | alias serverip=GetLocalIP 17 | # https://transfer.sh/ 18 | # https://gist.github.com/nl5887/a511f172d3fb3cd0e42d 19 | function transfer() { 20 | # check arguments 21 | if [ $# -eq 0 ]; 22 | then 23 | echo "No arguments specified. Usage:\necho transfer /tmp/test.md\ncat /tmp/test.md | transfer test.md" 24 | return 1 25 | fi 26 | 27 | # get temporarily filename, output is written to this file show progress can be showed 28 | tmpfile=$( mktemp -t transferXXX ) 29 | 30 | # upload stdin or file 31 | file=$1 32 | 33 | if tty -s; 34 | then 35 | basefile=$(basename "$file" | sed -e 's/[^a-zA-Z0-9._-]/-/g') 36 | 37 | if [ ! -e $file ]; 38 | then 39 | echo "File $file doesn't exists." 40 | return 1 41 | fi 42 | 43 | if [ -d $file ]; 44 | then 45 | # zip directory and transfer 46 | zipfile=$( mktemp -t transferXXX.zip ) 47 | cd $(dirname $file) && zip -r -q - $(basename $file) >> $zipfile 48 | curl --progress-bar --upload-file "$zipfile" "https://transfer.sh/$basefile.zip" >> $tmpfile 49 | rm -f $zipfile 50 | else 51 | # transfer file 52 | curl --progress-bar --upload-file "$file" "https://transfer.sh/$basefile" >> $tmpfile 53 | fi 54 | else 55 | # transfer pipe 56 | curl --progress-bar --upload-file "-" "https://transfer.sh/$file" >> $tmpfile 57 | fi 58 | 59 | # cat output link 60 | cat $tmpfile 61 | 62 | # cleanup 63 | rm -f $tmpfile 64 | } 65 | alias transfer=transfer 66 | 67 | expires=$(curl -m 1 -s https://otshosting.pl/api/otshosting/expires) 68 | 69 | echo "=================== MySQL ===================" 70 | echo " phpMyAdmin: https://$(GetLocalIP)/pma3380" 71 | echo " Username: `cat ~/.my.cnf | sed -n -e '2{p;q}' | awk -F'=' '{ print $2 }'`" 72 | echo " Password: `cat ~/.my.cnf | sed -n -e '3{p;q}' | awk -F'=' '{ print $2 }'`" 73 | echo -e ' You can execute \E[32;40mmysql'"\033[1m\033[0m commands without a password." 74 | echo " Total size and location of MySQL backups: `du -hs /var/lib/automysqlbackup/`" 75 | echo " Put your website files in /home/otsmanager/www/public_html" 76 | echo "" 77 | echo "=================== TFS commands ===================" 78 | echo " If you run TFS with the following commands, it will auto restart." 79 | echo -e ' Enable auto-start on boot: \E[32;40msudo systemctl enable tfs'"\033[1m\033[0m" 80 | echo -e ' Disable auto-start on boot: \E[32;40msudo systemctl disable tfs'"\033[1m\033[0m" 81 | echo -e ' Start TFS: \E[32;40msudo systemctl start tfs'"\033[1m\033[0m" 82 | echo -e ' Stop TFS: \E[32;40msudo systemctl stop tfs'"\033[1m\033[0m" 83 | echo -e ' Restart TFS: \E[32;40msudo systemctl restart tfs'"\033[1m\033[0m" 84 | echo -e ' Check status of TFS: \E[32;40msudo systemctl status tfs'"\033[1m\033[0m" 85 | echo -e ' Show full TFS log: \E[32;40mjournalctl -u tfs'"\033[1m\033[0m (q to exit)" 86 | echo -e ' Follow TFS console: \E[32;40mjournalctl -u tfs -f'"\033[1m\033[0m (CTRL+C to stop)" 87 | echo "" 88 | echo "=================== Useful commands ===================" 89 | echo -e 'Update TFS to latest master: \E[32;40mupdatetfs'"\033[1m\033[0m" 90 | echo -e ' Show service due date: \E[32;40mduedate'"\033[1m\033[0m" 91 | echo -e ' Show server IP: \E[32;40mserverip'"\033[1m\033[0m" 92 | echo -e ' Share a file: \E[32;40mtransfer path/to/file'"\033[1m\033[0m" 93 | 94 | echo "" 95 | if [ "not found" != "$expires" ]; then 96 | echo -e "\e[0;33mYour service expires on $(date -d $expires)\033[1m\033[0m" 97 | fi 98 | echo -n "Current TFS status: " 99 | status tfs 100 | -------------------------------------------------------------------------------- /templates/60-charset.cnf: -------------------------------------------------------------------------------- 1 | [mysqld] 2 | character-set-server = utf8mb4 3 | collation-server = utf8mb4_unicode_ci 4 | -------------------------------------------------------------------------------- /templates/61-otshosting-motd: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "" 3 | echo -e ' \E[37;42mWelcome to OTS Hosting preconfigured server!'"\033[1m\033[0m" 4 | echo "" 5 | echo "Community support available at https://otland.net/forums/support.16/" 6 | -------------------------------------------------------------------------------- /templates/nginx-vhost.conf: -------------------------------------------------------------------------------- 1 | limit_req_zone $binary_remote_addr zone=req_zone:10m rate=60r/m; 2 | 3 | map $http_upgrade $connection_upgrade { 4 | default upgrade; 5 | '' close; 6 | } 7 | 8 | server { 9 | listen 80 default_server; 10 | listen 443 ssl default_server; 11 | server_name _; 12 | root /home/otsmanager/www/public_html; 13 | 14 | ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; 15 | ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; 16 | ssl_protocols TLSv1.2 TLSv1.3; 17 | ssl_prefer_server_ciphers off; 18 | ssl_ciphers TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; 19 | ssl_ecdh_curve X25519:prime256v1:secp384r1; 20 | ssl_session_timeout 10m; 21 | ssl_session_cache shared:SSL:10m; 22 | ssl_session_tickets off; 23 | 24 | # https://wiki.mozilla.org/Security/Server_Side_TLS#OCSP_Stapling 25 | # https://tools.ietf.org/html/rfc6066#section-8 26 | # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling 27 | # 28 | # (1) Use Cloudflare 1.1.1.1 DNS resolver 29 | # https://developers.cloudflare.com/1.1.1.1/setting-up-1.1.1.1/ 30 | # 31 | # (2) Use Google 8.8.8.8 DNS resolver 32 | # https://developers.google.com/speed/public-dns/docs/using 33 | # 34 | # (3) Use Dyn DNS resolver 35 | # https://help.dyn.com/internet-guide-setup/ 36 | ssl_stapling on; 37 | ssl_stapling_verify on; 38 | 39 | resolver 40 | # (1) 41 | 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] 42 | # (2) 43 | 8.8.8.8 8.8.4.4 [2001:4860:4860::8888] [2001:4860:4860::8844] 44 | # (3) 45 | # 216.146.35.35 216.146.36.36 46 | valid=60s; 47 | resolver_timeout 2s; 48 | 49 | add_header X-Frame-Options DENY; 50 | add_header X-Content-Type-Options nosniff; 51 | add_header X-XSS-Protection "1; mode=block"; 52 | 53 | client_max_body_size 64M; 54 | error_page 404 @notfound; 55 | 56 | # internal otd server 57 | location /api-otd { 58 | rewrite /api-otd(/?)(.*) /$2 break; 59 | proxy_set_header Host $host; 60 | proxy_set_header X-Real-IP $remote_addr; 61 | proxy_http_version 1.1; 62 | proxy_set_header Upgrade $http_upgrade; 63 | proxy_set_header Connection $connection_upgrade; 64 | proxy_pass http://localhost:5555; 65 | } 66 | 67 | # mask known ZnoteAAC directories 68 | location /LUA { 69 | deny all; 70 | return 404; 71 | } 72 | 73 | location /engine/cache { 74 | deny all; 75 | return 404; 76 | } 77 | 78 | location /special { 79 | allow 127.0.0.1; 80 | deny all; 81 | } 82 | 83 | # mask known MyAAC directories 84 | location /cache { 85 | deny all; 86 | return 404; 87 | } 88 | 89 | location /logs { 90 | deny all; 91 | return 404; 92 | } 93 | 94 | location /migrations { 95 | deny all; 96 | return 404; 97 | } 98 | 99 | location /plugins { 100 | deny all; 101 | return 404; 102 | } 103 | 104 | location /system { 105 | deny all; 106 | return 404; 107 | } 108 | 109 | # our regular locations 110 | location / { 111 | index index.html index.php; 112 | try_files $uri $uri/ /index.php?$args; 113 | } 114 | 115 | location ~* \.(gif|jpg|jpeg|png|bmp|js|css)$ { 116 | expires max; 117 | } 118 | 119 | location ~ \.php$ { 120 | limit_req zone=req_zone burst=10 nodelay; 121 | try_files $fastcgi_script_name =404; 122 | fastcgi_pass unix:/var/run/php/php-fpm-otsmanager.sock; 123 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 124 | fastcgi_buffers 16 16k; 125 | fastcgi_buffer_size 32k; 126 | include fastcgi_params; 127 | # Bypass the fact that try_files resets $fastcgi_path_info 128 | # see: http://trac.nginx.org/nginx/ticket/321 129 | set $path_info $fastcgi_path_info; 130 | fastcgi_param PATH_INFO $path_info; 131 | } 132 | 133 | location @notfound { 134 | return 404 "The page or file you requested was not found. If this is your server, make sure you placed it under /home/otsmanager/www/public_html directory."; 135 | add_header Content-Type text/plain always; 136 | } 137 | 138 | # phpMyAdmin 139 | location /pma3380 { 140 | alias /usr/share/phpmyadmin; 141 | client_max_body_size 64M; 142 | 143 | index index.html index.php; 144 | try_files $uri $uri/ /index.php?$args; 145 | 146 | location ~ \.php$ { 147 | limit_req zone=req_zone burst=20 nodelay; 148 | try_files $fastcgi_script_name =404; 149 | fastcgi_split_path_info ^(.+\.php)(/.+)$; 150 | fastcgi_index index.php; 151 | fastcgi_pass unix:/var/run/php/{{ php_fpm_package_name }}.sock; 152 | fastcgi_param SCRIPT_FILENAME $request_filename; 153 | include fastcgi_params; 154 | # Bypass the fact that try_files resets $fastcgi_path_info 155 | # see: http://trac.nginx.org/nginx/ticket/321 156 | set $path_info $fastcgi_path_info; 157 | fastcgi_param PATH_INFO $path_info; 158 | } 159 | 160 | location ~* \.(gif|jpg|jpeg|png|js|css)$ { 161 | expires max; 162 | } 163 | 164 | location /pma3380/libraries { 165 | deny all; 166 | } 167 | 168 | location /pma3380/setup { 169 | deny all; 170 | } 171 | } 172 | 173 | # Cloudflare 174 | real_ip_header CF-Connecting-IP; 175 | 176 | set_real_ip_from 173.245.48.0/20; 177 | set_real_ip_from 103.21.244.0/22; 178 | set_real_ip_from 103.22.200.0/22; 179 | set_real_ip_from 103.31.4.0/22; 180 | set_real_ip_from 141.101.64.0/18; 181 | set_real_ip_from 108.162.192.0/18; 182 | set_real_ip_from 190.93.240.0/20; 183 | set_real_ip_from 188.114.96.0/20; 184 | set_real_ip_from 197.234.240.0/22; 185 | set_real_ip_from 198.41.128.0/17; 186 | set_real_ip_from 162.158.0.0/15; 187 | set_real_ip_from 104.16.0.0/13; 188 | set_real_ip_from 104.24.0.0/14; 189 | set_real_ip_from 172.64.0.0/13; 190 | set_real_ip_from 131.0.72.0/22; 191 | set_real_ip_from 2400:cb00::/32; 192 | set_real_ip_from 2606:4700::/32; 193 | set_real_ip_from 2803:f800::/32; 194 | set_real_ip_from 2405:b500::/32; 195 | set_real_ip_from 2405:8100::/32; 196 | set_real_ip_from 2a06:98c0::/29; 197 | set_real_ip_from 2c0f:f248::/32; 198 | 199 | include /etc/nginx/default.d/*.conf; 200 | } 201 | -------------------------------------------------------------------------------- /templates/php-fpm-pool.conf: -------------------------------------------------------------------------------- 1 | [otsmanager] 2 | listen = /var/run/php/php-fpm-otsmanager.sock 3 | listen.owner = www-data 4 | listen.group = www-data 5 | listen.mode = 0660 6 | user = otsmanager 7 | group = otsmanager 8 | pm = dynamic 9 | pm.max_children = 10 10 | pm.start_servers = 1 11 | pm.min_spare_servers = 1 12 | pm.max_spare_servers = 3 13 | pm.max_requests = 500 14 | php_admin_value[open_basedir] = /home/otsmanager:/tmp 15 | -------------------------------------------------------------------------------- /templates/systemd/journald.conf: -------------------------------------------------------------------------------- 1 | [Journal] 2 | Storage=persistent 3 | Compress=yes 4 | SplitMode=uid 5 | SystemMaxUse=500M 6 | -------------------------------------------------------------------------------- /templates/systemd/php-session-dir.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | ExecStartPre=-/bin/mount -t tmpfs -o size=32m,mode=0777,uid=33,gid=33 tmpfs /var/lib/php/sessions/ 3 | ExecStopPost=-/bin/umount -l /var/lib/php/sessions/ 4 | -------------------------------------------------------------------------------- /templates/tfs-gdb.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=The Forgotten Server 3 | After=network.target 4 | Wants=network-online.target mysql.service 5 | After=network-online.target mysql.service 6 | Conflicts=tfs.service 7 | 8 | [Service] 9 | Type=simple 10 | ExecStart=/usr/bin/gdb -q -batch -ex "handle SIGTERM nostop pass" -ex "handle SIGINT nostop pass" -ex "handle SIGHUP nostop pass" -ex "handle SIGUSR1 nostop pass" -ex "run" -ex "thread apply all backtrace" /home/otsmanager/forgottenserver/build/tfs 11 | WorkingDirectory=/home/otsmanager/forgottenserver 12 | User=otsmanager 13 | Group=otsmanager 14 | Restart=always 15 | LimitCORE=104857600 16 | LimitNOFILE=8192 17 | 18 | [Install] 19 | WantedBy=default.target 20 | -------------------------------------------------------------------------------- /templates/tfs.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=The Forgotten Server 3 | After=network.target 4 | Wants=network-online.target mysql.service 5 | After=network-online.target mysql.service 6 | 7 | [Service] 8 | Type=simple 9 | ExecStart=/home/otsmanager/forgottenserver/build/tfs 10 | WorkingDirectory=/home/otsmanager/forgottenserver 11 | User=otsmanager 12 | Group=otsmanager 13 | Restart=always 14 | LimitCORE=104857600 15 | LimitNOFILE=8192 16 | 17 | [Install] 18 | WantedBy=default.target 19 | --------------------------------------------------------------------------------