commit 2e64ef4894dc5f389cadee85672f29cd8d265078 Author: Mathieu Deloitte Date: Fri Aug 19 12:40:33 2016 +0200 Init with Ansible for MISP v0.1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8d82860 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +tmp +.DS_Store +*.retry diff --git a/README.md b/README.md new file mode 100644 index 0000000..15a9895 --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +MISP - Ansible installation script +---------------------------------------- + +- V0.1 + * Nginx support only + * Backup script provided + +Instructions +---------------------------------------- +- From the ansible repository, run the following command: + +```bash +ansible-playbook -i , misp.yml -k -K -u +``` + +- Update the self-signed certificate in /etc/nginx/ssl +- Create and export your GPG key: + +```bash +sudo -u www-data gpg --homedir /opt/misp-server/misp/.gnupg --gen-key +sudo -u www-data gpg --homedir /opt/misp-server/misp/.gnupg --export --armor YOUR-EMAIL > /opt/misp-server/misp/app/webroot/gpg.asc +``` + +- Login with: + * user: admin@admin.test + * password: admin +and update the admin password + +- Configure MISP in administration panel, server settings + +Notes +---------------------------------------- +- the user must have admin rights +- a self-signed certificate is generated to allow you to test the installation +- installation directory is: /opt/misp-server/misp +- backup directory is: /opt/misp-server/backup + +Backup script +---------------------------------------- +If enabled, a backup script create each day a new archive with a MySQL misp database dump and misp files to allow easy restore. +- these archives are created in: /opt/misp-server/backup +- a script to easy restore MISP from an archive is provided in the same directory +- to use the restore script, login as misp user and run the following command: + +```bash +./misp_restore .tar.gz +``` + diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..771d0b7 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,3 @@ +[ssh_connection] +ssh_args = -F ssh.cfg +pipelining = True diff --git a/misp.yml b/misp.yml new file mode 100644 index 0000000..5e739eb --- /dev/null +++ b/misp.yml @@ -0,0 +1,30 @@ +--- +- hosts: all + become: true + roles: + - { role: mysql} + - { role: misp} + - { role: nginx} + + vars_prompt: + - name: "proxy_host" + prompt: "Enter the proxy host (e.g. myproxy.be)" + private: no + - name: "proxy_port" + prompt: "Enter the proxy port (e.g. 3128)" + private: no + - name: "servername" + prompt: "Enter the servername address to use for the webserver (e.g. misp.com)" + private: no + - name: "mysql_root_old_pass" + prompt: "MySQL root password (current or default/empty)" + private: yes + - name: "mysql_root_new_pass" + prompt: "MySQL root password (new/current)" + private: yes + - name: mysql_misp_password + prompt: "Enter the mysql misp user password" + private: yes + - name: enable_auto_backup + prompt: "Do you want to enable automatic backup everyday ? (y/n)" + private: no diff --git a/roles/misp/defaults/main.yml b/roles/misp/defaults/main.yml new file mode 100644 index 0000000..e0f3215 --- /dev/null +++ b/roles/misp/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# default lower priority variables for this role diff --git a/roles/misp/handlers/main.yml b/roles/misp/handlers/main.yml new file mode 100644 index 0000000..ab87711 --- /dev/null +++ b/roles/misp/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# Handlers file diff --git a/roles/misp/meta/main.yml b/roles/misp/meta/main.yml new file mode 100644 index 0000000..526681f --- /dev/null +++ b/roles/misp/meta/main.yml @@ -0,0 +1,2 @@ +--- +# Role dependancies diff --git a/roles/misp/tasks/main.yml b/roles/misp/tasks/main.yml new file mode 100644 index 0000000..b6114e6 --- /dev/null +++ b/roles/misp/tasks/main.yml @@ -0,0 +1,364 @@ +--- +# Install basic packages +- name: Create misp user + user: + name: misp + state: present + +- name: Create Ansible directory + file: + path: "/home/misp/ansible" + owner: misp + group: misp + mode: 0775 + state: directory + +- name: Install all needed packages + apt: + pkg: "{{ item }}" + state: latest + update_cache: yes + with_items: + - gcc + - zip + - php-pear + - git + - redis-server + - make + - python-dev + - python-pip + - libxml2-dev + - libxslt1-dev + - zlib1g-dev + - php5-dev + - curl + - gnupg-agent + - php5-mysql + - php5-redis + +######### MISP users and groups ######### + +- name: Add MISP group + group: + name: "{{ item }}" + state: present + system: yes + with_items: + - "misp-server" + +- name: Add misp in misp-server + user: + name: misp + append: yes + groups: misp-server + state: present + +- name: Add www-data in misp-server + user: + name: www-data + append: yes + groups: misp-server + +######### MISP directories ######### + +- name: Create MISP server directory + file: + path: "{{ item }}" + owner: misp + group: misp-server + mode: 02775 + state: directory + with_items: + - "/opt/misp-server" + - "/opt/misp-server/misp" + - "/opt/misp-server/tmp" + - "/opt/misp-server/backup" + +######### PEAR: CRYPTPGP ######### +- name: Configure PEAR proxy + shell: "{{ item }}" + args: + creates: /home/misp/ansible/ansible_shell_pear_configure_proxy.log + with_items: + - "pear config-set http_proxy http://{{proxy_host}}:{{proxy_port}} > /home/misp/ansible/ansible_shell_pear_configure_proxy.log" + +- name: Configure PEAR tmp + shell: "{{ item }}" + args: + creates: /home/misp/ansible/ansible_shell_pear_configure_tmp.log + with_items: + - pear config-set temp_dir /opt/misp-server/tmp/ > /home/misp/ansible/ansible_shell_pear_configure_tmp.log + +- name: Install CryptGPG + pear: + name: Crypt_GPG + state: present + +######### MISP REPOSITORY ######### + +- name: Clone MISP repository + become: true + become_user: misp + git: + repo: "https://github.com/MISP/MISP.git" + dest: "/opt/misp-server/misp" + recursive: yes + force: no + update: no + version: v2.4.49 + accept_hostkey: yes + +- name: Configure Git + git_config: + name: core.filemode + scope: global + value: false + +- name: Create scripts directories + file: + path: "{{ item }}" + owner: misp + group: misp-server + mode: 02775 + state: directory + with_items: + - "/opt/misp-server/misp/app/files/scripts/python-cybox" + - "/opt/misp-server/misp/app/files/scripts/python-stix" + +- name: Clone MISP depedencies | Python-Cybox + become: true + become_user: misp + git: + repo: "https://github.com/CybOXProject/python-cybox.git" + dest: "/opt/misp-server/misp/app/files/scripts/python-cybox" + force: no + update: no + version: v2.1.0.12 + accept_hostkey: yes + +- name: Clone MISP depedencies | Python-Stix + become: true + become_user: misp + git: + repo: "https://github.com/STIXProject/python-stix.git" + dest: "/opt/misp-server/misp/app/files/scripts/python-stix" + force: no + update: no + version: v1.1.1.4 + accept_hostkey: yes + +- name: Install MISP depedencies | Python-Cybox + become: true + shell: "{{ item }}" + args: + chdir: /opt/misp-server/misp/app/files/scripts/python-cybox + creates: /home/misp/ansible/ansible_shell_pythoncybox_setup.log + with_items: + - python setup.py install > /home/misp/ansible/ansible_shell_pythoncybox_setup.log + +- name: Install MISP depedencies | Python-Stix + become: true + shell: "{{ item }}" + args: + chdir: /opt/misp-server/misp/app/files/scripts/python-stix + creates: /home/misp/ansible/ansible_shell_pythonstix_setup.log + with_items: + - python setup.py install > /home/misp/ansible/ansible_shell_pythonstix_setup.log + +######### CAKE PHP ######### + +- name: Curl PHP installer + shell: "{{ item }}" + args: + chdir: /opt/misp-server/misp/app/ + creates: /home/misp/ansible/ansible_shell_curl_php.log + with_items: + - curl -s https://getcomposer.org/installer | php > /home/misp/ansible/ansible_shell_curl_php.log + +- name: Install COMPOSER in /bin + copy: + remote_src: True + src: /opt/misp-server/misp/app/composer.phar + dest: /usr/local/bin/composer + owner: root + group: root + mode: 0755 + +- name: Cake-resque installation + composer: + command: "require" + arguments: "kamisama/cake-resque:4.1.2" + working_dir: "/opt/misp-server/misp/app" + register: cakeresque_install + +- name: Vendor configure + composer: + command: "config" + arguments: "vendor-dir Vendor" + working_dir: "/opt/misp-server/misp/app" + when: cakeresque_install.changed + +- name: PHP composer install + composer: + command: "install" + arguments: "" + working_dir: "/opt/misp-server/misp/app" + +- name: Copy CakeResque config file + copy: + remote_src: True + src: /opt/misp-server/misp/INSTALL/setup/config.php + dest: /opt/misp-server/misp/app/Plugin/CakeResque/Config/config.php + force: yes + owner: misp + group: misp-server + mode: 0774 + +######### MISP CONFIGURATION ######### + +- name: Copy MISP configuration files + template: + src: "misp/config/{{item}}" + dest: "/opt/misp-server/misp/app/Config/{{item}}" + force: yes + owner: misp + group: misp-server + mode: 0774 + with_items: + - bootstrap.php + - config.php + - core.php + - database.php + +######### GNUPG ######### + +- name: Create the directory for GNUPG + file: + path: "/opt/misp-server/misp/.gnupg" + owner: misp + group: misp-server + mode: 0770 + state: directory + +######### MISP WORKERS ######### + +- name: Check MISP worker launcher permissions + file: + path: /opt/misp-server/misp/app/Console/worker/start.sh + owner: misp + group: misp-server + mode: 0764 + +- name: Check MISP worker autolaunch at boot + lineinfile: + state: present + dest: /etc/rc.local + insertbefore: "exit 0" + line: "sudo -u www-data bash /opt/misp-server/misp/app/Console/worker/start.sh" + +######### ADD-ON ######### + +- name: Install ZeroMQ + pip: + name: pyzmq + state: latest + +- name: Install Python client for Redis + pip: + name: redis + state: latest + +######### MYSQL CONFIGURATION ######### + +- name: MySQL | Create MISP database + become: true + mysql_db: + login_user: root + login_password: "{{ mysql_root_new_pass }}" + name: misp + state: present + register: mysql_init + +- name: MySQL | Create MISP user + become: true + mysql_user: + login_user: root + login_password: "{{ mysql_root_new_pass }}" + name: misp + password: "{{mysql_misp_password}}" + priv: "misp.*:ALL,GRANT" + state: present + register: mysql_init + +- name: MySQL | Create password file + template: + src: "mysql/{{item}}" + dest: "/home/misp/{{item}}" + force: no + owner: misp + group: misp + mode: 0600 + with_items: + - .my.cnf + +- name: MySQL | Create password file for root + template: + src: "mysql/{{item}}" + dest: "/root/{{item}}" + force: no + owner: root + group: root + mode: 0600 + with_items: + - .my.cnf + +- name: MySQL | Initialize MISP database + shell: "{{ item }}" + with_items: + - mysql -D misp < /opt/misp-server/misp/INSTALL/MYSQL.sql + when: mysql_init.changed + +######### PERMISSIONS ######### + +- name: Fix all files permissions + file: + path: /opt/misp-server/misp + recurse: yes + state: directory + mode: "g=u" + +############################################ +##### BACKUP #### +############################################ + +- name: Copy backup script + become: true + template: + src: misp/{{item}} + dest: /bin/{{item}} + mode: 0755 + with_items: + - misp_backup + when: enable_auto_backup == 'y' + +- name: Copy restore script + template: + src: misp/{{item}} + dest: /opt/misp-server/backup/{{item}} + mode: 0755 + owner: misp + group: misp + with_items: + - misp_backup + when: enable_auto_backup == 'y' + +- name: Create backup cronjob + become: true + become_user: misp + cron: + name: "misp backup cronjob" + minute: "0" + hour: "4" + job: "sh /bin/misp_backup" + when: enable_auto_backup == 'y' + diff --git a/roles/misp/templates/misp/config/bootstrap.php b/roles/misp/templates/misp/config/bootstrap.php new file mode 100755 index 0000000..fb393c2 --- /dev/null +++ b/roles/misp/templates/misp/config/bootstrap.php @@ -0,0 +1,164 @@ + 'File', //[required] + * 'duration'=> 3600, //[optional] + * 'probability'=> 100, //[optional] + * 'path' => CACHE, //[optional] use system tmp directory - remember to use absolute path + * 'prefix' => 'cake_', //[optional] prefix every cache file with this string + * 'lock' => false, //[optional] use file locking + * 'serialize' => true, // [optional] + * 'mask' => 0666, // [optional] permission mask to use when creating cache files + * )); + * + * APC (http://pecl.php.net/package/APC) + * + * Cache::config('default', array( + * 'engine' => 'Apc', //[required] + * 'duration'=> 3600, //[optional] + * 'probability'=> 100, //[optional] + * 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string + * )); + * + * Xcache (http://xcache.lighttpd.net/) + * + * Cache::config('default', array( + * 'engine' => 'Xcache', //[required] + * 'duration'=> 3600, //[optional] + * 'probability'=> 100, //[optional] + * 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string + * 'user' => 'user', //user from xcache.admin.user settings + * 'password' => 'password', //plaintext password (xcache.admin.pass) + * )); + * + * Memcache (http://memcached.org/) + * + * Cache::config('default', array( + * 'engine' => 'Memcache', //[required] + * 'duration'=> 3600, //[optional] + * 'probability'=> 100, //[optional] + * 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string + * 'servers' => array( + * '127.0.0.1:11211' // localhost, default port 11211 + * ), //[optional] + * 'persistent' => true, // [optional] set this to false for non-persistent connections + * 'compress' => false, // [optional] compress data in Memcache (slower, but uses less memory) + * )); + * + * Wincache (http://php.net/wincache) + * + * Cache::config('default', array( + * 'engine' => 'Wincache', //[required] + * 'duration'=> 3600, //[optional] + * 'probability'=> 100, //[optional] + * 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string + * )); + * + * Redis (http://http://redis.io/) + * + * Cache::config('default', array( + * 'engine' => 'Redis', //[required] + * 'duration'=> 3600, //[optional] + * 'probability'=> 100, //[optional] + * 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string + * 'server' => '127.0.0.1' // localhost + * 'port' => 6379 // default port 6379 + * 'timeout' => 0 // timeout in seconds, 0 = unlimited + * 'persistent' => true, // [optional] set this to false for non-persistent connections + * )); + */ +Cache::config('default', array('engine' => 'File')); +Configure::load('config'); + +if (!Configure::read('MISP.baseurl')) { + if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) { + if ($_SERVER['SERVER_PORT'] == 443) { + Configure::write('MISP.baseurl', sprintf('https://%s', $_SERVER['SERVER_ADDR'])); + } else { + Configure::write('MISP.baseurl', sprintf('https://%s:%d', $_SERVER['SERVER_ADDR'], $_SERVER['SERVER_PORT'])); + } + } else { + if ($_SERVER['SERVER_PORT'] == 80) { + Configure::write('MISP.baseurl', sprintf('http://%s', $_SERVER['SERVER_ADDR'])); + } else { + Configure::write('MISP.baseurl', sprintf('http://%s:%d', $_SERVER['SERVER_ADDR'], $_SERVER['SERVER_PORT'])); + } + } +} + +/** + * Plugins need to be loaded manually, you can either load them one by one or all of them in a single call + * Uncomment one of the lines below, as you need. make sure you read the documentation on CakePlugin to use more + * advanced ways of loading plugins + * + * CakePlugin::loadAll(); // Loads all plugins at once + * CakePlugin::load('DebugKit'); //Loads a single plugin named DebugKit + * + */ + +CakePlugin::load('SysLog'); +CakePlugin::load('Assets'); // having Logable +CakePlugin::load('SysLogLogable'); +CakePlugin::load('UrlCache'); + +/** + * Uncomment the following line to enable client SSL certificate authentication. + * It's also necessary to configure the plugin — for more information, please read app/Plugin/CertAuth/reame.md + */ +// CakePlugin::load('CertAuth'); + +/** + * You can attach event listeners to the request lifecyle as Dispatcher Filter . By Default CakePHP bundles two filters: + * + * - AssetDispatcher filter will serve your asset files (css, images, js, etc) from your themes and plugins + * - CacheDispatcher filter will read the Cache.check configure variable and try to serve cached content generated from controllers + * + * Feel free to remove or add filters as you see fit for your application. A few examples: + * + * Configure::write('Dispatcher.filters', array( + * 'MyCacheFilter', // will use MyCacheFilter class from the Routing/Filter package in your app. + * 'MyPlugin.MyFilter', // will use MyFilter class from the Routing/Filter package in MyPlugin plugin. + * array('callable' => $aFunction, 'on' => 'before', 'priority' => 9), // A valid PHP callback type to be called on beforeDispatch + * array('callable' => $anotherMethod, 'on' => 'after'), // A valid PHP callback type to be called on afterDispatch + * + * )); + */ +Configure::write('Dispatcher.filters', array( + 'AssetDispatcher', + 'CacheDispatcher' +)); + +/** + * Configures default file logging options + */ +App::uses('CakeLog', 'Log'); +CakeLog::config('debug', array( + 'engine' => 'FileLog', + 'types' => array('notice', 'info', 'debug'), + 'file' => 'debug', +)); +CakeLog::config('error', array( + 'engine' => 'FileLog', + 'types' => array('warning', 'error', 'critical', 'alert', 'emergency'), + 'file' => 'error', +)); + +// comment the following out if you do not with to use the background processing (not recommended) +CakePlugin::loadAll(array( + 'CakeResque' => array('bootstrap' => true) +)); diff --git a/roles/misp/templates/misp/config/config.php b/roles/misp/templates/misp/config/config.php new file mode 100644 index 0000000..d280c25 --- /dev/null +++ b/roles/misp/templates/misp/config/config.php @@ -0,0 +1,83 @@ + 0, + 'Security' => + array ( + 'level' => 'medium', + 'salt' => 'juFghZsg7128Eeyo '', + //'auth'=>array('CertAuth.Certificate'), // additional authentication methods + ), + 'MISP' => + array ( + 'baseurl' => 'https://{{servername}}', + 'footermidleft' => '', + 'footermidright' => '', + 'org' => '', + 'showorg' => true, + 'background_jobs' => true, + 'cached_attachments' => true, + 'email' => '', + 'contact' => '', + 'cveurl' => 'http://cve.circl.lu/cve/', + 'disablerestalert' => false, + 'default_event_distribution' => '1', + 'default_attribute_distribution' => 'event', + 'tagging' => true, + 'full_tags_on_event_index' => true, + 'footer_logo' => '', + 'take_ownership_xml_import' => false, + 'unpublishedprivate' => false, + 'disable_emailing' => false, + ), + 'GnuPG' => + array ( + 'onlyencrypted' => false, + 'email' => '', + 'homedir' => '/opt/misp-server/misp/.gnupg', + 'password' => '', + 'bodyonlyencrypted' => false, + ), + 'Proxy' => + array ( + 'host' => '{{proxy_host}}', + 'port' => '{{proxy_port}}', + 'method' => '', + 'user' => '', + 'password' => '', + ), + 'SecureAuth' => + array ( + 'amount' => 5, + 'expire' => 300, + ), + // Uncomment the following to enable client SSL certificate authentication + /* + 'CertAuth' => + array( + 'ca' => array( 'FIRST.Org' ), // allowed CAs + 'caId' => 'O', // which attribute will be used to verify the CA + 'userModel' => 'User', // name of the User class to check if user exists + 'userModelKey' => 'nids_sid', // User field that will be used for querying + 'map' => array( // maps client certificate attributes to User properties + 'O' => 'org', + 'emailAddress'=>'email', + ), + 'syncUser' => true, // should the User be synchronized with an external REST API + 'userDefaults'=> array( // default user attributes, only used when creating new users + 'role_id' => 4, + ), + 'restApi' => array( // API parameters + 'url' => 'https://example.com/data/users', // URL to query + 'headers' => array(), // additional headers, used for authentication + 'param' => array( 'email' => 'email'), // query parameters to add to the URL, mapped to USer properties + 'map' => array( // maps REST result to the User properties + 'uid' => 'nids_sid', + 'team' => 'org', + 'email' => 'email', + 'pgp_public'=> 'gpgkey', + ), + ), + ), + */ +); diff --git a/roles/misp/templates/misp/config/core.php b/roles/misp/templates/misp/config/core.php new file mode 100644 index 0000000..2194430 --- /dev/null +++ b/roles/misp/templates/misp/config/core.php @@ -0,0 +1,286 @@ + 0 + * and log errors with CakeLog when debug = 0. + * + * Options: + * + * - `handler` - callback - The callback to handle errors. You can set this to any callable type, + * including anonymous functions. + * - `level` - int - The level of errors you are interested in capturing. + * - `trace` - boolean - Include stack traces for errors in log files. + * + * @see ErrorHandler for more information on error handling and configuration. + */ + Configure::write('Error', array( + 'handler' => 'ErrorHandler::handleError', + 'level' => E_ALL & ~E_DEPRECATED, + 'trace' => true + )); + +/** + * Configure the Exception handler used for uncaught exceptions. By default, + * ErrorHandler::handleException() is used. It will display a HTML page for the exception, and + * while debug > 0, framework errors like Missing Controller will be displayed. When debug = 0, + * framework errors will be coerced into generic HTTP errors. + * + * Options: + * + * - `handler` - callback - The callback to handle exceptions. You can set this to any callback type, + * including anonymous functions. + * - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you + * should place the file for that class in app/Lib/Error. This class needs to implement a render method. + * - `log` - boolean - Should Exceptions be logged? + * + * @see ErrorHandler for more information on exception handling and configuration. + */ + Configure::write('Exception', array( + 'handler' => 'ErrorHandler::handleException', + 'renderer' => 'ExceptionRenderer', + 'log' => true, + 'skipLog' => array( + 'NotFoundException', + ) + )); + +/** + * Application wide charset encoding + */ + Configure::write('App.encoding', 'UTF-8'); + +/** + * To configure CakePHP *not* to use mod_rewrite and to + * use CakePHP pretty URLs, remove these .htaccess + * files: + * + * /.htaccess + * /app/.htaccess + * /app/webroot/.htaccess + * + * And uncomment the App.baseUrl below: + */ + //Configure::write('App.baseUrl', env('SCRIPT_NAME')); + +/** + * Uncomment the define below to use CakePHP prefix routes. + * + * The value of the define determines the names of the routes + * and their associated controller actions: + * + * Set to an array of prefixes you want to use in your application. Use for + * admin or other prefixed routes. + * + * Routing.prefixes = array('admin', 'manager'); + * + * Enables: + * `admin_index()` and `/admin/controller/index` + * `manager_index()` and `/manager/controller/index` + * + */ + Configure::write('Routing.prefixes', array('admin')); + +/** + * Turn off all caching application-wide. + * + */ + Configure::write('Cache.disable', false); + +/** + * Enable cache checking. + * + * If set to true, for view caching you must still use the controller + * public $cacheAction inside your controllers to define caching settings. + * You can either set it controller-wide by setting public $cacheAction = true, + * or in each action using $this->cacheAction = true. + * + */ + //Configure::write('Cache.check', true); + +/** + * Defines the default error type when using the log() function. Used for + * differentiating error logging and debugging. Currently PHP supports LOG_DEBUG. + */ + define('LOG_ERROR', LOG_ERR); + +/** + * Session configuration. + * + * Contains an array of settings to use for session configuration. The defaults key is + * used to define a default preset to use for sessions, any settings declared here will override + * the settings of the default config. + * + * ## Options + * + * - `Session.cookie` - The name of the cookie to use. Defaults to 'CAKEPHP' + * - `Session.timeout` - The number of minutes you want sessions to live for. This timeout is handled by CakePHP + * - `Session.cookieTimeout` - The number of minutes you want session cookies to live for. + * - `Session.checkAgent` - Do you want the user agent to be checked when starting sessions? You might want to set the + * value to false, when dealing with older versions of IE, Chrome Frame or certain web-browsing devices and AJAX + * - `Session.defaults` - The default configuration set to use as a basis for your session. + * There are four builtins: php, cake, cache, database. + * - `Session.handler` - Can be used to enable a custom session handler. Expects an array of of callables, + * that can be used with `session_save_handler`. Using this option will automatically add `session.save_handler` + * to the ini array. + * - `Session.autoRegenerate` - Enabling this setting, turns on automatic renewal of sessions, and + * sessionids that change frequently. See CakeSession::$requestCountdown. + * - `Session.ini` - An associative array of additional ini values to set. + * + * The built in defaults are: + * + * - 'php' - Uses settings defined in your php.ini. + * - 'cake' - Saves session files in CakePHP's /tmp directory. + * - 'database' - Uses CakePHP's database sessions. + * - 'cache' - Use the Cache class to save sessions. + * + * To define a custom session handler, save it at /app/Model/Datasource/Session/.php. + * Make sure the class implements `CakeSessionHandlerInterface` and set Session.handler to + * + * To use database sessions, run the app/Config/Schema/sessions.php schema using + * the cake shell command: cake schema create Sessions + * + */ + Configure::write('Session', array( + 'timeout' => 60, // Session timeout, default is 1 hour + 'defaults' => 'database' + )); + +/** + * The level of CakePHP security. + */ + Configure::write('Security.level', 'medium'); + +/** + * A random string used in security hashing methods. + */ + Configure::write('Security.salt', 'Rooraenietu8Eeyo 0. Set to 'force' to always enable + * timestamping regardless of debug value. + */ + //Configure::write('Asset.timestamp', true); + +/** + * Compress CSS output by removing comments, whitespace, repeating tags, etc. + * This requires a/var/cache directory to be writable by the web server for caching. + * and /vendors/csspp/csspp.php + * + * To use, prefix the CSS link URL with '/ccss/' instead of '/css/' or use HtmlHelper::css(). + */ + //Configure::write('Asset.filter.css', 'css.php'); + +/** + * Plug in your own custom JavaScript compressor by dropping a script in your webroot to handle the + * output, and setting the config below to the name of the script. + * + * To use, prefix your JavaScript link URLs with '/cjs/' instead of '/js/' or use JavaScriptHelper::link(). + */ + //Configure::write('Asset.filter.js', 'custom_javascript_output_filter.php'); + +/** + * The classname and database used in CakePHP's + * access control lists. + */ + Configure::write('Acl.classname', 'DbAcl'); + Configure::write('Acl.database', 'default'); + +/** + * Uncomment this line and correct your server timezone to fix + * any date & time related errors. + */ + //date_default_timezone_set('UTC'); + +/** + * Pick the caching engine to use. If APC is enabled use it. + * If running via cli - apc is disabled by default. ensure it's available and enabled in this case + * + * Note: 'default' and other application caches should be configured in app/Config/bootstrap.php. + * Please check the comments in boostrap.php for more info on the cache engines available + * and their setttings. + */ +$engine = 'File'; +if (extension_loaded('apc') && function_exists('apc_dec') && (php_sapi_name() !== 'cli' || ini_get('apc.enable_cli'))) { + $engine = 'Apc'; +} + +// In development mode, caches should expire quickly. +$duration = '+999 days'; +if (Configure::read('debug') >= 1) { + $duration = '+10 seconds'; +} + +// Prefix each application on the same server with a different string, to avoid Memcache and APC conflicts. +$prefix = 'myapp_'; + +/** + * Configure the cache used for general framework caching. Path information, + * object listings, and translation cache files are stored with this configuration. + */ +Cache::config('_cake_core_', array( + 'engine' => $engine, + 'prefix' => $prefix . 'cake_core_', + 'path' => CACHE . 'persistent' . DS, + 'serialize' => ($engine === 'File'), + 'duration' => $duration +)); + +/** + * Configure the cache for model and datasource caches. This cache configuration + * is used to store schema descriptions, and table listings in connections. + */ +Cache::config('_cake_model_', array( + 'engine' => $engine, + 'prefix' => $prefix . 'cake_model_', + 'path' => CACHE . 'models' . DS, + 'serialize' => ($engine === 'File'), + 'duration' => $duration +)); + + +//Comment the following out if you do not with to use the background workers (not recommended) +require_once dirname(__DIR__) . '/Vendor/autoload.php'; \ No newline at end of file diff --git a/roles/misp/templates/misp/config/database.php b/roles/misp/templates/misp/config/database.php new file mode 100644 index 0000000..67b0ab0 --- /dev/null +++ b/roles/misp/templates/misp/config/database.php @@ -0,0 +1,73 @@ + The name of a supported datasource; valid options are as follows: + * Database/Mysql - MySQL 4 & 5, + * Database/Sqlite - SQLite (PHP5 only), + * Database/Postgres - PostgreSQL 7 and higher, + * Database/Sqlserver - Microsoft SQL Server 2005 and higher + * + * You can add custom database datasources (or override existing datasources) by adding the + * appropriate file to app/Model/Datasource/Database. Datasources should be named 'MyDatasource.php', + * + * + * persistent => true / false + * Determines whether or not the database should use a persistent connection + * + * host => + * the host you connect to the database. To add a socket or port number, use 'port' => # + * + * prefix => + * Uses the given prefix for all the tables in this database. This setting can be overridden + * on a per-table basis with the Model::$tablePrefix property. + * + * schema => + * For Postgres specifies which schema you would like to use the tables in. Postgres defaults to 'public'. + * + * encoding => + * For MySQL, Postgres specifies the character encoding to use when connecting to the + * database. Uses database default not specified. + * + * unix_socket => + * For MySQL to connect via socket specify the `unix_socket` parameter instead of `host` and `port` + */ +class DATABASE_CONFIG { + + public $default = array( + 'datasource' => 'Database/Mysql', + 'persistent' => false, + 'host' => 'localhost', + 'login' => 'misp', + 'port' => 3306, + 'password' => '{{mysql_misp_password}}', + 'database' => 'misp', + 'prefix' => '', + //'encoding' => 'utf8', + ); +} diff --git a/roles/misp/templates/misp/misp_backup b/roles/misp/templates/misp/misp_backup new file mode 100644 index 0000000..48aed50 --- /dev/null +++ b/roles/misp/templates/misp/misp_backup @@ -0,0 +1,35 @@ +#!/bin/bash + +########################################### +####### MISP BACKUP SCRIPT ####### +########################################### + +TIMESTAMP=`date +%m%d%Y%H%M` +BACKUP_PATH='/opt/misp-server/backup' +BACKUP_DIR="$BACKUP_PATH/$TIMESTAMP" + +BACKUP_MYSQL_DIR="$BACKUP_DIR/mysql" +BACKUP_FILES_DIR="$BACKUP_DIR/misp" + +MISP_FILES="/opt/misp-server/misp/app/files" +MISP_CONF="/opt/misp-server/misp/app/Config" + +mkdir "$BACKUP_DIR" +mkdir "$BACKUP_MYSQL_DIR" +mkdir "$BACKUP_FILES_DIR" + +#### 1 | MYSQL #### +mysqldump -u misp --opt --single-transaction misp > "$BACKUP_MYSQL_DIR/mysql_dump.sql" + +#### 2 | CONFIGURATION FILES #### +cp -R $MISP_CONF $BACKUP_FILES_DIR + +#### 3 | FILES #### +cp -R $MISP_FILES $BACKUP_FILES_DIR + +cd $BACKUP_PATH +tar -cpzf ${TIMESTAMP}.tar.gz ./${TIMESTAMP} +rm -rf $BACKUP_DIR + +#### Remove old backups #### +find . -mtime +30 -exec rm {} \; diff --git a/roles/misp/templates/misp/misp_restore b/roles/misp/templates/misp/misp_restore new file mode 100644 index 0000000..19483dd --- /dev/null +++ b/roles/misp/templates/misp/misp_restore @@ -0,0 +1,45 @@ +#!/bin/bash + +########################################### +####### MISP RESTORE SCRIPT ####### +########################################### + +ARCHIVE=$1 +EXTRACTION=${ARCHIVE::-7} + +BACKUP_MYSQL_DUMP_FILE="./$EXTRACTION/mysql/mysql_dump.sql" +BACKUP_CONFIG_DIR="./$EXTRACTION/misp/Config/" +BACKUP_FILES_DIR="./$EXTRACTION/misp/files/" + +MISP_INSTALL_DIR="/opt/misp-server/misp/" +MISP_INSTALL_APP_DIR="$MISP_INSTALL_DIR/app/" + +MYSQL_USER="misp" +MYSQL_DATABASE="misp" + +echo "------ MISP RESTORE SCRIPT ------" + +#### 0 | OPEN BACKUP ARCHIVE #### +echo "*** Unpacking $1 ***" +tar -xf $ARCHIVE +echo "Done." + +#### 1 | RESTORE MYSQL #### +echo "*** Restoring MySQL misp database ***" +echo "Connecting to MySQL database:" +echo "database:$MYSQL_DATABASE" +echo "user:$MYSQL_USER" +mysql -u $MYSQL_USER -p $MYSQL_DATABASE < $BACKUP_MYSQL_DUMP_FILE +echo "Done." + +#### 2 | RESTORE CONFIGURATION FILES #### +echo "*** Restoring MISP configuration files ***" +cp -R $BACKUP_CONFIG_DIR $MISP_INSTALL_APP_DIR +echo "Done." + +#### 3 | RESTORE MISP FILES #### +echo "*** Restoring MISP files ***" +cp -R $BACKUP_FILES_DIR $MISP_INSTALL_APP_DIR +echo "Done." + +echo "------ COMPLETE ------" diff --git a/roles/misp/templates/mysql/.my.cnf b/roles/misp/templates/mysql/.my.cnf new file mode 100644 index 0000000..8434dae --- /dev/null +++ b/roles/misp/templates/mysql/.my.cnf @@ -0,0 +1,7 @@ +[client] +user=misp +password="{{mysql_misp_password}}" + +[mysqldump] +user=misp +password="{{mysql_misp_password}}" diff --git a/roles/misp/vars/main.yml b/roles/misp/vars/main.yml new file mode 100644 index 0000000..cd21505 --- /dev/null +++ b/roles/misp/vars/main.yml @@ -0,0 +1,2 @@ +--- + diff --git a/roles/mysql/defaults/main.yml b/roles/mysql/defaults/main.yml new file mode 100644 index 0000000..e0f3215 --- /dev/null +++ b/roles/mysql/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# default lower priority variables for this role diff --git a/roles/mysql/files/empty b/roles/mysql/files/empty new file mode 100644 index 0000000..e69de29 diff --git a/roles/mysql/handlers/main.yml b/roles/mysql/handlers/main.yml new file mode 100644 index 0000000..aa05cf0 --- /dev/null +++ b/roles/mysql/handlers/main.yml @@ -0,0 +1,3 @@ +--- +# Handlers file + diff --git a/roles/mysql/meta/main.yml b/roles/mysql/meta/main.yml new file mode 100644 index 0000000..526681f --- /dev/null +++ b/roles/mysql/meta/main.yml @@ -0,0 +1,2 @@ +--- +# Role dependancies diff --git a/roles/mysql/tasks/main.yml b/roles/mysql/tasks/main.yml new file mode 100644 index 0000000..b126022 --- /dev/null +++ b/roles/mysql/tasks/main.yml @@ -0,0 +1,45 @@ +--- + +- name: mysql-server - installation + apt: + pkg: mysql-server-5.6 + state: present + +- name: python-mysqldb - installation + apt: + pkg: python-mysqldb + state: present + +- name: MySQL - Update mysql root passwd + mysql_user: + name: root + host: "{{item}}" + password: "{{mysql_root_new_pass}}" + login_user: root + login_password: "{{mysql_root_old_pass}}" + with_items: + - "{{ansible_hostname}}" + - 127.0.0.1 + - ::1 + - localhost + when: mysql_root_new_pass != mysql_root_old_pass and + mysql_root_new_pass != "" + +- name: MySQL - Delete anonymous mysql user + mysql_user: + name: "" + state: absent + login_user: root + login_password: "{{mysql_root_new_pass}}" + +- name: MySQL - Remove mysql test database + mysql_db: + name: test + state: absent + login_user: root + login_password: "{{mysql_root_new_pass}}" + +- name: Restart MySQL + service: + name: mysql + state: restarted diff --git a/roles/mysql/vars/main.yml b/roles/mysql/vars/main.yml new file mode 100644 index 0000000..c6b6cdf --- /dev/null +++ b/roles/mysql/vars/main.yml @@ -0,0 +1,2 @@ +--- +# Variables associated with this role diff --git a/roles/nginx/defaults/main.yml b/roles/nginx/defaults/main.yml new file mode 100644 index 0000000..e0f3215 --- /dev/null +++ b/roles/nginx/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# default lower priority variables for this role diff --git a/roles/nginx/files/empty b/roles/nginx/files/empty new file mode 100644 index 0000000..e69de29 diff --git a/roles/nginx/handlers/main.yml b/roles/nginx/handlers/main.yml new file mode 100644 index 0000000..aa05cf0 --- /dev/null +++ b/roles/nginx/handlers/main.yml @@ -0,0 +1,3 @@ +--- +# Handlers file + diff --git a/roles/nginx/meta/main.yml b/roles/nginx/meta/main.yml new file mode 100644 index 0000000..526681f --- /dev/null +++ b/roles/nginx/meta/main.yml @@ -0,0 +1,2 @@ +--- +# Role dependancies diff --git a/roles/nginx/tasks/main.yml b/roles/nginx/tasks/main.yml new file mode 100644 index 0000000..f8cf18c --- /dev/null +++ b/roles/nginx/tasks/main.yml @@ -0,0 +1,59 @@ +--- + +- name: Install all needed packages + apt: + pkg: "{{ item }}" + state: latest + update_cache: yes + with_items: + - nginx + - php5-fpm + +######### WEB-SERVER CONFIGURATION ######### + +- name: Make NGINX SSL directory + file: + path: /etc/nginx/ssl + state: directory + owner: root + group: root + mode: 0644 + register: nginx_init + +- name: Remove default NGINX configuration + file: + path: /etc/nginx/{{item}} + state: absent + with_items: + - sites-enabled/default + - sites-available/default + register: nginx_init + +- name: Copy Nginx site configurations + template: + src: nginx/{{item}} + dest: /etc/nginx/sites-available/{{item}} + force: no + mode: 0644 + with_items: + - misp + register: nginx_init + +- name: Create NGINX configuration symlinks + file: + src: /etc/nginx/sites-available/{{item}} + dest: /etc/nginx/sites-enabled/{{item}} + state: link + with_items: + - misp + register: nginx_init + +- name: Create self-signed SSL certificate for Nginx + command: openssl req -new -nodes -x509 -subj "/C=XX/ST=AAAAAAA/L=BBBBBB/O=Organization/CN={{servername}}" -days 3650 -newkey rsa:4096 -keyout /etc/nginx/ssl/misp.key -out /etc/nginx/ssl/misp.crt + when: nginx_init.changed + +- name: Restart Nginx + service: + name: mysql + state: restarted + when: nginx_init.changed diff --git a/roles/nginx/templates/nginx/misp b/roles/nginx/templates/nginx/misp new file mode 100644 index 0000000..43f2337 --- /dev/null +++ b/roles/nginx/templates/nginx/misp @@ -0,0 +1,27 @@ +# MISP WEB SERVER CONFIGURATION +server { + server_name {{servername}}; + listen 443 ssl spdy; + + root /opt/misp-server/misp/app/webroot; + index index.php; + + # Configure Crypto Keys/Certificates/DH + ssl_certificate /etc/nginx/ssl/misp.crt; + ssl_certificate_key /etc/nginx/ssl/misp.key; + + # enable HSTS + add_header Strict-Transport-Security "max-age=15768000; includeSubdomains"; + add_header X-Frame-Options SAMEORIGIN; + + location / { + try_files $uri $uri/ /index.php; + } + + location ~ \.php$ { + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass unix:/var/run/php5-fpm.sock; + fastcgi_index index.php; + include fastcgi_params; + } +} diff --git a/roles/nginx/vars/main.yml b/roles/nginx/vars/main.yml new file mode 100644 index 0000000..c6b6cdf --- /dev/null +++ b/roles/nginx/vars/main.yml @@ -0,0 +1,2 @@ +--- +# Variables associated with this role diff --git a/ssh.cfg b/ssh.cfg new file mode 100644 index 0000000..139597f --- /dev/null +++ b/ssh.cfg @@ -0,0 +1,2 @@ + +