اتوماتیک کردن فرآیندهای امنیتی با استفاده از Ansible
اتومات کردن امنیت با Ansible
براساس تعریف ویکیپدیا، Ansible یک نرم افزار متن باز برای اتومات کردن فرآیندهای تولید ، مدیریت تنظیمات و استقرار نرم افزار میباشد. در اینجا هدف ما الهام گرفتن از ایده اصلی Ansible برای اتومات کردن فرآیندهای امنیت اطلاعات میباشد. در این راستا در ادامه از Ansible برای نصب، استقرار و انجام تنظیمات Snort استفاده میکنیم.
مقدمهای بر Ansible
انسیبل با توجه به ساختارش این امکان را میدهد که بتوانیم Task های امنیتی را به صورت ساختارمند و ماژولار و در فرمتی ساده اتومات کنیم. در انسیبل فرمتی که برای تعریف استفاده میشود YAML میباشد. در هنکام کار با انسیبل بیشتر با اصطلاحات زیر سرکار خواهیم داشت.
- Playbook: یک Playbook در معنای کلاسیک به معنی بازی تدافعی و تهاجمی در بازی فوتبال است. بازیکنان در این حالت لیستی از انواع بازیها یا طرحهای عملیاتی را به صورت یک لیست، معمولا به صورت دیاگرام نگه میدارند. در IT یک Playbook لیستی از مراحل یا ساختار پشت سرم هم و منظم از یک فرآیند IT میباشد.
- Ansibel modules: ماژولها در انسیبل در واقع کتابخانههایی هستند که در هاست راه دور توسط Task ها برای انجام وظایف تعریف شده فراخوانی میشوند.
- YAML: درواقع YAML زبان نشانه گذاری برای نوشتن Playbook ها میباشد. این زبان به دلیل سادگی برای افرا بیشتر قابل درک میباشد.
- Roles: در حالی که Playbook ها راهی مناسب برای اجرای وظایف به صورت منظم میباشند با این وجود Role ها ویژگی منحصر به فردی برای دسته بندی Task ها میباشد که از منابعی مانند Asset ها و Template ها نیز پشتیبانی میکند. Role ها در انسیبل نقشی مشابه include در برنامه نویسی دارند. علاوه بر این استفاده از Role ها امکان استفاده مجدد از کدها را نیز فرآهم میکند.
- name: LAMP stack setup on ubuntu 20.04
hosts: all
gather_facts: False
remote_user: "{{remote_username}}"
become: yes
roles:
- common
- web
- db
- php
- Templates
نصب Snort3 با استفاده از Ansible
در ادامه برای درک بهتر ساختار انسیبل قصد داریم Snort3 را بر روی Ubuntu20.04 با استفاده از Ansible نصب و تنظیم نماییم. همانطور که در پست مربوط به نصب Snort3 بر روری Ubuntu20.04 دیدیم نصب اسنورت را میتوانیم به دو بخش زیر تقسیم کنیم.
- نصب پکیچها
- انجام تنظیمات
نصب پیش نیازهای لازم برای Snort3
برای شروع با استفاده از Playbook های زیر پیش نیازهای لازم را نصب میکنیم.
- name: installing basic packages
apt:
name: "{{ item }}"
state: present
update_cache: yes
with_items:
- liblzma-dev
- openssl
- libssl-dev
- cpputest
- libsqlite3-dev
- uuid-dev
- cmake
- libhwloc-dev
- pkg-config
- zlib1g-dev
- libpcap-dev
- libluajit-5.1-dev
- libdumbnet-dev
- autotools-dev
- build-essential
- pacemaker
- pcs
- asciidoc
- dblatex
- source-highlight
- w3m
- libtool
- git
- autoconf
- bison
- flex
- libcmocka-dev
- libnetfilter-queue-dev
- libmnl-dev
- libunwind-dev
نصب پیش نیازهای Snort DAQ (کتابخانه جمعآوری داده)
- name: create directory for snort installtion tarballs
file:
path: /home/ansible1/snort
state: directory
- name: copying Tarballs
copy:
src: /home/ansible1/snort/{{ item }}
dest: /home/ansible1/snort/
owner: ansible1
group: ansible1
remote_src: false
with_items:
- libsafec.tar.gz
- ragel-6.10.tar.gz
- pcre-8.43.tar.gz
- gperftools-2.7.90.tar.gz
- boost_1_72_0.tar.gz
- v5.2.1.tar.gz
- flatbuffers-v1.12.0.tar.gz
- name: unarchive Tarball files
unarchive:
src: /home/ansible1/snort/{{ item }}
dest: /home/ansible1/snort/
owner: ansible1
group: ansible1
remote_src: true
with_items:
- libsafec.tar.gz
- ragel-6.10.tar.gz
- pcre-8.43.tar.gz
- gperftools-2.7.90.tar.gz
- boost_1_72_0.tar.gz
- v5.2.1.tar.gz
- flatbuffers-v1.12.0.tar.gz
- name: Configure the libsafec tarball
shell: chdir=/home/ansible1/snort/{{item}} ./configure
with_items:
- libsafec-08112019.0-gad76c7
- ragel-6.10
- pcre-8.43
- gperftools-2.7.90
- name: make the libsafec tarball
shell: chdir=/home/ansible1/snort/{{item}} make
with_items:
- libsafec-08112019.0-gad76c7
- ragel-6.10
- pcre-8.43
- gperftools-2.7.90
- name: Install the libsafec tarball
become: true
shell: chdir=/home/ansible1/snort/{{item}} make install
with_items:
- libsafec-08112019.0-gad76c7
- ragel-6.10
- pcre-8.43
- gperftools-2.7.90
- name: create directory for hyperscan-5.2.1-build
file:
path: /home/ansible1/snort/hyperscan-5.2.1-build
state: directory
- name: Configure the Hayperscan tarball
shell: chdir=/home/ansible1/snort/hyperscan-5.2.1-build cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DBOOST_ROOT=/home/ansible1/snort/boost_1_72_0/ ../hyperscan-5.2.1
- name: make the Hayperscan tarball
shell: chdir=/home/ansible1/snort/hyperscan-5.2.1-build make
- name: make install the Hayperscan tarball
become: true
shell: chdir=/home/ansible1/snort/hyperscan-5.2.1-build make install
- name: create directory for flatbuffers-build
file:
path: /home/ansible1/snort/flatbuffers-build
state: directory
- name: Configure the flatbuffers tarball
shell: chdir=/home/ansible1/snort/flatbuffers-build cmake ../flatbuffers-1.12.0
- name: make the flatbuffers tarball
shell: chdir=/home/ansible1/snort/flatbuffers-build make
- name: make install the flatbuffers tarball
become: true
shell: chdir=/home/ansible1/snort/flatbuffers-build make install
- name: Cloning Snort3 from git repo
ansible.builtin.git:
repo: https://github.com/snort3/snort3.git
dest: /home/ansible1/snort/snort3/
accept_hostkey: yes
force: yes
version: master
- name: Cloning libdaq from git repo
ansible.builtin.git:
repo: https://github.com/snort3/libdaq.git
dest: /home/ansible1/snort/libdaq/
accept_hostkey: yes
force: yes
version: master
- name: Configure the libdaq tarball
shell: chdir=/home/ansible1/snort/libdaq ./bootstrap
- name: Configure the libdaq tarball
shell: chdir=/home/ansible1/snort/libdaq ./configure
- name: make the libdaq tarball
shell: chdir=/home/ansible1/snort/libdaq make
- name: make install the libdaq tarball
become: true
shell: chdir=/home/ansible1/snort/libdaq make install
- name: load the libdaq module to kernel
become: true
shell: ldconfig
- name: Build the Snort3
shell: chdir=/home/ansible1/snort/snort3 ./configure_cmake.sh --prefix=/usr/local --enable-tcmalloc
- name: make the Snort3
shell: chdir=/home/ansible1/snort/snort3/build make
- name: make install the Snort3
become: true
shell: chdir=/home/ansible1/snort/snort3/build make install
انجام تنظیمات کارت شبکههای سرور
- name: install Snort packages
hosts: Snortservers
remote_user: ansible1
tasks:
- name: Get mac addresses of all interfaces except local
set_fact: result1="{{ ansible_interfaces | difference(['lo']) | map('regex_replace', '^(.*)$', 'ansible_\\1' ) | map('extract', hostvars[inventory_hostname], 'macaddress') | list }}"
- name: show result1
debug:
msg: "{{ item }}"
with_items: "{{ result1 }}"
- name: copy interfaces IPConfig file
become: true
template:
src: 00-Interfaces-IP-Config.yaml
dest: /etc/netplan/00-Interfaces-IP-Config.yaml
- name: copy interfaces config file
become: true
template:
src: 00-persistent-net.link
dest: /lib/systemd/network/0{{my_idx}}-persistent-net.link
loop_control:
index_var: my_idx
with_items: "{{ result1 }}"
- name: changing interfaces mac address
ansible.builtin.replace:
path: /lib/systemd/network/0{{my_idx}}-persistent-net.link
regexp: "^MACAddress=.*"
replace: "MACAddress={{ item }}"
loop_control:
index_var: my_idx
with_items: "{{ result1 }}"
- name: changing interface name to eth0
ansible.builtin.replace:
path: /lib/systemd/network/0{{my_idx}}-persistent-net.link
regexp: "^Name=.*"
replace: "Name=eth{{my_idx}}"
loop_control:
index_var: my_idx
with_items: "{{ result1 }}"
ایجاد اسکریپت SystemD
- name: install Snort packages
hosts: Snortservers
remote_user: ansible1
tasks:
- name: add snort group
become: true
shell: groupadd snort
ignore_errors: yes
- name: add snort user
become: true
shell: useradd snort -r -s /sbin/nologin -c SNORT_IDS -g snort
ignore_errors: yes
- name:
become: true
template:
src: ethtool.conf
dest: /lib/systemd/system/ethtool.service
owner: root
group: root
mode: 0644
- name: enable ethtool on startup
become: true
systemd:
name: ethtool.service
enabled: yes
- name: Restart service ethtool, in all cases
ansible.builtin.service:
name: ethtool
state: restarted
- name:
become: true
template:
src: snort3.conf
dest: /lib/systemd/system/snort3.service
owner: root
group: root
mode: 0644
- name: enable snort3 on startup
become: true
systemd:
name: snort3.service
enabled: yes
- name: Restart service snort3, in all cases
ansible.builtin.service:
name: snort3
state: restarted
نصب مجموعه قوانین Snort
- name: setup snort rules
hosts: Snortservers
remote_user: ansible1
become: True
become_method: sudo
become_user: root
tasks:
- name: OpenAppId
copy:
src: /home/ansible1/snort/OpenAppId-21442.tar.gz
dest: /home/ansible1/snort/
owner: ansible1
group: ansible1
remote_src: false
- name: unarchive Tarball files
unarchive:
src: /home/ansible1/snort/OpenAppId-21442.tar.gz
dest: /home/ansible1/snort/
owner: ansible1
group: ansible1
remote_src: true
- name: Copy OpenAppId
copy:
src: /home/ansible1/snort/odp
dest: /usr/local/lib/
owner: ansible1
group: ansible1
remote_src: true
- name: create rules folders
file:
path: /usr/local/etc/{{item}}
state: directory
owner: root
group: root
mode: 5755
with_items:
- rules
- builtin_rules
- so_rules
- lists
- name: copying Snort config files
copy:
src: /home/ansible1/snort/{{item}}
dest: /usr/local/etc/snort
with_items:
- snort.lua
- snort_defaults.lua
- name: copying Snort rules
copy:
src: /home/ansible1/snort/snortrules-snapshot-3000.tar.gz
dest: /home/ansible1/snort/
owner: ansible1
group: ansible1
remote_src: false
- name: copying Snort rules
copy:
src: /usr/local/etc/snort/file_magic.lua
dest: /usr/local/etc/snort/
remote_src: false
- name: unarchive rules
unarchive:
src: /home/ansible1/snort/snortrules-snapshot-3000.tar.gz
dest: /usr/local/etc/
owner: root
group: root
remote_src: true
- name:
copy:
dest: /usr/local/etc/rules/local.rules
mode: 777
owner: ansible1
group: ansible1
content: |
alert tcp any any -> any any ( msg:"Facebook Detected"; appids:"Facebook";sid:10000001; )
alert icmp any any -> any any (msg:"ICMP Traffic Detected";sid:10000002; )
- name: Explicitly specifying named matched groups
ansible.builtin.replace:
path: /usr/local/etc/snort/snort.lua
regexp: "^HOME_NET = 192.168.21.0"
replace: "HOME_NET = '192.168.21.0/24'"
- name: Explicitly specifying named matched groups
ansible.builtin.replace:
path: /usr/local/etc/snort/snort.lua
regexp: "^HOME_NET = 192.168.21.0|^HOME_NET = 'any'"
replace: "HOME_NET = '192.168.21.0/24'"
- name: Print Snort service status
shell: service snort3 status
register: Snort_Status
- ansible.builtin.debug:
msg:
- "Provisioning based on YOUR_KEY which is: {{ lookup('dict', Snort_Status) }}"
- debug:
msg: "{{ item.key.stdout | regex_search('Active:\\s\\w{6}\\s.{9}') }}"
loop: "{{ lookup('dict', Snort_Status) }}"
when: "'(running)' in item.key"
- debug:
msg: "System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}"
- debug:
msg: "System {{ inventory_hostname }} has gateway {{ ansible_default_ipv4.gateway }}"
when: ansible_default_ipv4.gateway is defined
- shell: /usr/bin/uptime
register: result
- debug:
msg: result
verbosity: 2
- name: Display all variables/facts known for a host
debug:
msg: hostvars[inventory_hostname]
verbosity: 4
تنظیمات مسیر لاگ اسنورت
- name: setup snort log folder
hosts: Snortservers
remote_user: ansible1
tasks:
- name: create log folder
file:
path: /var/log/snort
state: directory
owner: snort
group: snort
mode: 5755